diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2001-05-03 13:41:28 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2001-05-03 13:41:28 +0000 |
commit | 32d5cfe8f4f4bd9647d36fc0f609479f02311103 (patch) | |
tree | 06bd5d3e7a2a46bf77a1da707955bfdc16acf068 /usr.bin/make/str.c | |
parent | a50fea6f0032902e640160d4c42a8c9ce003fc2d (diff) |
Synch with my current work.
Numerous changes:
- generate can build several tables
- style cleanup
- statistics code
- use variable names throughout (struct Name)
- recursive variables everywhere
- faster parser (pass buffer along instead of allocating multiple copies)
- correct parser. Handles comments everywhere, and ; correctly
- more string intervals
- simplified dir.c, less recursion.
- extended for loops
- sinclude()
- finished removing extra junk from Lst_*
- handles ${@D} and friends in a simpler way
- cleaned up and modular VarModifiers handling.
- recognizes some gnu Makefile usages and errors out about them.
Additionally, some extra functionality is defined by FEATURES. The set of
functionalities is currently hardcoded to OpenBSD defaults, but this may
include support for some NetBSD extensions, like ODE modifiers.
Backed by miod@ and millert@, who finally got sick of my endless patches...
Diffstat (limited to 'usr.bin/make/str.c')
-rw-r--r-- | usr.bin/make/str.c | 360 |
1 files changed, 182 insertions, 178 deletions
diff --git a/usr.bin/make/str.c b/usr.bin/make/str.c index 2490b4dd90b..d51f0cc6e29 100644 --- a/usr.bin/make/str.c +++ b/usr.bin/make/str.c @@ -1,4 +1,5 @@ -/* $OpenBSD: str.c,v 1.16 2000/09/14 13:35:38 espie Exp $ */ +/* $OpenPackages$ */ +/* $OpenBSD: str.c,v 1.17 2001/05/03 13:41:11 espie Exp $ */ /* $NetBSD: str.c,v 1.13 1996/11/06 17:59:23 christos Exp $ */ /*- @@ -43,31 +44,31 @@ #ifndef lint #if 0 -static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; +static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; #else UNUSED -static char rcsid[] = "$OpenBSD: str.c,v 1.16 2000/09/14 13:35:38 espie Exp $"; +static char rcsid[] = "$OpenBSD: str.c,v 1.17 2001/05/03 13:41:11 espie Exp $"; #endif #endif /* not lint */ /*- - * str_concat -- + * str_concati -- * concatenate the two strings, possibly inserting a separator * * returns -- * the resulting string in allocated space. */ char * -str_concat(s1, s2, sep) - const char *s1, *s2; - char sep; +str_concati(s1, s2, e2, sep) + const char *s1, *s2, *e2; + int sep; { size_t len1, len2; char *result; /* get the length of both strings */ len1 = strlen(s1); - len2 = strlen(s2); + len2 = e2 - s2; /* space for separator */ if (sep) @@ -78,7 +79,7 @@ str_concat(s1, s2, sep) memcpy(result, s1, len1); /* add separator character */ - if (sep) + if (sep) result[len1-1] = sep; /* copy second string plus EOS into place */ @@ -93,130 +94,117 @@ str_concat(s1, s2, sep) * are ignored. * * returns -- - * Pointer to the array of pointers to the words. To make life easier, + * Pointer to the array of pointers to the words. To make life easier, * the first word is always the value of the .MAKE variable. */ char ** -brk_string(str, store_argc, expand, buffer) - const char *str; - int *store_argc; - Boolean expand; - char **buffer; +brk_string(str, store_argc, buffer) + const char *str; + int *store_argc; + char **buffer; { - register int argc, ch; - char inquote; - const char *p; - char *start, *t; - size_t len; - int argmax = 50; - size_t curlen = 0; - char **argv = (char **)emalloc((argmax + 1) * sizeof(char *)); - - /* skip leading space chars. */ - for (; *str == ' ' || *str == '\t'; ++str) - continue; - - /* allocate room for a copy of the string */ - if ((len = strlen(str) + 1) > curlen) - *buffer = emalloc(curlen = len); - - /* - * copy the string; at the same time, parse backslashes, - * quotes and build the argument list. - */ - argc = 0; - inquote = '\0'; - for (p = str, start = t = *buffer;; ++p) { - switch(ch = *p) { - case '"': - case '\'': - if (inquote) { - if (inquote == ch) - inquote = '\0'; - else - break; - } else { - inquote = (char) ch; - /* Don't miss "" or '' */ - if (start == NULL && p[1] == inquote) { - start = t + 1; - break; - } - } - if (!expand) { - if (!start) - start = t; - *t++ = ch; - } - continue; - case ' ': - case '\t': - case '\n': - if (inquote) - break; - if (!start) - continue; - /* FALLTHROUGH */ - case '\0': - /* - * end of a token -- make sure there's enough argv - * space and save off a pointer. - */ - if (!start) - goto done; - - *t++ = '\0'; - if (argc == argmax) { - argmax *= 2; /* ramp up fast */ - argv = (char **)erealloc(argv, - (argmax + 1) * sizeof(char *)); - } - argv[argc++] = start; - start = (char *)NULL; - if (ch == '\n' || ch == '\0') - goto done; - continue; - case '\\': - if (!expand) { - if (!start) - start = t; - *t++ = '\\'; - ch = *++p; - break; - } - - switch (ch = *++p) { - case '\0': - case '\n': - /* hmmm; fix it up as best we can */ - ch = '\\'; - --p; - break; - case 'b': - ch = '\b'; - break; - case 'f': - ch = '\f'; - break; - case 'n': - ch = '\n'; - break; - case 'r': - ch = '\r'; - break; - case 't': - ch = '\t'; - break; - } - break; + int argc; + char ch; + char inquote; + const char *p; + char *start, *t; + size_t len; + int argmax = 50; + size_t curlen = 0; + char **argv = emalloc((argmax + 1) * sizeof(char *)); + + /* skip leading space chars. */ + for (; *str == ' ' || *str == '\t'; ++str) + continue; + + /* allocate room for a copy of the string */ + if ((len = strlen(str) + 1) > curlen) + *buffer = emalloc(curlen = len); + + /* + * copy the string; at the same time, parse backslashes, + * quotes and build the argument list. + */ + argc = 0; + inquote = '\0'; + for (p = str, start = t = *buffer;; ++p) { + switch (ch = *p) { + case '"': + case '\'': + if (inquote) { + if (inquote == ch) + inquote = '\0'; + else + break; + } else { + inquote = ch; + /* Don't miss "" or '' */ + if (start == NULL && p[1] == inquote) { + start = t + 1; + break; } - if (!start) - start = t; - *t++ = (char) ch; + } + continue; + case ' ': + case '\t': + case '\n': + if (inquote) + break; + if (!start) + continue; + /* FALLTHROUGH */ + case '\0': + /* + * end of a token -- make sure there's enough argv + * space and save off a pointer. + */ + if (!start) + goto done; + + *t++ = '\0'; + if (argc == argmax) { + argmax *= 2; /* ramp up fast */ + argv = erealloc(argv, (argmax + 1) * sizeof(char *)); + } + argv[argc++] = start; + start = NULL; + if (ch == '\n' || ch == '\0') + goto done; + continue; + case '\\': + switch (ch = *++p) { + case '\0': + case '\n': + /* hmmm; fix it up as best we can */ + ch = '\\'; + --p; + break; + case 'b': + ch = '\b'; + break; + case 'f': + ch = '\f'; + break; + case 'n': + ch = '\n'; + break; + case 'r': + ch = '\r'; + break; + case 't': + ch = '\t'; + break; + } + break; } -done: argv[argc] = (char *)NULL; - *store_argc = argc; - return(argv); + if (!start) + start = t; + *t++ = ch; + } +done: + argv[argc] = NULL; + *store_argc = argc; + return argv; } /* Iterate through a string word by word, @@ -230,45 +218,45 @@ done: argv[argc] = (char *)NULL; */ const char * iterate_words(end) - const char **end; + const char **end; { - const char *start, *p; + const char *start, *p; char state = 0; start = *end; while (isspace(*start)) - start++; + start++; if (*start == '\0') - return NULL; + return NULL; for (p = start;; p++) - switch(*p) { + switch(*p) { case '\\': - if (p[1] != '\0') + if (p[1] != '\0') p++; break; case '\'': case '"': - if (state == *p) + if (state == *p) state = 0; else if (state == 0) state = *p; break; case ' ': case '\t': - if (state != 0) + if (state != 0) break; - /* FALLTHROUGH */ + /* FALLTHROUGH */ case '\0': - *end = p; + *end = p; return start; default: - break; + break; } } - + /* - * Str_Match -- + * Str_Matchi -- * * See if a particular string matches a particular pattern. * @@ -277,11 +265,12 @@ iterate_words(end) * pattern: *?\[] (see the man page for details on what these mean). */ Boolean -Str_Match(string, pattern) - const char *string; /* String */ +Str_Matchi(string, pattern, end) + const char *string; /* String */ const char *pattern; /* Pattern */ + const char *end; /* End of Pattern */ { - while (*pattern != '\0') { + while (pattern != end) { /* Check for a "*" as the next pattern character. It matches * any substring. We handle this by calling ourselves * recursively for each postfix of string, until either we @@ -290,7 +279,7 @@ Str_Match(string, pattern) pattern++; /* Skip over contiguous sequences of `?*', so that recursive * calls only occur on `real' characters. */ - while (*pattern == '?' || *pattern == '*') { + while (pattern != end && (*pattern == '?' || *pattern == '*')) { if (*pattern == '?') { if (*string == '\0') return FALSE; @@ -299,35 +288,35 @@ Str_Match(string, pattern) } pattern++; } - if (*pattern == '\0') + if (pattern == end) return TRUE; for (; *string != '\0'; string++) - if (Str_Match(string, pattern)) + if (Str_Matchi(string, pattern, end)) return TRUE; return FALSE; - } else if (*string == '\0') + } else if (*string == '\0') return FALSE; /* Check for a "[" as the next pattern character. It is * followed by a list of characters that are acceptable, or * by a range (two characters separated by "-"). */ else if (*pattern == '[') { pattern++; - if (*pattern == '\0') - return FALSE; + if (pattern == end) + return FALSE; if (*pattern == '!' || *pattern == '^') { pattern++; - if (*pattern == '\0') + if (pattern == end) return FALSE; /* Negative match */ for (;;) { if (*pattern == '\\') { - if (*++pattern == '\0') + if (++pattern == end) return FALSE; } if (*pattern == *string) return FALSE; if (pattern[1] == '-') { - if (pattern[2] == '\0') + if (pattern + 2 == end) return FALSE; if (*pattern < *string && *string <= pattern[2]) return FALSE; @@ -336,23 +325,23 @@ Str_Match(string, pattern) pattern += 3; } else pattern++; - if (*pattern == '\0') - return FALSE; + if (pattern == end) + return FALSE; /* The test for ']' is done at the end so that ']' * can be used at the start of the range without '\' */ if (*pattern == ']') - break; + break; } } else { for (;;) { if (*pattern == '\\') { - if (*++pattern == '\0') + if (++pattern == end) return FALSE; } if (*pattern == *string) break; if (pattern[1] == '-') { - if (pattern[2] == '\0') + if (pattern + 2 == end) return FALSE; if (*pattern < *string && *string <= pattern[2]) break; @@ -363,15 +352,15 @@ Str_Match(string, pattern) pattern++; /* The test for ']' is done at the end so that ']' * can be used at the start of the range without '\' */ - if (*pattern == '\0' || *pattern == ']') - return FALSE; + if (pattern == end || *pattern == ']') + return FALSE; } /* Found matching character, skip over rest of class. */ while (*pattern != ']') { if (*pattern == '\\') pattern++; - /* A non-terminated character class is ok. */ - if (*pattern == '\0') + /* A non-terminated character class is ok. */ + if (pattern == end) break; pattern++; } @@ -382,10 +371,10 @@ Str_Match(string, pattern) /* If the next pattern character is '\', just strip off the * '\' so we do exact matching on the character that follows. */ if (*pattern == '\\') { - if (*++pattern == '\0') + if (++pattern == end) 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. */ if (*pattern != *string) return FALSE; @@ -399,6 +388,7 @@ Str_Match(string, pattern) return FALSE; } + /*- *----------------------------------------------------------------------- * Str_SYSVMatch -- @@ -420,21 +410,21 @@ Str_SYSVMatch(word, pattern, len) const char *m; if (*p == '\0') { - /* Null pattern is the whole string */ + /* Null pattern is the whole string. */ *len = strlen(w); return w; } if ((m = strchr(p, '%')) != NULL) { - /* check that the prefix matches */ + /* Check that the prefix matches. */ for (; p != m && *w && *w == *p; w++, p++) continue; if (p != m) - return NULL; /* No match */ + return NULL; /* No match. */ if (*++p == '\0') { - /* No more pattern, return the rest of the string */ + /* No more pattern, return the rest of the string. */ *len = strlen(w); return w; } @@ -442,13 +432,14 @@ Str_SYSVMatch(word, pattern, len) m = w; - /* Find a matching tail */ - do + /* Find a matching tail. */ + do { if (strcmp(p, w) == 0) { *len = w - m; return m; } - while (*w++ != '\0'); + } while (*w++ != '\0'); + return NULL; } @@ -475,16 +466,16 @@ Str_SYSVSubst(buf, pat, src, len) const char *m; if ((m = strchr(pat, '%')) != NULL) { - /* Copy the prefix */ + /* Copy the prefix. */ Buf_AddInterval(buf, pat, m); - /* skip the % */ + /* Skip the %. */ pat = m + 1; } - /* Copy the pattern */ + /* Copy the pattern. */ Buf_AddChars(buf, len, src); - /* append the rest */ + /* Append the rest. */ Buf_AddString(buf, pat); } @@ -512,14 +503,14 @@ escape_dup(begin, end, set) t = s = emalloc(end - begin + 1); while (begin != end) { - if (*begin == '\\') { + if (*begin == '\\') { begin++; if (begin == end) { - *t++ = '\\'; + *t++ = '\\'; break; } - if (strchr(set, *begin) == NULL) - *t++ = '\\'; + if (strchr(set, *begin) == NULL) + *t++ = '\\'; } *t++ = *begin++; } @@ -527,3 +518,16 @@ escape_dup(begin, end, set) return s; } +char * +lastchar(s, e, c) + const char *s; + const char *e; + int c; +{ + if (s != e) + do { + if (*--e == c) + return (char *)e; + } while (e != s); + return NULL; +} |