Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 1, or (at your option) any later
+Software Foundation; either version 2, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
$PRODUCES type.c
#include <config.h>
#include "../bashtypes.h"
-#include "../posixstat.h"
+#include "posixstat.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* ALIAS */
#include "common.h"
+#include "bashgetopt.h"
extern int find_reserved_word ();
+extern char *this_command_name;
+
/* For each word in LIST, find out what the shell is going to do with
it as a simple command. i.e., which file would this shell use to
execve, or if it is a builtin command, or an alias. Possible flag
arguments:
- -type Returns the "type" of the object, one of
+ -t Returns the "type" of the object, one of
`alias', `keyword', `function', `builtin',
or `file'.
- -path Returns the pathname of the file if -type is
+ -p Returns the pathname of the file if -type is
a file.
- -all Returns all occurrences of words, whether they
+ -a Returns all occurrences of words, whether they
be a filename in the path, alias, function,
or builtin.
Order of evaluation:
builtin
file
*/
+
int
type_builtin (list)
WORD_LIST *list;
{
int path_only, type_only, all, verbose;
- int successful_finds;
+ int successful_finds, opt;
+ WORD_LIST *prev, *this;
if (list == 0)
return (EXECUTION_SUCCESS);
path_only = type_only = all = 0;
successful_finds = 0;
- while (list && *(list->word->word) == '-')
+ /* Handle the obsolescent `-type', `-path', and `-all' by prescanning
+ the arguments and removing those options from the list before calling
+ internal_getopt. Recognize `--type', `--path', and `--all' also.
+ THIS SHOULD REALLY GO AWAY. */
+ for (this = list; this && this->word->word[0] == '-'; )
{
- char *flag = &(list->word->word[1]);
+ char *flag = &(this->word->word[1]);
- if (flag[0] == 't' && (!flag[1] || strcmp (flag + 1, "ype") == 0))
+ if (STREQ (flag, "type") || STREQ (flag, "-type"))
{
type_only = 1;
path_only = 0;
}
- else if (flag[0] == 'p' && (!flag[1] || strcmp (flag + 1, "ath") == 0))
+ else if (STREQ (flag, "path") || STREQ (flag, "-path"))
{
path_only = 1;
type_only = 0;
}
- else if (flag[0] == 'a' && (!flag[1] || strcmp (flag + 1, "ll") == 0))
+ else if (STREQ (flag, "all") || STREQ (flag, "-all"))
+ all = 1;
+ else
{
- all = 1;
+ prev = this;
+ this = this->next;
+ continue;
}
+
+ /* We found a long option; remove it from the argument list. Don't
+ free it if it's the head of the argument list, though -- the
+ argument list will be freed by the caller. */
+ if (this == list)
+ this = list = list->next;
else
{
- bad_option (flag);
+ prev->next = this->next;
+ this->next = (WORD_LIST *)NULL;
+ dispose_words (this);
+ this = prev->next;
+ }
+ }
+
+ reset_internal_getopt ();
+ while ((opt = internal_getopt (list, "apt")) != -1)
+ {
+ switch (opt)
+ {
+ case 't':
+ type_only = 1;
+ path_only = 0;
+ break;
+ case 'p':
+ path_only = 1;
+ type_only = 0;
+ break;
+ case 'a':
+ all = 1;
+ break;
+ default:
builtin_usage ();
return (EX_USAGE);
}
- list = list->next;
}
+ list = loptend;
if (type_only)
verbose = 1;
fflush (stdout);
- if (successful_finds != 0)
- return (EXECUTION_SUCCESS);
- else
- return (EXECUTION_FAILURE);
+ return ((successful_finds != 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
/*
char *command;
int verbose, all;
{
- int found, i, found_file;
- char *full_path;
+ int found, i, found_file, f;
+ char *full_path, *x, *cwd;
SHELL_VAR *func;
#if defined (ALIAS)
alias_t *alias;
printf ("%s is aliased to `%s'\n", command, alias->value);
else if (verbose == 4)
{
- char *x = single_quote (alias->value);
+ x = sh_single_quote (alias->value);
printf ("alias %s=%s\n", command, x);
free (x);
}
found = 1;
- if (!all)
+ if (all == 0)
return (1);
}
#endif /* ALIAS */
found = 1;
- if (!all)
+ if (all == 0)
return (1);
}
found = 1;
- if (!all)
+ if (all == 0)
return (1);
}
found = 1;
- if (!all)
+ if (all == 0)
return (1);
}
check to see if it is executable. */
if (absolute_program (command))
{
- int f = file_status (command);
+ f = file_status (command);
if (f & FS_EXECABLE)
- {
+ {
if (verbose == 1)
puts ("file");
else if (verbose == 2)
because they're not consulted when an absolute program
name is supplied. */
return (1);
- }
+ }
}
- /* If the user isn't doing "-all", then we might care about
+ /* If the user isn't doing "-a", then we might care about
whether the file is present in our hash table. */
- if (!all)
+ if (all == 0)
{
if ((full_path = find_hashed_filename (command)) != (char *)NULL)
{
/* Now search through $PATH. */
while (1)
{
- if (!all)
+ if (all == 0)
full_path = find_user_command (command);
else
full_path =
if (!full_path)
break;
+ /* If we found the command as itself by looking through $PATH, it
+ probably doesn't exist. Check whether or not the command is an
+ executable file. If it's not, don't report a match. */
+ if (STREQ (full_path, command))
+ {
+ f = file_status (full_path);
+ if ((f & FS_EXECABLE) == 0)
+ {
+ free (full_path);
+ full_path = (char *)NULL;
+ if (all == 0)
+ break;
+ }
+ else if (verbose >= 2)
+ full_path = sh_makepath ((char *)NULL, full_path, MP_DOCWD);
+ }
+
found_file++;
found = 1;
free (full_path);
full_path = (char *)NULL;
- if (!all)
+ if (all == 0)
break;
}