~ubuntu-branches/ubuntu/trusty/bash/trusty-security

1.5.1 by Matthias Klose
Import upstream version 4.3~rc1
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	128	/* 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->lcommand = (char *)NULL;
66
  ret->filterpat = (char *)NULL;
67
68
  return ret;
69
}
70
71
void
72
compspec_dispose (cs)
73
     COMPSPEC *cs;
74
{
75
  cs->refcount--;
76
  if (cs->refcount == 0)
77
    {
78
      FREE (cs->globpat);
79
      FREE (cs->words);
80
      FREE (cs->prefix);
81
      FREE (cs->suffix);
82
      FREE (cs->funcname);
83
      FREE (cs->command);
84
      FREE (cs->lcommand);
85
      FREE (cs->filterpat);
86
87
      free (cs);
88
    }
89
}
90
91
COMPSPEC *
92
compspec_copy (cs)
93
     COMPSPEC *cs;
94
{
95
  COMPSPEC *new;
96
97
  new = (COMPSPEC *)xmalloc (sizeof (COMPSPEC));
98
99
  new->refcount = cs->refcount;
100
  new->actions = cs->actions;
101
  new->options = cs->options;
102
103
  new->globpat = STRDUP (cs->globpat);
104
  new->words = STRDUP (cs->words);
105
  new->prefix = STRDUP (cs->prefix);
106
  new->suffix = STRDUP (cs->suffix);
107
  new->funcname = STRDUP (cs->funcname);
108
  new->command = STRDUP (cs->command);
109
  new->lcommand = STRDUP (cs->lcommand);
110
  new->filterpat = STRDUP (cs->filterpat);
111
112
  return new;
113
}
114
115
void
116
progcomp_create ()
117
{
118
  if (prog_completes == 0)
119
    prog_completes = hash_create (COMPLETE_HASH_BUCKETS);
120
}
121
122
int
123
progcomp_size ()
124
{
125
  return (HASH_ENTRIES (prog_completes));
126
}
127
128
static void
129
free_progcomp (data)
130
     PTR_T data;
131
{
132
  COMPSPEC *cs;
133
134
  cs = (COMPSPEC *)data;
135
  compspec_dispose (cs);
136
}
137
  
138
void
139
progcomp_flush ()
140
{
141
  if (prog_completes)
142
    hash_flush (prog_completes, free_progcomp);
143
}
144
145
void
146
progcomp_dispose ()
147
{
148
  if (prog_completes)
149
    hash_dispose (prog_completes);
150
  prog_completes = (HASH_TABLE *)NULL;
151
}
152
153
int
154
progcomp_remove (cmd)
155
     char *cmd;
156
{
157
  register BUCKET_CONTENTS *item;
158
159
  if (prog_completes == 0)
160
    return 1;
161
162
  item = hash_remove (cmd, prog_completes, 0);
163
  if (item)
164
    {
165
      if (item->data)
166
	free_progcomp (item->data);
167
      free (item->key);
168
      free (item);
169
      return (1);
170
    }
171
  return (0);
172
}
173
174
int
175
progcomp_insert (cmd, cs)
176
      char *cmd;
177
      COMPSPEC *cs;
178
{
179
  register BUCKET_CONTENTS *item;
180
181
  if (cs == NULL)
182
    programming_error (_("progcomp_insert: %s: NULL COMPSPEC"), cmd);
183
184
  if (prog_completes == 0)
185
    progcomp_create ();
186
187
  cs->refcount++;
188
  item = hash_insert (cmd, prog_completes, 0);
189
  if (item->data)
190
    free_progcomp (item->data);
191
  else
192
    item->key = savestring (cmd);
193
  item->data = cs;
194
195
  return 1;
196
}
197
198
COMPSPEC *
199
progcomp_search (cmd)
200
     const char *cmd;
201
{
202
  register BUCKET_CONTENTS *item;
203
  COMPSPEC *cs;
204
205
  if (prog_completes == 0)
206
    return ((COMPSPEC *)NULL);
207
208
  item = hash_search (cmd, prog_completes, 0);
209
210
  if (item == NULL)
211
    return ((COMPSPEC *)NULL);
212
213
  cs = (COMPSPEC *)item->data;
214
215
  return (cs);
216
}
217
218
void
219
progcomp_walk (pfunc)
220
     hash_wfunc *pfunc;
221
{
222
  if (prog_completes == 0 || pfunc == 0 || HASH_ENTRIES (prog_completes) == 0)
223
    return;
224
225
  hash_walk (prog_completes, pfunc);
226
}
227
228
#endif /* PROGRAMMABLE_COMPLETION */