summaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c132
1 files changed, 60 insertions, 72 deletions
diff --git a/read.c b/read.c
index 4b66c93..a74b9e3 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 ; that is not after an unquoted #. */
+/* 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. */
-static char *
-find_semicolon (string)
+char *
+find_char_unquote (string, stopchar, blank)
char *string;
+ int stopchar;
+ int blank;
{
- char *found, *p;
+ unsigned int string_len = strlen (string);
+ register char *p = string;
- found = index (string, ';');
- while (found != 0 && found[-1] == '\\')
+ while (1)
{
- register char *q = &found[-1];
- register int backslash = 0;
- while (*q-- == '\\')
- backslash = !backslash;
- if (backslash)
- found = index (found + 1, ';');
+ if (blank)
+ {
+ while (*p != '\0' && *p != stopchar && !isblank (*p))
+ ++p;
+ if (*p == '\0')
+ break;
+ }
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, '#');
+ {
+ 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
- break;
+ /* No backslash in sight. */
+ return p;
}
- if (p == 0)
- return found;
+
+ /* Never hit a STOPCHAR or blank (with BLANK nonzero). */
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. */
+
+/* Search PATTERN for an unquoted %. */
char *
find_percent (pattern)
char *pattern;
{
- unsigned int pattern_len = strlen (pattern);
- register char *p = pattern;
+ return find_char_unquote (pattern, '%', 0);
+}
- 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;
+/* Search STRING for an unquoted ; that is not after an unquoted #. */
- /* Never hit a %. */
- return 0;
+static char *
+find_semicolon (string)
+ char *string;
+{
+ 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. */