diff options
Diffstat (limited to 'str.c')
-rw-r--r-- | str.c | 241 |
1 files changed, 68 insertions, 173 deletions
@@ -1,4 +1,4 @@ -/* $NetBSD: str.c,v 1.51 2020/07/03 07:40:13 rillig Exp $ */ +/* $NetBSD: str.c,v 1.64 2020/08/30 19:56:02 rillig Exp $ */ /*- * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,85 +69,85 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: str.c,v 1.51 2020/07/03 07:40:13 rillig Exp $"; +static char rcsid[] = "$NetBSD: str.c,v 1.64 2020/08/30 19:56:02 rillig Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; #else -__RCSID("$NetBSD: str.c,v 1.51 2020/07/03 07:40:13 rillig Exp $"); +__RCSID("$NetBSD: str.c,v 1.64 2020/08/30 19:56:02 rillig Exp $"); #endif #endif /* not lint */ #endif #include "make.h" -/*- - * str_concat -- - * concatenate the two strings, inserting a space or slash between them, - * freeing them if requested. - * - * returns -- - * the resulting string in allocated space. - */ +/* Return the concatenation of s1 and s2, freshly allocated. */ char * -str_concat(const char *s1, const char *s2, int flags) +str_concat2(const char *s1, const char *s2) { - int len1, len2; - char *result; - - /* get the length of both strings */ - len1 = strlen(s1); - len2 = strlen(s2); - - /* allocate length plus separator plus EOS */ - result = bmake_malloc((unsigned int)(len1 + len2 + 2)); - - /* copy first string into place */ + size_t len1 = strlen(s1); + size_t len2 = strlen(s2); + char *result = bmake_malloc(len1 + len2 + 1); memcpy(result, s1, len1); - - /* add separator character */ - if (flags & STR_ADDSPACE) { - result[len1] = ' '; - ++len1; - } else if (flags & STR_ADDSLASH) { - result[len1] = '/'; - ++len1; - } - - /* copy second string plus EOS into place */ memcpy(result + len1, s2, len2 + 1); + return result; +} +/* Return the concatenation of s1, s2 and s3, freshly allocated. */ +char * +str_concat3(const char *s1, const char *s2, const char *s3) +{ + size_t len1 = strlen(s1); + size_t len2 = strlen(s2); + size_t len3 = strlen(s3); + char *result = bmake_malloc(len1 + len2 + len3 + 1); + memcpy(result, s1, len1); + memcpy(result + len1, s2, len2); + memcpy(result + len1 + len2, s3, len3 + 1); return result; } -/*- - * brk_string -- - * Fracture a string into an array of words (as delineated by tabs or - * spaces) taking quotation marks into account. Leading tabs/spaces - * are ignored. +/* Return the concatenation of s1, s2, s3 and s4, freshly allocated. */ +char * +str_concat4(const char *s1, const char *s2, const char *s3, const char *s4) +{ + size_t len1 = strlen(s1); + size_t len2 = strlen(s2); + size_t len3 = strlen(s3); + size_t len4 = strlen(s4); + char *result = bmake_malloc(len1 + len2 + len3 + len4 + 1); + memcpy(result, s1, len1); + memcpy(result + len1, s2, len2); + memcpy(result + len1 + len2, s3, len3); + memcpy(result + len1 + len2 + len3, s4, len4 + 1); + return result; +} + +/* Fracture a string into an array of words (as delineated by tabs or spaces) + * taking quotation marks into account. Leading tabs/spaces are ignored. * - * If expand is TRUE, quotes are removed and escape sequences - * such as \r, \t, etc... are expanded. + * If expand is TRUE, quotes are removed and escape sequences such as \r, \t, + * etc... are expanded. In this case, the return value is NULL on parse + * errors. * - * returns -- - * Pointer to the array of pointers to the words. - * Memory containing the actual words in *store_words_buf. - * Both of these must be free'd by the caller. - * Number of words in *store_words_len. + * Returns the fractured words, which must be freed later using Words_Free. + * If expand was TRUE and there was a parse error, words is NULL, and in that + * case, nothing needs to be freed. */ -char ** -brk_string(const char *str, int *store_words_len, Boolean expand, - char **store_words_buf) +Words +Str_Words(const char *str, Boolean expand) { + size_t str_len; + char *words_buf; + size_t words_cap; + char **words; + size_t words_len; char inquote; + char *word_start; + char *word_end; 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) @@ -166,10 +166,11 @@ brk_string(const char *str, int *store_words_len, Boolean expand, */ words_len = 0; inquote = '\0'; - word_start = word_end = words_buf; + word_start = words_buf; + word_end = words_buf; for (str_p = str;; ++str_p) { char ch = *str_p; - switch(ch) { + switch (ch) { case '"': case '\'': if (inquote) { @@ -177,9 +178,8 @@ brk_string(const char *str, int *store_words_len, Boolean expand, inquote = '\0'; else break; - } - else { - inquote = (char) ch; + } else { + inquote = (char)ch; /* Don't miss "" or '' */ if (word_start == NULL && str_p[1] == inquote) { if (!expand) { @@ -212,13 +212,14 @@ brk_string(const char *str, int *store_words_len, Boolean expand, * space and save off a pointer. */ if (word_start == NULL) - goto done; + goto done; *word_end++ = '\0'; if (words_len == words_cap) { + size_t new_size; words_cap *= 2; /* ramp up fast */ - words = (char **)bmake_realloc(words, - (words_cap + 1) * sizeof(char *)); + new_size = (words_cap + 1) * sizeof(char *); + words = bmake_realloc(words, new_size); } words[words_len++] = word_start; word_start = NULL; @@ -226,8 +227,7 @@ brk_string(const char *str, int *store_words_len, Boolean expand, if (expand && inquote) { free(words); free(words_buf); - *store_words_buf = NULL; - return NULL; + return (Words){ NULL, 0, NULL }; } goto done; } @@ -273,10 +273,9 @@ brk_string(const char *str, int *store_words_len, Boolean expand, word_start = word_end; *word_end++ = ch; } -done: words[words_len] = NULL; - *store_words_len = words_len; - *store_words_buf = words_buf; - return words; +done: + words[words_len] = NULL; + return (Words){ words, words_len, words_buf }; } /* @@ -375,7 +374,7 @@ Str_Match(const char *str, const char *pat) */ if (*pat == '[') { Boolean neg = pat[1] == '^'; - pat += 1 + neg; + pat += neg ? 2 : 1; for (;;) { if (*pat == ']' || *pat == 0) { @@ -423,107 +422,3 @@ Str_Match(const char *str, const char *pat) str++; } } - -/*- - *----------------------------------------------------------------------- - * Str_SYSVMatch -- - * Check word against pattern for a match (% is wild), - * - * Input: - * word Word to examine - * pattern Pattern to examine against - * len Number of characters to substitute - * - * Results: - * Returns the beginning position of a match or null. The number - * of characters matched is returned in len. - * - * Side Effects: - * None - * - *----------------------------------------------------------------------- - */ -char * -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); - return UNCONST(w); - } - - 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; - - if (p != m) - return NULL; /* No match */ - - if (*++p == '\0') { - /* No more pattern, return the rest of the string */ - *len = strlen(w); - return UNCONST(w); - } - } - - m = w; - - /* Find a matching tail */ - do - if (strcmp(p, w) == 0) { - *len = w - m; - return UNCONST(m); - } - while (*w++ != '\0'); - - return NULL; -} - - -/*- - *----------------------------------------------------------------------- - * Str_SYSVSubst -- - * Substitute '%' on the pattern with len characters from src. - * If the pattern does not contain a '%' prepend len characters - * from src. - * - * Results: - * None - * - * Side Effects: - * Places result on buf - * - *----------------------------------------------------------------------- - */ -void -Str_SYSVSubst(Buffer *buf, char *pat, char *src, size_t len, - Boolean lhsHasPercent) -{ - char *m; - - if ((m = strchr(pat, '%')) != NULL && lhsHasPercent) { - /* Copy the prefix */ - Buf_AddBytes(buf, m - pat, pat); - /* skip the % */ - pat = m + 1; - } - if (m != NULL || !lhsHasPercent) { - /* Copy the pattern */ - Buf_AddBytes(buf, len, src); - } - - /* append the rest */ - Buf_AddBytes(buf, strlen(pat), pat); -} |