1 This file is hash.def, from which is created hash.c.
2 It implements the builtin "hash" in Bash.
4 Copyright (C) 1987, 1989, 1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
25 $FUNCTION hash_builtin
26 $SHORT_DOC hash [-r] [-p pathname] [name ...]
27 For each NAME, the full pathname of the command is determined and
28 remembered. If the -p option is supplied, PATHNAME is used as the
29 full pathname of NAME, and no path search is performed. The -r
30 option causes the shell to forget all remembered locations. If no
31 arguments are given, information about remembered commands is displayed.
36 #include <sys/types.h>
37 #include "../posixstat.h"
41 #if defined (HAVE_UNISTD_H)
45 #include "../bashansi.h"
48 #include "../builtins.h"
50 #include "../execute_cmd.h"
53 #include "bashgetopt.h"
55 extern int dot_found_in_search;
56 extern char *this_command_name;
58 static int add_hashed_command ();
59 static int print_hashed_commands ();
61 static int hashing_initialized = 0;
63 HASH_TABLE *hashed_filenames;
66 initialize_filename_hashing ()
68 if (hashing_initialized == 0)
70 hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
71 hashing_initialized = 1;
76 free_filename_data (data)
79 free (((PATH_DATA *)data)->path);
84 flush_hashed_filenames ()
86 flush_hash_table (hashed_filenames, free_filename_data);
89 /* Remove FILENAME from the table of hashed commands. */
91 remove_hashed_filename (filename)
94 register BUCKET_CONTENTS *item;
96 if (hashing_enabled == 0)
99 item = remove_hash_item (filename, hashed_filenames);
103 free_filename_data (item->data);
109 /* Print statistics on the current state of hashed commands. If LIST is
110 not empty, then rehash (or hash in the first place) the specified
116 int expunge_hash_table, opt;
117 char *word, *pathname;
119 if (hashing_enabled == 0)
121 builtin_error ("hashing disabled");
122 return (EXECUTION_FAILURE);
125 expunge_hash_table = 0;
126 pathname = (char *)NULL;
127 reset_internal_getopt ();
128 while ((opt = internal_getopt (list, "rp:")) != -1)
133 expunge_hash_table = 1;
136 pathname = list_optarg;
145 /* We want hash -r to be silent, but hash -- to print hashing info. That
146 is the reason for the test of expunge_hash_table. */
147 if (list == 0 && expunge_hash_table == 0)
149 if (print_hashed_commands () == 0)
150 printf ("%s: hash table empty\n", this_command_name);
152 return (EXECUTION_SUCCESS);
155 if (expunge_hash_table)
156 flush_hashed_filenames ();
158 for (opt = EXECUTION_SUCCESS; list; list = list->next)
160 /* Add or rehash the specified commands. */
161 word = list->word->word;
163 remember_filename (word, pathname, 0, 0);
166 if (absolute_program (word))
172 if (add_hashed_command (word))
173 opt = EXECUTION_FAILURE;
182 /* Place FILENAME (key) and FULL_PATHNAME (data->path) into the
183 hash table. CHECK_DOT if non-null is for future calls to
184 find_hashed_filename (); it means that this file was found
185 in a directory in $PATH that is not an absolute pathname.
186 FOUND is the initial value for times_found. */
188 remember_filename (filename, full_pathname, check_dot, found)
189 char *filename, *full_pathname;
190 int check_dot, found;
192 register BUCKET_CONTENTS *item;
194 if (hashing_enabled == 0)
197 item = add_hash_item (filename, hashed_filenames);
199 free (pathdata(item)->path);
202 item->key = savestring (filename);
203 item->data = xmalloc (sizeof (PATH_DATA));
205 pathdata(item)->path = savestring (full_pathname);
206 pathdata(item)->flags = 0;
208 pathdata(item)->flags |= HASH_CHKDOT;
209 if (*full_pathname != '/')
210 pathdata(item)->flags |= HASH_RELPATH;
211 item->times_found = found;
215 add_hashed_command (word, quiet)
223 if (find_function (word) == 0 && find_shell_builtin (word) == 0)
225 full_path = find_user_command (word);
226 if (full_path && executable_file (full_path))
227 remember_filename (word, full_path, dot_found_in_search, 0);
231 builtin_error ("%s: not found", word);
240 /* Print information about current hashed info. */
242 print_hashed_commands ()
244 BUCKET_CONTENTS *item_list;
245 int bucket, any_printed;
247 for (bucket = any_printed = 0; bucket < hashed_filenames->nbuckets; bucket++)
249 item_list = get_hash_bucket (bucket, hashed_filenames);
253 if (any_printed == 0)
255 printf ("hits\tcommand\n");
259 for ( ; item_list; item_list = item_list->next)
260 printf ("%4d\t%s\n", item_list->times_found, pathdata(item_list)->path);
263 return (any_printed);