migration from private to rsa
[external/bash.git] / pcomplib.c
1 /* pcomplib.c - library functions for programmable completion. */
2
3 /* Copyright (C) 1999-2009 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
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
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 "bashintl.h"
36
37 #include "shell.h"
38 #include "pcomplete.h"
39
40 #define COMPLETE_HASH_BUCKETS   32      /* must be power of two */
41
42 #define STRDUP(x)       ((x) ? savestring (x) : (char *)NULL)
43
44 HASH_TABLE *prog_completes = (HASH_TABLE *)NULL;
45
46 static void free_progcomp __P((PTR_T));
47
48 COMPSPEC *
49 compspec_create ()
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 compspec_dispose (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 compspec_copy (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 progcomp_create ()
114 {
115   if (prog_completes == 0)
116     prog_completes = hash_create (COMPLETE_HASH_BUCKETS);
117 }
118
119 int
120 progcomp_size ()
121 {
122   return (HASH_ENTRIES (prog_completes));
123 }
124
125 static void
126 free_progcomp (data)
127      PTR_T data;
128 {
129   COMPSPEC *cs;
130
131   cs = (COMPSPEC *)data;
132   compspec_dispose (cs);
133 }
134   
135 void
136 progcomp_flush ()
137 {
138   if (prog_completes)
139     hash_flush (prog_completes, free_progcomp);
140 }
141
142 void
143 progcomp_dispose ()
144 {
145   if (prog_completes)
146     hash_dispose (prog_completes);
147   prog_completes = (HASH_TABLE *)NULL;
148 }
149
150 int
151 progcomp_remove (cmd)
152      char *cmd;
153 {
154   register BUCKET_CONTENTS *item;
155
156   if (prog_completes == 0)
157     return 1;
158
159   item = hash_remove (cmd, prog_completes, 0);
160   if (item)
161     {
162       if (item->data)
163         free_progcomp (item->data);
164       free (item->key);
165       free (item);
166       return (1);
167     }
168   return (0);
169 }
170
171 int
172 progcomp_insert (cmd, cs)
173       char *cmd;
174       COMPSPEC *cs;
175 {
176   register BUCKET_CONTENTS *item;
177
178   if (cs == NULL)
179     programming_error (_("progcomp_insert: %s: NULL COMPSPEC"), cmd);
180
181   if (prog_completes == 0)
182     progcomp_create ();
183
184   cs->refcount++;
185   item = hash_insert (cmd, prog_completes, 0);
186   if (item->data)
187     free_progcomp (item->data);
188   else
189     item->key = savestring (cmd);
190   item->data = cs;
191
192   return 1;
193 }
194
195 COMPSPEC *
196 progcomp_search (cmd)
197      const char *cmd;
198 {
199   register BUCKET_CONTENTS *item;
200   COMPSPEC *cs;
201
202   if (prog_completes == 0)
203     return ((COMPSPEC *)NULL);
204
205   item = hash_search (cmd, prog_completes, 0);
206
207   if (item == NULL)
208     return ((COMPSPEC *)NULL);
209
210   cs = (COMPSPEC *)item->data;
211
212   return (cs);
213 }
214
215 void
216 progcomp_walk (pfunc)
217      hash_wfunc *pfunc;
218 {
219   if (prog_completes == 0 || pfunc == 0 || HASH_ENTRIES (prog_completes) == 0)
220     return;
221
222   hash_walk (prog_completes, pfunc);
223 }
224
225 #endif /* PROGRAMMABLE_COMPLETION */