xref: /freebsd/contrib/bmake/unit-tests/deptgt-makeflags.mk (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
1# $NetBSD: deptgt-makeflags.mk,v 1.9 2023/11/19 22:32:44 rillig Exp $
2#
3# Tests for the special target .MAKEFLAGS in dependency declarations,
4# which adds command line options later, at parse time.
5#
6# In these unit tests, it is often used to temporarily toggle the debug log
7# during parsing.
8
9# The -D option sets a variable in the "Global" scope and thus can be
10# undefined later.
11.MAKEFLAGS: -D VAR
12.if ${VAR} != 1
13.  error
14.endif
15
16# Variables that are set via the -D command line option are normal global
17# variables and can thus be undefined later.
18.undef VAR
19.if defined(VAR)
20.  error
21.endif
22
23# The -D command line option can define a variable again, after it has been
24# undefined.
25.MAKEFLAGS: -D VAR
26.if ${VAR} != 1
27.  error
28.endif
29
30# The "dependency" for .MAKEFLAGS is split into words, interpreting the usual
31# quotes and escape sequences from the backslash.
32.MAKEFLAGS: VAR="value"' with'\ spaces
33.if ${VAR} != "value with spaces"
34.  error
35.endif
36
37# Variables set on the command line as VAR=value are placed in the
38# "Command" scope and thus cannot be undefined.
39.undef VAR
40.if ${VAR} != "value with spaces"
41.  error
42.endif
43
44# When parsing this line, each '$$' becomes '$', resulting in '$$$$'.
45# This is assigned to the variable DOLLAR.
46# In the condition, that variable is expanded, and at that point, each '$$'
47# becomes '$' again, the final expression is thus '$$'.
48.MAKEFLAGS: -dcv
49.MAKEFLAGS: DOLLAR=$$$$$$$$
50.if ${DOLLAR} != "\$\$"
51.endif
52.MAKEFLAGS: -d0
53
54# An empty command line is skipped.
55.MAKEFLAGS: # none
56
57# Escape sequences like \n are interpreted.
58# The following line looks as if it assigned a newline to nl, but it doesn't.
59# Instead, the \n ends up as a line that is then interpreted as a variable
60# assignment.  At that point, the line is simply "nl=\n", and the \n is
61# skipped since it is whitespace (see Parse_IsVar).
62.MAKEFLAGS: nl="\n"
63.if ${nl} != ""
64.  error
65.endif
66
67# Next try at defining another newline variable.  Since whitespace around the
68# variable value is trimmed, two empty expressions ${:U} surround the
69# literal newline now.  This prevents the newline from being skipped during
70# parsing.  The ':=' assignment operator expands the empty
71# expressions, leaving only the newline as the variable value.
72#
73# This is one of the very few ways (maybe even the only one) to inject literal
74# newlines into a line that is being parsed.  This may confuse the parser.
75# For example, in cond.c the parser only expects horizontal whitespace (' '
76# and '\t'), but no newlines.
77#.MAKEFLAGS: -dcpv
78.MAKEFLAGS: nl:="$${:U}\n$${:U}"
79.if ${nl} != ${.newline}
80.  error
81.endif
82#.MAKEFLAGS: -d0
83
84# Now do the same for the other escape sequences; see Substring_Words.
85.MAKEFLAGS: CHAR_BS:="$${:U}\b$${:U}"
86.MAKEFLAGS: CHAR_FF:="$${:U}\f$${:U}"
87.MAKEFLAGS: CHAR_NL:="$${:U}\n$${:U}"
88.MAKEFLAGS: CHAR_CR:="$${:U}\r$${:U}"
89.MAKEFLAGS: CHAR_TAB:="$${:U}\t$${:U}"
90
91# Note: backspace is not whitespace, it is a control character.
92.if ${CHAR_BS:C,^[[:cntrl:]]$,found,W} != "found"
93.  error
94.endif
95.if ${CHAR_FF:C,^[[:space:]]$,found,W} != "found"
96.  error
97.endif
98.if ${CHAR_NL:C,^[[:space:]]$,found,W} != "found"
99.  error
100.endif
101.if ${CHAR_CR:C,^[[:space:]]$,found,W} != "found"
102.  error
103.endif
104.if ${CHAR_TAB:C,^[[:space:]]$,found,W} != "found"
105.  error
106.endif
107
108
109# Unbalanced quotes produce an error message.  If they occur anywhere in the
110# command line, the whole command line is skipped.
111.MAKEFLAGS: VAR=previous
112.MAKEFLAGS: VAR=initial UNBALANCED='
113.if ${VAR} != "previous"
114.  error
115.endif
116
117all:
118	@:;
119