i-bash/stringlib.c

288 lines
6.5 KiB
C
Raw Permalink Normal View History

1996-12-23 17:02:34 +00:00
/* stringlib.c - Miscellaneous string functions. */
2009-01-12 13:36:28 +00:00
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
1996-12-23 17:02:34 +00:00
This file is part of GNU Bash, the Bourne Again SHell.
2009-01-12 13:36:28 +00:00
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
1996-12-23 17:02:34 +00:00
2009-01-12 13:36:28 +00:00
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
1996-12-23 17:02:34 +00:00
2009-01-12 13:36:28 +00:00
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
1996-12-23 17:02:34 +00:00
#include "config.h"
#include "bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include <stdio.h>
2001-11-13 17:56:06 +00:00
#include "chartypes.h"
1996-12-23 17:02:34 +00:00
#include "shell.h"
2000-03-17 21:46:59 +00:00
#include "pathexp.h"
2001-11-13 17:56:06 +00:00
#include <glob/glob.h>
2000-03-17 21:46:59 +00:00
#if defined (EXTENDED_GLOB)
2001-11-13 17:56:06 +00:00
# include <glob/strmatch.h>
2000-03-17 21:46:59 +00:00
#endif
1996-12-23 17:02:34 +00:00
/* **************************************************************** */
/* */
/* Functions to manage arrays of strings */
/* */
/* **************************************************************** */
2002-07-17 14:10:11 +00:00
/* Find STRING in ALIST, a list of string key/int value pairs. If FLAGS
is 1, STRING is treated as a pattern and matched using strmatch. */
int
find_string_in_alist (string, alist, flags)
char *string;
STRING_INT_ALIST *alist;
int flags;
1996-12-23 17:02:34 +00:00
{
2002-07-17 14:10:11 +00:00
register int i;
int r;
1996-12-23 17:02:34 +00:00
2002-07-17 14:10:11 +00:00
for (i = r = 0; alist[i].word; i++)
{
#if defined (EXTENDED_GLOB)
if (flags)
r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH;
else
#endif
r = STREQ (string, alist[i].word);
1996-12-23 17:02:34 +00:00
2002-07-17 14:10:11 +00:00
if (r)
return (alist[i].token);
}
return -1;
1996-12-23 17:02:34 +00:00
}
2002-07-17 14:10:11 +00:00
/* Find TOKEN in ALIST, a list of string/int value pairs. Return the
corresponding string. Allocates memory for the returned
string. FLAGS is currently ignored, but reserved. */
char *
find_token_in_alist (token, alist, flags)
int token;
STRING_INT_ALIST *alist;
int flags;
1996-12-23 17:02:34 +00:00
{
2002-07-17 14:10:11 +00:00
register int i;
1996-12-23 17:02:34 +00:00
2002-07-17 14:10:11 +00:00
for (i = 0; alist[i].word; i++)
1996-12-23 17:02:34 +00:00
{
2002-07-17 14:10:11 +00:00
if (alist[i].token == token)
return (savestring (alist[i].word));
1996-12-23 17:02:34 +00:00
}
2002-07-17 14:10:11 +00:00
return ((char *)NULL);
1996-12-23 17:02:34 +00:00
}
2000-03-17 21:46:59 +00:00
int
2002-07-17 14:10:11 +00:00
find_index_in_alist (string, alist, flags)
2000-03-17 21:46:59 +00:00
char *string;
STRING_INT_ALIST *alist;
int flags;
{
register int i;
int r;
for (i = r = 0; alist[i].word; i++)
{
#if defined (EXTENDED_GLOB)
if (flags)
2001-11-13 17:56:06 +00:00
r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH;
2000-03-17 21:46:59 +00:00
else
#endif
2001-04-06 19:14:31 +00:00
r = STREQ (string, alist[i].word);
2000-03-17 21:46:59 +00:00
if (r)
2002-07-17 14:10:11 +00:00
return (i);
2000-03-17 21:46:59 +00:00
}
2002-07-17 14:10:11 +00:00
2000-03-17 21:46:59 +00:00
return -1;
}
1996-12-23 17:02:34 +00:00
/* **************************************************************** */
/* */
/* String Management Functions */
/* */
/* **************************************************************** */
2002-07-17 14:10:11 +00:00
/* Cons a new string from STRING starting at START and ending at END,
not including END. */
char *
substring (string, start, end)
2011-11-21 20:51:19 -05:00
const char *string;
2002-07-17 14:10:11 +00:00
int start, end;
{
register int len;
register char *result;
len = end - start;
result = (char *)xmalloc (len + 1);
memcpy (result, string + start, len);
2002-07-17 14:10:11 +00:00
result[len] = '\0';
return (result);
}
1996-12-23 17:02:34 +00:00
/* Replace occurrences of PAT with REP in STRING. If GLOBAL is non-zero,
replace all occurrences, otherwise replace only the first.
This returns a new string; the caller should free it. */
char *
strsub (string, pat, rep, global)
char *string, *pat, *rep;
int global;
{
1998-04-17 19:52:44 +00:00
int patlen, replen, templen, tempsize, repl, i;
1996-12-23 17:02:34 +00:00
char *temp, *r;
patlen = strlen (pat);
1998-04-17 19:52:44 +00:00
replen = strlen (rep);
1996-12-23 17:02:34 +00:00
for (temp = (char *)NULL, i = templen = tempsize = 0, repl = 1; string[i]; )
{
if (repl && STREQN (string + i, pat, patlen))
2001-04-06 19:14:31 +00:00
{
2001-11-13 17:56:06 +00:00
if (replen)
RESIZE_MALLOCED_BUFFER (temp, templen, replen, tempsize, (replen * 2));
1996-12-23 17:02:34 +00:00
for (r = rep; *r; ) /* can rep == "" */
1996-12-23 17:02:34 +00:00
temp[templen++] = *r++;
2001-11-13 17:56:06 +00:00
i += patlen ? patlen : 1; /* avoid infinite recursion */
1996-12-23 17:02:34 +00:00
repl = global != 0;
2001-04-06 19:14:31 +00:00
}
1996-12-23 17:02:34 +00:00
else
{
RESIZE_MALLOCED_BUFFER (temp, templen, 1, tempsize, 16);
temp[templen++] = string[i++];
}
}
2009-01-12 13:36:28 +00:00
if (temp)
temp[templen] = 0;
else
temp = savestring (string);
1996-12-23 17:02:34 +00:00
return (temp);
}
2000-03-17 21:46:59 +00:00
/* Replace all instances of C in STRING with TEXT. TEXT may be empty or
NULL. If DO_GLOB is non-zero, we quote the replacement text for
globbing. Backslash may be used to quote C. */
char *
strcreplace (string, c, text, do_glob)
char *string;
int c;
const char *text;
2000-03-17 21:46:59 +00:00
int do_glob;
{
char *ret, *p, *r, *t;
int len, rlen, ind, tlen;
len = STRLEN (text);
rlen = len + strlen (string) + 2;
2001-11-13 17:56:06 +00:00
ret = (char *)xmalloc (rlen);
2000-03-17 21:46:59 +00:00
for (p = string, r = ret; p && *p; )
{
if (*p == c)
{
if (len)
{
ind = r - ret;
if (do_glob && (glob_pattern_p (text) || strchr (text, '\\')))
{
t = quote_globbing_chars (text);
tlen = strlen (t);
RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
r = ret + ind; /* in case reallocated */
strcpy (r, t);
r += tlen;
free (t);
}
else
{
RESIZE_MALLOCED_BUFFER (ret, ind, len, rlen, rlen);
r = ret + ind; /* in case reallocated */
strcpy (r, text);
r += len;
}
}
p++;
continue;
}
2001-04-06 19:14:31 +00:00
if (*p == '\\' && p[1] == c)
2000-03-17 21:46:59 +00:00
p++;
2001-11-13 17:56:06 +00:00
ind = r - ret;
2001-04-06 19:14:31 +00:00
RESIZE_MALLOCED_BUFFER (ret, ind, 2, rlen, rlen);
r = ret + ind; /* in case reallocated */
2000-03-17 21:46:59 +00:00
*r++ = *p++;
}
*r = '\0';
return ret;
}
1997-06-05 14:59:13 +00:00
#ifdef INCLUDE_UNUSED
1996-12-23 17:02:34 +00:00
/* Remove all leading whitespace from STRING. This includes
newlines. STRING should be terminated with a zero. */
void
strip_leading (string)
char *string;
{
char *start = string;
while (*string && (whitespace (*string) || *string == '\n'))
string++;
if (string != start)
{
int len = strlen (string);
FASTCOPY (string, start, len);
start[len] = '\0';
}
}
1997-06-05 14:59:13 +00:00
#endif
1996-12-23 17:02:34 +00:00
/* Remove all trailing whitespace from STRING. This includes
newlines. If NEWLINES_ONLY is non-zero, only trailing newlines
are removed. STRING should be terminated with a zero. */
void
1997-06-05 14:59:13 +00:00
strip_trailing (string, len, newlines_only)
1996-12-23 17:02:34 +00:00
char *string;
1997-06-05 14:59:13 +00:00
int len;
1996-12-23 17:02:34 +00:00
int newlines_only;
{
while (len >= 0)
{
if ((newlines_only && string[len] == '\n') ||
2001-04-06 19:14:31 +00:00
(!newlines_only && whitespace (string[len])))
len--;
1996-12-23 17:02:34 +00:00
else
2001-04-06 19:14:31 +00:00
break;
1996-12-23 17:02:34 +00:00
}
string[len + 1] = '\0';
}
/* A wrapper for bcopy that can be prototyped in general.h */
void
xbcopy (s, d, n)
char *s, *d;
int n;
{
FASTCOPY (s, d, n);
}