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