Module Name: src Committed By: rillig Date: Sun Oct 25 16:14:08 UTC 2020
Modified Files: src/usr.bin/make: for.c Log Message: make(1): extract code to see if a directive is a .for or .endfor To generate a diff of this commit: cvs rdiff -u -r1.105 -r1.106 src/usr.bin/make/for.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/for.c diff -u src/usr.bin/make/for.c:1.105 src/usr.bin/make/for.c:1.106 --- src/usr.bin/make/for.c:1.105 Sun Oct 25 15:58:04 2020 +++ src/usr.bin/make/for.c Sun Oct 25 16:14:08 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.105 2020/10/25 15:58:04 rillig Exp $ */ +/* $NetBSD: for.c,v 1.106 2020/10/25 16:14:08 rillig Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -60,8 +60,10 @@ #include "make.h" /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ -MAKE_RCSID("$NetBSD: for.c,v 1.105 2020/10/25 15:58:04 rillig Exp $"); +MAKE_RCSID("$NetBSD: for.c,v 1.106 2020/10/25 16:14:08 rillig Exp $"); +/* The .for loop substitutes the items as ${:U<value>...}, which means + * that characters that break this syntax must be backslash-escaped. */ typedef enum ForEscapes { FOR_SUB_ESCAPE_CHAR = 0x0001, FOR_SUB_ESCAPE_BRACE = 0x0002, @@ -146,6 +148,19 @@ GetEscapes(const char *word) return escapes; } +static Boolean +IsFor(const char *p) +{ + return p[0] == 'f' && p[1] == 'o' && p[2] == 'r' && ch_isspace(p[3]); +} + +static Boolean +IsEndfor(const char *p) +{ + return p[0] == 'e' && strncmp(p, "endfor", 6) == 0 && + (p[6] == '\0' || ch_isspace(p[6])); +} + /* Evaluate the for loop in the passed line. The line looks like this: * .for <varname...> in <value...> * @@ -171,8 +186,8 @@ For_Eval(const char *line) * If we are not in a for loop quickly determine if the statement is * a for. */ - if (p[0] != 'f' || p[1] != 'o' || p[2] != 'r' || !ch_isspace(p[3])) { - if (p[0] == 'e' && strncmp(p + 1, "ndfor", 5) == 0) { + if (!IsFor(p)) { + if (IsEndfor(p)) { Parse_Error(PARSE_FATAL, "for-less endfor"); return -1; } @@ -205,7 +220,7 @@ For_Eval(const char *line) } /* XXX: This allows arbitrary variable names; see directive-for.mk. */ - for (len = 1; p[len] && !ch_isspace(p[len]); len++) + for (len = 1; p[len] != '\0' && !ch_isspace(p[len]); len++) continue; if (len == 2 && p[0] == 'i' && p[1] == 'n') { @@ -227,14 +242,6 @@ For_Eval(const char *line) cpp_skip_whitespace(&p); - /* - * Make a list with the remaining words. - * The values are later substituted as ${:U<value>...} so we must - * backslash-escape characters that break that syntax. - * Variables are fully expanded - so it is safe for escape $. - * We can't do the escapes here - because we don't know whether - * we will be substituting into ${...} or $(...). - */ { char *items; (void)Var_Subst(p, VAR_GLOBAL, VARE_WANTRES, &items); @@ -281,11 +288,11 @@ For_Accum(const char *line) ptr++; cpp_skip_whitespace(&ptr); - if (strncmp(ptr, "endfor", 6) == 0 && (ch_isspace(ptr[6]) || !ptr[6])) { + if (IsEndfor(ptr)) { DEBUG1(FOR, "For: end for %d\n", forLevel); if (--forLevel <= 0) return FALSE; - } else if (strncmp(ptr, "for", 3) == 0 && ch_isspace(ptr[3])) { + } else if (IsFor(ptr)) { forLevel++; DEBUG1(FOR, "For: new loop %d\n", forLevel); }