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: allow targets to be used as multiple-incl...
details: https://anonhg.NetBSD.org/src/rev/01564b7d90c8
branches: trunk
changeset: 376487:01564b7d90c8
user: rillig <rillig%NetBSD.org@localhost>
date: Tue Jun 20 09:25:33 2023 +0000
description:
make: allow targets to be used as multiple-inclusion guards
This style is used by FreeBSD, among others.
diffstat:
usr.bin/make/cond.c | 63 ++++++++++---
usr.bin/make/make.h | 12 ++-
usr.bin/make/parse.c | 76 +++++++++-------
usr.bin/make/unit-tests/Makefile | 3 +-
usr.bin/make/unit-tests/directive-include-guard.exp | 26 ++++-
usr.bin/make/unit-tests/directive-include-guard.mk | 96 +++++++++++++++++---
6 files changed, 200 insertions(+), 76 deletions(-)
diffs (truncated from 517 to 300 lines):
diff -r 546b0ae7fd2f -r 01564b7d90c8 usr.bin/make/cond.c
--- a/usr.bin/make/cond.c Tue Jun 20 08:51:24 2023 +0000
+++ b/usr.bin/make/cond.c Tue Jun 20 09:25:33 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.349 2023/06/19 20:07:35 rillig Exp $ */
+/* $NetBSD: cond.c,v 1.350 2023/06/20 09:25:33 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -92,7 +92,7 @@
#include "dir.h"
/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
-MAKE_RCSID("$NetBSD: cond.c,v 1.349 2023/06/19 20:07:35 rillig Exp $");
+MAKE_RCSID("$NetBSD: cond.c,v 1.350 2023/06/20 09:25:33 rillig Exp $");
/*
* Conditional expressions conform to this grammar:
@@ -1252,15 +1252,30 @@ ParseVarnameGuard(const char **pp, const
return false;
}
-/*
- * Tests whether the line is a conditional that forms a multiple-inclusion
- * guard, and if so, extracts the guard variable name.
- */
-char *
+static bool
+ParseTargetGuard(const char **pp, const char **target)
+{
+ const char *p = *pp;
+
+ if (ch_isalpha(*p) || *p == '_') {
+ while (ch_isalnum(*p) || *p == '_' || *p == '-'
+ || *p == '<' || *p == '>' || *p == '.' || *p == '/')
+ p++;
+ *target = *pp;
+ *pp = p;
+ return true;
+ }
+ return false;
+}
+
+/* Extracts the multiple-inclusion guard from a conditional, if any. */
+Guard *
Cond_ExtractGuard(const char *line)
{
- const char *p, *varname;
+ const char *p, *name;
Substring dir;
+ enum GuardKind kind;
+ Guard *guard;
p = line + 1; /* skip the '.' */
cpp_skip_hspace(&p);
@@ -1271,14 +1286,32 @@ Cond_ExtractGuard(const char *line)
dir.end = p;
cpp_skip_hspace(&p);
- if (Substring_Equals(dir, "if"))
- return skip_string(&p, "!defined(")
- && ParseVarnameGuard(&p, &varname) && strcmp(p, ")") == 0
- ? bmake_strsedup(varname, p) : NULL;
- if (Substring_Equals(dir, "ifndef"))
- return ParseVarnameGuard(&p, &varname) && *p == '\0'
- ? bmake_strsedup(varname, p) : NULL;
+ if (Substring_Equals(dir, "if")) {
+ if (skip_string(&p, "!defined(")) {
+ if (ParseVarnameGuard(&p, &name)
+ && strcmp(p, ")") == 0)
+ goto found_variable;
+ } else if (skip_string(&p, "!target(")) {
+ if (ParseTargetGuard(&p, &name)
+ && strcmp(p, ")") == 0)
+ goto found_target;
+ }
+ } else if (Substring_Equals(dir, "ifndef")) {
+ if (ParseVarnameGuard(&p, &name) && *p == '\0')
+ goto found_variable;
+ }
return NULL;
+
+found_variable:
+ kind = GK_VARIABLE;
+ goto found;
+found_target:
+ kind = GK_TARGET;
+found:
+ guard = bmake_malloc(sizeof(*guard));
+ guard->kind = kind;
+ guard->name = bmake_strsedup(name, p);
+ return guard;
}
void
diff -r 546b0ae7fd2f -r 01564b7d90c8 usr.bin/make/make.h
--- a/usr.bin/make/make.h Tue Jun 20 08:51:24 2023 +0000
+++ b/usr.bin/make/make.h Tue Jun 20 09:25:33 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.322 2023/06/19 12:53:57 rillig Exp $ */
+/* $NetBSD: make.h,v 1.323 2023/06/20 09:25:33 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -539,6 +539,14 @@ typedef enum CondResult {
CR_ERROR /* Unknown directive or parse error */
} CondResult;
+typedef struct {
+ enum GuardKind {
+ GK_VARIABLE,
+ GK_TARGET
+ } kind;
+ char *name;
+} Guard;
+
/* Names of the variables that are "local" to a specific target. */
#define TARGET "@" /* Target of dependency */
#define OODATE "?" /* All out-of-date sources */
@@ -793,7 +801,7 @@ void Compat_Make(GNode *, GNode *);
extern unsigned int cond_depth;
CondResult Cond_EvalCondition(const char *) MAKE_ATTR_USE;
CondResult Cond_EvalLine(const char *) MAKE_ATTR_USE;
-char *Cond_ExtractGuard(const char *) MAKE_ATTR_USE;
+Guard *Cond_ExtractGuard(const char *) MAKE_ATTR_USE;
void Cond_EndFile(void);
/* dir.c; see also dir.h */
diff -r 546b0ae7fd2f -r 01564b7d90c8 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c Tue Jun 20 08:51:24 2023 +0000
+++ b/usr.bin/make/parse.c Tue Jun 20 09:25:33 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.701 2023/06/19 17:30:56 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.702 2023/06/20 09:25:33 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -105,7 +105,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.701 2023/06/19 17:30:56 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.702 2023/06/20 09:25:33 rillig Exp $");
/* Detects a multiple-inclusion guard in a makefile. */
typedef enum {
@@ -136,8 +136,8 @@ typedef struct IncludedFile {
char *buf_ptr; /* next char to be read */
char *buf_end; /* buf_end[-1] == '\n' */
- GuardState guard;
- char *guardVarname;
+ GuardState guardState;
+ Guard *guard;
struct ForLoop *forLoop;
} IncludedFile;
@@ -310,7 +310,7 @@ static const struct {
enum PosixState posix_state = PS_NOT_YET;
-static HashTable guards;
+static HashTable /* full file name -> Guard */ guards;
static IncludedFile *
GetInclude(size_t i)
@@ -1213,13 +1213,19 @@ FindInQuotPath(const char *file)
static bool
SkipGuarded(const char *fullname)
{
- char *guard = HashTable_FindValue(&guards, fullname);
- if (guard != NULL && GNode_ValueDirect(SCOPE_GLOBAL, guard) != NULL) {
- DEBUG2(PARSE, "Skipping '%s' because '%s' is already set\n",
- fullname, guard);
- return true;
- }
+ Guard *guard = HashTable_FindValue(&guards, fullname);
+ if (guard != NULL && guard->kind == GK_VARIABLE
+ && GNode_ValueDirect(SCOPE_GLOBAL, guard->name) != NULL)
+ goto skip;
+ if (guard != NULL && guard->kind == GK_TARGET
+ && Targ_FindNode(guard->name) != NULL)
+ goto skip;
return false;
+
+skip:
+ DEBUG2(PARSE, "Skipping '%s' because '%s' is defined\n",
+ fullname, guard->name);
+ return true;
}
/*
@@ -2202,8 +2208,8 @@ Parse_PushInput(const char *name, unsign
curFile->forBodyReadLines = readLines;
curFile->buf = buf;
curFile->depending = doing_depend; /* restore this on EOF */
- curFile->guard = forLoop == NULL ? GS_START : GS_NO;
- curFile->guardVarname = NULL;
+ curFile->guardState = forLoop == NULL ? GS_START : GS_NO;
+ curFile->guard = NULL;
curFile->forLoop = forLoop;
if (forLoop != NULL && !For_NextIteration(forLoop, &curFile->buf))
@@ -2346,15 +2352,15 @@ ParseEOF(void)
Cond_EndFile();
- if (curFile->guard == GS_DONE) {
- HashTable_Set(&guards,
- curFile->name.str, curFile->guardVarname);
- curFile->guardVarname = NULL;
+ if (curFile->guardState == GS_DONE)
+ HashTable_Set(&guards, curFile->name.str, curFile->guard);
+ else if (curFile->guard != NULL) {
+ free(curFile->guard->name);
+ free(curFile->guard);
}
FStr_Done(&curFile->name);
Buf_Done(&curFile->buf);
- free(curFile->guardVarname);
if (curFile->forLoop != NULL)
ForLoop_Free(curFile->forLoop);
Vector_Pop(&includes);
@@ -2665,22 +2671,22 @@ ReadHighLevelLine(void)
if (line == NULL)
return NULL;
- if (curFile->guard != GS_NO
- && ((curFile->guard == GS_START && line[0] != '.')
- || curFile->guard == GS_DONE))
- curFile->guard = GS_NO;
+ if (curFile->guardState != GS_NO
+ && ((curFile->guardState == GS_START && line[0] != '.')
+ || curFile->guardState == GS_DONE))
+ curFile->guardState = GS_NO;
if (line[0] != '.')
return line;
condResult = Cond_EvalLine(line);
- if (curFile->guard == GS_START) {
- char *varname;
+ if (curFile->guardState == GS_START) {
+ Guard *guard;
if (condResult == CR_TRUE
- && (varname = Cond_ExtractGuard(line)) != NULL) {
- curFile->guard = GS_COND;
- curFile->guardVarname = varname;
+ && (guard = Cond_ExtractGuard(line)) != NULL) {
+ curFile->guardState = GS_COND;
+ curFile->guard = guard;
} else
- curFile->guard = GS_NO;
+ curFile->guardState = GS_NO;
}
switch (condResult) {
case CR_FALSE: /* May also mean a syntax error. */
@@ -2842,15 +2848,16 @@ Parse_GuardElse(void)
{
IncludedFile *curFile = CurFile();
if (cond_depth == curFile->condMinDepth + 1)
- curFile->guard = GS_NO;
+ curFile->guardState = GS_NO;
}
void
Parse_GuardEndif(void)
{
IncludedFile *curFile = CurFile();
- if (cond_depth == curFile->condMinDepth && curFile->guard == GS_COND)
- curFile->guard = GS_DONE;
+ if (cond_depth == curFile->condMinDepth
+ && curFile->guardState == GS_COND)
+ curFile->guardState = GS_DONE;
}
static char *
@@ -3061,8 +3068,11 @@ Parse_End(void)
assert(includes.len == 0);
Vector_Done(&includes);
HashIter_Init(&hi, &guards);
- while (HashIter_Next(&hi) != NULL)
- free(hi.entry->value);
+ while (HashIter_Next(&hi) != NULL) {
+ Guard *guard = hi.entry->value;
+ free(guard->name);
+ free(guard);
+ }
HashTable_Done(&guards);
#endif
}
diff -r 546b0ae7fd2f -r 01564b7d90c8 usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile Tue Jun 20 08:51:24 2023 +0000
+++ b/usr.bin/make/unit-tests/Makefile Tue Jun 20 09:25:33 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.338 2023/06/16 09:25:13 rillig Exp $
+# $NetBSD: Makefile,v 1.339 2023/06/20 09:25:34 rillig Exp $
#
# Unit tests for make(1)
#
Home |
Main Index |
Thread Index |
Old Index