Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make make: migrate ParseModifierPart to use Substring



details:   https://anonhg.NetBSD.org/src/rev/3f30da5e3573
branches:  trunk
changeset: 1020404:3f30da5e3573
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun Apr 11 20:38:43 2021 +0000

description:
make: migrate ParseModifierPart to use Substring

This will reduce memory allocation for modifier parts without the escape
characters '$' or '\'.

No functional change.

diffstat:

 usr.bin/make/str.h |   19 +++-
 usr.bin/make/var.c |  233 ++++++++++++++++++++++++++++++----------------------
 2 files changed, 150 insertions(+), 102 deletions(-)

diffs (truncated from 647 to 300 lines):

diff -r 96d4324da7fd -r 3f30da5e3573 usr.bin/make/str.h
--- a/usr.bin/make/str.h        Sun Apr 11 20:26:42 2021 +0000
+++ b/usr.bin/make/str.h        Sun Apr 11 20:38:43 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: str.h,v 1.3 2021/04/11 19:05:06 rillig Exp $   */
+/*     $NetBSD: str.h,v 1.4 2021/04/11 20:38:43 rillig Exp $   */
 
 /*
  Copyright (c) 2021 Roland Illig <rillig%NetBSD.org@localhost>
@@ -46,7 +46,7 @@
 } MFStr;
 
 /* A read-only range of a character array, NOT null-terminated. */
-typedef struct {
+typedef struct Substring {
        const char *start;
        const char *end;
 } Substring;
@@ -279,6 +279,21 @@
                LazyBuf_Add(buf, *p);
 }
 
+MAKE_INLINE void
+LazyBuf_AddBytesBetween(LazyBuf *buf, const char *start, const char *end)
+{
+       const char *p;
+
+       for (p = start; p != end; p++)
+               LazyBuf_Add(buf, *p);
+}
+
+MAKE_INLINE void
+LazyBuf_AddSubstring(LazyBuf *buf, Substring sub)
+{
+       LazyBuf_AddBytesBetween(buf, sub.start, sub.end);
+}
+
 MAKE_INLINE Substring
 LazyBuf_Get(const LazyBuf *buf)
 {
diff -r 96d4324da7fd -r 3f30da5e3573 usr.bin/make/var.c
--- a/usr.bin/make/var.c        Sun Apr 11 20:26:42 2021 +0000
+++ b/usr.bin/make/var.c        Sun Apr 11 20:38:43 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: var.c,v 1.920 2021/04/11 19:05:06 rillig Exp $ */
+/*     $NetBSD: var.c,v 1.921 2021/04/11 20:38:43 rillig Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
 #include "metachar.h"
 
 /*     "@(#)var.c      8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.920 2021/04/11 19:05:06 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.921 2021/04/11 20:38:43 rillig Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -1618,7 +1618,7 @@
                return;
        }
 
-       if (args->lhs.start[0] == '\0')
+       if (Substring_IsEmpty(args->lhs))
                goto nosub;
 
        /* unanchored case, may match more than once */
@@ -1626,7 +1626,7 @@
                SepBuf_AddBytesBetween(buf, word.start, match);
                SepBuf_AddSubstring(buf, args->rhs);
                args->matched = true;
-               word.start += (size_t)(match - word.start) + lhsLen;
+               word.start = match + lhsLen;
                if (Substring_IsEmpty(word) || !args->pflags.subGlobal)
                        break;
        }
@@ -1649,7 +1649,7 @@
 struct ModifyWord_SubstRegexArgs {
        regex_t re;
        size_t nsub;
-       char *replace;
+       const char *replace;
        VarPatternFlags pflags;
        bool matched;
 };
@@ -1664,7 +1664,7 @@
        struct ModifyWord_SubstRegexArgs *args = data;
        int xrv;
        const char *wp;
-       char *rp;
+       const char *rp;
        int flags = 0;
        regmatch_t m[10];
 
@@ -1749,8 +1749,8 @@
 
 struct ModifyWord_LoopArgs {
        GNode *scope;
-       char *tvar;             /* name of temporary variable */
-       char *str;              /* string to expand */
+       const char *tvar;       /* name of temporary variable */
+       const char *str;        /* string to expand */
        VarEvalMode emode;
 };
 
@@ -2157,17 +2157,22 @@
 }
 
 static void
+Expr_SetValue(Expr *expr, FStr value)
+{
+       FStr_Done(&expr->value);
+       expr->value = value;
+}
+
+static void
 Expr_SetValueOwn(Expr *expr, char *value)
 {
-       FStr_Done(&expr->value);
-       expr->value = FStr_InitOwn(value);
+       Expr_SetValue(expr, FStr_InitOwn(value));
 }
 
 static void
 Expr_SetValueRefer(Expr *expr, const char *value)
 {
-       FStr_Done(&expr->value);
-       expr->value = FStr_InitRefer(value);
+       Expr_SetValue(expr, FStr_InitRefer(value));
 }
 
 static bool
@@ -2216,10 +2221,7 @@
     char delim,
     VarEvalMode emode,
     ModChain *ch,
-    char **out_part,
-    /* Optionally stores the end of the returned string, just to save
-     * another strlen call. */
-    const char **out_part_end,
+    LazyBuf *part,
     /* For the first part of the :S modifier, sets the VARP_ANCHOR_END flag
      * if the last character of the pattern is a $. */
     VarPatternFlags *out_pflags,
@@ -2228,31 +2230,29 @@
     struct ModifyWord_SubstArgs *subst
 )
 {
-       Buffer buf;
        const char *p;
 
-       Buf_Init(&buf);
+       p = *pp;
+       LazyBuf_Init(part, Substring_InitStr(p)); /* TODO: O(n^2) */
 
        /*
         * Skim through until the matching delimiter is found; pick up
         * variable expressions on the way.
         */
-       p = *pp;
        while (*p != '\0' && *p != delim) {
                const char *varstart;
 
                if (IsEscapedModifierPart(p, delim, subst)) {
-                       Buf_AddByte(&buf, p[1]);
+                       LazyBuf_Add(part, p[1]);
                        p += 2;
                        continue;
                }
 
                if (*p != '$') {        /* Unescaped, simple text */
                        if (subst != NULL && *p == '&')
-                               Buf_AddBytesBetween(&buf,
-                                   subst->lhs.start, subst->lhs.end);
+                               LazyBuf_AddSubstring(part, subst->lhs);
                        else
-                               Buf_AddByte(&buf, *p);
+                               LazyBuf_Add(part, *p);
                        p++;
                        continue;
                }
@@ -2261,7 +2261,7 @@
                        if (out_pflags != NULL)
                                out_pflags->anchorEnd = true;
                        else
-                               Buf_AddByte(&buf, *p);
+                               LazyBuf_Add(part, *p);
                        p++;
                        continue;
                }
@@ -2274,7 +2274,7 @@
                        (void)Var_Parse(&nested_p, ch->expr->scope,
                            VarEvalMode_WithoutKeepDollar(emode), &nested_val);
                        /* TODO: handle errors */
-                       Buf_AddStr(&buf, nested_val.str);
+                       LazyBuf_AddStr(part, nested_val.str);
                        FStr_Done(&nested_val);
                        p += nested_p - p;
                        continue;
@@ -2312,9 +2312,9 @@
                                                depth--;
                                }
                        }
-                       Buf_AddBytesBetween(&buf, varstart, p);
+                       LazyBuf_AddBytesBetween(part, varstart, p);
                } else {
-                       Buf_AddByte(&buf, *varstart);
+                       LazyBuf_Add(part, *varstart);
                        p++;
                }
        }
@@ -2323,16 +2323,18 @@
                *pp = p;
                Error("Unfinished modifier for \"%s\" ('%c' missing)",
                    ch->expr->name, delim);
-               *out_part = NULL;
+               LazyBuf_Done(part);
                return VPR_ERR;
        }
 
        *pp = p + 1;
-       if (out_part_end != NULL)
-               *out_part_end = buf.data + buf.len;
-
-       *out_part = Buf_DoneData(&buf);
-       DEBUG1(VAR, "Modifier part: \"%s\"\n", *out_part);
+
+       {
+               Substring sub = LazyBuf_Get(part);
+               DEBUG2(VAR, "Modifier part: \"%.*s\"\n",
+                   (int)Substring_Length(sub), sub.start);
+       }
+
        return VPR_OK;
 }
 
@@ -2356,11 +2358,10 @@
     /* Mode for evaluating nested variables. */
     VarEvalMode emode,
     ModChain *ch,
-    char **out_part
+    LazyBuf *part
 )
 {
-       return ParseModifierPartSubst(pp, delim, emode, ch, out_part,
-           NULL, NULL, NULL);
+       return ParseModifierPartSubst(pp, delim, emode, ch, part, NULL, NULL);
 }
 
 MAKE_INLINE bool
@@ -2499,13 +2500,17 @@
        struct ModifyWord_LoopArgs args;
        char prev_sep;
        VarParseResult res;
+       LazyBuf tvarBuf, strBuf;
+       FStr tvar, str;
 
        args.scope = expr->scope;
 
        (*pp)++;                /* Skip the first '@' */
-       res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &args.tvar);
+       res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &tvarBuf);
        if (res != VPR_OK)
                return AMR_CLEANUP;
+       tvar = LazyBuf_DoneGet(&tvarBuf);
+       args.tvar = tvar.str;
        if (strchr(args.tvar, '$') != NULL) {
                Parse_Error(PARSE_FATAL,
                    "In the :@ modifier of \"%s\", the variable name \"%s\" "
@@ -2514,9 +2519,11 @@
                return AMR_CLEANUP;
        }
 
-       res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &args.str);
+       res = ParseModifierPart(pp, '@', VARE_PARSE_ONLY, ch, &strBuf);
        if (res != VPR_OK)
                return AMR_CLEANUP;
+       str = LazyBuf_DoneGet(&strBuf);
+       args.str = str.str;
 
        if (!Expr_ShouldEval(expr))
                goto done;
@@ -2530,8 +2537,8 @@
        Var_Delete(expr->scope, args.tvar);
 
 done:
-       free(args.tvar);
-       free(args.str);
+       FStr_Done(&tvar);
+       FStr_Done(&str);
        return AMR_OK;
 }
 
@@ -2740,23 +2747,26 @@
 ApplyModifier_ShellCommand(const char **pp, ModChain *ch)
 {
        Expr *expr = ch->expr;
-       char *cmd;
        const char *errfmt;
        VarParseResult res;



Home | Main Index | Thread Index | Old Index