make: use simpler code for handling .for loops

Since the body of a .for loop is scanned from start to end, there is no
need to remember the length of a variable name.

Using memcmp for comparing the variable name was probably overkill since
the variable names are usually very short, so rather compare them byte
by byte.

No functional change.
This commit is contained in:
rillig 2022-01-07 20:04:49 +00:00
parent 596c2276c5
commit d8d5dfa77e
1 changed files with 18 additions and 36 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: for.c,v 1.154 2022/01/02 01:54:43 rillig Exp $ */ /* $NetBSD: for.c,v 1.155 2022/01/07 20:04:49 rillig Exp $ */
/* /*
* Copyright (c) 1992, The Regents of the University of California. * Copyright (c) 1992, The Regents of the University of California.
@ -58,18 +58,12 @@
#include "make.h" #include "make.h"
/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
MAKE_RCSID("$NetBSD: for.c,v 1.154 2022/01/02 01:54:43 rillig Exp $"); MAKE_RCSID("$NetBSD: for.c,v 1.155 2022/01/07 20:04:49 rillig Exp $");
/* One of the variables to the left of the "in" in a .for loop. */
typedef struct ForVar {
char *name;
size_t nameLen;
} ForVar;
typedef struct ForLoop { typedef struct ForLoop {
Buffer body; /* Unexpanded body of the loop */ Buffer body; /* Unexpanded body of the loop */
Vector /* of ForVar */ vars; /* Iteration variables */ Vector /* of 'char *' */ vars; /* Iteration variables */
SubstringWords items; /* Substitution items */ SubstringWords items; /* Substitution items */
unsigned int nextItem; /* Where to continue iterating */ unsigned int nextItem; /* Where to continue iterating */
} ForLoop; } ForLoop;
@ -85,7 +79,7 @@ ForLoop_New(void)
ForLoop *f = bmake_malloc(sizeof *f); ForLoop *f = bmake_malloc(sizeof *f);
Buf_Init(&f->body); Buf_Init(&f->body);
Vector_Init(&f->vars, sizeof(ForVar)); Vector_Init(&f->vars, sizeof(char *));
SubstringWords_Init(&f->items); SubstringWords_Init(&f->items);
f->nextItem = 0; f->nextItem = 0;
@ -97,10 +91,8 @@ ForLoop_Free(ForLoop *f)
{ {
Buf_Done(&f->body); Buf_Done(&f->body);
while (f->vars.len > 0) { while (f->vars.len > 0)
ForVar *var = Vector_Pop(&f->vars); free(*(char **)Vector_Pop(&f->vars));
free(var->name);
}
Vector_Done(&f->vars); Vector_Done(&f->vars);
SubstringWords_Free(f->items); SubstringWords_Free(f->items);
@ -108,14 +100,6 @@ ForLoop_Free(ForLoop *f)
free(f); free(f);
} }
static void
ForLoop_AddVar(ForLoop *f, const char *name, size_t len)
{
ForVar *var = Vector_Push(&f->vars);
var->name = bmake_strldup(name, len);
var->nameLen = len;
}
static bool static bool
ForLoop_ParseVarnames(ForLoop *f, const char **pp) ForLoop_ParseVarnames(ForLoop *f, const char **pp)
{ {
@ -142,7 +126,7 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp)
break; break;
} }
ForLoop_AddVar(f, p, len); *(char **)Vector_Push(&f->vars) = bmake_strldup(p, len);
p += len; p += len;
} }
@ -374,31 +358,29 @@ ForLoop_SubstVarLong(ForLoop *f, Buffer *body, const char **pp,
const char *end, char endc, const char **inout_mark) const char *end, char endc, const char **inout_mark)
{ {
size_t i; size_t i;
const char *p = *pp; const char *start = *pp;
const char **vars = Vector_Get(&f->vars, 0);
for (i = 0; i < f->vars.len; i++) { for (i = 0; i < f->vars.len; i++) {
const ForVar *forVar = Vector_Get(&f->vars, i); const char *p = start;
const char *varname = forVar->name; const char *varname = vars[i];
size_t varnameLen = forVar->nameLen;
if (varnameLen >= (size_t)(end - p)) while (p < end && *varname != '\0' && *p == *varname)
continue; p++, varname++;
if (memcmp(p, varname, varnameLen) != 0) if (*varname != '\0')
continue; continue;
/* XXX: why test for backslash here? */ /* XXX: why test for backslash here? */
if (p[varnameLen] != ':' && p[varnameLen] != endc && if (*p != ':' && *p != endc && *p != '\\')
p[varnameLen] != '\\')
continue; continue;
/* /*
* Found a variable match. Skip over the variable name and * Found a variable match. Skip over the variable name and
* instead add ':U<value>' to the current body. * instead add ':U<value>' to the current body.
*/ */
Buf_AddBytesBetween(body, *inout_mark, p); Buf_AddBytesBetween(body, *inout_mark, start);
Buf_AddStr(body, ":U"); Buf_AddStr(body, ":U");
Buf_AddEscaped(body, f->items.words[f->nextItem + i], endc); Buf_AddEscaped(body, f->items.words[f->nextItem + i], endc);
p += varnameLen;
*inout_mark = p; *inout_mark = p;
*pp = p; *pp = p;
return; return;
@ -414,7 +396,7 @@ ForLoop_SubstVarShort(ForLoop *f, Buffer *body,
const char *p, const char **inout_mark) const char *p, const char **inout_mark)
{ {
const char ch = *p; const char ch = *p;
const ForVar *vars; const char **vars;
size_t i; size_t i;
/* Skip $$ and stupid ones. */ /* Skip $$ and stupid ones. */
@ -423,7 +405,7 @@ ForLoop_SubstVarShort(ForLoop *f, Buffer *body,
vars = Vector_Get(&f->vars, 0); vars = Vector_Get(&f->vars, 0);
for (i = 0; i < f->vars.len; i++) { for (i = 0; i < f->vars.len; i++) {
const char *varname = vars[i].name; const char *varname = vars[i];
if (varname[0] == ch && varname[1] == '\0') if (varname[0] == ch && varname[1] == '\0')
goto found; goto found;
} }