1 /* stringlib.c - Miscellaneous string functions. */
3 /* Copyright (C) 1996-2009 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne Again SHell.
7 Bush 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 Bush 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 Bush. If not, see <http://www.gnu.org/licenses/>.
23 #include "bushtypes.h"
25 #if defined (HAVE_UNISTD_H)
31 #include "chartypes.h"
34 #include "impl/pathexp.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 memcpy (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));
161 for (r
= rep
; *r
; ) /* can rep == "" */
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 */