Allow guard targets to use variables.
I commonly use __${.PARSEDIR:tA}__ where a unique guard is needed, __${.PARSEDIR}__ is also useful in many cases. Combination of patch from rillig and mine
This commit is contained in:
parent
399bc09bd8
commit
e06cdfbde9
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cond.c,v 1.350 2023/06/20 09:25:33 rillig Exp $ */
|
||||
/* $NetBSD: cond.c,v 1.351 2023/06/21 04:20:20 sjg 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.350 2023/06/20 09:25:33 rillig Exp $");
|
||||
MAKE_RCSID("$NetBSD: cond.c,v 1.351 2023/06/21 04:20:20 sjg Exp $");
|
||||
|
||||
/*
|
||||
* Conditional expressions conform to this grammar:
|
||||
|
@ -1252,22 +1252,6 @@ ParseVarnameGuard(const char **pp, const char **varname)
|
|||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -1292,9 +1276,17 @@ Cond_ExtractGuard(const char *line)
|
|||
&& strcmp(p, ")") == 0)
|
||||
goto found_variable;
|
||||
} else if (skip_string(&p, "!target(")) {
|
||||
if (ParseTargetGuard(&p, &name)
|
||||
&& strcmp(p, ")") == 0)
|
||||
goto found_target;
|
||||
name = p;
|
||||
free(ParseWord(&p, false));
|
||||
if (strcmp(p, ")") == 0) {
|
||||
char *target;
|
||||
p = name;
|
||||
target = ParseWord(&p, true);
|
||||
guard = bmake_malloc(sizeof(*guard));
|
||||
guard->kind = GK_TARGET;
|
||||
guard->name = target;
|
||||
return guard;
|
||||
}
|
||||
}
|
||||
} else if (Substring_Equals(dir, "ifndef")) {
|
||||
if (ParseVarnameGuard(&p, &name) && *p == '\0')
|
||||
|
@ -1304,10 +1296,6 @@ Cond_ExtractGuard(const char *line)
|
|||
|
||||
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);
|
||||
|
|
|
@ -47,7 +47,13 @@ Skipping 'target.tmp' because '__target.tmp__' is defined
|
|||
Parse_PushInput: file target-sys.tmp, line 1
|
||||
Skipping 'target-sys.tmp' because '__<target-sys.tmp>__' is defined
|
||||
Parse_PushInput: file target-indirect.tmp, line 1
|
||||
Parse_PushInput: file target-indirect.tmp, line 1
|
||||
Skipping 'target-indirect.tmp' because 'target-indirect.tmp' is defined
|
||||
Parse_PushInput: file target-indirect-PARSEFILE.tmp, line 1
|
||||
Skipping 'target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
|
||||
Parse_PushInput: file target-indirect-PARSEFILE2.tmp, line 1
|
||||
Skipping 'target-indirect-PARSEFILE2.tmp' because '__target-indirect-PARSEFILE2.tmp__' is defined
|
||||
Parse_PushInput: file target-indirect-PARSEFILE-tA.tmp, line 1
|
||||
Skipping 'target-indirect-PARSEFILE-tA.tmp' because '__target-indirect-PARSEFILE-tA.tmp__' is defined
|
||||
Parse_PushInput: file target-unguarded.tmp, line 1
|
||||
Parse_PushInput: file target-unguarded.tmp, line 1
|
||||
Parse_PushInput: file target-plus.tmp, line 1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: directive-include-guard.mk,v 1.7 2023/06/20 09:25:34 rillig Exp $
|
||||
# $NetBSD: directive-include-guard.mk,v 1.8 2023/06/21 04:20:21 sjg Exp $
|
||||
#
|
||||
# Tests for multiple-inclusion guards in makefiles.
|
||||
#
|
||||
|
@ -282,14 +282,45 @@ LINES.target-sys= \
|
|||
# expect: Parse_PushInput: file target-sys.tmp, line 1
|
||||
# expect: Skipping 'target-sys.tmp' because '__<target-sys.tmp>__' is defined
|
||||
|
||||
# The target name must not include '$' or other special characters.
|
||||
# The target name may include variable references - which will be expanded.
|
||||
INCS+= target-indirect
|
||||
LINES.target-indirect= \
|
||||
'.if !target($${target-indirect.tmp:L})' \
|
||||
'target-indirect.tmp: .PHONY' \
|
||||
'.endif'
|
||||
# expect: Parse_PushInput: file target-indirect.tmp, line 1
|
||||
# expect: Parse_PushInput: file target-indirect.tmp, line 1
|
||||
# expect: Skipping 'target-indirect.tmp' because 'target-indirect.tmp' is defined
|
||||
|
||||
# A common form of guard target is __${.PARSEFILE}__.
|
||||
# This is only useful of course if basename is unique.
|
||||
INCS+= target-indirect-PARSEFILE
|
||||
LINES.target-indirect-PARSEFILE= \
|
||||
'.if !target(__$${.PARSEFILE}__)' \
|
||||
'__$${.PARSEFILE}__: .NOTMAIN' \
|
||||
'.endif'
|
||||
# expect: Parse_PushInput: file target-indirect-PARSEFILE.tmp, line 1
|
||||
# expect: Skipping 'target-indirect-PARSEFILE.tmp' because '__target-indirect-PARSEFILE.tmp__' is defined
|
||||
|
||||
# Confirm that two such guards do not conflict
|
||||
# again, assuming the basenames are unique.
|
||||
INCS+= target-indirect-PARSEFILE2
|
||||
LINES.target-indirect-PARSEFILE2= \
|
||||
'.if !target(__$${.PARSEFILE}__)' \
|
||||
'__$${.PARSEFILE}__: .NOTMAIN' \
|
||||
'.endif'
|
||||
# expect: Parse_PushInput: file target-indirect-PARSEFILE2.tmp, line 1
|
||||
# expect: Skipping 'target-indirect-PARSEFILE2.tmp' because '__target-indirect-PARSEFILE2.tmp__' is defined
|
||||
|
||||
# Another common form of guard target is __${.PARSEFILE:tA}__.
|
||||
INCS+= target-indirect-PARSEFILE-tA
|
||||
LINES.target-indirect-PARSEFILE-tA= \
|
||||
'.if !target(__$${.PARSEFILE:tA}__)' \
|
||||
'__$${.PARSEFILE:tA}__: .NOTMAIN' \
|
||||
'.endif'
|
||||
# expect: Parse_PushInput: file target-indirect-PARSEFILE-tA.tmp, line 1
|
||||
# expect: Skipping 'target-indirect-PARSEFILE-tA.tmp' because '__target-indirect-PARSEFILE-tA.tmp__' is defined
|
||||
# The actual target is __${.OBJDIR}/target-indirect-PARSEFILE-tA.tmp__ but
|
||||
# ${.OBJDIR}/ gets stripped in post processing.
|
||||
|
||||
# If the target is not defined when including the file the next time, the file
|
||||
# is not guarded.
|
||||
|
|
Loading…
Reference in New Issue