]>
git.ipfire.org Git - thirdparty/bash.git/blob - stringlib.c
1 /* stringlib.c - Miscellaneous string functions. */
4 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
24 #include "bashtypes.h"
26 #if defined (HAVE_UNISTD_H)
32 #include "chartypes.h"
37 #include <glob/glob.h>
39 #if defined (EXTENDED_GLOB)
40 # include <glob/strmatch.h>
43 /* **************************************************************** */
45 /* Functions to manage arrays of strings */
47 /* **************************************************************** */
49 /* Cons up a new array of words. The words are taken from LIST,
50 which is a WORD_LIST *. If COPY is true, everything is malloc'ed,
51 so you should free everything in this array when you are done.
52 The array is NULL terminated. If IP is non-null, it gets the
53 number of words in the returned array. STARTING_INDEX says where
54 to start filling in the returned array; it can be used to reserve
55 space at the beginning of the array. */
57 word_list_to_argv (list
, copy
, starting_index
, ip
)
59 int copy
, starting_index
, *ip
;
64 count
= list_length (list
);
65 array
= (char **)xmalloc ((1 + count
+ starting_index
) * sizeof (char *));
67 for (count
= 0; count
< starting_index
; count
++)
68 array
[count
] = (char *)NULL
;
69 for (count
= starting_index
; list
; count
++, list
= list
->next
)
70 array
[count
] = copy
? savestring (list
->word
->word
) : list
->word
->word
;
71 array
[count
] = (char *)NULL
;
78 /* Convert an array of strings into the form used internally by the shell.
79 COPY means to copy the values in ARRAY into the returned list rather
80 than allocate new storage. STARTING_INDEX says where in ARRAY to begin. */
82 argv_to_word_list (array
, copy
, starting_index
)
84 int copy
, starting_index
;
90 if (array
== 0 || array
[0] == 0)
91 return (WORD_LIST
*)NULL
;
93 for (count
= 0; array
[count
]; count
++)
96 for (i
= starting_index
, list
= (WORD_LIST
*)NULL
; i
< count
; i
++)
98 w
= make_bare_word (copy
? "" : array
[i
]);
104 list
= make_word_list (w
, list
);
106 return (REVERSE_LIST(list
, WORD_LIST
*));
109 /* Find STRING in ALIST, a list of string key/int value pairs. If FLAGS
110 is 1, STRING is treated as a pattern and matched using strmatch. */
112 find_string_in_alist (string
, alist
, flags
)
114 STRING_INT_ALIST
*alist
;
120 for (i
= r
= 0; alist
[i
].word
; i
++)
122 #if defined (EXTENDED_GLOB)
124 r
= strmatch (alist
[i
].word
, string
, FNM_EXTMATCH
) != FNM_NOMATCH
;
127 r
= STREQ (string
, alist
[i
].word
);
130 return (alist
[i
].token
);
135 /* **************************************************************** */
137 /* String Management Functions */
139 /* **************************************************************** */
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
++];
177 /* Replace all instances of C in STRING with TEXT. TEXT may be empty or
178 NULL. If DO_GLOB is non-zero, we quote the replacement text for
179 globbing. Backslash may be used to quote C. */
181 strcreplace (string
, c
, text
, do_glob
)
187 char *ret
, *p
, *r
, *t
;
188 int len
, rlen
, ind
, tlen
;
191 rlen
= len
+ strlen (string
) + 2;
192 ret
= (char *)xmalloc (rlen
);
194 for (p
= string
, r
= ret
; p
&& *p
; )
201 if (do_glob
&& (glob_pattern_p (text
) || strchr (text
, '\\')))
203 t
= quote_globbing_chars (text
);
205 RESIZE_MALLOCED_BUFFER (ret
, ind
, tlen
, rlen
, rlen
);
206 r
= ret
+ ind
; /* in case reallocated */
213 RESIZE_MALLOCED_BUFFER (ret
, ind
, len
, rlen
, rlen
);
214 r
= ret
+ ind
; /* in case reallocated */
223 if (*p
== '\\' && p
[1] == c
)
227 RESIZE_MALLOCED_BUFFER (ret
, ind
, 2, rlen
, rlen
);
228 r
= ret
+ ind
; /* in case reallocated */
236 #ifdef INCLUDE_UNUSED
237 /* Remove all leading whitespace from STRING. This includes
238 newlines. STRING should be terminated with a zero. */
240 strip_leading (string
)
243 char *start
= string
;
245 while (*string
&& (whitespace (*string
) || *string
== '\n'))
250 int len
= strlen (string
);
251 FASTCOPY (string
, start
, len
);
257 /* Remove all trailing whitespace from STRING. This includes
258 newlines. If NEWLINES_ONLY is non-zero, only trailing newlines
259 are removed. STRING should be terminated with a zero. */
261 strip_trailing (string
, len
, newlines_only
)
268 if ((newlines_only
&& string
[len
] == '\n') ||
269 (!newlines_only
&& whitespace (string
[len
])))
274 string
[len
+ 1] = '\0';
277 /* A wrapper for bcopy that can be prototyped in general.h */