OpenCoverage

alias.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/alias.c
Source codeSwitch to Preprocessed file
LineSourceCount
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-2015 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-
9 it under the terms of the GNU General Public License as published by-
10 the Free Software Foundation, either version 3 of the License, or-
11 (at your option) any later version.-
12-
13 Bash is distributed in the hope that it will be useful,-
14 but WITHOUT ANY WARRANTY; without even the implied warranty of-
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
16 GNU General Public License for more details.-
17-
18 You should have received a copy of the GNU General Public License-
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.-
20*/-
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#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)-
46# include <mbstr.h> /* mbschr */-
47#endif-
48-
49#define ALIAS_HASH_BUCKETS 64 /* must be power of two */-
50-
51typedef int sh_alias_map_func_t __P((alias_t *));-
52-
53static void free_alias_data __P((PTR_T));-
54static alias_t **map_over_aliases __P((sh_alias_map_func_t *));-
55static void sort_aliases __P((alias_t **));-
56static int qsort_alias_compare __P((alias_t **, alias_t **));-
57-
58#if defined (READLINE)-
59static int skipquotes __P((char *, int));-
60static int skipws __P((char *, int));-
61static int rd_token __P((char *, int));-
62#endif-
63-
64/* Non-zero means expand all words on the line. Otherwise, expand-
65 after first expansion if the expansion ends in a space. */-
66int alias_expand_all = 0;-
67-
68/* The list of aliases that we have. */-
69HASH_TABLE *aliases = (HASH_TABLE *)NULL;-
70-
71void-
72initialize_aliases ()-
73{-
74 if (aliases == 0)
aliases == 0Description
TRUEevaluated 49 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-49
75 aliases = hash_create (ALIAS_HASH_BUCKETS);
executed 49 times by 1 test: aliases = hash_create (64);
Executed by:
  • Self test
49
76}
executed 49 times by 1 test: end of block
Executed by:
  • Self test
49
77-
78/* Scan the list of aliases looking for one with NAME. Return NULL-
79 if the alias doesn't exist, else a pointer to the alias_t. */-
80alias_t *-
81find_alias (name)-
82 char *name;-
83{-
84 BUCKET_CONTENTS *al;-
85-
86 if (aliases == 0)
aliases == 0Description
TRUEevaluated 3518 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 3726 times by 1 test
Evaluated by:
  • Self test
3518-3726
87 return ((alias_t *)NULL);
executed 3518 times by 1 test: return ((alias_t *) ((void *)0) );
Executed by:
  • Self test
3518
88-
89 al = hash_search (name, aliases, 0);-
90 return (al ? (alias_t *)al->data : (alias_t *)NULL);
executed 3726 times by 1 test: return (al ? (alias_t *)al->data : (alias_t *) ((void *)0) );
Executed by:
  • Self test
3726
91}-
92-
93/* Return the value of the alias for NAME, or NULL if there is none. */-
94char *-
95get_alias_value (name)-
96 char *name;-
97{-
98 alias_t *alias;-
99-
100 if (aliases == 0)
aliases == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
101 return ((char *)NULL);
never executed: return ((char *) ((void *)0) );
0
102-
103 alias = find_alias (name);-
104 return (alias ? alias->value : (char *)NULL);
never executed: return (alias ? alias->value : (char *) ((void *)0) );
0
105}-
106-
107/* Make a new alias from NAME and VALUE. If NAME can be found,-
108 then replace its value. */-
109void-
110add_alias (name, value)-
111 char *name, *value;-
112{-
113 BUCKET_CONTENTS *elt;-
114 alias_t *temp;-
115 int n;-
116-
117 if (aliases == 0)
aliases == 0Description
TRUEevaluated 49 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 46 times by 1 test
Evaluated by:
  • Self test
46-49
118 {-
119 initialize_aliases ();-
120 temp = (alias_t *)NULL;-
121 }
executed 49 times by 1 test: end of block
Executed by:
  • Self test
49
122 else-
123 temp = find_alias (name);
executed 46 times by 1 test: temp = find_alias (name);
Executed by:
  • Self test
46
124-
125 if (temp)
tempDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 93 times by 1 test
Evaluated by:
  • Self test
2-93
126 {-
127 free (temp->value);-
128 temp->value = savestring (value);-
129 temp->flags &= ~AL_EXPANDNEXT;-
130 n = value[strlen (value) - 1];-
131 if (n == ' ' || n == '\t')
n == ' 'Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test
n == '\t'Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test
0-2
132 temp->flags |= AL_EXPANDNEXT;
never executed: temp->flags |= 0x1;
0
133 }
executed 2 times by 1 test: end of block
Executed by:
  • Self test
2
134 else-
135 {-
136 temp = (alias_t *)xmalloc (sizeof (alias_t));-
137 temp->name = savestring (name);-
138 temp->value = savestring (value);-
139 temp->flags = 0;-
140-
141 n = value[strlen (value) - 1];-
142 if (n == ' ' || n == '\t')
n == ' 'Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 88 times by 1 test
Evaluated by:
  • Self test
n == '\t'Description
TRUEnever evaluated
FALSEevaluated 88 times by 1 test
Evaluated by:
  • Self test
0-88
143 temp->flags |= AL_EXPANDNEXT;
executed 5 times by 1 test: temp->flags |= 0x1;
Executed by:
  • Self test
5
144-
145 elt = hash_insert (savestring (name), aliases, HASH_NOSRCH);-
146 elt->data = temp;-
147#if defined (PROGRAMMABLE_COMPLETION)-
148 set_itemlist_dirty (&it_aliases);-
149#endif-
150 }
executed 93 times by 1 test: end of block
Executed by:
  • Self test
93
151}-
152-
153/* Delete a single alias structure. */-
154static void-
155free_alias_data (data)-
156 PTR_T data;-
157{-
158 register alias_t *a;-
159-
160 a = (alias_t *)data;-
161-
162 if (a->flags & AL_BEINGEXPANDED)
a->flags & 0x2Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 45 times by 1 test
Evaluated by:
  • Self test
4-45
163 clear_string_list_expander (a); /* call back to the parser */
executed 4 times by 1 test: clear_string_list_expander (a);
Executed by:
  • Self test
4
164-
165 free (a->value);-
166 free (a->name);-
167 free (data);-
168}
executed 49 times by 1 test: end of block
Executed by:
  • Self test
49
169-
170/* Remove the alias with name NAME from the alias table. Returns-
171 the number of aliases left in the table, or -1 if the alias didn't-
172 exist. */-
173int-
174remove_alias (name)-
175 char *name;-
176{-
177 BUCKET_CONTENTS *elt;-
178-
179 if (aliases == 0)
aliases == 0Description
TRUEnever evaluated
FALSEevaluated 15 times by 1 test
Evaluated by:
  • Self test
0-15
180 return (-1);
never executed: return (-1);
0
181-
182 elt = hash_remove (name, aliases, 0);-
183 if (elt)
eltDescription
TRUEevaluated 15 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-15
184 {-
185 free_alias_data (elt->data);-
186 free (elt->key); /* alias name */-
187 free (elt); /* XXX */-
188#if defined (PROGRAMMABLE_COMPLETION)-
189 set_itemlist_dirty (&it_aliases);-
190#endif-
191 return (aliases->nentries);
executed 15 times by 1 test: return (aliases->nentries);
Executed by:
  • Self test
15
192 }-
193 return (-1);
never executed: return (-1);
0
194}-
195-
196/* Delete all aliases. */-
197void-
198delete_all_aliases ()-
199{-
200 if (aliases == 0)
aliases == 0Description
TRUEevaluated 12 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 21 times by 1 test
Evaluated by:
  • Self test
12-21
201 return;
executed 12 times by 1 test: return;
Executed by:
  • Self test
12
202-
203 hash_flush (aliases, free_alias_data);-
204 hash_dispose (aliases);-
205 aliases = (HASH_TABLE *)NULL;-
206#if defined (PROGRAMMABLE_COMPLETION)-
207 set_itemlist_dirty (&it_aliases);-
208#endif-
209}
executed 21 times by 1 test: end of block
Executed by:
  • Self test
21
210-
211/* Return an array of aliases that satisfy the conditions tested by FUNCTION.-
212 If FUNCTION is NULL, return all aliases. */-
213static alias_t **-
214map_over_aliases (function)-
215 sh_alias_map_func_t *function;-
216{-
217 register int i;-
218 register BUCKET_CONTENTS *tlist;-
219 alias_t *alias, **list;-
220 int list_index;-
221-
222 i = HASH_ENTRIES (aliases);
(aliases)Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-5
223 if (i == 0)
i == 0Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
0-5
224 return ((alias_t **)NULL);
never executed: return ((alias_t **) ((void *)0) );
0
225-
226 list = (alias_t **)xmalloc ((i + 1) * sizeof (alias_t *));-
227 for (i = list_index = 0; i < aliases->nbuckets; i++)
i < aliases->nbucketsDescription
TRUEevaluated 320 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
5-320
228 {-
229 for (tlist = hash_items (i, aliases); tlist; tlist = tlist->next)
tlistDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 320 times by 1 test
Evaluated by:
  • Self test
8-320
230 {-
231 alias = (alias_t *)tlist->data;-
232-
233 if (!function || (*function) (alias))
!functionDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
(*function) (alias)Description
TRUEnever evaluated
FALSEnever evaluated
0-8
234 {-
235 list[list_index++] = alias;-
236 list[list_index] = (alias_t *)NULL;-
237 }
executed 8 times by 1 test: end of block
Executed by:
  • Self test
8
238 }
executed 8 times by 1 test: end of block
Executed by:
  • Self test
8
239 }
executed 320 times by 1 test: end of block
Executed by:
  • Self test
320
240 return (list);
executed 5 times by 1 test: return (list);
Executed by:
  • Self test
5
241}-
242-
243static void-
244sort_aliases (array)-
245 alias_t **array;-
246{-
247 qsort (array, strvec_len ((char **)array), sizeof (alias_t *), (QSFUNC *)qsort_alias_compare);-
248}
executed 5 times by 1 test: end of block
Executed by:
  • Self test
5
249-
250static int-
251qsort_alias_compare (as1, as2)-
252 alias_t **as1, **as2;-
253{-
254 int result;-
255-
256 if ((result = (*as1)->name[0] - (*as2)->name[0]) == 0)
(result = (*as...>name[0]) == 0Description
TRUEnever evaluated
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
0-5
257 result = strcmp ((*as1)->name, (*as2)->name);
never executed: result = __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( (*as1)->name ) && __builtin_constant_p ( (*as2)->name ) && (__s1_len = __builtin_strlen ( (*as1)->name ), __s2_len = __builtin_strlen ( (*as2)->name ), (!((size_t)(const void *)(... char *) (const char *) ( (*as2)->name ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( (*as2)->name ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( (*as1)->name , (*as2)->name )))); }) ;
never executed: __result = (((const unsigned char *) (const char *) ( (*as1)->name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( (*as2)->name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
258-
259 return (result);
executed 5 times by 1 test: return (result);
Executed by:
  • Self test
5
260}-
261-
262/* Return a sorted list of all defined aliases */-
263alias_t **-
264all_aliases ()-
265{-
266 alias_t **list;-
267-
268 if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
(aliases)Description
TRUEevaluated 7 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
aliases == 0Description
TRUEnever evaluated
FALSEevaluated 7 times by 1 test
Evaluated by:
  • Self test
((aliases) ? (...ries : 0) == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5 times by 1 test
Evaluated by:
  • Self test
0-7
269 return ((alias_t **)NULL);
executed 2 times by 1 test: return ((alias_t **) ((void *)0) );
Executed by:
  • Self test
2
270-
271 list = map_over_aliases ((sh_alias_map_func_t *)NULL);-
272 if (list)
listDescription
TRUEevaluated 5 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-5
273 sort_aliases (list);
executed 5 times by 1 test: sort_aliases (list);
Executed by:
  • Self test
5
274 return (list);
executed 5 times by 1 test: return (list);
Executed by:
  • Self test
5
275}-
276-
277char *-
278alias_expand_word (s)-
279 char *s;-
280{-
281 alias_t *r;-
282-
283 r = find_alias (s);-
284 return (r ? savestring (r->value) : (char *)NULL);
never executed: return (r ? (char *)strcpy (sh_xmalloc((1 + strlen (r->value)), "alias.c", 284), (r->value)) : (char *) ((void *)0) );
0
285}-
286-
287/* Readline support functions -- expand all aliases in a line. */-
288-
289#if defined (READLINE)-
290-
291/* Return non-zero if CHARACTER is a member of the class of characters-
292 that are self-delimiting in the shell (this really means that these-
293 characters delimit tokens). */-
294#define self_delimiting(character) (member ((character), " \t\n\r;|&()"))-
295-
296/* Return non-zero if CHARACTER is a member of the class of characters-
297 that delimit commands in the shell. */-
298#define command_separator(character) (member ((character), "\r\n;|&("))-
299-
300/* If this is 1, we are checking the next token read for alias expansion-
301 because it is the first word in a command. */-
302static int command_word;-
303-
304/* This is for skipping quoted strings in alias expansions. */-
305#define quote_char(c) (((c) == '\'') || ((c) == '"'))-
306-
307/* Consume a quoted string from STRING, starting at string[START] (so-
308 string[START] is the opening quote character), and return the index-
309 of the closing quote character matching the opening quote character.-
310 This handles single matching pairs of unquoted quotes; it could afford-
311 to be a little smarter... This skips words between balanced pairs of-
312 quotes, words where the first character is quoted with a `\', and other-
313 backslash-escaped characters. */-
314-
315static int-
316skipquotes (string, start)-
317 char *string;-
318 int start;-
319{-
320 register int i;-
321 int delimiter = string[start];-
322-
323 /* i starts at START + 1 because string[START] is the opening quote-
324 character. */-
325 for (i = start + 1 ; string[i] ; i++)
string[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
326 {-
327 if (string[i] == '\\')
string[i] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
328 {-
329 i++; /* skip backslash-quoted quote characters, too */-
330 if (string[i] == 0)
string[i] == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
331 break;
never executed: break;
0
332 continue;
never executed: continue;
0
333 }-
334-
335 if (string[i] == delimiter)
string[i] == delimiterDescription
TRUEnever evaluated
FALSEnever evaluated
0
336 return i;
never executed: return i;
0
337 }
never executed: end of block
0
338 return (i);
never executed: return (i);
0
339}-
340-
341/* Skip the white space and any quoted characters in STRING, starting at-
342 START. Return the new index into STRING, after zero or more characters-
343 have been skipped. */-
344static int-
345skipws (string, start)-
346 char *string;-
347 int start;-
348{-
349 register int i;-
350 int pass_next, backslash_quoted_word;-
351 unsigned char peekc;-
352-
353 /* skip quoted strings, in ' or ", and words in which a character is quoted-
354 with a `\'. */-
355 i = backslash_quoted_word = pass_next = 0;-
356-
357 /* Skip leading whitespace (or separator characters), and quoted words.-
358 But save it in the output. */-
359-
360 for (i = start; string[i]; i++)
string[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
361 {-
362 if (pass_next)
pass_nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
363 {-
364 pass_next = 0;-
365 continue;
never executed: continue;
0
366 }-
367-
368 if (whitespace (string[i]))
((string[i]) == ' ')Description
TRUEnever evaluated
FALSEnever evaluated
((string[i]) == '\t')Description
TRUEnever evaluated
FALSEnever evaluated
0
369 {-
370 backslash_quoted_word = 0; /* we are no longer in a backslash-quoted word */-
371 continue;
never executed: continue;
0
372 }-
373-
374 if (string[i] == '\\')
string[i] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
375 {-
376 peekc = string[i+1];-
377 if (peekc == 0)
peekc == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
378 break;
never executed: break;
0
379 if (ISLETTER (peekc))
((*__ctype_b_l...int) _ISalpha)Description
TRUEnever evaluated
FALSEnever evaluated
0
380 backslash_quoted_word++; /* this is a backslash-quoted word */
never executed: backslash_quoted_word++;
0
381 else-
382 pass_next++;
never executed: pass_next++;
0
383 continue;
never executed: continue;
0
384 }-
385-
386 /* This only handles single pairs of non-escaped quotes. This-
387 overloads backslash_quoted_word to also mean that a word like-
388 ""f is being scanned, so that the quotes will inhibit any expansion-
389 of the word. */-
390 if (quote_char(string[i]))
((string[i]) == '\'')Description
TRUEnever evaluated
FALSEnever evaluated
((string[i]) == '"')Description
TRUEnever evaluated
FALSEnever evaluated
0
391 {-
392 i = skipquotes (string, i);-
393 /* This could be a line that contains a single quote character,-
394 in which case skipquotes () terminates with string[i] == '\0'-
395 (the end of the string). Check for that here. */-
396 if (string[i] == '\0')
string[i] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
397 break;
never executed: break;
0
398-
399 peekc = string[i + 1];-
400 if (ISLETTER (peekc))
((*__ctype_b_l...int) _ISalpha)Description
TRUEnever evaluated
FALSEnever evaluated
0
401 backslash_quoted_word++;
never executed: backslash_quoted_word++;
0
402 continue;
never executed: continue;
0
403 }-
404-
405 /* If we're in the middle of some kind of quoted word, let it-
406 pass through. */-
407 if (backslash_quoted_word)
backslash_quoted_wordDescription
TRUEnever evaluated
FALSEnever evaluated
0
408 continue;
never executed: continue;
0
409-
410 /* If this character is a shell command separator, then set a hint for-
411 alias_expand that the next token is the first word in a command. */-
412-
413 if (command_separator (string[i]))
((((string[i])...d *)0) ) : 0))Description
TRUEnever evaluated
FALSEnever evaluated
((string[i]))Description
TRUEnever evaluated
FALSEnever evaluated
0
414 {-
415 command_word++;-
416 continue;
never executed: continue;
0
417 }-
418 break;
never executed: break;
0
419 }-
420 return (i);
never executed: return (i);
0
421}-
422-
423/* Characters that may appear in a token. Basically, anything except white-
424 space and a token separator. */-
425#define token_char(c) (!((whitespace (string[i]) || self_delimiting (string[i]))))-
426-
427/* Read from START in STRING until the next separator character, and return-
428 the index of that separator. Skip backslash-quoted characters. Call-
429 skipquotes () for quoted strings in the middle or at the end of tokens,-
430 so all characters show up (e.g. foo'' and foo""bar) */-
431static int-
432rd_token (string, start)-
433 char *string;-
434 int start;-
435{-
436 register int i;-
437-
438 /* From here to next separator character is a token. */-
439 for (i = start; string[i] && token_char (string[i]); i++)
((string[i]))Description
TRUEnever evaluated
FALSEnever evaluated
string[i]Description
TRUEnever evaluated
FALSEnever evaluated
((string[i]) == ' ')Description
TRUEnever evaluated
FALSEnever evaluated
((string[i]) == '\t')Description
TRUEnever evaluated
FALSEnever evaluated
((((string[i])...d *)0) ) : 0))Description
TRUEnever evaluated
FALSEnever evaluated
0
440 {-
441 if (string[i] == '\\')
string[i] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
442 {-
443 i++; /* skip backslash-escaped character */-
444 if (string[i] == 0)
string[i] == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
445 break;
never executed: break;
0
446 continue;
never executed: continue;
0
447 }-
448-
449 /* If this character is a quote character, we want to call skipquotes-
450 to get the whole quoted portion as part of this word. That word-
451 will not generally match an alias, even if te unquoted word would-
452 have. The presence of the quotes in the token serves then to-
453 inhibit expansion. */-
454 if (quote_char (string[i]))
((string[i]) == '\'')Description
TRUEnever evaluated
FALSEnever evaluated
((string[i]) == '"')Description
TRUEnever evaluated
FALSEnever evaluated
0
455 {-
456 i = skipquotes (string, i);-
457 /* This could be a line that contains a single quote character,-
458 in which case skipquotes () terminates with string[i] == '\0'-
459 (the end of the string). Check for that here. */-
460 if (string[i] == '\0')
string[i] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
461 break;
never executed: break;
0
462-
463 /* Now string[i] is the matching quote character, and the-
464 quoted portion of the token has been scanned. */-
465 continue;
never executed: continue;
0
466 }-
467 }
never executed: end of block
0
468 return (i);
never executed: return (i);
0
469}-
470-
471/* Return a new line, with any aliases substituted. */-
472char *-
473alias_expand (string)-
474 char *string;-
475{-
476 register int i, j, start;-
477 char *line, *token;-
478 int line_len, tl, real_start, expand_next, expand_this_token;-
479 alias_t *alias;-
480-
481 line_len = strlen (string) + 1;-
482 line = (char *)xmalloc (line_len);-
483 token = (char *)xmalloc (line_len);-
484-
485 line[0] = i = 0;-
486 expand_next = 0;-
487 command_word = 1; /* initialized to expand the first word on the line */-
488-
489 /* Each time through the loop we find the next word in line. If it-
490 has an alias, substitute the alias value. If the value ends in ` ',-
491 then try again with the next word. Else, if there is no value, or if-
492 the value does not end in space, we are done. */-
493-
494 for (;;)-
495 {-
496-
497 token[0] = 0;-
498 start = i;-
499-
500 /* Skip white space and quoted characters */-
501 i = skipws (string, start);-
502-
503 if (start == i && string[i] == '\0')
start == iDescription
TRUEnever evaluated
FALSEnever evaluated
string[i] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
504 {-
505 free (token);-
506 return (line);
never executed: return (line);
0
507 }-
508-
509 /* copy the just-skipped characters into the output string,-
510 expanding it if there is not enough room. */-
511 j = strlen (line);-
512 tl = i - start; /* number of characters just skipped */-
513 RESIZE_MALLOCED_BUFFER (line, j, (tl + 1), line_len, (tl + 50));
never executed: line_len += ((tl + 50));
never executed: end of block
(j) + ((tl + 1)) >= line_lenDescription
TRUEnever evaluated
FALSEnever evaluated
(j) + ((tl + 1)) >= line_lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
514 strncpy (line + j, string + start, tl);-
515 line[j + tl] = '\0';-
516-
517 real_start = i;-
518-
519 command_word = command_word || (command_separator (string[i]));
((string[i]))Description
TRUEnever evaluated
FALSEnever evaluated
command_wordDescription
TRUEnever evaluated
FALSEnever evaluated
(((((string[i]... *)0) ) : 0)))Description
TRUEnever evaluated
FALSEnever evaluated
0
520 expand_this_token = (command_word || expand_next);
command_wordDescription
TRUEnever evaluated
FALSEnever evaluated
expand_nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
521 expand_next = 0;-
522-
523 /* Read the next token, and copy it into TOKEN. */-
524 start = i;-
525 i = rd_token (string, start);-
526-
527 tl = i - start; /* token length */-
528-
529 /* If tl == 0, but we're not at the end of the string, then we have a-
530 single-character token, probably a delimiter */-
531 if (tl == 0 && string[i] != '\0')
tl == 0Description
TRUEnever evaluated
FALSEnever evaluated
string[i] != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
532 {-
533 tl = 1;-
534 i++; /* move past it */-
535 }
never executed: end of block
0
536-
537 strncpy (token, string + start, tl);-
538 token [tl] = '\0';-
539-
540 /* If there is a backslash-escaped character quoted in TOKEN,-
541 then we don't do alias expansion. This should check for all-
542 other quoting characters, too. */-
543 if (mbschr (token, '\\'))
mbschr (token, '\\')Description
TRUEnever evaluated
FALSEnever evaluated
0
544 expand_this_token = 0;
never executed: expand_this_token = 0;
0
545-
546 /* If we should be expanding here, if we are expanding all words, or if-
547 we are in a location in the string where an expansion is supposed to-
548 take place, see if this word has a substitution. If it does, then do-
549 the expansion. Note that we defer the alias value lookup until we-
550 are sure we are expanding this token. */-
551-
552 if ((token[0]) &&
(token[0])Description
TRUEnever evaluated
FALSEnever evaluated
0
553 (expand_this_token || alias_expand_all) &&
expand_this_tokenDescription
TRUEnever evaluated
FALSEnever evaluated
alias_expand_allDescription
TRUEnever evaluated
FALSEnever evaluated
0
554 (alias = find_alias (token)))
(alias = find_alias (token))Description
TRUEnever evaluated
FALSEnever evaluated
0
555 {-
556 char *v;-
557 int vlen, llen;-
558-
559 v = alias->value;-
560 vlen = strlen (v);-
561 llen = strlen (line);-
562-
563 /* +3 because we possibly add one more character below. */-
564 RESIZE_MALLOCED_BUFFER (line, llen, (vlen + 3), line_len, (vlen + 50));
never executed: line_len += ((vlen + 50));
never executed: end of block
(llen) + ((vle...)) >= line_lenDescription
TRUEnever evaluated
FALSEnever evaluated
(llen) + ((vle...)) >= line_lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
565-
566 strcpy (line + llen, v);-
567-
568 if ((expand_this_token && vlen && whitespace (v[vlen - 1])) ||
expand_this_tokenDescription
TRUEnever evaluated
FALSEnever evaluated
vlenDescription
TRUEnever evaluated
FALSEnever evaluated
((v[vlen - 1]) == ' ')Description
TRUEnever evaluated
FALSEnever evaluated
((v[vlen - 1]) == '\t')Description
TRUEnever evaluated
FALSEnever evaluated
0
569 alias_expand_all)
alias_expand_allDescription
TRUEnever evaluated
FALSEnever evaluated
0
570 expand_next = 1;
never executed: expand_next = 1;
0
571 }
never executed: end of block
0
572 else-
573 {-
574 int llen, tlen;-
575-
576 llen = strlen (line);-
577 tlen = i - real_start; /* tlen == strlen(token) */-
578-
579 RESIZE_MALLOCED_BUFFER (line, llen, (tlen + 1), line_len, (llen + tlen + 50));
never executed: line_len += ((llen + tlen + 50));
never executed: end of block
(llen) + ((tle...)) >= line_lenDescription
TRUEnever evaluated
FALSEnever evaluated
(llen) + ((tle...)) >= line_lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
580-
581 strncpy (line + llen, string + real_start, tlen);-
582 line[llen + tlen] = '\0';-
583 }
never executed: end of block
0
584 command_word = 0;-
585 }
never executed: end of block
0
586}
never executed: end of block
0
587#endif /* READLINE */-
588#endif /* ALIAS */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2