]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/hash.def
Imported from ../bash-1.14.7.tar.gz.
[thirdparty/bash.git] / builtins / hash.def
1 This file is hash.def, from which is created hash.c.
2 It implements the builtin "hash" in Bash.
3
4 Copyright (C) 1987, 1989, 1991 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 hash.c
23
24 $BUILTIN hash
25 $FUNCTION hash_builtin
26 $SHORT_DOC hash [-r] [name ...]
27 For each NAME, the full pathname of the command is determined and
28 remembered. The -r option causes the shell to forget all remembered
29 locations. If no arguments are given, information about remembered
30 commands is presented.
31 $END
32
33 #include <sys/types.h>
34 #include "../posixstat.h"
35
36 #include <stdio.h>
37
38 #if defined (HAVE_STRING_H)
39 # include <string.h>
40 #else /* !HAVE_STRING_H */
41 # include <strings.h>
42 #endif /* !HAVE_STRING_H */
43
44 #include "../shell.h"
45 #include "../builtins.h"
46 #include "../flags.h"
47 #include "hashcom.h"
48 #include "common.h"
49 #include "../execute_cmd.h"
50
51 extern int dot_found_in_search;
52
53 void
54 initialize_filename_hashing ()
55 {
56 hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
57 }
58
59 /* Print statistics on the current state of hashed commands. If LIST is
60 not empty, then rehash (or hash in the first place) the specified
61 commands. */
62 hash_builtin (list)
63 WORD_LIST *list;
64 {
65 int expunge_hash_table = 0;
66 int any_failed = 0;
67
68 if (hashing_disabled)
69 {
70 builtin_error ("hashing disabled");
71 return (EXECUTION_FAILURE);
72 }
73
74 while (list)
75 {
76 char *arg = list->word->word;
77
78 if (ISOPTION (arg, 'r'))
79 {
80 expunge_hash_table = 1;
81 list = list->next;
82 }
83 else if (ISOPTION (arg, '-'))
84 {
85 list = list->next;
86 break;
87 }
88 else if (*arg == '-')
89 {
90 bad_option (list->word->word);
91 builtin_error ("usage: hash [-r] [command ...]");
92 return (EX_USAGE);
93 }
94 else
95 break;
96 }
97
98 /* We want hash -r to be silent, but hash -- to print hashing info. That
99 is the reason for the !expunge_hash_table. */
100 if (!list && !expunge_hash_table)
101 {
102 /* Print information about current hashed info. */
103 int any_printed = 0;
104 int bucket = 0;
105 register BUCKET_CONTENTS *item_list;
106
107 while (bucket < hashed_filenames->nbuckets)
108 {
109 item_list = get_hash_bucket (bucket, hashed_filenames);
110 if (item_list)
111 {
112 if (!any_printed)
113 {
114 printf ("hits\tcommand\n");
115 any_printed++;
116 }
117 while (item_list)
118 {
119 printf ("%4d\t%s\n",
120 item_list->times_found, pathdata(item_list)->path);
121 item_list = item_list->next;
122 }
123 }
124 bucket++;
125 }
126
127 if (!any_printed)
128 printf ("No commands in hash table.\n");
129
130 return (EXECUTION_SUCCESS);
131 }
132
133 if (expunge_hash_table)
134 {
135 int bucket = 0;
136 register BUCKET_CONTENTS *item_list, *prev;
137
138 while (bucket < hashed_filenames->nbuckets)
139 {
140 item_list = get_hash_bucket (bucket, hashed_filenames);
141 if (item_list)
142 {
143 while (item_list)
144 {
145 prev = item_list;
146 free (item_list->key);
147 free (pathdata(item_list)->path);
148 free (item_list->data);
149 item_list = item_list->next;
150 free (prev);
151 }
152 hashed_filenames->bucket_array[bucket] = (BUCKET_CONTENTS *)NULL;
153 }
154 bucket++;
155 }
156 }
157
158 while (list)
159 {
160 /* Add or rehash the specified commands. */
161 char *word;
162 char *full_path;
163 SHELL_VAR *var;
164
165 word = list->word->word;
166 if (absolute_program (word))
167 {
168 list = list->next;
169 continue;
170 }
171 full_path = find_user_command (word);
172 var = find_function (word);
173
174 if (!find_shell_builtin (word) && (!var))
175 {
176 if (full_path && executable_file (full_path))
177 remember_filename (word, full_path, dot_found_in_search, 0);
178 else
179 {
180 builtin_error ("%s: not found", word);
181 any_failed++;
182 }
183 }
184 if (full_path)
185 free (full_path);
186
187 list = list->next;
188 }
189
190 fflush (stdout);
191
192 if (any_failed)
193 return (EXECUTION_FAILURE);
194 else
195 return (EXECUTION_SUCCESS);
196 }
197
198 /* Place FILENAME (key) and FULL_PATHNAME (data->path) into the
199 hash table. CHECK_DOT if non-null is for future calls to
200 find_hashed_filename (). FOUND is the initial value for
201 times_found. */
202 void
203 remember_filename (filename, full_pathname, check_dot, found)
204 char *filename, *full_pathname;
205 int check_dot, found;
206 {
207 register BUCKET_CONTENTS *item;
208
209 if (hashing_disabled)
210 return;
211 item = add_hash_item (filename, hashed_filenames);
212 if (item->data)
213 free (pathdata(item)->path);
214 else
215 {
216 item->key = savestring (filename);
217 item->data = (char *)xmalloc (sizeof (PATH_DATA));
218 }
219 pathdata(item)->path = savestring (full_pathname);
220 pathdata(item)->check_dot = check_dot;
221 item->times_found = found;
222 }