]>
Commit | Line | Data |
---|---|---|
726f6388 JA |
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 | |
ccc6cda3 | 26 | $SHORT_DOC hash [-r] [-p pathname] [name ...] |
726f6388 | 27 | For each NAME, the full pathname of the command is determined and |
ccc6cda3 JA |
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. | |
726f6388 JA |
32 | $END |
33 | ||
ccc6cda3 JA |
34 | #include <config.h> |
35 | ||
726f6388 JA |
36 | #include <stdio.h> |
37 | ||
cce855bc JA |
38 | #include "../bashtypes.h" |
39 | ||
ccc6cda3 JA |
40 | #if defined (HAVE_UNISTD_H) |
41 | # include <unistd.h> | |
42 | #endif | |
43 | ||
44 | #include "../bashansi.h" | |
726f6388 JA |
45 | |
46 | #include "../shell.h" | |
47 | #include "../builtins.h" | |
d166f048 | 48 | #include "../flags.h" |
cce855bc | 49 | #include "../findcmd.h" |
d166f048 | 50 | #include "../hashcmd.h" |
726f6388 | 51 | #include "common.h" |
ccc6cda3 | 52 | #include "bashgetopt.h" |
726f6388 JA |
53 | |
54 | extern int dot_found_in_search; | |
ccc6cda3 JA |
55 | extern char *this_command_name; |
56 | ||
57 | static int add_hashed_command (); | |
58 | static int print_hashed_commands (); | |
59 | ||
726f6388 JA |
60 | /* Print statistics on the current state of hashed commands. If LIST is |
61 | not empty, then rehash (or hash in the first place) the specified | |
62 | commands. */ | |
ccc6cda3 | 63 | int |
726f6388 JA |
64 | hash_builtin (list) |
65 | WORD_LIST *list; | |
66 | { | |
ccc6cda3 | 67 | int expunge_hash_table, opt; |
cce855bc | 68 | char *w, *pathname; |
726f6388 | 69 | |
ccc6cda3 | 70 | if (hashing_enabled == 0) |
726f6388 JA |
71 | { |
72 | builtin_error ("hashing disabled"); | |
73 | return (EXECUTION_FAILURE); | |
74 | } | |
75 | ||
ccc6cda3 JA |
76 | expunge_hash_table = 0; |
77 | pathname = (char *)NULL; | |
78 | reset_internal_getopt (); | |
79 | while ((opt = internal_getopt (list, "rp:")) != -1) | |
726f6388 | 80 | { |
ccc6cda3 | 81 | switch (opt) |
726f6388 | 82 | { |
ccc6cda3 | 83 | case 'r': |
726f6388 | 84 | expunge_hash_table = 1; |
726f6388 | 85 | break; |
ccc6cda3 JA |
86 | case 'p': |
87 | pathname = list_optarg; | |
88 | break; | |
89 | default: | |
90 | builtin_usage (); | |
726f6388 JA |
91 | return (EX_USAGE); |
92 | } | |
726f6388 | 93 | } |
ccc6cda3 | 94 | list = loptend; |
726f6388 JA |
95 | |
96 | /* We want hash -r to be silent, but hash -- to print hashing info. That | |
ccc6cda3 JA |
97 | is the reason for the test of expunge_hash_table. */ |
98 | if (list == 0 && expunge_hash_table == 0) | |
726f6388 | 99 | { |
ccc6cda3 JA |
100 | if (print_hashed_commands () == 0) |
101 | printf ("%s: hash table empty\n", this_command_name); | |
726f6388 JA |
102 | |
103 | return (EXECUTION_SUCCESS); | |
104 | } | |
105 | ||
106 | if (expunge_hash_table) | |
ccc6cda3 | 107 | flush_hashed_filenames (); |
726f6388 | 108 | |
ccc6cda3 | 109 | for (opt = EXECUTION_SUCCESS; list; list = list->next) |
726f6388 JA |
110 | { |
111 | /* Add or rehash the specified commands. */ | |
cce855bc | 112 | w = list->word->word; |
ccc6cda3 | 113 | if (pathname) |
cce855bc JA |
114 | remember_filename (w, pathname, 0, 0); |
115 | else if (absolute_program (w)) | |
d166f048 | 116 | continue; |
cce855bc | 117 | else if (add_hashed_command (w, 0)) |
d166f048 | 118 | opt = EXECUTION_FAILURE; |
726f6388 JA |
119 | } |
120 | ||
121 | fflush (stdout); | |
ccc6cda3 | 122 | return (opt); |
726f6388 JA |
123 | } |
124 | ||
ccc6cda3 | 125 | static int |
cce855bc JA |
126 | add_hashed_command (w, quiet) |
127 | char *w; | |
ccc6cda3 JA |
128 | int quiet; |
129 | { | |
130 | int rv; | |
131 | char *full_path; | |
132 | ||
133 | rv = 0; | |
cce855bc | 134 | if (find_function (w) == 0 && find_shell_builtin (w) == 0) |
ccc6cda3 | 135 | { |
cce855bc | 136 | full_path = find_user_command (w); |
ccc6cda3 | 137 | if (full_path && executable_file (full_path)) |
cce855bc | 138 | remember_filename (w, full_path, dot_found_in_search, 0); |
ccc6cda3 JA |
139 | else |
140 | { | |
141 | if (quiet == 0) | |
cce855bc | 142 | builtin_error ("%s: not found", w); |
ccc6cda3 JA |
143 | rv++; |
144 | } | |
145 | if (full_path) | |
146 | free (full_path); | |
147 | } | |
148 | return (rv); | |
149 | } | |
150 | ||
151 | /* Print information about current hashed info. */ | |
152 | static int | |
153 | print_hashed_commands () | |
154 | { | |
155 | BUCKET_CONTENTS *item_list; | |
156 | int bucket, any_printed; | |
157 | ||
d166f048 JA |
158 | if (hashed_filenames == 0) |
159 | return (0); | |
160 | ||
ccc6cda3 JA |
161 | for (bucket = any_printed = 0; bucket < hashed_filenames->nbuckets; bucket++) |
162 | { | |
163 | item_list = get_hash_bucket (bucket, hashed_filenames); | |
164 | if (item_list == 0) | |
165 | continue; | |
166 | ||
167 | if (any_printed == 0) | |
168 | { | |
169 | printf ("hits\tcommand\n"); | |
170 | any_printed++; | |
171 | } | |
172 | ||
173 | for ( ; item_list; item_list = item_list->next) | |
174 | printf ("%4d\t%s\n", item_list->times_found, pathdata(item_list)->path); | |
175 | ||
176 | } | |
177 | return (any_printed); | |
178 | } |