]> git.ipfire.org Git - thirdparty/bash.git/blame - pcomplib.c
allow some job notifications while running $PROMPT_COMMAND; allow notifications while...
[thirdparty/bash.git] / pcomplib.c
CommitLineData
bb70624e
JA
1/* pcomplib.c - library functions for programmable completion. */
2
a61ffa78 3/* Copyright (C) 1999-2022 Free Software Foundation, Inc.
bb70624e
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
2e4498b3
CR
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.
bb70624e 11
2e4498b3
CR
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.
bb70624e 16
2e4498b3
CR
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*/
bb70624e
JA
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
5e13499c
CR
35#include "bashintl.h"
36
bb70624e
JA
37#include "shell.h"
38#include "pcomplete.h"
39
1fff64ac 40#define COMPLETE_HASH_BUCKETS 512 /* must be power of two */
bb70624e
JA
41
42#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
43
44HASH_TABLE *prog_completes = (HASH_TABLE *)NULL;
45
a61ffa78 46static void free_progcomp (PTR_T);
f73dda09 47
bb70624e 48COMPSPEC *
a61ffa78 49compspec_create (void)
bb70624e
JA
50{
51 COMPSPEC *ret;
52
53 ret = (COMPSPEC *)xmalloc (sizeof (COMPSPEC));
54 ret->refcount = 0;
55
56 ret->actions = (unsigned long)0;
28ef6c31 57 ret->options = (unsigned long)0;
bb70624e
JA
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;
e054386f 65 ret->lcommand = (char *)NULL;
bb70624e
JA
66 ret->filterpat = (char *)NULL;
67
68 return ret;
69}
70
71void
a61ffa78 72compspec_dispose (COMPSPEC *cs)
bb70624e
JA
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);
e054386f 83 FREE (cs->lcommand);
bb70624e
JA
84 FREE (cs->filterpat);
85
86 free (cs);
87 }
88}
89
90COMPSPEC *
a61ffa78 91compspec_copy (COMPSPEC *cs)
bb70624e
JA
92{
93 COMPSPEC *new;
94
95 new = (COMPSPEC *)xmalloc (sizeof (COMPSPEC));
96
bce12dd7 97 new->refcount = 1; /* was cs->refcount, but this is a fresh copy */
bb70624e 98 new->actions = cs->actions;
28ef6c31 99 new->options = cs->options;
bb70624e
JA
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);
e054386f 107 new->lcommand = STRDUP (cs->lcommand);
bb70624e
JA
108 new->filterpat = STRDUP (cs->filterpat);
109
110 return new;
111}
112
113void
a61ffa78 114progcomp_create (void)
bb70624e 115{
7117c2d2
JA
116 if (prog_completes == 0)
117 prog_completes = hash_create (COMPLETE_HASH_BUCKETS);
bb70624e
JA
118}
119
120int
a61ffa78 121progcomp_size (void)
bb70624e 122{
7117c2d2 123 return (HASH_ENTRIES (prog_completes));
bb70624e
JA
124}
125
126static void
a61ffa78 127free_progcomp (PTR_T data)
bb70624e
JA
128{
129 COMPSPEC *cs;
130
131 cs = (COMPSPEC *)data;
7117c2d2 132 compspec_dispose (cs);
bb70624e
JA
133}
134
135void
a61ffa78 136progcomp_flush (void)
7117c2d2
JA
137{
138 if (prog_completes)
139 hash_flush (prog_completes, free_progcomp);
140}
141
142void
a61ffa78 143progcomp_dispose (void)
bb70624e
JA
144{
145 if (prog_completes)
7117c2d2
JA
146 hash_dispose (prog_completes);
147 prog_completes = (HASH_TABLE *)NULL;
bb70624e
JA
148}
149
150int
a61ffa78 151progcomp_remove (const char *cmd)
bb70624e
JA
152{
153 register BUCKET_CONTENTS *item;
154
155 if (prog_completes == 0)
156 return 1;
157
7117c2d2 158 item = hash_remove (cmd, prog_completes, 0);
bb70624e
JA
159 if (item)
160 {
7117c2d2
JA
161 if (item->data)
162 free_progcomp (item->data);
bb70624e
JA
163 free (item->key);
164 free (item);
165 return (1);
166 }
167 return (0);
168}
169
170int
a61ffa78 171progcomp_insert (char *cmd, COMPSPEC *cs)
bb70624e
JA
172{
173 register BUCKET_CONTENTS *item;
174
bb70624e 175 if (cs == NULL)
5e13499c 176 programming_error (_("progcomp_insert: %s: NULL COMPSPEC"), cmd);
7117c2d2
JA
177
178 if (prog_completes == 0)
179 progcomp_create ();
bb70624e 180
d3a24ed2 181 cs->refcount++;
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;
d3a24ed2 188
bb70624e
JA
189 return 1;
190}
191
192COMPSPEC *
a61ffa78 193progcomp_search (const char *cmd)
bb70624e
JA
194{
195 register BUCKET_CONTENTS *item;
196 COMPSPEC *cs;
197
198 if (prog_completes == 0)
199 return ((COMPSPEC *)NULL);
200
7117c2d2 201 item = hash_search (cmd, prog_completes, 0);
bb70624e
JA
202
203 if (item == NULL)
204 return ((COMPSPEC *)NULL);
205
206 cs = (COMPSPEC *)item->data;
207
208 return (cs);
209}
210
211void
a61ffa78 212progcomp_walk (hash_wfunc *pfunc)
bb70624e 213{
7117c2d2 214 if (prog_completes == 0 || pfunc == 0 || HASH_ENTRIES (prog_completes) == 0)
bb70624e
JA
215 return;
216
7117c2d2 217 hash_walk (prog_completes, pfunc);
bb70624e
JA
218}
219
220#endif /* PROGRAMMABLE_COMPLETION */