]> git.ipfire.org Git - thirdparty/bash.git/blame - stringlib.c
Bash-5.2 patch 26: fix typo when specifying readline's custom color prefix
[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{
74091dd4
CR
149 size_t patlen, replen, templen, tempsize, i;
150 int repl;
ccc6cda3
JA
151 char *temp, *r;
152
153 patlen = strlen (pat);
cce855bc 154 replen = strlen (rep);
ccc6cda3
JA
155 for (temp = (char *)NULL, i = templen = tempsize = 0, repl = 1; string[i]; )
156 {
157 if (repl && STREQN (string + i, pat, patlen))
28ef6c31 158 {
f73dda09
JA
159 if (replen)
160 RESIZE_MALLOCED_BUFFER (temp, templen, replen, tempsize, (replen * 2));
ccc6cda3 161
ac50fbac 162 for (r = rep; *r; ) /* can rep == "" */
ccc6cda3
JA
163 temp[templen++] = *r++;
164
f73dda09 165 i += patlen ? patlen : 1; /* avoid infinite recursion */
ccc6cda3 166 repl = global != 0;
28ef6c31 167 }
ccc6cda3
JA
168 else
169 {
170 RESIZE_MALLOCED_BUFFER (temp, templen, 1, tempsize, 16);
171 temp[templen++] = string[i++];
172 }
173 }
3185942a
JA
174 if (temp)
175 temp[templen] = 0;
176 else
177 temp = savestring (string);
ccc6cda3
JA
178 return (temp);
179}
180
bb70624e 181/* Replace all instances of C in STRING with TEXT. TEXT may be empty or
74091dd4
CR
182 NULL. If (FLAGS & 1) is non-zero, we quote the replacement text for
183 globbing. Backslash may be used to quote C. If (FLAGS & 2) we allow
184 backslash to escape backslash as well. */
bb70624e 185char *
74091dd4 186strcreplace (string, c, text, flags)
bb70624e
JA
187 char *string;
188 int c;
a0c0a00f 189 const char *text;
74091dd4 190 int flags;
bb70624e
JA
191{
192 char *ret, *p, *r, *t;
74091dd4
CR
193 size_t len, rlen, ind, tlen;
194 int do_glob, escape_backslash;
195
196 do_glob = flags & 1;
197 escape_backslash = flags & 2;
bb70624e
JA
198
199 len = STRLEN (text);
200 rlen = len + strlen (string) + 2;
f73dda09 201 ret = (char *)xmalloc (rlen);
bb70624e
JA
202
203 for (p = string, r = ret; p && *p; )
204 {
205 if (*p == c)
206 {
207 if (len)
208 {
209 ind = r - ret;
210 if (do_glob && (glob_pattern_p (text) || strchr (text, '\\')))
211 {
212 t = quote_globbing_chars (text);
213 tlen = strlen (t);
214 RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
215 r = ret + ind; /* in case reallocated */
216 strcpy (r, t);
217 r += tlen;
218 free (t);
219 }
220 else
221 {
222 RESIZE_MALLOCED_BUFFER (ret, ind, len, rlen, rlen);
223 r = ret + ind; /* in case reallocated */
224 strcpy (r, text);
225 r += len;
226 }
227 }
228 p++;
229 continue;
230 }
231
28ef6c31 232 if (*p == '\\' && p[1] == c)
bb70624e 233 p++;
74091dd4
CR
234 else if (escape_backslash && *p == '\\' && p[1] == '\\')
235 p++;
bb70624e 236
f73dda09 237 ind = r - ret;
28ef6c31
JA
238 RESIZE_MALLOCED_BUFFER (ret, ind, 2, rlen, rlen);
239 r = ret + ind; /* in case reallocated */
bb70624e
JA
240 *r++ = *p++;
241 }
242 *r = '\0';
243
244 return ret;
245}
246
d166f048 247#ifdef INCLUDE_UNUSED
ccc6cda3
JA
248/* Remove all leading whitespace from STRING. This includes
249 newlines. STRING should be terminated with a zero. */
250void
251strip_leading (string)
252 char *string;
253{
254 char *start = string;
255
256 while (*string && (whitespace (*string) || *string == '\n'))
257 string++;
258
259 if (string != start)
260 {
261 int len = strlen (string);
262 FASTCOPY (string, start, len);
263 start[len] = '\0';
264 }
265}
d166f048 266#endif
ccc6cda3
JA
267
268/* Remove all trailing whitespace from STRING. This includes
269 newlines. If NEWLINES_ONLY is non-zero, only trailing newlines
270 are removed. STRING should be terminated with a zero. */
271void
d166f048 272strip_trailing (string, len, newlines_only)
ccc6cda3 273 char *string;
d166f048 274 int len;
ccc6cda3
JA
275 int newlines_only;
276{
ccc6cda3
JA
277 while (len >= 0)
278 {
279 if ((newlines_only && string[len] == '\n') ||
28ef6c31
JA
280 (!newlines_only && whitespace (string[len])))
281 len--;
ccc6cda3 282 else
28ef6c31 283 break;
ccc6cda3
JA
284 }
285 string[len + 1] = '\0';
286}
287
ccc6cda3
JA
288/* A wrapper for bcopy that can be prototyped in general.h */
289void
290xbcopy (s, d, n)
291 char *s, *d;
292 int n;
293{
294 FASTCOPY (s, d, n);
295}