summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorespie <espie@openbsd.org>2000-09-14 13:35:38 +0000
committerespie <espie@openbsd.org>2000-09-14 13:35:38 +0000
commit032093b68a4f1257981ebe8272c0b6e0321743d2 (patch)
tree609b26e6cc119ac0e000c7994d2203cd30654d39
parentSome systematic clean-up. (diff)
downloadwireguard-openbsd-032093b68a4f1257981ebe8272c0b6e0321743d2.tar.xz
wireguard-openbsd-032093b68a4f1257981ebe8272c0b6e0321743d2.zip
Two new functions:
iterate_words: light-weight equivalent to brk_string, which does not need to copy the string, and does not do \ interpretation which are only needed for the string. escape_dup: handles escape sequence in a systematic way. This speeds up variable modifiers. This also makes .for loops more consistent, as they use the same definition of `a word' as the rest of make.
-rw-r--r--usr.bin/make/extern.h4
-rw-r--r--usr.bin/make/for.c21
-rw-r--r--usr.bin/make/str.c79
-rw-r--r--usr.bin/make/varmodifiers.c38
4 files changed, 107 insertions, 35 deletions
diff --git a/usr.bin/make/extern.h b/usr.bin/make/extern.h
index 195104511b0..0afd9d673a5 100644
--- a/usr.bin/make/extern.h
+++ b/usr.bin/make/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.30 2000/09/14 13:32:06 espie Exp $ */
+/* $OpenBSD: extern.h,v 1.31 2000/09/14 13:35:38 espie Exp $ */
/* $NetBSD: nonints.h,v 1.12 1996/11/06 17:59:19 christos Exp $ */
/*-
@@ -105,10 +105,12 @@ extern void str_init __P((void));
extern void str_end __P((void));
extern char *str_concat __P((const char *, const char *, char));
extern char **brk_string __P((const char *, int *, Boolean, char **));
+extern const char *iterate_words __P((const char **));
extern int Str_Match __P((const char *, const char *));
extern const char *Str_SYSVMatch __P((const char *, const char *, size_t *len));
extern void Str_SYSVSubst __P((Buffer, const char *, const char *, size_t));
extern char *interval_dup __P((const char *begin, const char *end));
+extern char *escape_dup __P((const char *, const char *, const char *));
/* suff.c */
extern void Suff_ClearSuffixes __P((void));
diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c
index 96df436b6c7..b2b0fc11c37 100644
--- a/usr.bin/make/for.c
+++ b/usr.bin/make/for.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: for.c,v 1.21 2000/09/14 13:32:06 espie Exp $ */
+/* $OpenBSD: for.c,v 1.22 2000/09/14 13:35:38 espie Exp $ */
/* $NetBSD: for.c,v 1.4 1996/11/06 17:59:05 christos Exp $ */
/*
@@ -83,7 +83,7 @@
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
UNUSED
-static char rcsid[] = "$OpenBSD: for.c,v 1.21 2000/09/14 13:32:06 espie Exp $";
+static char rcsid[] = "$OpenBSD: for.c,v 1.22 2000/09/14 13:35:38 espie Exp $";
#endif
#endif /* not lint */
@@ -121,19 +121,12 @@ build_words_list(lst, s)
Lst lst;
const char *s;
{
- const char *wrd;
+ const char *end, *wrd;
- for (;;) {
- for (; *s != '\0' && isspace(*s); s++)
- continue;
- if (*s == '\0')
- break;
- for (wrd = s; *s != '\0' && !isspace(*s); s++)
- continue;
- /* note that we fill the list backward, since
- * Parse_FromString stacks strings. */
- Lst_AtFront(lst, interval_dup(wrd, s));
- }
+ end = s;
+
+ while ((wrd = iterate_words(&end)) != NULL)
+ Lst_AtFront(lst, escape_dup(wrd, end, "\"'"));
}
/*
diff --git a/usr.bin/make/str.c b/usr.bin/make/str.c
index 0858a3e76ca..2490b4dd90b 100644
--- a/usr.bin/make/str.c
+++ b/usr.bin/make/str.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: str.c,v 1.15 2000/09/14 13:32:07 espie Exp $ */
+/* $OpenBSD: str.c,v 1.16 2000/09/14 13:35:38 espie Exp $ */
/* $NetBSD: str.c,v 1.13 1996/11/06 17:59:23 christos Exp $ */
/*-
@@ -46,7 +46,7 @@
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
#else
UNUSED
-static char rcsid[] = "$OpenBSD: str.c,v 1.15 2000/09/14 13:32:07 espie Exp $";
+static char rcsid[] = "$OpenBSD: str.c,v 1.16 2000/09/14 13:35:38 espie Exp $";
#endif
#endif /* not lint */
@@ -219,6 +219,54 @@ done: argv[argc] = (char *)NULL;
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 *
+iterate_words(end)
+ const char **end;
+{
+ const char *start, *p;
+ char state = 0;
+ start = *end;
+
+ while (isspace(*start))
+ start++;
+ if (*start == '\0')
+ return NULL;
+
+ for (p = start;; p++)
+ switch(*p) {
+ case '\\':
+ if (p[1] != '\0')
+ p++;
+ break;
+ case '\'':
+ case '"':
+ if (state == *p)
+ state = 0;
+ else if (state == 0)
+ state = *p;
+ break;
+ case ' ':
+ case '\t':
+ if (state != 0)
+ break;
+ /* FALLTHROUGH */
+ case '\0':
+ *end = p;
+ return start;
+ default:
+ break;
+ }
+}
+
/*
* Str_Match --
*
@@ -452,3 +500,30 @@ interval_dup(begin, end)
s[end-begin] = '\0';
return s;
}
+
+/* copy interval, skipping characters in the set. */
+char *
+escape_dup(begin, end, set)
+ const char *begin;
+ const char *end;
+ const char *set;
+{
+ char *s, *t;
+
+ t = s = emalloc(end - begin + 1);
+ while (begin != end) {
+ if (*begin == '\\') {
+ begin++;
+ if (begin == end) {
+ *t++ = '\\';
+ break;
+ }
+ if (strchr(set, *begin) == NULL)
+ *t++ = '\\';
+ }
+ *t++ = *begin++;
+ }
+ *t++ = '\0';
+ return s;
+}
+
diff --git a/usr.bin/make/varmodifiers.c b/usr.bin/make/varmodifiers.c
index cacb91cd478..e2b7eee46c1 100644
--- a/usr.bin/make/varmodifiers.c
+++ b/usr.bin/make/varmodifiers.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: varmodifiers.c,v 1.4 2000/07/24 21:57:28 espie Exp $ */
+/* $OpenBSD: varmodifiers.c,v 1.5 2000/09/14 13:35:38 espie Exp $ */
/* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */
/*
@@ -118,7 +118,7 @@ static Boolean VarSubstitute __P((const char *, Boolean, Buffer, void *));
static char *VarGetPattern __P((SymTable *, int, char **, int, int *, size_t *,
VarPattern *));
static char *VarQuote __P((const char *));
-static char *VarModify __P((const char *, Boolean (*)(const char *, Boolean, Buffer, void *), void *));
+static char *VarModify __P((char *, Boolean (*)(const char *, Boolean, Buffer, void *), void *));
static Boolean VarUppercase __P((const char *, Boolean, Buffer, void *));
static Boolean VarLowercase __P((const char *, Boolean, Buffer, void *));
@@ -769,19 +769,18 @@ VarRESubstitute(word, addSpace, buf, patternp)
*-----------------------------------------------------------------------
*/
static char *
-VarModify (str, modProc, datum)
- const char *str; /* String whose words should be trimmed */
- /* Function to use to modify them */
+VarModify(str, modProc, datum)
+ char *str; /* String whose words should be trimmed */
+ /* Function to use to modify them */
Boolean (*modProc) __P((const char *, Boolean, Buffer, void *));
- void *datum; /* Datum to pass it */
+ void *datum; /* Datum to pass it */
{
- BUFFER buf; /* Buffer for the new string */
- Boolean addSpace; /* TRUE if need to add a space to the
- * buffer before adding the trimmed
- * word */
- char **av; /* word list */
- char *as; /* word list memory */
- int ac, i;
+ BUFFER buf; /* Buffer for the new string */
+ Boolean addSpace; /* TRUE if need to add a space to the
+ * buffer before adding the trimmed
+ * word */
+ char *end;
+ char *word;
if (str == NULL)
return NULL;
@@ -789,13 +788,16 @@ VarModify (str, modProc, datum)
Buf_Init(&buf, 0);
addSpace = FALSE;
- av = brk_string(str, &ac, FALSE, &as);
+ end = str;
- for (i = 0; i < ac; i++)
- addSpace = (*modProc)(av[i], addSpace, &buf, datum);
+ while ((word = iterate_words(&end)) != NULL) {
+ char termc;
- free(as);
- free(av);
+ termc = *end;
+ *end = '\0';
+ addSpace = (*modProc)(word, addSpace, &buf, datum);
+ *end = termc;
+ }
return Buf_Retrieve(&buf);
}