]> git.ipfire.org Git - thirdparty/bash.git/blob - pcomplib.c
Imported from ../bash-2.05a.tar.gz.
[thirdparty/bash.git] / pcomplib.c
1 /* pcomplib.c - library functions for programmable completion. */
2
3 /* Copyright (C) 1999 Free Software Foundation, Inc.
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
38 #define COMPLETE_HASH_BUCKETS 29 /* for testing */
39
40 #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
41
42 HASH_TABLE *prog_completes = (HASH_TABLE *)NULL;
43
44 static void free_progcomp __P((PTR_T));
45
46 static int progcomp_initialized = 0;
47
48 COMPSPEC *
49 alloc_compspec ()
50 {
51 COMPSPEC *ret;
52
53 ret = (COMPSPEC *)xmalloc (sizeof (COMPSPEC));
54 ret->refcount = 0;
55
56 ret->actions = (unsigned long)0;
57 ret->options = (unsigned long)0;
58
59 ret->globpat = (char *)NULL;
60 ret->words = (char *)NULL;
61 ret->prefix = (char *)NULL;
62 ret->suffix = (char *)NULL;
63 ret->funcname = (char *)NULL;
64 ret->command = (char *)NULL;
65 ret->filterpat = (char *)NULL;
66
67 return ret;
68 }
69
70 void
71 free_compspec (cs)
72 COMPSPEC *cs;
73 {
74 cs->refcount--;
75 if (cs->refcount == 0)
76 {
77 FREE (cs->globpat);
78 FREE (cs->words);
79 FREE (cs->prefix);
80 FREE (cs->suffix);
81 FREE (cs->funcname);
82 FREE (cs->command);
83 FREE (cs->filterpat);
84
85 free (cs);
86 }
87 }
88
89 COMPSPEC *
90 copy_compspec (cs)
91 COMPSPEC *cs;
92 {
93 COMPSPEC *new;
94
95 new = (COMPSPEC *)xmalloc (sizeof (COMPSPEC));
96
97 new->refcount = cs->refcount;
98 new->actions = cs->actions;
99 new->options = cs->options;
100
101 new->globpat = STRDUP (cs->globpat);
102 new->words = STRDUP (cs->words);
103 new->prefix = STRDUP (cs->prefix);
104 new->suffix = STRDUP (cs->suffix);
105 new->funcname = STRDUP (cs->funcname);
106 new->command = STRDUP (cs->command);
107 new->filterpat = STRDUP (cs->filterpat);
108
109 return new;
110 }
111
112 void
113 initialize_progcomp ()
114 {
115 if (progcomp_initialized == 0)
116 {
117 prog_completes = make_hash_table (COMPLETE_HASH_BUCKETS);
118 progcomp_initialized = 1;
119 }
120 }
121
122 int
123 num_progcomps ()
124 {
125 if (progcomp_initialized == 0 || prog_completes == 0)
126 return (0);
127 return (prog_completes->nentries);
128 }
129
130 static void
131 free_progcomp (data)
132 PTR_T data;
133 {
134 COMPSPEC *cs;
135
136 cs = (COMPSPEC *)data;
137 free_compspec (cs);
138 }
139
140 void
141 clear_progcomps ()
142 {
143 if (prog_completes)
144 flush_hash_table (prog_completes, free_progcomp);
145 }
146
147 int
148 remove_progcomp (cmd)
149 char *cmd;
150 {
151 register BUCKET_CONTENTS *item;
152
153 if (prog_completes == 0)
154 return 1;
155
156 item = remove_hash_item (cmd, prog_completes);
157 if (item)
158 {
159 free_progcomp (item->data);
160 free (item->key);
161 free (item);
162 return (1);
163 }
164 return (0);
165 }
166
167 int
168 add_progcomp (cmd, cs)
169 char *cmd;
170 COMPSPEC *cs;
171 {
172 register BUCKET_CONTENTS *item;
173
174 if (progcomp_initialized == 0 || prog_completes == 0)
175 initialize_progcomp ();
176
177 if (cs == NULL)
178 programming_error ("add_progcomp: %s: NULL COMPSPEC", cmd);
179
180 item = add_hash_item (cmd, prog_completes);
181 if (item->data)
182 free_progcomp (item->data);
183 else
184 item->key = savestring (cmd);
185 item->data = (char *)cs;
186 cs->refcount++;
187 return 1;
188 }
189
190 COMPSPEC *
191 find_compspec (cmd)
192 const char *cmd;
193 {
194 register BUCKET_CONTENTS *item;
195 COMPSPEC *cs;
196
197 if (prog_completes == 0)
198 return ((COMPSPEC *)NULL);
199
200 item = find_hash_item (cmd, prog_completes);
201
202 if (item == NULL)
203 return ((COMPSPEC *)NULL);
204
205 cs = (COMPSPEC *)item->data;
206
207 return (cs);
208 }
209
210 void
211 print_all_compspecs (pfunc)
212 sh_csprint_func_t *pfunc;
213 {
214 BUCKET_CONTENTS *item_list;
215 int bucket;
216 COMPSPEC *cs;
217
218 if (prog_completes == 0 || pfunc == 0)
219 return;
220
221 for (bucket = 0; bucket < prog_completes->nbuckets; bucket++)
222 {
223 item_list = get_hash_bucket (bucket, prog_completes);
224 if (item_list == 0)
225 continue;
226
227 for ( ; item_list; item_list = item_list->next)
228 {
229 cs = (COMPSPEC *)item_list->data;
230 (*pfunc) (item_list->key, cs);
231 }
232 }
233 }
234
235 #endif /* PROGRAMMABLE_COMPLETION */