Module Name: src Committed By: rillig Date: Sat Nov 7 23:41:39 UTC 2020
Modified Files: src/usr.bin/make: parse.c Log Message: make(1): replace strstr in ParseMaybeSubMake with optimized code This code is called for each command that is parsed. Calling strstr with 4 strings that all start with the same character is unnecessary work. Therefore, replace strstr with manually optimized code. Neither GCC 5.5.0 nor GCC 10 inlines strncmp like this, otherwise I would have used that. Change in behavior: previously, a${MAKE}b would not be considered to be a sub-make command, which is probably correct but does not occur in practice. The check for non-alphanumeric characters around the found string was probably meant only for the plain word "make". To generate a diff of this commit: cvs rdiff -u -r1.431 -r1.432 src/usr.bin/make/parse.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/parse.c diff -u src/usr.bin/make/parse.c:1.431 src/usr.bin/make/parse.c:1.432 --- src/usr.bin/make/parse.c:1.431 Sat Nov 7 22:26:42 2020 +++ src/usr.bin/make/parse.c Sat Nov 7 23:41:38 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.431 2020/11/07 22:26:42 rillig Exp $ */ +/* $NetBSD: parse.c,v 1.432 2020/11/07 23:41:38 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -117,7 +117,7 @@ #include "pathnames.h" /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: parse.c,v 1.431 2020/11/07 22:26:42 rillig Exp $"); +MAKE_RCSID("$NetBSD: parse.c,v 1.432 2020/11/07 23:41:38 rillig Exp $"); /* types and constants */ @@ -2031,36 +2031,41 @@ Parse_DoVar(VarAssign *var, GNode *ctxt) } -/* - * ParseMaybeSubMake -- - * Scan the command string to see if it a possible submake node - * Input: - * cmd the command to scan - * Results: - * TRUE if the command is possibly a submake, FALSE if not. - */ +/* See if the command possibly calls a sub-make by using the variable + * expressions ${.MAKE}, ${MAKE} or the plain word "make". */ static Boolean -ParseMaybeSubMake(const char *cmd) +MaybeSubMake(const char *cmd) { - size_t i; - static struct { - const char *name; - size_t len; - } vals[] = { -#define MKV(A) { A, sizeof (A) - 1 } - MKV("${MAKE}"), - MKV("${.MAKE}"), - MKV("$(MAKE)"), - MKV("$(.MAKE)"), - MKV("make"), - }; - for (i = 0; i < sizeof vals / sizeof vals[0]; i++) { - char *ptr; - if ((ptr = strstr(cmd, vals[i].name)) == NULL) + const char *start; + + for (start = cmd; *start != '\0'; start++) { + const char *p = start; + char endc; + + /* XXX: What if progname != "make"? */ + if (p[0] == 'm' && p[1] == 'a' && p[2] == 'k' && p[3] == 'e') + if (start == cmd || !ch_isalnum(p[-1])) + if (!ch_isalnum(p[4])) + return TRUE; + + if (*p != '$') continue; - if ((ptr == cmd || !ch_isalnum(ptr[-1])) - && !ch_isalnum(ptr[vals[i].len])) - return TRUE; + p++; + + if (*p == '{') + endc = '}'; + else if (*p == '(') + endc = ')'; + else + continue; + p++; + + if (*p == '.') /* Accept either ${.MAKE} or ${MAKE}. */ + p++; + + if (p[0] == 'M' && p[1] == 'A' && p[2] == 'K' && p[3] == 'E') + if (p[4] == endc) + return TRUE; } return FALSE; } @@ -2079,7 +2084,7 @@ ParseAddCmd(GNode *gn, char *cmd) /* if target already supplied, ignore commands */ if (!(gn->type & OP_HAS_COMMANDS)) { Lst_Append(gn->commands, cmd); - if (ParseMaybeSubMake(cmd)) + if (MaybeSubMake(cmd)) gn->type |= OP_SUBMAKE; ParseMark(gn); } else {