summaryrefslogtreecommitdiff
path: root/str.c
diff options
context:
space:
mode:
Diffstat (limited to 'str.c')
-rw-r--r--str.c241
1 files changed, 68 insertions, 173 deletions
diff --git a/str.c b/str.c
index c3138b67b95b5..59fdccb288670 100644
--- a/str.c
+++ b/str.c
@@ -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);
-}