From 8c218dc01b376e7a560d2b7fcbacca532b75fe4b Mon Sep 17 00:00:00 2001 From: nia Date: Sun, 24 May 2020 05:35:51 +0000 Subject: Import bmake- --- devel/bmake/files/str.c | 160 ++++++++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 67 deletions(-) (limited to 'devel/bmake/files/str.c') diff --git a/devel/bmake/files/str.c b/devel/bmake/files/str.c index 2f521979e8c..408c2b175c5 100644 --- a/devel/bmake/files/str.c +++ b/devel/bmake/files/str.c @@ -1,4 +1,4 @@ -/* $NetBSD: str.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $ */ +/* $NetBSD: str.c,v 1.1.1.7 2020/05/24 05:35:53 nia Exp $ */ /*- * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: str.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $"; +static char rcsid[] = "$NetBSD: str.c,v 1.1.1.7 2020/05/24 05:35:53 nia Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; #else -__RCSID("$NetBSD: str.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $"); +__RCSID("$NetBSD: str.c,v 1.1.1.7 2020/05/24 05:35:53 nia Exp $"); #endif #endif /* not lint */ #endif @@ -102,7 +102,7 @@ str_concat(const char *s1, const char *s2, int flags) len2 = strlen(s2); /* allocate length plus separator plus EOS */ - result = bmake_malloc((u_int)(len1 + len2 + 2)); + result = bmake_malloc((unsigned int)(len1 + len2 + 2)); /* copy first string into place */ memcpy(result, s1, len1); @@ -133,42 +133,43 @@ str_concat(const char *s1, const char *s2, int flags) * * returns -- * Pointer to the array of pointers to the words. - * Memory containing the actual words in *buffer. + * Memory containing the actual words in *store_words_buf. * Both of these must be free'd by the caller. - * Number of words in *store_argc. + * Number of words in *store_words_len. */ char ** -brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) +brk_string(const char *str, int *store_words_len, Boolean expand, + char **store_words_buf) { - int argc, ch; - char inquote, *start, *t; - const char *p; - int len; - int argmax = 50, curlen = 0; - char **argv; + char inquote; + const char *str_p; + size_t str_len; + char **words; + int words_len; + int words_cap = 50; + char *words_buf, *word_start, *word_end; /* 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 = bmake_malloc(curlen = len); + /* words_buf holds the words, separated by '\0'. */ + str_len = strlen(str); + words_buf = bmake_malloc(strlen(str) + 1); - /* - * initial argmax based on len - */ - argmax = MAX((len / 5), 50); - argv = bmake_malloc((argmax + 1) * sizeof(char *)); + words_cap = MAX((str_len / 5), 50); + words = bmake_malloc((words_cap + 1) * sizeof(char *)); /* * copy the string; at the same time, parse backslashes, - * quotes and build the argument list. + * quotes and build the word list. */ - argc = 0; + words_len = 0; inquote = '\0'; - for (p = str, start = t = *buffer;; ++p) { - switch(ch = *p) { + word_start = word_end = words_buf; + for (str_p = str;; ++str_p) { + char ch = *str_p; + switch(ch) { case '"': case '\'': if (inquote) { @@ -180,21 +181,21 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) else { inquote = (char) ch; /* Don't miss "" or '' */ - if (start == NULL && p[1] == inquote) { + if (word_start == NULL && str_p[1] == inquote) { if (!expand) { - start = t; - *t++ = ch; + word_start = word_end; + *word_end++ = ch; } else - start = t + 1; - p++; + word_start = word_end + 1; + str_p++; inquote = '\0'; break; } } if (!expand) { - if (!start) - start = t; - *t++ = ch; + if (word_start == NULL) + word_start = word_end; + *word_end++ = ch; } continue; case ' ': @@ -202,30 +203,30 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) case '\n': if (inquote) break; - if (!start) + if (word_start == NULL) continue; /* FALLTHROUGH */ case '\0': /* - * end of a token -- make sure there's enough argv + * end of a token -- make sure there's enough words * space and save off a pointer. */ - if (!start) + if (word_start == NULL) goto done; - *t++ = '\0'; - if (argc == argmax) { - argmax *= 2; /* ramp up fast */ - argv = (char **)bmake_realloc(argv, - (argmax + 1) * sizeof(char *)); + *word_end++ = '\0'; + if (words_len == words_cap) { + words_cap *= 2; /* ramp up fast */ + words = (char **)bmake_realloc(words, + (words_cap + 1) * sizeof(char *)); } - argv[argc++] = start; - start = NULL; + words[words_len++] = word_start; + word_start = NULL; if (ch == '\n' || ch == '\0') { if (expand && inquote) { - free(argv); - free(*buffer); - *buffer = NULL; + free(words); + free(words_buf); + *store_words_buf = NULL; return NULL; } goto done; @@ -233,21 +234,22 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) continue; case '\\': if (!expand) { - if (!start) - start = t; - *t++ = '\\'; - if (*(p+1) == '\0') /* catch '\' at end of line */ + if (word_start == NULL) + word_start = word_end; + *word_end++ = '\\'; + /* catch '\' at end of line */ + if (str_p[1] == '\0') continue; - ch = *++p; + ch = *++str_p; break; } - switch (ch = *++p) { + switch (ch = *++str_p) { case '\0': case '\n': /* hmmm; fix it up as best we can */ ch = '\\'; - --p; + --str_p; break; case 'b': ch = '\b'; @@ -267,13 +269,14 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) } break; } - if (!start) - start = t; - *t++ = (char) ch; + if (word_start == NULL) + word_start = word_end; + *word_end++ = ch; } -done: argv[argc] = NULL; - *store_argc = argc; - return(argv); +done: words[words_len] = NULL; + *store_words_len = words_len; + *store_words_buf = words_buf; + return words; } /* @@ -373,16 +376,26 @@ Str_Match(const char *string, const char *pattern) * by a range (two characters separated by "-"). */ if (*pattern == '[') { + int nomatch; + ++pattern; + if (*pattern == '^') { + ++pattern; + nomatch = 1; + } else + nomatch = 0; for (;;) { - if ((*pattern == ']') || (*pattern == 0)) + if ((*pattern == ']') || (*pattern == 0)) { + if (nomatch) + break; return(0); + } if (*pattern == *string) break; if (pattern[1] == '-') { c2 = pattern[2]; if (c2 == 0) - return(0); + return(nomatch); if ((*pattern <= *string) && (c2 >= *string)) break; @@ -393,8 +406,12 @@ Str_Match(const char *string, const char *pattern) } ++pattern; } + if (nomatch && (*pattern != ']') && (*pattern != 0)) + return 0; while ((*pattern != ']') && (*pattern != 0)) ++pattern; + if (*pattern == 0) + --pattern; goto thisCharOK; } /* @@ -438,12 +455,14 @@ thisCharOK: ++pattern; *----------------------------------------------------------------------- */ char * -Str_SYSVMatch(const char *word, const char *pattern, int *len) +Str_SYSVMatch(const char *word, const char *pattern, size_t *len, + Boolean *hasPercent) { const char *p = pattern; const char *w = word; const char *m; + *hasPercent = FALSE; if (*p == '\0') { /* Null pattern is the whole string */ *len = strlen(w); @@ -451,6 +470,11 @@ Str_SYSVMatch(const char *word, const char *pattern, int *len) } if ((m = strchr(p, '%')) != NULL) { + *hasPercent = TRUE; + if (*w == '\0') { + /* empty word does not match pattern */ + return NULL; + } /* check that the prefix matches */ for (; p != m && *w && *w == *p; w++, p++) continue; @@ -495,19 +519,21 @@ Str_SYSVMatch(const char *word, const char *pattern, int *len) *----------------------------------------------------------------------- */ void -Str_SYSVSubst(Buffer *buf, char *pat, char *src, int len) +Str_SYSVSubst(Buffer *buf, char *pat, char *src, size_t len, + Boolean lhsHasPercent) { char *m; - if ((m = strchr(pat, '%')) != NULL) { + if ((m = strchr(pat, '%')) != NULL && lhsHasPercent) { /* Copy the prefix */ Buf_AddBytes(buf, m - pat, pat); /* skip the % */ pat = m + 1; } - - /* Copy the pattern */ - Buf_AddBytes(buf, len, src); + if (m != NULL || !lhsHasPercent) { + /* Copy the pattern */ + Buf_AddBytes(buf, len, src); + } /* append the rest */ Buf_AddBytes(buf, strlen(pat), pat); -- cgit v1.2.3