]> git.ipfire.org Git - thirdparty/bash.git/blob - pcomplib.c
Imported from ../bash-2.05b.tar.gz.
[thirdparty/bash.git] / pcomplib.c
1 /* pcomplib.c - library functions for programmable completion. */
2
3 /* Copyright (C) 1999-2002 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 32 /* must be power of two */
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 COMPSPEC *
47 compspec_create ()
48 {
49 COMPSPEC *ret;
50
51 ret = (COMPSPEC *)xmalloc (sizeof (COMPSPEC));
52 ret->refcount = 0;
53
54 ret->actions = (unsigned long)0;
55 ret->options = (unsigned long)0;
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
69 compspec_dispose (cs)
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 *
88 compspec_copy (cs)
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;
97 new->options = cs->options;
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
111 progcomp_create ()
112 {
113 if (prog_completes == 0)
114 prog_completes = hash_create (COMPLETE_HASH_BUCKETS);
115 }
116
117 int
118 progcomp_size ()
119 {
120 return (HASH_ENTRIES (prog_completes));
121 }
122
123 static void
124 free_progcomp (data)
125 PTR_T data;
126 {
127 COMPSPEC *cs;
128
129 cs = (COMPSPEC *)data;
130 compspec_dispose (cs);
131 }
132
133 void
134 progcomp_flush ()
135 {
136 if (prog_completes)
137 hash_flush (prog_completes, free_progcomp);
138 }
139
140 void
141 progcomp_dispose ()
142 {
143 if (prog_completes)
144 hash_dispose (prog_completes);
145 prog_completes = (HASH_TABLE *)NULL;
146 }
147
148 int
149 progcomp_remove (cmd)
150 char *cmd;
151 {
152 register BUCKET_CONTENTS *item;
153
154 if (prog_completes == 0)
155 return 1;
156
157 item = hash_remove (cmd, prog_completes, 0);
158 if (item)
159 {
160 if (item->data)
161 free_progcomp (item->data);
162 free (item->key);
163 free (item);
164 return (1);
165 }
166 return (0);
167 }
168
169 int
170 progcomp_insert (cmd, cs)
171 char *cmd;
172 COMPSPEC *cs;
173 {
174 register BUCKET_CONTENTS *item;
175
176 if (cs == NULL)
177 programming_error ("progcomp_insert: %s: NULL COMPSPEC", cmd);
178
179 if (prog_completes == 0)
180 progcomp_create ();
181
182 item = hash_insert (cmd, prog_completes, 0);
183 if (item->data)
184 free_progcomp (item->data);
185 else
186 item->key = savestring (cmd);
187 item->data = cs;
188 cs->refcount++;
189 return 1;
190 }
191
192 COMPSPEC *
193 progcomp_search (cmd)
194 const char *cmd;
195 {
196 register BUCKET_CONTENTS *item;
197 COMPSPEC *cs;
198
199 if (prog_completes == 0)
200 return ((COMPSPEC *)NULL);
201
202 item = hash_search (cmd, prog_completes, 0);
203
204 if (item == NULL)
205 return ((COMPSPEC *)NULL);
206
207 cs = (COMPSPEC *)item->data;
208
209 return (cs);
210 }
211
212 void
213 progcomp_walk (pfunc)
214 hash_wfunc *pfunc;
215 {
216 if (prog_completes == 0 || pfunc == 0 || HASH_ENTRIES (prog_completes) == 0)
217 return;
218
219 hash_walk (prog_completes, pfunc);
220 }
221
222 #endif /* PROGRAMMABLE_COMPLETION */