source: trunk/essentials/app-shells/bash/alias.c@ 3253

Last change on this file since 3253 was 3231, checked in by bird, 19 years ago

eol style.

  • Property svn:eol-style set to native
File size: 14.6 KB
Line 
1/* alias.c -- Not a full alias, but just the kind that we use in the
2 shell. Csh style alias is somewhere else (`over there, in a box'). */
3
4/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bash; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
21
22#include "config.h"
23
24#if defined (ALIAS)
25
26#if defined (HAVE_UNISTD_H)
27# ifdef _MINIX
28# include <sys/types.h>
29# endif
30# include <unistd.h>
31#endif
32
33#include <stdio.h>
34#include "chartypes.h"
35#include "bashansi.h"
36#include "command.h"
37#include "general.h"
38#include "externs.h"
39#include "alias.h"
40
41#if defined (PROGRAMMABLE_COMPLETION)
42# include "pcomplete.h"
43#endif
44
45#define ALIAS_HASH_BUCKETS 16 /* must be power of two */
46
47typedef int sh_alias_map_func_t __P((alias_t *));
48
49static void free_alias_data __P((PTR_T));
50static alias_t **map_over_aliases __P((sh_alias_map_func_t *));
51static void sort_aliases __P((alias_t **));
52static int qsort_alias_compare __P((alias_t **, alias_t **));
53
54#if defined (READLINE)
55static int skipquotes __P((char *, int));
56static int skipws __P((char *, int));
57static int rd_token __P((char *, int));
58#endif
59
60/* Non-zero means expand all words on the line. Otherwise, expand
61 after first expansion if the expansion ends in a space. */
62int alias_expand_all = 0;
63
64/* The list of aliases that we have. */
65HASH_TABLE *aliases = (HASH_TABLE *)NULL;
66
67void
68initialize_aliases ()
69{
70 if (!aliases)
71 aliases = hash_create (ALIAS_HASH_BUCKETS);
72}
73
74/* Scan the list of aliases looking for one with NAME. Return NULL
75 if the alias doesn't exist, else a pointer to the alias_t. */
76alias_t *
77find_alias (name)
78 char *name;
79{
80 BUCKET_CONTENTS *al;
81
82 if (aliases == 0)
83 return ((alias_t *)NULL);
84
85 al = hash_search (name, aliases, 0);
86 return (al ? (alias_t *)al->data : (alias_t *)NULL);
87}
88
89/* Return the value of the alias for NAME, or NULL if there is none. */
90char *
91get_alias_value (name)
92 char *name;
93{
94 alias_t *alias;
95
96 if (aliases == 0)
97 return ((char *)NULL);
98
99 alias = find_alias (name);
100 return (alias ? alias->value : (char *)NULL);
101}
102
103/* Make a new alias from NAME and VALUE. If NAME can be found,
104 then replace its value. */
105void
106add_alias (name, value)
107 char *name, *value;
108{
109 BUCKET_CONTENTS *elt;
110 alias_t *temp;
111 int n;
112
113 if (!aliases)
114 {
115 initialize_aliases ();
116 temp = (alias_t *)NULL;
117 }
118 else
119 temp = find_alias (name);
120
121 if (temp)
122 {
123 free (temp->value);
124 temp->value = savestring (value);
125 temp->flags &= ~AL_EXPANDNEXT;
126 n = value[strlen (value) - 1];
127 if (n == ' ' || n == '\t')
128 temp->flags |= AL_EXPANDNEXT;
129 }
130 else
131 {
132 temp = (alias_t *)xmalloc (sizeof (alias_t));
133 temp->name = savestring (name);
134 temp->value = savestring (value);
135 temp->flags = 0;
136
137 n = value[strlen (value) - 1];
138 if (n == ' ' || n == '\t')
139 temp->flags |= AL_EXPANDNEXT;
140
141 elt = hash_insert (savestring (name), aliases, HASH_NOSRCH);
142 elt->data = temp;
143#if defined (PROGRAMMABLE_COMPLETION)
144 set_itemlist_dirty (&it_aliases);
145#endif
146 }
147}
148
149/* Delete a single alias structure. */
150static void
151free_alias_data (data)
152 PTR_T data;
153{
154 register alias_t *a;
155
156 a = (alias_t *)data;
157 free (a->value);
158 free (a->name);
159 free (data);
160}
161
162/* Remove the alias with name NAME from the alias table. Returns
163 the number of aliases left in the table, or -1 if the alias didn't
164 exist. */
165int
166remove_alias (name)
167 char *name;
168{
169 BUCKET_CONTENTS *elt;
170
171 if (aliases == 0)
172 return (-1);
173
174 elt = hash_remove (name, aliases, 0);
175 if (elt)
176 {
177 free_alias_data (elt->data);
178 free (elt->key); /* alias name */
179 free (elt); /* XXX */
180#if defined (PROGRAMMABLE_COMPLETION)
181 set_itemlist_dirty (&it_aliases);
182#endif
183 return (aliases->nentries);
184 }
185 return (-1);
186}
187
188/* Delete all aliases. */
189void
190delete_all_aliases ()
191{
192 if (aliases == 0)
193 return;
194
195 hash_flush (aliases, free_alias_data);
196 hash_dispose (aliases);
197 aliases = (HASH_TABLE *)NULL;
198#if defined (PROGRAMMABLE_COMPLETION)
199 set_itemlist_dirty (&it_aliases);
200#endif
201}
202
203/* Return an array of aliases that satisfy the conditions tested by FUNCTION.
204 If FUNCTION is NULL, return all aliases. */
205static alias_t **
206map_over_aliases (function)
207 sh_alias_map_func_t *function;
208{
209 register int i;
210 register BUCKET_CONTENTS *tlist;
211 alias_t *alias, **list;
212 int list_index;
213
214 i = HASH_ENTRIES (aliases);
215 if (i == 0)
216 return ((alias_t **)NULL);
217
218 list = (alias_t **)xmalloc ((i + 1) * sizeof (alias_t *));
219 for (i = list_index = 0; i < aliases->nbuckets; i++)
220 {
221 for (tlist = hash_items (i, aliases); tlist; tlist = tlist->next)
222 {
223 alias = (alias_t *)tlist->data;
224
225 if (!function || (*function) (alias))
226 {
227 list[list_index++] = alias;
228 list[list_index] = (alias_t *)NULL;
229 }
230 }
231 }
232 return (list);