]> git.ipfire.org Git - thirdparty/bash.git/blame - stringlib.c
fix for SIGINT in sourced script
[thirdparty/bash.git] / stringlib.c
CommitLineData
ccc6cda3
JA
1/* stringlib.c - Miscellaneous string functions. */
2
3185942a 3/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
ccc6cda3
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
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.
ccc6cda3 11
3185942a
JA
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.
ccc6cda3 16
3185942a
JA
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*/
ccc6cda3
JA
20
21#include "config.h"
22
23#include "bashtypes.h"
24
25#if defined (HAVE_UNISTD_H)
26# include <unistd.h>
27#endif
28
29#include "bashansi.h"
30#include <stdio.h>
f73dda09 31#include "chartypes.h"
ccc6cda3
JA
32
33#include "shell.h"
bb70624e
JA
34#include "pathexp.h"
35
f73dda09
JA
36#include <glob/glob.h>
37
bb70624e 38#if defined (EXTENDED_GLOB)
f73dda09 39# include <glob/strmatch.h>
bb70624e 40#endif
ccc6cda3 41
ccc6cda3
JA
42/* **************************************************************** */
43/* */
44/* Functions to manage arrays of strings */
45/* */
46/* **************************************************************** */
47
7117c2d2
JA
48/* Find STRING in ALIST, a list of string key/int value pairs. If FLAGS
49 is 1, STRING is treated as a pattern and matched using strmatch. */
50int
51find_string_in_alist (string, alist, flags)
52 char *string;
53 STRING_INT_ALIST *alist;
54 int flags;
ccc6cda3 55{
7117c2d2
JA
56 register int i;
57 int r;
ccc6cda3 58
7117c2d2
JA
59 for (i = r = 0; alist[i].word; i++)
60 {
61#if defined (EXTENDED_GLOB)
62 if (flags)
63 r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH;
64 else
65#endif
66 r = STREQ (string, alist[i].word);
ccc6cda3 67
7117c2d2
JA
68 if (r)
69 return (alist[i].token);
70 }
71 return -1;
ccc6cda3
JA
72}
73
7117c2d2
JA
74/* Find TOKEN in ALIST, a list of string/int value pairs. Return the
75 corresponding string. Allocates memory for the returned
76 string. FLAGS is currently ignored, but reserved. */
77char *
78find_token_in_alist (token, alist, flags)
79 int token;
80 STRING_INT_ALIST *alist;
81 int flags;
ccc6cda3 82{
7117c2d2 83 register int i;
ccc6cda3 84
7117c2d2 85 for (i = 0; alist[i].word; i++)
ccc6cda3 86 {
7117c2d2
JA
87 if (alist[i].token == token)
88 return (savestring (alist[i].word));
ccc6cda3 89 }
7117c2d2 90 return ((char *)NULL);
ccc6cda3
JA
91}
92
bb70624e 93int
7117c2d2 94find_index_in_alist (string, alist, flags)
bb70624e
JA
95 char *string;
96 STRING_INT_ALIST *alist;
97 int flags;
98{
99 register int i;
100 int r;
101
102 for (i = r = 0; alist[i].word; i++)
103 {
104#if defined (EXTENDED_GLOB)
105 if (flags)
f73dda09 106 r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH;
bb70624e
JA
107 else
108#endif
28ef6c31 109 r = STREQ (string, alist[i].word);
bb70624e
JA
110
111 if (r)
7117c2d2 112 return (i);
bb70624e 113 }
7117c2d2 114
bb70624e
JA
115 return -1;
116}
117
ccc6cda3
JA
118/* **************************************************************** */
119/* */
120/* String Management Functions */
121/* */
122/* **************************************************************** */
123
7117c2d2
JA
124/* Cons a new string from STRING starting at START and ending at END,
125 not including END. */
126char *
127substring (string, start, end)
0001803f 128 const char *string;
7117c2d2
JA
129 int start, end;
130{
131 register int len;
132 register char *result;
133
134 len = end - start;
135 result = (char *)xmalloc (len + 1);
ac50fbac 136 memcpy (result, string + start, len);
7117c2d2
JA
137 result[len] = '\0';
138 return (result);
139}
140
ccc6cda3
JA
141/* Replace occurrences of PAT with REP in STRING. If GLOBAL is non-zero,
142 replace all occurrences, otherwise replace only the first.
143 This returns a new string; the caller should free it. */
144char *
145strsub (string, pat, rep, global)
146 char *string, *pat, *rep;
147 int global;
148{
cce855bc 149 int patlen, replen, templen, tempsize, repl, i;
ccc6cda3
JA
150 char *temp, *r;
151
152 patlen = strlen (pat);
cce855bc 153 replen = strlen (rep);
ccc6cda3
JA
154 for (temp = (char *)NULL, i = templen = tempsize = 0, repl = 1; string[i]; )
155 {
156 if (repl && STREQN (string + i, pat, patlen))
28ef6c31 157 {
f73dda09
JA
158 if (replen)
159 RESIZE_MALLOCED_BUFFER (temp, templen, replen, tempsize, (replen * 2));
ccc6cda3 160
ac50fbac 161 for (r = rep; *r; ) /* can rep == "" */
ccc6cda3
JA
162 temp[templen++] = *r++;
163
f73dda09 164 i += patlen ? patlen : 1; /* avoid infinite recursion */
ccc6cda3 165 repl = global != 0;
28ef6c31 166 }
ccc6cda3
JA
167 else
168 {
169 RESIZE_MALLOCED_BUFFER (temp, templen, 1, tempsize, 16);
170 temp[templen++] = string[i++];
171 }
172 }
3185942a
JA
173 if (temp)
174 temp[templen] = 0;
175 else
176 temp = savestring (string);
ccc6cda3
JA
177 return (temp);
178}
179
bb70624e
JA
180/* Replace all instances of C in STRING with TEXT. TEXT may be empty or
181 NULL. If DO_GLOB is non-zero, we quote the replacement text for
182 globbing. Backslash may be used to quote C. */
183char *
184strcreplace (string, c, text, do_glob)
185 char *string;
186 int c;
a0c0a00f 187 const char *text;
bb70624e
JA
188 int do_glob;
189{
190 char *ret, *p, *r, *t;
191 int len, rlen, ind, tlen;
192
193 len = STRLEN (text);
194 rlen = len + strlen (string) + 2;
f73dda09 195 ret = (char *)xmalloc (rlen);
bb70624e
JA
196
197 for (p = string, r = ret; p && *p; )
198 {
199 if (*p == c)
200 {
201 if (len)
202 {
203 ind = r - ret;
204 if (do_glob && (glob_pattern_p (text) || strchr (text, '\\')))
205 {
206 t = quote_globbing_chars (text);
207 tlen = strlen (t);
208 RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
209 r = ret + ind; /* in case reallocated */
210 strcpy (r, t);
211 r += tlen;
212 free (t);
213 }
214 else
215 {
216 RESIZE_MALLOCED_BUFFER (ret, ind, len, rlen, rlen);
217 r = ret + ind; /* in case reallocated */
218 strcpy (r, text);
219 r += len;
220 }
221 }
222 p++;
223 continue;
224 }
225
28ef6c31 226 if (*p == '\\' && p[1] == c)
bb70624e
JA
227 p++;
228
f73dda09 229 ind = r - ret;
28ef6c31
JA
230 RESIZE_MALLOCED_BUFFER (ret, ind, 2, rlen, rlen);
231 r = ret + ind; /* in case reallocated */
bb70624e
JA
232 *r++ = *p++;
233 }
234 *r = '\0';
235
236 return ret;
237}
238
d166f048 239#ifdef INCLUDE_UNUSED
ccc6cda3
JA
240/* Remove all leading whitespace from STRING. This includes
241 newlines. STRING should be terminated with a zero. */
242void
243strip_leading (string)
244 char *string;
245{
246 char *start = string;
247
248 while (*string && (whitespace (*string) || *string == '\n'))
249 string++;
250
251 if (string != start)
252 {
253 int len = strlen (string);
254 FASTCOPY (string, start, len);
255 start[len] = '\0';
256 }
257}
d166f048 258#endif
ccc6cda3
JA
259
260/* Remove all trailing whitespace from STRING. This includes
261 newlines. If NEWLINES_ONLY is non-zero, only trailing newlines
262 are removed. STRING should be terminated with a zero. */
263void
d166f048 264strip_trailing (string, len, newlines_only)
ccc6cda3 265 char *string;
d166f048 266 int len;
ccc6cda3
JA
267 int newlines_only;
268{
ccc6cda3
JA
269 while (len >= 0)
270 {
271 if ((newlines_only && string[len] == '\n') ||
28ef6c31
JA
272 (!newlines_only && whitespace (string[len])))
273 len--;
ccc6cda3 274 else
28ef6c31 275 break;
ccc6cda3
JA
276 }
277 string[len + 1] = '\0';
278}
279
ccc6cda3
JA
280/* A wrapper for bcopy that can be prototyped in general.h */
281void
282xbcopy (s, d, n)
283 char *s, *d;
284 int n;
285{
286 FASTCOPY (s, d, n);
287}