]>
Commit | Line | Data |
---|---|---|
bb70624e JA |
1 | /* pcomplib.c - library functions for programmable completion. */ |
2 | ||
7117c2d2 | 3 | /* Copyright (C) 1999-2002 Free Software Foundation, Inc. |
bb70624e JA |
4 | |
5 | This file is part of GNU Bash, the Bourne Again SHell. | |
6 | ||
7 | Bash is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 2, or (at your option) any later | |
10 | version. | |
11 | ||
12 | Bash is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License along | |
18 | with Bash; see the file COPYING. If not, write to the Free Software | |
19 | Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ | |
20 | ||
21 | #include <config.h> | |
22 | ||
23 | #if defined (PROGRAMMABLE_COMPLETION) | |
24 | ||
25 | #include "bashansi.h" | |
26 | #include <stdio.h> | |
27 | ||
28 | #if defined (HAVE_UNISTD_H) | |
29 | # ifdef _MINIX | |
30 | # include <sys/types.h> | |
31 | # endif | |
32 | # include <unistd.h> | |
33 | #endif | |
34 | ||
35 | #include "shell.h" | |
36 | #include "pcomplete.h" | |
37 | ||
7117c2d2 | 38 | #define COMPLETE_HASH_BUCKETS 32 /* must be power of two */ |
bb70624e JA |
39 | |
40 | #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) | |
41 | ||
42 | HASH_TABLE *prog_completes = (HASH_TABLE *)NULL; | |
43 | ||
f73dda09 JA |
44 | static void free_progcomp __P((PTR_T)); |
45 | ||
bb70624e | 46 | COMPSPEC * |
7117c2d2 | 47 | compspec_create () |
bb70624e JA |
48 | { |
49 | COMPSPEC *ret; | |
50 | ||
51 | ret = (COMPSPEC *)xmalloc (sizeof (COMPSPEC)); | |
52 | ret->refcount = 0; | |
53 | ||
54 | ret->actions = (unsigned long)0; | |
28ef6c31 | 55 | ret->options = (unsigned long)0; |
bb70624e JA |
56 | |
57 | ret->globpat = (char *)NULL; | |
58 | ret->words = (char *)NULL; | |
59 | ret->prefix = (char *)NULL; | |
60 | ret->suffix = (char *)NULL; | |
61 | ret->funcname = (char *)NULL; | |
62 | ret->command = (char *)NULL; | |
63 | ret->filterpat = (char *)NULL; | |
64 | ||
65 | return ret; | |
66 | } | |
67 | ||
68 | void | |
7117c2d2 | 69 | compspec_dispose (cs) |
bb70624e JA |
70 | COMPSPEC *cs; |
71 | { | |
72 | cs->refcount--; | |
73 | if (cs->refcount == 0) | |
74 | { | |
75 | FREE (cs->globpat); | |
76 | FREE (cs->words); | |
77 | FREE (cs->prefix); | |
78 | FREE (cs->suffix); | |
79 | FREE (cs->funcname); | |
80 | FREE (cs->command); | |
81 | FREE (cs->filterpat); | |
82 | ||
83 | free (cs); | |
84 | } | |
85 | } | |
86 | ||
87 | COMPSPEC * | |
7117c2d2 | 88 | compspec_copy (cs) |
bb70624e JA |
89 | COMPSPEC *cs; |
90 | { | |
91 | COMPSPEC *new; | |
92 | ||
93 | new = (COMPSPEC *)xmalloc (sizeof (COMPSPEC)); | |
94 | ||
95 | new->refcount = cs->refcount; | |
96 | new->actions = cs->actions; | |
28ef6c31 | 97 | new->options = cs->options; |
bb70624e JA |
98 | |
99 | new->globpat = STRDUP (cs->globpat); | |
100 | new->words = STRDUP (cs->words); | |
101 | new->prefix = STRDUP (cs->prefix); | |
102 | new->suffix = STRDUP (cs->suffix); | |
103 | new->funcname = STRDUP (cs->funcname); | |
104 | new->command = STRDUP (cs->command); | |
105 | new->filterpat = STRDUP (cs->filterpat); | |
106 | ||
107 | return new; | |
108 | } | |
109 | ||
110 | void | |
7117c2d2 | 111 | progcomp_create () |
bb70624e | 112 | { |
7117c2d2 JA |
113 | if (prog_completes == 0) |
114 | prog_completes = hash_create (COMPLETE_HASH_BUCKETS); | |
bb70624e JA |
115 | } |
116 | ||
117 | int | |
7117c2d2 | 118 | progcomp_size () |
bb70624e | 119 | { |
7117c2d2 | 120 | return (HASH_ENTRIES (prog_completes)); |
bb70624e JA |
121 | } |
122 | ||
123 | static void | |
124 | free_progcomp (data) | |
f73dda09 | 125 | PTR_T data; |
bb70624e JA |
126 | { |
127 | COMPSPEC *cs; | |
128 | ||
129 | cs = (COMPSPEC *)data; | |
7117c2d2 | 130 | compspec_dispose (cs); |
bb70624e JA |
131 | } |
132 | ||
133 | void | |
7117c2d2 JA |
134 | progcomp_flush () |
135 | { | |
136 | if (prog_completes) | |
137 | hash_flush (prog_completes, free_progcomp); | |
138 | } | |
139 | ||
140 | void | |
141 | progcomp_dispose () | |
bb70624e JA |
142 | { |
143 | if (prog_completes) | |
7117c2d2 JA |
144 | hash_dispose (prog_completes); |
145 | prog_completes = (HASH_TABLE *)NULL; | |
bb70624e JA |
146 | } |
147 | ||
148 | int | |
7117c2d2 | 149 | progcomp_remove (cmd) |
bb70624e JA |
150 | char *cmd; |
151 | { | |
152 | register BUCKET_CONTENTS *item; | |
153 | ||
154 | if (prog_completes == 0) | |
155 | return 1; | |
156 | ||
7117c2d2 | 157 | item = hash_remove (cmd, prog_completes, 0); |
bb70624e JA |
158 | if (item) |
159 | { | |
7117c2d2 JA |
160 | if (item->data) |
161 | free_progcomp (item->data); | |
bb70624e JA |
162 | free (item->key); |
163 | free (item); | |
164 | return (1); | |
165 | } | |
166 | return (0); | |
167 | } | |
168 | ||
169 | int | |
7117c2d2 | 170 | progcomp_insert (cmd, cs) |
bb70624e JA |
171 | char *cmd; |
172 | COMPSPEC *cs; | |
173 | { | |
174 | register BUCKET_CONTENTS *item; | |
175 | ||
bb70624e | 176 | if (cs == NULL) |
7117c2d2 JA |
177 | programming_error ("progcomp_insert: %s: NULL COMPSPEC", cmd); |
178 | ||
179 | if (prog_completes == 0) | |
180 | progcomp_create (); | |
bb70624e | 181 | |
7117c2d2 | 182 | item = hash_insert (cmd, prog_completes, 0); |
bb70624e JA |
183 | if (item->data) |
184 | free_progcomp (item->data); | |
185 | else | |
186 | item->key = savestring (cmd); | |
7117c2d2 | 187 | item->data = cs; |
bb70624e JA |
188 | cs->refcount++; |
189 | return 1; | |
190 | } | |
191 | ||
192 | COMPSPEC * | |
7117c2d2 | 193 | progcomp_search (cmd) |
28ef6c31 | 194 | const char *cmd; |
bb70624e JA |
195 | { |
196 | register BUCKET_CONTENTS *item; | |
197 | COMPSPEC *cs; | |
198 | ||
199 | if (prog_completes == 0) | |
200 | return ((COMPSPEC *)NULL); | |
201 | ||
7117c2d2 | 202 | item = hash_search (cmd, prog_completes, 0); |
bb70624e JA |
203 | |
204 | if (item == NULL) | |
205 | return ((COMPSPEC *)NULL); | |
206 | ||
207 | cs = (COMPSPEC *)item->data; | |
208 | ||
209 | return (cs); | |
210 | } | |
211 | ||
212 | void | |
7117c2d2 JA |
213 | progcomp_walk (pfunc) |
214 | hash_wfunc *pfunc; | |
bb70624e | 215 | { |
7117c2d2 | 216 | if (prog_completes == 0 || pfunc == 0 || HASH_ENTRIES (prog_completes) == 0) |
bb70624e JA |
217 | return; |
218 | ||
7117c2d2 | 219 | hash_walk (prog_completes, pfunc); |
bb70624e JA |
220 | } |
221 | ||
222 | #endif /* PROGRAMMABLE_COMPLETION */ |