Imported from ../bash-2.05b.tar.gz.
[platform/upstream/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 */