]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/type.def
Imported from ../bash-2.02.tar.gz.
[thirdparty/bash.git] / builtins / type.def
CommitLineData
726f6388
JA
1This file is type.def, from which is created type.c.
2It implements the builtin "type" in Bash.
3
4Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 1, or (at your option) any later
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
20Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22$PRODUCES type.c
23
24$BUILTIN type
25$FUNCTION type_builtin
ccc6cda3 26$SHORT_DOC type [-apt] name [name ...]
726f6388
JA
27For each NAME, indicate how it would be interpreted if used as a
28command name.
29
cce855bc 30If the -t option is used, `type' outputs a single word which is one of
726f6388
JA
31`alias', `keyword', `function', `builtin', `file' or `', if NAME is an
32alias, shell reserved word, shell function, shell builtin, disk file,
33or unfound, respectively.
34
cce855bc
JA
35If the -p flag is used, `type' either returns the name of the disk
36file that would be executed, or nothing if `type -t NAME' would not
37return `file'.
726f6388 38
cce855bc
JA
39If the -a flag is used, `type' displays all of the places that contain
40an executable named `file'. This includes aliases and functions, if
41and only if the -p flag is not also used.
726f6388
JA
42$END
43
ccc6cda3
JA
44#include <config.h>
45
46#include "../bashtypes.h"
726f6388 47#include "../posixstat.h"
ccc6cda3
JA
48
49#if defined (HAVE_UNISTD_H)
50# include <unistd.h>
51#endif
52
53#include <stdio.h>
54#include "../bashansi.h"
55
726f6388 56#include "../shell.h"
cce855bc 57#include "../findcmd.h"
d166f048 58#include "../hashcmd.h"
726f6388
JA
59
60#if defined (ALIAS)
61#include "../alias.h"
62#endif /* ALIAS */
63
64#include "common.h"
65
ccc6cda3 66extern int find_reserved_word ();
726f6388
JA
67
68/* For each word in LIST, find out what the shell is going to do with
69 it as a simple command. i.e., which file would this shell use to
70 execve, or if it is a builtin command, or an alias. Possible flag
71 arguments:
72 -type Returns the "type" of the object, one of
73 `alias', `keyword', `function', `builtin',
74 or `file'.
75
76 -path Returns the pathname of the file if -type is
77 a file.
78
79 -all Returns all occurrences of words, whether they
80 be a filename in the path, alias, function,
81 or builtin.
82 Order of evaluation:
83 alias
84 keyword
85 function
86 builtin
87 file
88 */
ccc6cda3 89int
726f6388
JA
90type_builtin (list)
91 WORD_LIST *list;
92{
93 int path_only, type_only, all, verbose;
94 int successful_finds;
95
ccc6cda3
JA
96 if (list == 0)
97 return (EXECUTION_SUCCESS);
98
726f6388
JA
99 path_only = type_only = all = 0;
100 successful_finds = 0;
101
726f6388
JA
102 while (list && *(list->word->word) == '-')
103 {
104 char *flag = &(list->word->word[1]);
105
106 if (flag[0] == 't' && (!flag[1] || strcmp (flag + 1, "ype") == 0))
107 {
108 type_only = 1;
109 path_only = 0;
110 }
111 else if (flag[0] == 'p' && (!flag[1] || strcmp (flag + 1, "ath") == 0))
112 {
113 path_only = 1;
114 type_only = 0;
115 }
116 else if (flag[0] == 'a' && (!flag[1] || strcmp (flag + 1, "ll") == 0))
117 {
118 all = 1;
119 }
120 else
121 {
122 bad_option (flag);
ccc6cda3 123 builtin_usage ();
726f6388
JA
124 return (EX_USAGE);
125 }
126 list = list->next;
127 }
128
129 if (type_only)
130 verbose = 1;
ccc6cda3 131 else if (path_only == 0)
726f6388
JA
132 verbose = 2;
133 else if (path_only)
134 verbose = 3;
135 else
136 verbose = 0;
137
138 while (list)
139 {
140 int found;
141
142 found = describe_command (list->word->word, verbose, all);
143
144 if (!found && !path_only && !type_only)
145 builtin_error ("%s: not found", list->word->word);
146
147 successful_finds += found;
148 list = list->next;
149 }
150
151 fflush (stdout);
152
153 if (successful_finds != 0)
154 return (EXECUTION_SUCCESS);
155 else
156 return (EXECUTION_FAILURE);
157}
158
159/*
160 * Describe COMMAND as required by the type builtin.
161 *
162 * If VERBOSE == 0, don't print anything
163 * If VERBOSE == 1, print short description as for `type -t'
164 * If VERBOSE == 2, print long description as for `type' and `command -V'
165 * If VERBOSE == 3, print path name only for disk files
166 * If VERBOSE == 4, print string used to invoke COMMAND, for `command -v'
167 *
168 * ALL says whether or not to look for all occurrences of COMMAND, or
169 * return after finding it once.
170 */
ccc6cda3 171int
726f6388
JA
172describe_command (command, verbose, all)
173 char *command;
174 int verbose, all;
175{
ccc6cda3
JA
176 int found, i, found_file;
177 char *full_path;
726f6388 178 SHELL_VAR *func;
ccc6cda3
JA
179#if defined (ALIAS)
180 alias_t *alias;
181#endif
182
183 found = found_file = 0;
184 full_path = (char *)NULL;
726f6388
JA
185
186#if defined (ALIAS)
187 /* Command is an alias? */
ccc6cda3 188 alias = find_alias (command);
726f6388
JA
189
190 if (alias)
191 {
192 if (verbose == 1)
ccc6cda3 193 puts ("alias");
726f6388
JA
194 else if (verbose == 2)
195 printf ("%s is aliased to `%s'\n", command, alias->value);
196 else if (verbose == 4)
197 {
198 char *x = single_quote (alias->value);
199 printf ("alias %s=%s\n", command, x);
200 free (x);
201 }
202
203 found = 1;
204
205 if (!all)
206 return (1);
207 }
208#endif /* ALIAS */
209
210 /* Command is a shell reserved word? */
211 i = find_reserved_word (command);
212 if (i >= 0)
213 {
214 if (verbose == 1)
ccc6cda3 215 puts ("keyword");
726f6388
JA
216 else if (verbose == 2)
217 printf ("%s is a shell keyword\n", command);
218 else if (verbose == 4)
219 printf ("%s\n", command);
220
221 found = 1;
222
223 if (!all)
224 return (1);
225 }
226
227 /* Command is a function? */
228 func = find_function (command);
229
230 if (func)
231 {
232 if (verbose == 1)
ccc6cda3 233 puts ("function");
726f6388
JA
234 else if (verbose == 2)
235 {
236#define PRETTY_PRINT_FUNC 1
237 char *result;
238
239 printf ("%s is a function\n", command);
240
241 /* We're blowing away THE_PRINTED_COMMAND here... */
242
243 result = named_function_string (command,
244 (COMMAND *) function_cell (func),
245 PRETTY_PRINT_FUNC);
246 printf ("%s\n", result);
247#undef PRETTY_PRINT_FUNC
248 }
249 else if (verbose == 4)
250 printf ("%s\n", command);
251
252 found = 1;
253
254 if (!all)
255 return (1);
256 }
257
258 /* Command is a builtin? */
259 if (find_shell_builtin (command))
260 {
261 if (verbose == 1)
ccc6cda3 262 puts ("builtin");
726f6388
JA
263 else if (verbose == 2)
264 printf ("%s is a shell builtin\n", command);
265 else if (verbose == 4)
266 printf ("%s\n", command);
267
268 found = 1;
269
270 if (!all)
271 return (1);
272 }
273
274 /* Command is a disk file? */
275 /* If the command name given is already an absolute command, just
276 check to see if it is executable. */
277 if (absolute_program (command))
278 {
279 int f = file_status (command);
280 if (f & FS_EXECABLE)
281 {
282 if (verbose == 1)
ccc6cda3 283 puts ("file");
726f6388
JA
284 else if (verbose == 2)
285 printf ("%s is %s\n", command, command);
286 else if (verbose == 3 || verbose == 4)
287 printf ("%s\n", command);
288
289 /* There's no use looking in the hash table or in $PATH,
290 because they're not consulted when an absolute program
291 name is supplied. */
292 return (1);
293 }
294 }
295
296 /* If the user isn't doing "-all", then we might care about
297 whether the file is present in our hash table. */
298 if (!all)
299 {
300 if ((full_path = find_hashed_filename (command)) != (char *)NULL)
301 {
302 if (verbose == 1)
ccc6cda3 303 puts ("file");
726f6388
JA
304 else if (verbose == 2)
305 printf ("%s is hashed (%s)\n", command, full_path);
306 else if (verbose == 3 || verbose == 4)
307 printf ("%s\n", full_path);
308
d166f048 309 free (full_path);
726f6388
JA
310 return (1);
311 }
312 }
313
314 /* Now search through $PATH. */
315 while (1)
316 {
317 if (!all)
318 full_path = find_user_command (command);
319 else
320 full_path =
321 user_command_matches (command, FS_EXEC_ONLY, found_file);
322 /* XXX - should that be FS_EXEC_PREFERRED? */
323
324 if (!full_path)
325 break;
326
327 found_file++;
328 found = 1;
329
330 if (verbose == 1)
ccc6cda3 331 puts ("file");
726f6388
JA
332 else if (verbose == 2)
333 printf ("%s is %s\n", command, full_path);
334 else if (verbose == 3 || verbose == 4)
335 printf ("%s\n", full_path);
336
337 free (full_path);
338 full_path = (char *)NULL;
339
340 if (!all)
341 break;
342 }
343
344 return (found);
345}