Am 22.02.2023 um 03:01 schrieb Mouse:
121 $(x:C;^.*\.([0-9].*)$$;$(INSTMANDIR)/cat\1;):
The same code works with 5.2's make (which, of course, says only moderately little for its correctness...). So, I'm wondering, is this a bug in 9.1's make, or am I doing something wrong here?
TL;DR: There are several cases in which make silently ignores parse errors, such as '$$' in variable modifiers. In other cases, it has become stricter over time, or the accepted syntax just changed. The crucial part in your example is the '$$'. In normal strings, '$$' is used to escape a '$'. But in variable modifiers such as ':C', '\$' is used instead to escape a '$'. Well, in most variable modifiers, as some of them have their own parsing rules. In netbsd-5.2:usr.bin/make/var.c, the '$$' is parsed as the variable named '$', so the parser continues by looking at the ';', which is a delimiter for the ':C' modifier, just as you expected. In netbsd-9:usr.bin/make/var.c, the variable name '$$' is silently no longer accepted, see the comment "Error out some really stupid names" in var.c, but that's not even relevant in this case. In netbsd-9:usr.bin/make/var.c, the parser looks at '$(x:...(...)$$)', trying to figure out which parentheses match, see the comment "Attempt to avoid ';' inside substitution patterns" in parse.c. In this case, the parser fails. It counts the '$(' as starting a subexpression, then ignores the following '(', and when it sees the first ')', it considers the expression completed, leaving the '$$)' for a syntax error. This ad-hoc parentheses-counting code is still present in the latest version of make. To avoid all these edge cases, you should rewrite your makefile: * In the ':C' modifier, replace '$$' with '$', as there is no need to double it. * In dependency lines, avoid modifiers containing ';'. To make the makefile easier readable and at the same time avoiding line noise, you can use a multi-variable .for loop, which are available since 2000: .for base ext in $(INSTALLMAN:C;^(.*)\.([0-9].*)$;\1 \2;) install_files:: $(INSTMANDIR)/cat${ext}/${base}.0 .endfor Roland