1 This file is type.def, from which is created type.c.
2 It implements the builtin "type" in Bash.
4 Copyright (C) 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
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 2, or (at your option) any later
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
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, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
25 $FUNCTION type_builtin
26 $SHORT_DOC type [-apt] name [name ...]
27 For each NAME, indicate how it would be interpreted if used as a
30 If the -t option is used, `type' outputs 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.
35 If the -p flag is used, `type' either returns the name of the disk
36 file that would be executed, or nothing if `type -t NAME' would not
39 If the -a flag is used, `type' displays all of the places that contain
40 an executable named `file'. This includes aliases and functions, if
41 and only if the -p flag is not also used.
46 #include "../bashtypes.h"
47 #include "posixstat.h"
49 #if defined (HAVE_UNISTD_H)
54 #include "../bashansi.h"
57 #include "../findcmd.h"
58 #include "../hashcmd.h"
65 #include "bashgetopt.h"
67 extern int find_reserved_word ();
69 extern char *this_command_name;
71 /* For each word in LIST, find out what the shell is going to do with
72 it as a simple command. i.e., which file would this shell use to
73 execve, or if it is a builtin command, or an alias. Possible flag
75 -t Returns the "type" of the object, one of
76 `alias', `keyword', `function', `builtin',
79 -p Returns the pathname of the file if -type is
82 -a Returns all occurrences of words, whether they
83 be a filename in the path, alias, function,
97 int path_only, type_only, all, verbose;
98 int successful_finds, opt;
99 WORD_LIST *prev, *this;
102 return (EXECUTION_SUCCESS);
104 path_only = type_only = all = 0;
105 successful_finds = 0;
107 /* Handle the obsolescent `-type', `-path', and `-all' by prescanning
108 the arguments and removing those options from the list before calling
109 internal_getopt. Recognize `--type', `--path', and `--all' also.
110 THIS SHOULD REALLY GO AWAY. */
111 for (this = list; this && this->word->word[0] == '-'; )
113 char *flag = &(this->word->word[1]);
115 if (STREQ (flag, "type") || STREQ (flag, "-type"))
120 else if (STREQ (flag, "path") || STREQ (flag, "-path"))
125 else if (STREQ (flag, "all") || STREQ (flag, "-all"))
134 /* We found a long option; remove it from the argument list. Don't
135 free it if it's the head of the argument list, though -- the
136 argument list will be freed by the caller. */
138 this = list = list->next;
141 prev->next = this->next;
142 this->next = (WORD_LIST *)NULL;
143 dispose_words (this);
148 reset_internal_getopt ();
149 while ((opt = internal_getopt (list, "apt")) != -1)
173 else if (path_only == 0)
184 found = describe_command (list->word->word, verbose, all);
186 if (!found && !path_only && !type_only)
187 builtin_error ("%s: not found", list->word->word);
189 successful_finds += found;
195 return ((successful_finds != 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
199 * Describe COMMAND as required by the type builtin.
201 * If VERBOSE == 0, don't print anything
202 * If VERBOSE == 1, print short description as for `type -t'
203 * If VERBOSE == 2, print long description as for `type' and `command -V'
204 * If VERBOSE == 3, print path name only for disk files
205 * If VERBOSE == 4, print string used to invoke COMMAND, for `command -v'
207 * ALL says whether or not to look for all occurrences of COMMAND, or
208 * return after finding it once.
211 describe_command (command, verbose, all)
215 int found, i, found_file, f;
216 char *full_path, *x, *cwd;
222 found = found_file = 0;
223 full_path = (char *)NULL;
226 /* Command is an alias? */
227 alias = find_alias (command);
233 else if (verbose == 2)
234 printf ("%s is aliased to `%s'\n", command, alias->value);
235 else if (verbose == 4)
237 x = sh_single_quote (alias->value);
238 printf ("alias %s=%s\n", command, x);
249 /* Command is a shell reserved word? */
250 i = find_reserved_word (command);
255 else if (verbose == 2)
256 printf ("%s is a shell keyword\n", command);
257 else if (verbose == 4)
258 printf ("%s\n", command);
266 /* Command is a function? */
267 func = find_function (command);
273 else if (verbose == 2)
275 #define PRETTY_PRINT_FUNC 1
278 printf ("%s is a function\n", command);
280 /* We're blowing away THE_PRINTED_COMMAND here... */
282 result = named_function_string (command,
283 (COMMAND *) function_cell (func),
285 printf ("%s\n", result);
286 #undef PRETTY_PRINT_FUNC
288 else if (verbose == 4)
289 printf ("%s\n", command);
297 /* Command is a builtin? */
298 if (find_shell_builtin (command))
302 else if (verbose == 2)
303 printf ("%s is a shell builtin\n", command);
304 else if (verbose == 4)
305 printf ("%s\n", command);
313 /* Command is a disk file? */
314 /* If the command name given is already an absolute command, just
315 check to see if it is executable. */
316 if (absolute_program (command))
318 f = file_status (command);
323 else if (verbose == 2)
324 printf ("%s is %s\n", command, command);
325 else if (verbose == 3 || verbose == 4)
326 printf ("%s\n", command);
328 /* There's no use looking in the hash table or in $PATH,
329 because they're not consulted when an absolute program
335 /* If the user isn't doing "-a", then we might care about
336 whether the file is present in our hash table. */
339 if ((full_path = find_hashed_filename (command)) != (char *)NULL)
343 else if (verbose == 2)
344 printf ("%s is hashed (%s)\n", command, full_path);
345 else if (verbose == 3 || verbose == 4)
346 printf ("%s\n", full_path);
353 /* Now search through $PATH. */
357 full_path = find_user_command (command);
360 user_command_matches (command, FS_EXEC_ONLY, found_file);
361 /* XXX - should that be FS_EXEC_PREFERRED? */
366 /* If we found the command as itself by looking through $PATH, it
367 probably doesn't exist. Check whether or not the command is an
368 executable file. If it's not, don't report a match. */
369 if (STREQ (full_path, command))
371 f = file_status (full_path);
372 if ((f & FS_EXECABLE) == 0)
375 full_path = (char *)NULL;
379 else if (verbose >= 2)
380 full_path = sh_makepath ((char *)NULL, full_path, MP_DOCWD);
388 else if (verbose == 2)
389 printf ("%s is %s\n", command, full_path);
390 else if (verbose == 3 || verbose == 4)
391 printf ("%s\n", full_path);
394 full_path = (char *)NULL;