From 5c807f54573f3cb63dda2e478f9d8accc7726afe Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 21 Apr 1994 20:36:47 +0000 Subject: [PATCH] (find_char_unquote): New function, generalized from find_percent. (find_percent, find_semicolon, parse_file_seq): Use that. --- read.c | 154 ++++++++++++++++++++++++++------------------------------- 1 file changed, 71 insertions(+), 83 deletions(-) diff --git a/read.c b/read.c index 4b66c935..a74b9e32 100644 --- a/read.c +++ b/read.c @@ -1411,83 +1411,80 @@ record_files (filenames, pattern, pattern_percent, deps, commands_started, } } +/* Search STRING for an unquoted STOPCHAR or blank (if BLANK is nonzero). + Backslashes quote STOPCHAR, blanks if BLANK is nonzero, and backslash. + Quoting backslashes are removed from STRING by compacting it into + itself. Returns a pointer to the first unquoted STOPCHAR if there is + one, or nil if there are none. */ + +char * +find_char_unquote (string, stopchar, blank) + char *string; + int stopchar; + int blank; +{ + unsigned int string_len = strlen (string); + register char *p = string; + + while (1) + { + if (blank) + { + while (*p != '\0' && *p != stopchar && !isblank (*p)) + ++p; + if (*p == '\0') + break; + } + else + { + p = index (p, stopchar); + if (p == 0) + break; + } + if (p > string && p[-1] == '\\') + { + /* Search for more backslashes. */ + register int i = -2; + while (&p[i] >= string && p[i] == '\\') + --i; + ++i; + /* The number of backslashes is now -I. + Copy P over itself to swallow half of them. */ + bcopy (&p[i / 2], &p[i], (string_len - (p - string)) - (i / 2) + 1); + p += i / 2; + if (i % 2 == 0) + /* All the backslashes quoted each other; the STOPCHAR was + unquoted. */ + return p; + + /* The STOPCHAR was quoted by a backslash. Look for another. */ + } + else + /* No backslash in sight. */ + return p; + } + + /* Never hit a STOPCHAR or blank (with BLANK nonzero). */ + return 0; +} + +/* Search PATTERN for an unquoted %. */ + +char * +find_percent (pattern) + char *pattern; +{ + return find_char_unquote (pattern, '%', 0); +} + /* Search STRING for an unquoted ; that is not after an unquoted #. */ static char * find_semicolon (string) char *string; { - char *found, *p; - - found = index (string, ';'); - while (found != 0 && found[-1] == '\\') - { - register char *q = &found[-1]; - register int backslash = 0; - while (*q-- == '\\') - backslash = !backslash; - if (backslash) - found = index (found + 1, ';'); - else - break; - } - if (found == 0) - return 0; - - /* Look for a comment character (#) before the ; we found. */ - p = lindex (string, found, '#'); - while (p != 0 && p[-1] == '\\') - { - register char *q = &p[-1]; - register int backslash = 0; - while (*q-- == '\\') - backslash = !backslash; - if (backslash) - p = lindex (p + 1, found, '#'); - else - break; - } - if (p == 0) - return found; - return 0; -} - -/* Search PATTERN for an unquoted %. Backslashes quote % and backslash. - Quoting backslashes are removed from PATTERN by compacting it into - itself. Returns a pointer to the first unquoted % if there is one, - or nil if there are none. */ - -char * -find_percent (pattern) - char *pattern; -{ - unsigned int pattern_len = strlen (pattern); - register char *p = pattern; - - while ((p = index (p, '%')) != 0) - if (p > pattern && p[-1] == '\\') - { - /* Search for more backslashes. */ - register int i = -2; - while (&p[i] >= pattern && p[i] == '\\') - --i; - ++i; - /* The number of backslashes is now -I. - Copy P over itself to swallow half of them. */ - bcopy (&p[i / 2], &p[i], (pattern_len - (p - pattern)) - (i / 2) + 1); - p += i / 2; - if (i % 2 == 0) - /* All the backslashes quoted each other; the % was unquoted. */ - return p; - - /* The % was quoted by a backslash. Look for another. */ - } - else - /* No backslash in sight. */ - return p; - - /* Never hit a %. */ - return 0; + return (find_char_unquote (string, '#', 0) == 0 + ? find_char_unquote (string, ';', 0) : 0); } /* Parse a string into a sequence of filenames represented as a @@ -1527,18 +1524,9 @@ parse_file_seq (stringp, stopchar, size, strip) break; /* Yes, find end of next name. */ q = p; - while (1) - { - c = *p++; - if (c == '\0') - break; - else if (c == '\\' && - (*p == '\\' || isblank (*p) || *p == stopchar)) - ++p; - else if (isblank (c) || c == stopchar) - break; - } - p--; + p = find_char_unquote (q, stopchar, 1); + if (p == 0) + p = q + strlen (q) if (strip) /* Skip leading `./'s. */