version 1.18, 2001/05/07 22:54:53 |
version 1.19, 2001/05/23 12:34:49 |
|
|
* SUCH DAMAGE. |
* SUCH DAMAGE. |
*/ |
*/ |
|
|
#include "make.h" |
#include <ctype.h> |
|
#include <string.h> |
|
#include "config.h" |
|
#include "defines.h" |
|
#include "str.h" |
|
#include "memory.h" |
|
#include "buf.h" |
|
|
#ifndef lint |
|
#if 0 |
|
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; |
|
#else |
|
UNUSED |
|
static char rcsid[] = "$OpenBSD$"; |
|
#endif |
|
#endif /* not lint */ |
|
|
|
/*- |
|
* str_concati -- |
|
* concatenate the two strings, possibly inserting a separator |
|
* |
|
* returns -- |
|
* the resulting string in allocated space. |
|
*/ |
|
char * |
char * |
str_concati(s1, s2, e2, sep) |
Str_concati(s1, e1, s2, e2, sep) |
const char *s1, *s2, *e2; |
const char *s1, *e1, *s2, *e2; |
int sep; |
int sep; |
{ |
{ |
size_t len1, len2; |
size_t len1, len2; |
char *result; |
char *result; |
|
|
/* get the length of both strings */ |
/* get the length of both strings */ |
len1 = strlen(s1); |
len1 = e1 - s1; |
len2 = e2 - s2; |
len2 = e2 - s2; |
|
|
/* space for separator */ |
/* space for separator */ |
|
|
return argv; |
return argv; |
} |
} |
|
|
/* Iterate through a string word by word, |
|
* without needing to copy anything. |
|
* More light-weight than brk_string, handles \ ' " as well. |
|
* |
|
* position = s; |
|
* while ((begin = iterate_words(&position)) != NULL) { |
|
* do_something_with_word_interval(begin, position); |
|
* } |
|
*/ |
|
const char * |
const char * |
iterate_words(end) |
iterate_words(end) |
const char **end; |
const char **end; |
|
|
} |
} |
} |
} |
|
|
/* |
bool |
* Str_Matchi -- |
Str_Matchi(string, estring, pattern, end) |
* |
|
* See if a particular string matches a particular pattern. |
|
* |
|
* Results: TRUE is returned if string matches pattern, FALSE otherwise. The |
|
* matching operation permits the following special characters in the |
|
* pattern: *?\[] (see the man page for details on what these mean). |
|
*/ |
|
Boolean |
|
Str_Matchi(string, pattern, end) |
|
const char *string; /* String */ |
const char *string; /* String */ |
|
const char *estring; /* End of string */ |
const char *pattern; /* Pattern */ |
const char *pattern; /* Pattern */ |
const char *end; /* End of Pattern */ |
const char *end; /* End of Pattern */ |
{ |
{ |
|
|
* calls only occur on `real' characters. */ |
* calls only occur on `real' characters. */ |
while (pattern != end && (*pattern == '?' || *pattern == '*')) { |
while (pattern != end && (*pattern == '?' || *pattern == '*')) { |
if (*pattern == '?') { |
if (*pattern == '?') { |
if (*string == '\0') |
if (string == estring) |
return FALSE; |
return false; |
else |
else |
string++; |
string++; |
} |
} |
pattern++; |
pattern++; |
} |
} |
if (pattern == end) |
if (pattern == end) |
return TRUE; |
return true; |
for (; *string != '\0'; string++) |
for (; string != estring; string++) |
if (Str_Matchi(string, pattern, end)) |
if (Str_Matchi(string, estring, pattern, end)) |
return TRUE; |
return true; |
return FALSE; |
return false; |
} else if (*string == '\0') |
} else if (string == estring) |
return FALSE; |
return false; |
/* Check for a "[" as the next pattern character. It is |
/* Check for a "[" as the next pattern character. It is |
* followed by a list of characters that are acceptable, or |
* followed by a list of characters that are acceptable, or |
* by a range (two characters separated by "-"). */ |
* by a range (two characters separated by "-"). */ |
else if (*pattern == '[') { |
else if (*pattern == '[') { |
pattern++; |
pattern++; |
if (pattern == end) |
if (pattern == end) |
return FALSE; |
return false; |
if (*pattern == '!' || *pattern == '^') { |
if (*pattern == '!' || *pattern == '^') { |
pattern++; |
pattern++; |
if (pattern == end) |
if (pattern == end) |
return FALSE; |
return false; |
/* Negative match */ |
/* Negative match */ |
for (;;) { |
for (;;) { |
if (*pattern == '\\') { |
if (*pattern == '\\') { |
if (++pattern == end) |
if (++pattern == end) |
return FALSE; |
return false; |
} |
} |
if (*pattern == *string) |
if (*pattern == *string) |
return FALSE; |
return false; |
if (pattern[1] == '-') { |
if (pattern[1] == '-') { |
if (pattern + 2 == end) |
if (pattern + 2 == end) |
return FALSE; |
return false; |
if (*pattern < *string && *string <= pattern[2]) |
if (*pattern < *string && *string <= pattern[2]) |
return FALSE; |
return false; |
if (pattern[2] <= *string && *string < *pattern) |
if (pattern[2] <= *string && *string < *pattern) |
return FALSE; |
return false; |
pattern += 3; |
pattern += 3; |
} else |
} else |
pattern++; |
pattern++; |
if (pattern == end) |
if (pattern == end) |
return FALSE; |
return false; |
/* The test for ']' is done at the end so that ']' |
/* The test for ']' is done at the end so that ']' |
* can be used at the start of the range without '\' */ |
* can be used at the start of the range without '\' */ |
if (*pattern == ']') |
if (*pattern == ']') |
|
|
for (;;) { |
for (;;) { |
if (*pattern == '\\') { |
if (*pattern == '\\') { |
if (++pattern == end) |
if (++pattern == end) |
return FALSE; |
return false; |
} |
} |
if (*pattern == *string) |
if (*pattern == *string) |
break; |
break; |
if (pattern[1] == '-') { |
if (pattern[1] == '-') { |
if (pattern + 2 == end) |
if (pattern + 2 == end) |
return FALSE; |
return false; |
if (*pattern < *string && *string <= pattern[2]) |
if (*pattern < *string && *string <= pattern[2]) |
break; |
break; |
if (pattern[2] <= *string && *string < *pattern) |
if (pattern[2] <= *string && *string < *pattern) |
|
|
/* The test for ']' is done at the end so that ']' |
/* The test for ']' is done at the end so that ']' |
* can be used at the start of the range without '\' */ |
* can be used at the start of the range without '\' */ |
if (pattern == end || *pattern == ']') |
if (pattern == end || *pattern == ']') |
return FALSE; |
return false; |
} |
} |
/* Found matching character, skip over rest of class. */ |
/* Found matching character, skip over rest of class. */ |
while (*pattern != ']') { |
while (*pattern != ']') { |
|
|
* '\' so we do exact matching on the character that follows. */ |
* '\' so we do exact matching on the character that follows. */ |
if (*pattern == '\\') { |
if (*pattern == '\\') { |
if (++pattern == end) |
if (++pattern == end) |
return FALSE; |
return false; |
} |
} |
/* There's no special character. Just make sure that |
/* There's no special character. Just make sure that |
* the next characters of each string match. */ |
* the next characters of each string match. */ |
if (*pattern != *string) |
if (*pattern != *string) |
return FALSE; |
return false; |
} |
} |
pattern++; |
pattern++; |
string++; |
string++; |
} |
} |
if (*string == '\0') |
if (string == estring) |
return TRUE; |
return true; |
else |
else |
return FALSE; |
return false; |
} |
} |
|
|
|
|
|
|
|
|
if ((m = strchr(pat, '%')) != NULL) { |
if ((m = strchr(pat, '%')) != NULL) { |
/* Copy the prefix. */ |
/* Copy the prefix. */ |
Buf_AddInterval(buf, pat, m); |
Buf_Addi(buf, pat, m); |
/* Skip the %. */ |
/* Skip the %. */ |
pat = m + 1; |
pat = m + 1; |
} |
} |
|
|
} |
} |
|
|
char * |
char * |
interval_dup(begin, end) |
Str_dupi(begin, end) |
const char *begin; |
const char *begin; |
const char *end; |
const char *end; |
{ |
{ |
|
|
return s; |
return s; |
} |
} |
|
|
/* copy interval, skipping characters in the set. */ |
|
char * |
char * |
escape_dup(begin, end, set) |
escape_dupi(begin, end, set) |
const char *begin; |
const char *begin; |
const char *end; |
const char *end; |
const char *set; |
const char *set; |
|
|
} |
} |
|
|
char * |
char * |
lastchar(s, e, c) |
Str_rchri(s, e, c) |
const char *s; |
const char *s; |
const char *e; |
const char *e; |
int c; |
int c; |