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