1 /* stringlib.c - Miscellaneous string functions. */
3 /* Copyright (C) 1996-2009 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
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.
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.
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/>.
23 #include "bashtypes.h"
25 #if defined (HAVE_UNISTD_H)
31 #include "chartypes.h"
36 #include <glob/glob.h>
38 #if defined (EXTENDED_GLOB)
39 # include <glob/strmatch.h>
42 /* **************************************************************** */
44 /* Functions to manage arrays of strings */
46 /* **************************************************************** */
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. */
51 find_string_in_alist (string, alist, flags)
53 STRING_INT_ALIST *alist;
59 for (i = r = 0; alist[i].word; i++)
61 #if defined (EXTENDED_GLOB)
63 r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH;
66 r = STREQ (string, alist[i].word);
69 return (alist[i].token);
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. */
78 find_token_in_alist (token, alist, flags)
80 STRING_INT_ALIST *alist;
85 for (i = 0; alist[i].word; i++)
87 if (alist[i].token == token)
88 return (savestring (alist[i].word));
90 return ((char *)NULL);
94 find_index_in_alist (string, alist, flags)
96 STRING_INT_ALIST *alist;
102 for (i = r = 0; alist[i].word; i++)
104 #if defined (EXTENDED_GLOB)
106 r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH;
109 r = STREQ (string, alist[i].word);
118 /* **************************************************************** */
120 /* String Management Functions */
122 /* **************************************************************** */
124 /* Cons a new string from STRING starting at START and ending at END,
125 not including END. */
127 substring (string, start, end)
132 register char *result;
135 result = (char *)xmalloc (len + 1);
136 strncpy (result, string + start, len);
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. */
145 strsub (string, pat, rep, global)
146 char *string, *pat, *rep;
149 int patlen, replen, templen, tempsize, repl, i;
152 patlen = strlen (pat);
153 replen = strlen (rep);
154 for (temp = (char *)NULL, i = templen = tempsize = 0, repl = 1; string[i]; )
156 if (repl && STREQN (string + i, pat, patlen))
159 RESIZE_MALLOCED_BUFFER (temp, templen, replen, tempsize, (replen * 2));
162 temp[templen++] = *r++;
164 i += patlen ? patlen : 1; /* avoid infinite recursion */
169 RESIZE_MALLOCED_BUFFER (temp, templen, 1, tempsize, 16);
170 temp[templen++] = string[i++];
176 temp = savestring (string);
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. */
184 strcreplace (string, c, text, do_glob)
190 char *ret, *p, *r, *t;
191 int len, rlen, ind, tlen;
194 rlen = len + strlen (string) + 2;
195 ret = (char *)xmalloc (rlen);
197 for (p = string, r = ret; p && *p; )
204 if (do_glob && (glob_pattern_p (text) || strchr (text, '\\')))
206 t = quote_globbing_chars (text);
208 RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
209 r = ret + ind; /* in case reallocated */
216 RESIZE_MALLOCED_BUFFER (ret, ind, len, rlen, rlen);
217 r = ret + ind; /* in case reallocated */
226 if (*p == '\\' && p[1] == c)
230 RESIZE_MALLOCED_BUFFER (ret, ind, 2, rlen, rlen);
231 r = ret + ind; /* in case reallocated */
239 #ifdef INCLUDE_UNUSED
240 /* Remove all leading whitespace from STRING. This includes
241 newlines. STRING should be terminated with a zero. */
243 strip_leading (string)
246 char *start = string;
248 while (*string && (whitespace (*string) || *string == '\n'))
253 int len = strlen (string);
254 FASTCOPY (string, start, len);
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. */
264 strip_trailing (string, len, newlines_only)
271 if ((newlines_only && string[len] == '\n') ||
272 (!newlines_only && whitespace (string[len])))
277 string[len + 1] = '\0';
280 /* A wrapper for bcopy that can be prototyped in general.h */