diff options
203 files changed, 1973 insertions, 1015 deletions
@@ -27,6 +27,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW: world, or to merely disable the most expensive debugging functionality at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20250719: + Commits 392a82b225 and c00baac0ab both changed the + internal API between the NFS modules. As such, all + these modules need to be rebuilt from sources. + __FreeBSD_version was bumped to 1500053 for this. + 20250710: The shar(1) utility has been removed from base. The sysutils/freebsd-shar port was created to maintain this version of diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog index 0a5eced2d439..5a1c30a95750 100644 --- a/contrib/bmake/ChangeLog +++ b/contrib/bmake/ChangeLog @@ -1,3 +1,30 @@ +2025-07-07 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20250707 + Merge with NetBSD make, pick up + o cond.c: improve debug log message for 'exists' function. + complain about unfinished escape sequences or string literals. + +2025-07-04 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20250704 + Merge with NetBSD make, pick up + o make.1: add a DIAGNOSTICS section for make to reference. + o main.c: simplify the warning for invalid -J by refering to + manual page. + +2025-06-30 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20250630 + Merge with NetBSD make, pick up + o consistently use double quotes in error messages + o cond.c: if a condition is erroneous, skip the whole .if/.endif + o make_malloc.c: in cleanup mode, initialize freshly allocated memory + o str.c: error out on an ":M" modifier whose pattern ends with + backslash + o var.c: fix parsing of modifier parts for :gmtime and :localtime + add POSIX $^ support + 2025-06-18 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250618 diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES index 8bed07d546a3..1cec16b73ef4 100644 --- a/contrib/bmake/FILES +++ b/contrib/bmake/FILES @@ -76,6 +76,8 @@ unit-tests/archive-suffix.exp unit-tests/archive-suffix.mk unit-tests/archive.exp unit-tests/archive.mk +unit-tests/char-005c-reverse-solidus.exp +unit-tests/char-005c-reverse-solidus.mk unit-tests/check-expect.lua unit-tests/cmd-errors-jobs.exp unit-tests/cmd-errors-jobs.mk @@ -602,8 +604,6 @@ unit-tests/shell-ksh.exp unit-tests/shell-ksh.mk unit-tests/shell-sh.exp unit-tests/shell-sh.mk -unit-tests/suff.exp -unit-tests/suff.mk unit-tests/suff-add-later.exp unit-tests/suff-add-later.mk unit-tests/suff-clear-regular.exp @@ -634,6 +634,8 @@ unit-tests/suff-transform-select.exp unit-tests/suff-transform-select.mk unit-tests/suff-use.exp unit-tests/suff-use.mk +unit-tests/suff.exp +unit-tests/suff.mk unit-tests/sunshcmd.exp unit-tests/sunshcmd.mk unit-tests/ternary.exp @@ -780,6 +782,8 @@ unit-tests/varmod-unique.exp unit-tests/varmod-unique.mk unit-tests/varmod.exp unit-tests/varmod.mk +unit-tests/varname-circumflex.exp +unit-tests/varname-circumflex.mk unit-tests/varname-dollar.exp unit-tests/varname-dollar.mk unit-tests/varname-dot-alltargets.exp diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION index 1467403891f1..eef1ef4b8ba9 100644 --- a/contrib/bmake/VERSION +++ b/contrib/bmake/VERSION @@ -1,2 +1,2 @@ # keep this compatible with sh and make -_MAKE_VERSION=20250618 +_MAKE_VERSION=20250707 diff --git a/contrib/bmake/arch.c b/contrib/bmake/arch.c index 77ac7f3c5707..87e2b128ae00 100644 --- a/contrib/bmake/arch.c +++ b/contrib/bmake/arch.c @@ -1,4 +1,4 @@ -/* $NetBSD: arch.c,v 1.222 2024/08/06 17:46:01 rillig Exp $ */ +/* $NetBSD: arch.c,v 1.223 2025/06/28 22:39:27 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -147,7 +147,7 @@ struct ar_hdr { #include "dir.h" /* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */ -MAKE_RCSID("$NetBSD: arch.c,v 1.222 2024/08/06 17:46:01 rillig Exp $"); +MAKE_RCSID("$NetBSD: arch.c,v 1.223 2025/06/28 22:39:27 rillig Exp $"); typedef struct List ArchList; typedef struct ListNode ArchListNode; @@ -314,7 +314,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope) if (*cp == '\0') { Parse_Error(PARSE_FATAL, - "Missing ')' in archive specification"); + "Missing \")\" in archive specification"); return false; } diff --git a/contrib/bmake/bmake.1 b/contrib/bmake/bmake.1 index 92ed9e201ea5..01f173bc1a69 100644 --- a/contrib/bmake/bmake.1 +++ b/contrib/bmake/bmake.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.385 2025/06/13 03:51:18 rillig Exp $ +.\" $NetBSD: make.1,v 1.387 2025/07/02 17:11:56 rillig Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd June 12, 2025 +.Dd July 2, 2025 .Dt BMAKE 1 .Os .Sh NAME @@ -785,11 +785,13 @@ Is redundant with respect to global variables, which have already been expanded. .El .Pp -The seven built-in local variables are: +The built-in local variables are: .Bl -tag -width ".Va .ARCHIVE" -offset indent .It Va .ALLSRC The list of all sources for this target; also known as -.Sq Va \&> . +.Sq Va \&> +or +.Sq Va \&^ . .It Va .ARCHIVE The name of the archive file; also known as .Sq Va \&! . @@ -823,6 +825,7 @@ in archive member rules. The shorter forms .Po .Sq Va \&> , +.Sq Va \&^ , .Sq Va \&! , .Sq Va \&< , .Sq Va \&% , @@ -2714,6 +2717,8 @@ If the environment variable is set to .Dq yes , any stack traces include the call chain of the parent processes. +.\" .Sh EXIT STATUS +.\" .Sh ENVIRONMENT .Sh FILES .Bl -tag -width /usr/share/mk -compact .It .depend @@ -2727,6 +2732,68 @@ system makefile .It /usr/share/mk system makefile directory .El +.\" .Sh EXAMPLES +.Sh DIAGNOSTICS +.Bl -tag +.It Dv Invalid internal option \(dq-J\(dq in \(dq Ns Ar directory Ns Dv \(dq +The internal +.Fl J +option coordinates the main +.Nm +process with the sub-make processes to limit +the number of jobs that run in parallel. +The option is passed to all child processes via the +.Ev MAKEFLAGS +environment variable. +To become valid, +this option requires that the target running the sub-make is marked with the +.Dv .MAKE +special source, +or that one of the target's commands directly contains the word +.Dq make +or one of the expressions +.Dq ${MAKE} , +.Dq ${.MAKE} , +.Dq $(MAKE) , +.Dq $(.MAKE) . +If that's not the case, +make issues the above warning and falls back to compat mode. +.Pp +To see the chain of sub-makes that leads to the invalid option, set the +.Ev MAKE_STACK_TRACE +environment variable to +.Dq yes . +.Pp +To run the sub-make in parallel mode, even in dry-run mode (see the +.Fl n +option), add the +.Dv .MAKE +pseudo source to the target. +This is appropriate when the sub-make runs the same target in a subdirectory. +.Pp +To run the sub-make in parallel mode but not in dry-mode, +add a +.Dq ${:D make} +marker to one of the target's commands. +This marker expands to an empty string +and thus does not affect the executed commands. +.\" The marker can even be added before any of the "@+-" modifiers, +.\" so no need to mention this explicitly. +.Pp +To run the sub-make in compat mode, add the +.Fl B +option to its invocation. +This is appropriate when the sub-make is only used to print a variable's +value using the +.Fl v +or +.Fl V +options. +.Pp +To make the sub-make independent from the parent make, unset the +.Ev MAKEFLAGS +environment variable in the target's commands. +.El .Sh COMPATIBILITY The basic make syntax is compatible between different make variants; however the special variables, variable modifiers and conditionals are not. @@ -2813,6 +2880,7 @@ not trying to chain transformations together, etc.) is also reasonably portable. .Sh SEE ALSO .Xr mkdep 1 +.\" .Sh STANDARDS .Sh HISTORY .Nm is derived from NetBSD @@ -2837,6 +2905,8 @@ has been used to FoRCe rebuilding (since the target/dependency does not exist ... unless someone creates an .Pa FRC file). +.\" .Sh AUTHORS +.\" .Sh CAVEATS .Sh BUGS The .Nm @@ -2858,3 +2928,4 @@ using that token pool to abort the build and exit with error code 6. Sometimes the attempt to suppress a cascade of unnecessary errors, can result in a seemingly unexplained .Ql *** Error code 6 +.\" .Sh SECURITY CONSIDERATIONS diff --git a/contrib/bmake/bmake.cat1 b/contrib/bmake/bmake.cat1 index 667c80898def..950437a8db9c 100644 --- a/contrib/bmake/bmake.cat1 +++ b/contrib/bmake/bmake.cat1 @@ -507,10 +507,10 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS ::== Is redundant with respect to global variables, which have already been expanded. - The seven built-in local variables are: + The built-in local variables are: _._A_L_L_S_R_C The list of all sources for this target; also known as - `_>'. + `_>' or `_^'. _._A_R_C_H_I_V_E The name of the archive file; also known as `_!'. @@ -531,9 +531,9 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS compatibility with other makes this is an alias for _._A_R_C_H_I_V_E in archive member rules. - The shorter forms (`_>', `_!', `_<', `_%', `_?', `_*', and `_@') are permitted - for backward compatibility with historical makefiles and legacy POSIX - make and are not recommended. + The shorter forms (`_>', `_^', `_!', `_<', `_%', `_?', `_*', and `_@') are + permitted for backward compatibility with historical makefiles and legacy + POSIX make and are not recommended. Variants of these variables with the punctuation followed immediately by `D' or `F', e.g. `$(@D)', are legacy forms equivalent to using the `:H' @@ -1748,6 +1748,39 @@ FFIILLEESS sys.mk system makefile /usr/share/mk system makefile directory +DDIIAAGGNNOOSSTTIICCSS + Invalid internal option "-J" in "_d_i_r_e_c_t_o_r_y" + The internal --JJ option coordinates the main bbmmaakkee process with + the sub-make processes to limit the number of jobs that run in + parallel. The option is passed to all child processes via the + MAKEFLAGS environment variable. To become valid, this option + requires that the target running the sub-make is marked with the + .MAKE special source, or that one of the target's commands + directly contains the word "make" or one of the expressions + "${MAKE}", "${.MAKE}", "$(MAKE)", "$(.MAKE)". If that's not the + case, make issues the above warning and falls back to compat + mode. + + To see the chain of sub-makes that leads to the invalid option, + set the MAKE_STACK_TRACE environment variable to "yes". + + To run the sub-make in parallel mode, even in dry-run mode (see + the --nn option), add the .MAKE pseudo source to the target. This + is appropriate when the sub-make runs the same target in a + subdirectory. + + To run the sub-make in parallel mode but not in dry-mode, add a + "${:D make}" marker to one of the target's commands. This marker + expands to an empty string and thus does not affect the executed + commands. + + To run the sub-make in compat mode, add the --BB option to its + invocation. This is appropriate when the sub-make is only used + to print a variable's value using the --vv or --VV options. + + To make the sub-make independent from the parent make, unset the + MAKEFLAGS environment variable in the target's commands. + CCOOMMPPAATTIIBBIILLIITTYY The basic make syntax is compatible between different make variants; however the special variables, variable modifiers and conditionals are @@ -1831,4 +1864,4 @@ BBUUGGSS attempt to suppress a cascade of unnecessary errors, can result in a seemingly unexplained `*** Error code 6' -FreeBSD 14.2-RELEASE-p1 June 12, 2025 FreeBSD 14.2-RELEASE-p1 +FreeBSD 14.2-RELEASE-p1 July 2, 2025 FreeBSD 14.2-RELEASE-p1 diff --git a/contrib/bmake/compat.c b/contrib/bmake/compat.c index 7a51a99be4ba..f32213bf67e5 100644 --- a/contrib/bmake/compat.c +++ b/contrib/bmake/compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: compat.c,v 1.267 2025/06/13 03:51:18 rillig Exp $ */ +/* $NetBSD: compat.c,v 1.268 2025/07/06 07:11:31 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -97,7 +97,7 @@ #include "pathnames.h" /* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: compat.c,v 1.267 2025/06/13 03:51:18 rillig Exp $"); +MAKE_RCSID("$NetBSD: compat.c,v 1.268 2025/07/06 07:11:31 rillig Exp $"); static GNode *curTarg; static pid_t compatChild; @@ -334,11 +334,8 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln) if (useShell) { static const char *shargv[5]; - if (Cmd_Argv(cmd, cmd_len, shargv, 5, - cmd_file, sizeof(cmd_file), - errCheck && shellErrFlag != NULL, - DEBUG(SHELL)) < 0) - Fatal("cannot run \"%s\"", cmd); + Cmd_Argv(cmd, cmd_len, shargv, cmd_file, sizeof(cmd_file), + errCheck && shellErrFlag != NULL, DEBUG(SHELL)); av = shargv; bp = NULL; mav = NULL; diff --git a/contrib/bmake/cond.c b/contrib/bmake/cond.c index f83163cbb50e..b3613bbadf5d 100644 --- a/contrib/bmake/cond.c +++ b/contrib/bmake/cond.c @@ -1,4 +1,4 @@ -/* $NetBSD: cond.c,v 1.373 2025/04/22 19:28:50 rillig Exp $ */ +/* $NetBSD: cond.c,v 1.378 2025/07/06 07:56:16 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -77,9 +77,8 @@ * '.if <cond>', '.elifnmake <cond>', '.else', '.endif'. * * Cond_EvalCondition - * Evaluate the conditional, which is either the argument - * of one of the .if directives or the condition in a - * ':?then:else' variable modifier. + * Evaluate a condition, either from one of the .if + * directives, or from a ':?then:else' modifier. * * Cond_EndFile At the end of reading a makefile, ensure that the * conditional directives are well-balanced. @@ -91,14 +90,14 @@ #include "dir.h" /* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ -MAKE_RCSID("$NetBSD: cond.c,v 1.373 2025/04/22 19:28:50 rillig Exp $"); +MAKE_RCSID("$NetBSD: cond.c,v 1.378 2025/07/06 07:56:16 rillig Exp $"); /* * Conditional expressions conform to this grammar: * Or -> And ('||' And)* * And -> Term ('&&' Term)* * Term -> Function '(' Argument ')' - * Term -> Leaf Operator Leaf + * Term -> Leaf ComparisonOp Leaf * Term -> Leaf * Term -> '(' Or ')' * Term -> '!' Term @@ -106,7 +105,7 @@ MAKE_RCSID("$NetBSD: cond.c,v 1.373 2025/04/22 19:28:50 rillig Exp $"); * Leaf -> Number * Leaf -> VariableExpression * Leaf -> BareWord - * Operator -> '==' | '!=' | '>' | '<' | '>=' | '<=' + * ComparisonOp -> '==' | '!=' | '>' | '<' | '>=' | '<=' * * BareWord is an unquoted string literal, its evaluation depends on the kind * of '.if' directive. @@ -156,12 +155,12 @@ typedef struct CondParser { * been an expression or a plain word. * * In conditional directives like '.if', the left-hand side must - * either be an expression, a quoted string or a number. + * either be a defined expression, a quoted string or a number. */ bool leftUnquotedOK; const char *p; /* The remaining condition to parse */ - Token curr; /* Single push-back token used in parsing */ + Token curr; /* The push-back token, or TOK_NONE */ } CondParser; static CondResult CondParser_Or(CondParser *, bool); @@ -255,7 +254,7 @@ ParseFuncArg(const char **pp, bool doEval, const char *func) len++; Parse_Error(PARSE_FATAL, - "Missing ')' after argument '%.*s' for '%.*s'", + "Missing \")\" after argument \"%.*s\" for \"%.*s\"", (int)(argEnd - argStart), argStart, len, func); free(res); return NULL; @@ -284,7 +283,8 @@ FuncMake(const char *targetPattern) if (res.error != NULL && !warned) { warned = true; Parse_Error(PARSE_WARNING, - "%s in pattern argument '%s' to function 'make'", + "%s in pattern argument \"%s\" " + "to function \"make\"", res.error, targetPattern); } if (res.matched) @@ -301,14 +301,16 @@ FuncExists(const char *file) char *path; path = Dir_FindFile(file, &dirSearchPath); - DEBUG2(COND, "exists(%s) result is \"%s\"\n", - file, path != NULL ? path : ""); result = path != NULL; + if (result) + DEBUG2(COND, "\"%s\" exists in \"%s\"\n", file, path); + else + DEBUG1(COND, "\"%s\" does not exist\n", file); free(path); return result; } -/* See if the given node exists and is an actual target. */ +/* See if the given node is an actual target. */ static bool FuncTarget(const char *node) { @@ -316,10 +318,7 @@ FuncTarget(const char *node) return gn != NULL && GNode_IsTarget(gn); } -/* - * See if the given node exists and is an actual target with commands - * associated with it. - */ +/* See if the given node is an actual target with commands. */ static bool FuncCommands(const char *node) { @@ -374,38 +373,37 @@ is_separator(char ch) * * Return whether to continue parsing the leaf. * - * Example: .if x${CENTER}y == "${PREFIX}${SUFFIX}" || 0x${HEX} + * Examples: .if x${CENTER}y == "${PREFIX}${SUFFIX}" || 0x${HEX} */ static bool CondParser_StringExpr(CondParser *par, const char *start, bool doEval, bool quoted, - Buffer *buf, FStr *inout_str) + Buffer *buf, FStr *out_str) { VarEvalMode emode; const char *p; - bool atStart; /* true means an expression outside quotes */ + bool outsideQuotes; emode = doEval && quoted ? VARE_EVAL : doEval ? VARE_EVAL_DEFINED_LOUD : VARE_PARSE; p = par->p; - atStart = p == start; - *inout_str = Var_Parse(&p, SCOPE_CMDLINE, emode); - /* TODO: handle errors */ - if (inout_str->str == var_Error) { - FStr_Done(inout_str); - *inout_str = FStr_InitRefer(NULL); + outsideQuotes = p == start; + *out_str = Var_Parse(&p, SCOPE_CMDLINE, emode); + if (out_str->str == var_Error) { + FStr_Done(out_str); + *out_str = FStr_InitRefer(NULL); return false; } par->p = p; - if (atStart && is_separator(par->p[0])) + if (outsideQuotes && is_separator(par->p[0])) return false; - Buf_AddStr(buf, inout_str->str); - FStr_Done(inout_str); - *inout_str = FStr_InitRefer(NULL); /* not finished yet */ + Buf_AddStr(buf, out_str->str); + FStr_Done(out_str); + *out_str = FStr_InitRefer(NULL); /* not finished yet */ return true; } @@ -414,7 +412,7 @@ CondParser_StringExpr(CondParser *par, const char *start, * on the left-hand and right-hand sides of comparisons. * * Return the string without any enclosing quotes, or NULL on error. - * Sets out_quoted if the leaf was a quoted string literal. + * Set out_quoted if the leaf was a quoted string literal. */ static FStr CondParser_Leaf(CondParser *par, bool doEval, bool unquotedOK, @@ -439,12 +437,14 @@ CondParser_Leaf(CondParser *par, bool doEval, bool unquotedOK, if (par->p[0] != '\0') { Buf_AddByte(&buf, par->p[0]); par->p++; - } + } else + Parse_Error(PARSE_FATAL, + "Unfinished backslash escape sequence"); continue; case '"': par->p++; if (quoted) - goto return_buf; /* skip the closing quote */ + goto return_buf; Buf_AddByte(&buf, '"'); continue; case ')': /* see is_separator */ @@ -475,6 +475,9 @@ CondParser_Leaf(CondParser *par, bool doEval, bool unquotedOK, continue; } } + if (quoted) + Parse_Error(PARSE_FATAL, + "Unfinished string literal \"%s\"", start); return_buf: str = FStr_InitOwn(buf.data); buf.data = NULL; @@ -528,8 +531,8 @@ EvalCompareStr(const char *lhs, ComparisonOp op, const char *rhs) { if (op != EQ && op != NE) { Parse_Error(PARSE_FATAL, - "Comparison with '%s' requires both operands " - "'%s' and '%s' to be numeric", + "Comparison with \"%s\" requires both operands " + "\"%s\" and \"%s\" to be numeric", opname[op], lhs, rhs); return TOK_ERROR; } @@ -603,7 +606,7 @@ CondParser_Comparison(CondParser *par, bool doEval) if (par->p[0] == '\0') { Parse_Error(PARSE_FATAL, - "Missing right-hand side of operator '%s'", opname[op]); + "Missing right-hand side of operator \"%s\"", opname[op]); goto done_lhs; } @@ -768,7 +771,7 @@ CondParser_Token(CondParser *par, bool doEval) if (par->p[0] == '|') par->p++; else { - Parse_Error(PARSE_FATAL, "Unknown operator '|'"); + Parse_Error(PARSE_FATAL, "Unknown operator \"|\""); return TOK_ERROR; } return TOK_OR; @@ -778,7 +781,7 @@ CondParser_Token(CondParser *par, bool doEval) if (par->p[0] == '&') par->p++; else { - Parse_Error(PARSE_FATAL, "Unknown operator '&'"); + Parse_Error(PARSE_FATAL, "Unknown operator \"&\""); return TOK_ERROR; } return TOK_AND; @@ -825,7 +828,7 @@ CondParser_Skip(CondParser *par, Token t) /* * Term -> '(' Or ')' * Term -> '!' Term - * Term -> Leaf Operator Leaf + * Term -> Leaf ComparisonOp Leaf * Term -> Leaf */ static CondResult @@ -923,8 +926,10 @@ CondEvalExpression(const char *cond, bool plain, if (par.curr != TOK_EOF) rval = CR_ERROR; - if (rval == CR_ERROR && eprint && parseErrors == parseErrorsBefore) - Parse_Error(PARSE_FATAL, "Malformed conditional '%s'", cond); + if (parseErrors != parseErrorsBefore) + rval = CR_ERROR; + else if (rval == CR_ERROR && eprint) + Parse_Error(PARSE_FATAL, "Malformed conditional \"%s\"", cond); return rval; } diff --git a/contrib/bmake/for.c b/contrib/bmake/for.c index 438fb4e84de0..904853107db8 100644 --- a/contrib/bmake/for.c +++ b/contrib/bmake/for.c @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.185 2025/04/22 19:28:50 rillig Exp $ */ +/* $NetBSD: for.c,v 1.186 2025/06/28 22:39:27 rillig Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -58,7 +58,7 @@ #include "make.h" /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ -MAKE_RCSID("$NetBSD: for.c,v 1.185 2025/04/22 19:28:50 rillig Exp $"); +MAKE_RCSID("$NetBSD: for.c,v 1.186 2025/06/28 22:39:27 rillig Exp $"); typedef struct ForLoop { @@ -153,7 +153,8 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp) for (;;) { cpp_skip_whitespace(&p); if (*p == '\0') { - Parse_Error(PARSE_FATAL, "missing `in' in for"); + Parse_Error(PARSE_FATAL, + "Missing \"in\" in .for loop"); goto cleanup; } @@ -168,7 +169,8 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp) } if (f->vars.len == 0) { - Parse_Error(PARSE_FATAL, "no iteration variables in for"); + Parse_Error(PARSE_FATAL, + "Missing iteration variables in .for loop"); return; } @@ -177,7 +179,7 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp) invalid_variable_name: Parse_Error(PARSE_FATAL, - "invalid character '%c' in .for loop variable name", *p); + "Invalid character \"%c\" in .for loop variable name", *p); cleanup: while (f->vars.len > 0) free(*(char **)Vector_Pop(&f->vars)); diff --git a/contrib/bmake/job.c b/contrib/bmake/job.c index 582870088f2d..0c54e710afeb 100644 --- a/contrib/bmake/job.c +++ b/contrib/bmake/job.c @@ -1,4 +1,4 @@ -/* $NetBSD: job.c,v 1.516 2025/06/13 06:13:19 rillig Exp $ */ +/* $NetBSD: job.c,v 1.517 2025/07/06 07:11:31 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -89,7 +89,7 @@ * define the shell that is used for the creation * commands in jobs mode. * - * Job_Finish Make the .END target. Must only be called when the + * Job_MakeDotEnd Make the .END target. Must only be called when the * job table is empty. * * Job_AbortAll Kill all currently running jobs, in an emergency. @@ -137,7 +137,7 @@ #include "trace.h" /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: job.c,v 1.516 2025/06/13 06:13:19 rillig Exp $"); +MAKE_RCSID("$NetBSD: job.c,v 1.517 2025/07/06 07:11:31 rillig Exp $"); #ifdef USE_SELECT @@ -599,7 +599,7 @@ Job_Pid(Job *job) } static void -DumpJobs(const char *where) +JobTable_Dump(const char *where) { const Job *job; char flags[4]; @@ -663,6 +663,13 @@ SetNonblocking(int fd) } static void +SetCloseOnExec(int fd) +{ + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + Punt("SetCloseOnExec: %s", strerror(errno)); +} + +static void JobCreatePipe(Job *job, int minfd) { int i; @@ -683,10 +690,8 @@ JobCreatePipe(Job *job, int minfd) job->inPipe = pipe_fds[0]; job->outPipe = pipe_fds[1]; - if (fcntl(job->inPipe, F_SETFD, FD_CLOEXEC) == -1) - Punt("SetCloseOnExec: %s", strerror(errno)); - if (fcntl(job->outPipe, F_SETFD, FD_CLOEXEC) == -1) - Punt("SetCloseOnExec: %s", strerror(errno)); + SetCloseOnExec(job->inPipe); + SetCloseOnExec(job->outPipe); /* * We mark the input side of the pipe non-blocking; we poll(2) the @@ -822,7 +827,7 @@ JobFindPid(int pid, enum JobStatus status, bool isJobs) return job; } if (DEBUG(JOB) && isJobs) - DumpJobs("no pid"); + JobTable_Dump("no pid"); return NULL; } @@ -1624,7 +1629,7 @@ JobExec(Job *job, char **argv) debug_printf( "JobExec: target %s, pid %d added to jobs table\n", job->node->name, job->pid); - DumpJobs("job started"); + JobTable_Dump("job started"); } JobsTable_Unlock(&mask); } @@ -2433,7 +2438,6 @@ static void JobInterrupt(bool runINTERRUPT, int signo) { Job *job; - GNode *interrupt; sigset_t mask; aborting = ABORT_INTERRUPT; @@ -2460,10 +2464,10 @@ JobInterrupt(bool runINTERRUPT, int signo) JobsTable_Unlock(&mask); if (runINTERRUPT && !opts.touch) { - interrupt = Targ_FindNode(".INTERRUPT"); - if (interrupt != NULL) { + GNode *dotInterrupt = Targ_FindNode(".INTERRUPT"); + if (dotInterrupt != NULL) { opts.ignoreErrors = false; - JobRun(interrupt); + JobRun(dotInterrupt); } } Trace_Log(MAKEINTR, NULL); @@ -2472,15 +2476,15 @@ JobInterrupt(bool runINTERRUPT, int signo) /* Make the .END target, returning the number of job-related errors. */ int -Job_Finish(void) +Job_MakeDotEnd(void) { - GNode *endNode = Targ_GetEndNode(); - if (!Lst_IsEmpty(&endNode->commands) || - !Lst_IsEmpty(&endNode->children)) { + GNode *dotEnd = Targ_GetEndNode(); + if (!Lst_IsEmpty(&dotEnd->commands) || + !Lst_IsEmpty(&dotEnd->children)) { if (job_errors != 0) Error("Errors reported so .END ignored"); else - JobRun(endNode); + JobRun(dotEnd); } return job_errors; } diff --git a/contrib/bmake/job.h b/contrib/bmake/job.h index 901be0eef1dd..2b4b5e59c37e 100644 --- a/contrib/bmake/job.h +++ b/contrib/bmake/job.h @@ -1,4 +1,4 @@ -/* $NetBSD: job.h,v 1.84 2025/04/22 19:28:50 rillig Exp $ */ +/* $NetBSD: job.h,v 1.85 2025/07/06 07:11:31 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -101,7 +101,7 @@ void Job_CatchOutput(void); void Job_Make(GNode *); void Job_Init(void); bool Job_ParseShell(char *) MAKE_ATTR_USE; -int Job_Finish(void); +int Job_MakeDotEnd(void); #ifdef CLEANUP void Job_End(void); #endif diff --git a/contrib/bmake/main.c b/contrib/bmake/main.c index d020ba85f16b..a773b44f42c4 100644 --- a/contrib/bmake/main.c +++ b/contrib/bmake/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.659 2025/06/13 05:41:36 rillig Exp $ */ +/* $NetBSD: main.c,v 1.661 2025/07/06 07:11:31 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -111,7 +111,7 @@ #include "trace.h" /* "@(#)main.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: main.c,v 1.659 2025/06/13 05:41:36 rillig Exp $"); +MAKE_RCSID("$NetBSD: main.c,v 1.661 2025/07/06 07:11:31 rillig Exp $"); #if defined(MAKE_NATIVE) __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 " "The Regents of the University of California. " @@ -1221,23 +1221,8 @@ InitMaxJobs(void) if (bogusJflag && !opts.compatMake) { opts.compatMake = true; Parse_Error(PARSE_WARNING, - "internal option \"-J\" in \"%s\" " - "refers to unopened file descriptors; " - "falling back to compat mode.\n" - "\t" - "To run the target even in -n mode, " - "add the .MAKE pseudo-source to the target.\n" - "\t" - "To run the target in default mode only, " - "add a ${:D make} marker to a target's command. " - "(This marker expression expands to an empty string.)\n" - "\t" - "To make the sub-make run in compat mode, add -B to " - "its invocation.\n" - "\t" - "To make the sub-make independent from the parent make, " - "unset the MAKEFLAGS environment variable in the " - "target's commands.", + "Invalid internal option \"-J\" in \"%s\"; " + "see the manual page", curdir); PrintStackTrace(true); return; @@ -1734,11 +1719,10 @@ found: } /* populate av for Cmd_Exec and Compat_RunCommand */ -int -Cmd_Argv(const char *cmd, size_t cmd_len, const char **av, size_t avsz, +void +Cmd_Argv(const char *cmd, size_t cmd_len, const char *av[5], char *cmd_file, size_t cmd_filesz, bool eflag, bool xflag) { - int ac = 0; int cmd_fd = -1; if (shellPath == NULL) @@ -1764,23 +1748,19 @@ Cmd_Argv(const char *cmd, size_t cmd_len, const char **av, size_t avsz, cmd_file[0] = '\0'; } - if (avsz < 4 || (eflag && avsz < 5)) - return -1; - /* The following works for any of the builtin shell specs. */ - av[ac++] = shellPath; + *av++ = shellPath; if (eflag) - av[ac++] = shellErrFlag; + *av++ = shellErrFlag; if (cmd_fd >= 0) { if (xflag) - av[ac++] = "-x"; - av[ac++] = cmd_file; + *av++ = "-x"; + *av++ = cmd_file; } else { - av[ac++] = xflag ? "-xc" : "-c"; - av[ac++] = cmd; + *av++ = xflag ? "-xc" : "-c"; + *av++ = cmd; } - av[ac] = NULL; - return ac; + *av = NULL; } /* @@ -1790,7 +1770,7 @@ Cmd_Argv(const char *cmd, size_t cmd_len, const char **av, size_t avsz, char * Cmd_Exec(const char *cmd, char **error) { - const char *args[4]; /* Arguments for invoking the shell */ + const char *args[5]; /* Arguments for invoking the shell */ int pipefds[2]; int cpid; /* Child PID */ int pid; /* PID from wait() */ @@ -1804,8 +1784,8 @@ Cmd_Exec(const char *cmd, char **error) DEBUG1(VAR, "Capturing the output of command \"%s\"\n", cmd); - if (Cmd_Argv(cmd, 0, args, 4, cmd_file, sizeof(cmd_file), false, false) < 0 - || pipe(pipefds) == -1) { + Cmd_Argv(cmd, 0, args, cmd_file, sizeof(cmd_file), false, false); + if (pipe(pipefds) == -1) { *error = str_concat3( "Couldn't create pipe for \"", cmd, "\""); return bmake_strdup(""); @@ -2083,7 +2063,7 @@ shouldDieQuietly(GNode *gn, int bf) else if (bf >= 0) quietly = bf; else - quietly = (gn != NULL && (gn->type & OP_MAKE)) ? 1 : 0; + quietly = gn != NULL && gn->type & OP_MAKE ? 1 : 0; } return quietly != 0; } diff --git a/contrib/bmake/make.1 b/contrib/bmake/make.1 index f05653af7e31..de67759290c4 100644 --- a/contrib/bmake/make.1 +++ b/contrib/bmake/make.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.385 2025/06/13 03:51:18 rillig Exp $ +.\" $NetBSD: make.1,v 1.387 2025/07/02 17:11:56 rillig Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd June 12, 2025 +.Dd July 2, 2025 .Dt MAKE 1 .Os .Sh NAME @@ -785,11 +785,13 @@ Is redundant with respect to global variables, which have already been expanded. .El .Pp -The seven built-in local variables are: +The built-in local variables are: .Bl -tag -width ".Va .ARCHIVE" -offset indent .It Va .ALLSRC The list of all sources for this target; also known as -.Sq Va \&> . +.Sq Va \&> +or +.Sq Va \&^ . .It Va .ARCHIVE The name of the archive file; also known as .Sq Va \&! . @@ -823,6 +825,7 @@ in archive member rules. The shorter forms .Po .Sq Va \&> , +.Sq Va \&^ , .Sq Va \&! , .Sq Va \&< , .Sq Va \&% , @@ -2725,6 +2728,8 @@ If the environment variable is set to .Dq yes , any stack traces include the call chain of the parent processes. +.\" .Sh EXIT STATUS +.\" .Sh ENVIRONMENT .Sh FILES .Bl -tag -width /usr/share/mk -compact .It .depend @@ -2738,6 +2743,68 @@ system makefile .It /usr/share/mk system makefile directory .El +.\" .Sh EXAMPLES +.Sh DIAGNOSTICS +.Bl -tag +.It Dv Invalid internal option \(dq-J\(dq in \(dq Ns Ar directory Ns Dv \(dq +The internal +.Fl J +option coordinates the main +.Nm +process with the sub-make processes to limit +the number of jobs that run in parallel. +The option is passed to all child processes via the +.Ev MAKEFLAGS +environment variable. +To become valid, +this option requires that the target running the sub-make is marked with the +.Dv .MAKE +special source, +or that one of the target's commands directly contains the word +.Dq make +or one of the expressions +.Dq ${MAKE} , +.Dq ${.MAKE} , +.Dq $(MAKE) , +.Dq $(.MAKE) . +If that's not the case, +make issues the above warning and falls back to compat mode. +.Pp +To see the chain of sub-makes that leads to the invalid option, set the +.Ev MAKE_STACK_TRACE +environment variable to +.Dq yes . +.Pp +To run the sub-make in parallel mode, even in dry-run mode (see the +.Fl n +option), add the +.Dv .MAKE +pseudo source to the target. +This is appropriate when the sub-make runs the same target in a subdirectory. +.Pp +To run the sub-make in parallel mode but not in dry-mode, +add a +.Dq ${:D make} +marker to one of the target's commands. +This marker expands to an empty string +and thus does not affect the executed commands. +.\" The marker can even be added before any of the "@+-" modifiers, +.\" so no need to mention this explicitly. +.Pp +To run the sub-make in compat mode, add the +.Fl B +option to its invocation. +This is appropriate when the sub-make is only used to print a variable's +value using the +.Fl v +or +.Fl V +options. +.Pp +To make the sub-make independent from the parent make, unset the +.Ev MAKEFLAGS +environment variable in the target's commands. +.El .Sh COMPATIBILITY The basic make syntax is compatible between different make variants; however the special variables, variable modifiers and conditionals are not. @@ -2825,6 +2892,7 @@ portable. .Sh SEE ALSO .Xr mkdep 1 , .Xr style.Makefile 5 +.\" .Sh STANDARDS .Sh HISTORY A .Nm @@ -2844,6 +2912,8 @@ has been used to FoRCe rebuilding (since the target/dependency does not exist ... unless someone creates an .Pa FRC file). +.\" .Sh AUTHORS +.\" .Sh CAVEATS .Sh BUGS The .Nm @@ -2865,3 +2935,4 @@ using that token pool to abort the build and exit with error code 6. Sometimes the attempt to suppress a cascade of unnecessary errors, can result in a seemingly unexplained .Ql *** Error code 6 +.\" .Sh SECURITY CONSIDERATIONS diff --git a/contrib/bmake/make.c b/contrib/bmake/make.c index 3826c4d4e6a1..811f6e0849c4 100644 --- a/contrib/bmake/make.c +++ b/contrib/bmake/make.c @@ -1,4 +1,4 @@ -/* $NetBSD: make.c,v 1.272 2025/05/18 07:02:00 rillig Exp $ */ +/* $NetBSD: make.c,v 1.273 2025/07/06 07:11:31 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -107,7 +107,7 @@ #endif /* "@(#)make.c 8.1 (Berkeley) 6/6/93" */ -MAKE_RCSID("$NetBSD: make.c,v 1.272 2025/05/18 07:02:00 rillig Exp $"); +MAKE_RCSID("$NetBSD: make.c,v 1.273 2025/07/06 07:11:31 rillig Exp $"); /* Sequence # to detect recursion. */ static unsigned checked_seqno = 1; @@ -1404,7 +1404,7 @@ Make_MakeParallel(GNodeList *targets) (void)MakeStartJobs(); } - errors = Job_Finish(); + errors = Job_MakeDotEnd(); DEBUG1(MAKE, "done: errors %d\n", errors); if (errors == 0) { diff --git a/contrib/bmake/make.h b/contrib/bmake/make.h index 405f03144b69..6b2b215592dd 100644 --- a/contrib/bmake/make.h +++ b/contrib/bmake/make.h @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.360 2025/06/13 18:31:08 rillig Exp $ */ +/* $NetBSD: make.h,v 1.361 2025/07/06 07:11:31 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -884,7 +884,8 @@ void JobReapChild(pid_t, int, bool); #endif /* main.c */ void Main_ParseArgLine(const char *); -int Cmd_Argv(const char *, size_t, const char **, size_t, char *, size_t, bool, bool); +void Cmd_Argv(const char *, size_t, const char *[5], char *, size_t, + bool, bool); char *Cmd_Exec(const char *, char **) MAKE_ATTR_USE; void Var_ExportStackTrace(const char *, const char *); void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); diff --git a/contrib/bmake/make_malloc.c b/contrib/bmake/make_malloc.c index d7a735b8b08e..86e339de5dd2 100644 --- a/contrib/bmake/make_malloc.c +++ b/contrib/bmake/make_malloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: make_malloc.c,v 1.27 2025/06/12 18:51:05 rillig Exp $ */ +/* $NetBSD: make_malloc.c,v 1.28 2025/06/29 09:37:58 rillig Exp $ */ /* * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ #include "make.h" -MAKE_RCSID("$NetBSD: make_malloc.c,v 1.27 2025/06/12 18:51:05 rillig Exp $"); +MAKE_RCSID("$NetBSD: make_malloc.c,v 1.28 2025/06/29 09:37:58 rillig Exp $"); #ifndef USE_EMALLOC @@ -50,6 +50,9 @@ bmake_malloc(size_t len) if ((p = malloc(len)) == NULL) enomem(); +#ifdef CLEANUP + memset(p, 'Z', len); +#endif return p; } diff --git a/contrib/bmake/mk/ChangeLog b/contrib/bmake/mk/ChangeLog index 1822f917a138..db524d2343b6 100644 --- a/contrib/bmake/mk/ChangeLog +++ b/contrib/bmake/mk/ChangeLog @@ -1,3 +1,7 @@ +2025-07-04 Simon J Gerraty <sjg@beast.crufty.net> + + * prog.mk: .MADE is a special source not a target! + 2025-05-28 Simon J Gerraty <sjg@beast.crufty.net> * install-mk (MK_VERSION): 20250528 diff --git a/contrib/bmake/mk/prog.mk b/contrib/bmake/mk/prog.mk index 119645c49859..a7ced7b15d31 100644 --- a/contrib/bmake/mk/prog.mk +++ b/contrib/bmake/mk/prog.mk @@ -1,4 +1,4 @@ -# $Id: prog.mk,v 1.45 2024/12/12 19:56:36 sjg Exp $ +# $Id: prog.mk,v 1.46 2025/07/05 16:43:03 sjg Exp $ # should be set properly in sys.mk _this ?= ${.PARSEFILE:S,bsd.,,} @@ -27,11 +27,11 @@ CFLAGS+= -mcmodel=medlow .if ${OBJECT_FMT} == "ELF" .ifndef LIBCRTBEGIN LIBCRTBEGIN= ${DESTDIR}/usr/lib/crtbegin.o -.MADE: ${LIBCRTBEGIN} +${LIBCRTBEGIN}: .MADE .endif .ifndef LIBCRTEND LIBCRTEND= ${DESTDIR}/usr/lib/crtend.o -.MADE: ${LIBCRTEND} +${LIBCRTEND}: .MADE .endif _SHLINKER= ${SHLINKDIR}/ld.elf_so .else @@ -42,7 +42,7 @@ _SHLINKER= ${SHLINKDIR}/ld.so .ifndef LIBCRT0 LIBCRT0= ${DESTDIR}/usr/lib/crt0.o -.MADE: ${LIBCRT0} +${LIBCRT0}: .MADE .endif .endif # NetBSD diff --git a/contrib/bmake/parse.c b/contrib/bmake/parse.c index 844d4db207ca..ecc77366d2d7 100644 --- a/contrib/bmake/parse.c +++ b/contrib/bmake/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.752 2025/06/16 18:20:00 rillig Exp $ */ +/* $NetBSD: parse.c,v 1.753 2025/06/28 22:39:27 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -110,7 +110,7 @@ #include "pathnames.h" /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: parse.c,v 1.752 2025/06/16 18:20:00 rillig Exp $"); +MAKE_RCSID("$NetBSD: parse.c,v 1.753 2025/06/28 22:39:27 rillig Exp $"); /* Detects a multiple-inclusion guard in a makefile. */ typedef enum { @@ -954,10 +954,10 @@ InvalidLineType(const char *line, const char *unexpanded_line) Parse_Error(PARSE_FATAL, "Unknown directive \"%.*s\"", (int)(dirend - dirstart), dirstart); } else if (strcmp(line, unexpanded_line) == 0) - Parse_Error(PARSE_FATAL, "Invalid line '%s'", line); + Parse_Error(PARSE_FATAL, "Invalid line \"%s\"", line); else Parse_Error(PARSE_FATAL, - "Invalid line '%s', expanded to '%s'", + "Invalid line \"%s\", expanded to \"%s\"", unexpanded_line, line); } @@ -1063,7 +1063,7 @@ HandleDependencyTargetPath(const char *suffixName, path = Suff_GetPath(suffixName); if (path == NULL) { Parse_Error(PARSE_FATAL, - "Suffix '%s' not defined (yet)", suffixName); + "Suffix \"%s\" not defined (yet)", suffixName); return false; } @@ -1159,7 +1159,7 @@ SkipExtraTargets(char **pp, const char *lstart) if (warning) { const char *start = *pp; cpp_skip_whitespace(&start); - Parse_Error(PARSE_WARNING, "Extra target '%.*s' ignored", + Parse_Error(PARSE_WARNING, "Extra target \"%.*s\" ignored", (int)(p - start), start); } @@ -1446,7 +1446,8 @@ ApplyDependencyTarget(char *name, char *nameEnd, ParseSpecial *inout_special, if (*inout_special == SP_NOT && *name != '\0') HandleDependencyTargetMundane(name); else if (*inout_special == SP_PATH && *name != '.' && *name != '\0') - Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", name); + Parse_Error(PARSE_WARNING, "Extra target \"%s\" ignored", + name); *nameEnd = savedNameEnd; return true; @@ -2066,7 +2067,7 @@ ParseInclude(char *directive) if (*p != '"' && *p != '<') { Parse_Error(PARSE_FATAL, - ".include filename must be delimited by '\"' or '<'"); + ".include filename must be delimited by \"\" or <>"); return; } @@ -2078,7 +2079,7 @@ ParseInclude(char *directive) if (*p != endc) { Parse_Error(PARSE_FATAL, - "Unclosed .include filename. '%c' expected", endc); + "Unclosed .include filename, \"%c\" expected", endc); return; } diff --git a/contrib/bmake/str.c b/contrib/bmake/str.c index f705b0deb874..e66cdbc8682e 100644 --- a/contrib/bmake/str.c +++ b/contrib/bmake/str.c @@ -1,4 +1,4 @@ -/* $NetBSD: str.c,v 1.105 2024/07/07 07:50:57 rillig Exp $ */ +/* $NetBSD: str.c,v 1.106 2025/06/28 21:09:43 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -71,7 +71,7 @@ #include "make.h" /* "@(#)str.c 5.8 (Berkeley) 6/1/90" */ -MAKE_RCSID("$NetBSD: str.c,v 1.105 2024/07/07 07:50:57 rillig Exp $"); +MAKE_RCSID("$NetBSD: str.c,v 1.106 2025/06/28 21:09:43 rillig Exp $"); static HashTable interned_strings; @@ -363,8 +363,11 @@ match_fixed_length: continue; } - if (*pat == '\\') /* match the next character exactly */ + if (*pat == '\\') { /* match the next character exactly */ pat++; + if (*pat == '\0') + res.error = "Unfinished backslash at the end"; + } if (*pat != *str) { if (asterisk && str == fixed_str) { while (*str != '\0' && *str != *pat) diff --git a/contrib/bmake/unit-tests/Makefile b/contrib/bmake/unit-tests/Makefile index 618a5959e304..4e639056815a 100644 --- a/contrib/bmake/unit-tests/Makefile +++ b/contrib/bmake/unit-tests/Makefile @@ -1,6 +1,6 @@ -# $Id: Makefile,v 1.239 2025/06/15 21:32:16 sjg Exp $ +# $Id: Makefile,v 1.240 2025/06/30 18:40:54 sjg Exp $ # -# $NetBSD: Makefile,v 1.367 2025/06/13 20:23:16 rillig Exp $ +# $NetBSD: Makefile,v 1.369 2025/06/29 09:40:13 rillig Exp $ # # Unit tests for make(1) # @@ -58,6 +58,7 @@ rm-tmpdir: .NOMETA # src/tests/usr.bin/make/t_make.sh as well. #TESTS+= archive #TESTS+= archive-suffix +TESTS+= char-005c-reverse-solidus TESTS+= cmd-errors TESTS+= cmd-errors-jobs TESTS+= cmd-errors-lint @@ -413,6 +414,7 @@ TESTS+= varmod-to-upper TESTS+= varmod-undefined TESTS+= varmod-unique TESTS+= varname +TESTS+= varname-circumflex TESTS+= varname-dollar TESTS+= varname-dot-alltargets TESTS+= varname-dot-curdir @@ -541,7 +543,6 @@ TESTS:= ${TESTS:${BROKEN_TESTS:S,^,N,:ts:}} # Ideas for more tests: # char-0020-space.mk -# char-005C-backslash.mk # escape-cond-str.mk # escape-cond-func-arg.mk # escape-varmod.mk diff --git a/contrib/bmake/unit-tests/char-005c-reverse-solidus.exp b/contrib/bmake/unit-tests/char-005c-reverse-solidus.exp new file mode 100644 index 000000000000..351ef95040e5 --- /dev/null +++ b/contrib/bmake/unit-tests/char-005c-reverse-solidus.exp @@ -0,0 +1,13 @@ +make: char-005c-reverse-solidus.mk:57: Unclosed expression, expecting "}" for modifier "Mx\}" + while evaluating variable "BACKSLASH" with value "" +make: char-005c-reverse-solidus.mk:64: Unclosed expression, expecting "}" for modifier "Mx\\}" + while evaluating variable "BACKSLASH" with value "" +make: char-005c-reverse-solidus.mk:71: Unclosed expression, expecting "}" for modifier "Mx\\\\\\\\}" + while evaluating variable "BACKSLASH" with value "" +make: char-005c-reverse-solidus.mk:100: Unfinished backslash at the end in pattern "\" of modifier ":M" + while evaluating variable "BACKSLASH" with value "\" +make: char-005c-reverse-solidus.mk:111: Unclosed expression, expecting "}" for modifier "M${:U\\\\}} != "\\"" + while evaluating variable "BACKSLASH" with value "" +make: Fatal errors encountered -- cannot continue +make: stopped in unit-tests +exit status 1 diff --git a/contrib/bmake/unit-tests/char-005c-reverse-solidus.mk b/contrib/bmake/unit-tests/char-005c-reverse-solidus.mk new file mode 100644 index 000000000000..7a151ac46322 --- /dev/null +++ b/contrib/bmake/unit-tests/char-005c-reverse-solidus.mk @@ -0,0 +1,131 @@ +# $NetBSD: char-005c-reverse-solidus.mk,v 1.2 2025/06/29 11:27:21 rillig Exp $ +# +# Tests for the character U+005C "REVERSE SOLIDUS". +# +# See also: +# TODO +# TODO +# TODO + +# TODO: Where is this character used normally? +# TODO: What are the edge cases? + +# TODO: escape '#' in lines +# TODO: escape '#' in comments +# TODO: escape ':' in modifiers +# TODO: escape any character in condition strings + +# begin https://gnats.netbsd.org/46139 + +# Too see the details of parsing, uncomment the following line. +#.MAKEFLAGS: -dcpv + +# This backslash is treated as a line continuation. +# It does not end up in the variable value. +LINE_CONTINUATION=foo\ +# This line is still part of the variable assignment +.if ${LINE_CONTINUATION:C,[^a-z],<>,gW} != "foo" +. error +.endif + +# The variable value contains two backslashes. +TWO_BACKSLASHES_AT_EOL=foo\\ +.if ${TWO_BACKSLASHES_AT_EOL:C,[^a-z],<>,gW} != "foo<><>" +. error +.endif + +TRAILING_WHITESPACE=foo\ # trailing space +.if ${TRAILING_WHITESPACE:C,[^a-z],<>,gW} != "foo<><>" +. error +.endif + +# The simplest was to produce a single backslash is the :U modifier. +BACKSLASH= ${:U\\} +.if ${BACKSLASH} != "\\" +. error +.endif +BACKSLASH_C= ${:U1:C,.,\\,} +.if ${BACKSLASH_C} != "\\" +. error +.endif + +# expect+5: Unclosed expression, expecting "}" for modifier "Mx\}" +# At the point where the unclosed expression is detected, the ":M" modifier +# has been applied to the expression. Its pattern is "x}", which doesn't +# match the single backslash. +# expect: while evaluating variable "BACKSLASH" with value "" +.if ${BACKSLASH:Mx\} +. error +.else +. error +.endif + +# expect+1: Unclosed expression, expecting "}" for modifier "Mx\\}" +.if ${BACKSLASH:Mx\\} +. error +.else +. error +.endif + +# expect+1: Unclosed expression, expecting "}" for modifier "Mx\\\\\\\\}" +.if ${BACKSLASH:Mx\\\\\\\\} +. error +.else +. error +.endif + +# Adding more text after the backslash adds to the pattern, as the backslash +# serves to escape the ":" that is otherwise used to separate the modifiers. +# The result is a single ":M" modifier with the pattern "x:Nzzz". +.if ${BACKSLASH:Mx\:Nzzz} != "" +. error +.endif + +# The pattern ends up as "x\:Nzzz". Only the sequence "\:" is unescaped, all +# others, including "\\", are left as-is. +.if ${BACKSLASH:Mx\\:Nzzz} != "" +. error +.endif + +# The pattern for the ":M" modifier ends up as "x\\\\\\\:Nzzz". Only the +# sequence "\:" is unescaped, all others, including "\\", are left as-is. +.if ${BACKSLASH:Mx\\\\\\\\:Nzzz} != "" +. error +.endif + +# The ":M" modifier is parsed differently than the other modifiers. To +# circumvent the peculiarities of that parser, the pattern can be passed via +# an expression. There, the usual escaping rules for modifiers apply. +# expect+1: Unfinished backslash at the end in pattern "\" of modifier ":M" +.if ${BACKSLASH:M${BACKSLASH}} != "\\" +. error +.else +. error +.endif + +# Trying to bypass the parser by using a direct expression doesn't work, as +# the parser for the ":M" modifier does not parse the subexpression like in +# all other places, but instead counts the braces and tries to decode the +# escaping, which fails in this case. +# expect+1: Unclosed expression, expecting "}" for modifier "M${:U\\\\}} != "\\"" +.if ${BACKSLASH:M${:U\\\\}} != "\\" +. error +.else +. error +.endif + +# Matching a backslash with the pattern matching characters works. +.if ${BACKSLASH:M?} != "\\" +. error +.endif +.if ${BACKSLASH:M*} != "\\" +. error +.endif +.if ${BACKSLASH:M[Z-a]} != "\\" +. error +.endif +.if ${BACKSLASH:M[\\]} != "\\" +. error +.endif + +# end https://gnats.netbsd.org/46139 diff --git a/contrib/bmake/unit-tests/check-expect.lua b/contrib/bmake/unit-tests/check-expect.lua index 218056fbc021..2f3adf49baa6 100644 --- a/contrib/bmake/unit-tests/check-expect.lua +++ b/contrib/bmake/unit-tests/check-expect.lua @@ -1,5 +1,5 @@ #! /usr/bin/lua --- $NetBSD: check-expect.lua,v 1.13 2025/04/13 09:29:32 rillig Exp $ +-- $NetBSD: check-expect.lua,v 1.17 2025/07/01 05:03:18 rillig Exp $ --[[ @@ -9,29 +9,32 @@ Check that the various 'expect' comments in the .mk files produce the expected text in the corresponding .exp file. # expect: <line> - All of these lines must occur in the .exp file, in the same order as - in the .mk file. - -# expect-reset - Search the following 'expect:' comments from the top of the .exp - file again. + Each <line> must occur in the .exp file. + The order in the .mk file must be the same as in the .exp file. # expect[+-]offset: <message> - Each message must occur in the .exp file and refer back to the + Each <message> must occur in the .exp file and refer back to the source line in the .mk file. + Each such line in the .exp file must have a corresponding expect line + in the .mk file. + The order in the .mk file must be the same as in the .exp file. + +# expect-reset + Search the following "expect:" and "expect[+-]offset:" comments + from the top of the .exp file again. # expect-not: <substring> - The substring must not occur as part of any line of the .exp file. + The <substring> must not occur as part of any line in the .exp file. # expect-not-matches: <pattern> - The pattern (see https://lua.org/manual/5.4/manual.html#6.4.1) - must not occur as part of any line of the .exp file. + The <pattern> (see https://lua.org/manual/5.4/manual.html#6.4.1) + must not occur as part of any line in the .exp file. ]] local had_errors = false ---@param fmt string -function print_error(fmt, ...) +local function print_error(fmt, ...) print(fmt:format(...)) had_errors = true end @@ -42,7 +45,9 @@ local function load_lines(fname) local lines = {} local f = io.open(fname, "r") - if f == nil then return nil end + if f == nil then + return nil + end for line in f:lines() do table.insert(lines, line) @@ -53,135 +58,129 @@ local function load_lines(fname) end ----@param exp_lines string[] -local function collect_lineno_diagnostics(exp_lines) - ---@type table<string, string[]> - local by_location = {} +--- @shape ExpLine +--- @field filename string | nil +--- @field lineno number | nil +--- @field text string - for _, line in ipairs(exp_lines) do - ---@type string | nil, string, string - local l_fname, l_lineno, l_msg = - line:match('^make: ([^:]+):(%d+): (.*)') - if l_fname ~= nil then - local location = ("%s:%d"):format(l_fname, l_lineno) - if by_location[location] == nil then - by_location[location] = {} - end - table.insert(by_location[location], l_msg) + +--- @param lines string[] +--- @return ExpLine[] +local function parse_exp(lines) + local exp_lines = {} + for _, line in ipairs(lines) do + local l_filename, l_lineno, l_text = + line:match('^make: ([^:]+%.mk):(%d+):%s+(.*)') + if not l_filename then + l_text = line end + l_text = l_text:gsub("^%s+", ""):gsub("%s+$", "") + table.insert(exp_lines, { + filename = l_filename, + lineno = tonumber(l_lineno), + text = l_text, + }) end - - return by_location + return exp_lines end - -local function missing(by_location) - ---@type {filename: string, lineno: number, location: string, message: string}[] - local missing_expectations = {} - - for location, messages in pairs(by_location) do - for _, message in ipairs(messages) do - if message ~= "" and location:find(".mk:") then - local filename, lineno = location:match("^(%S+):(%d+)$") - table.insert(missing_expectations, { - filename = filename, - lineno = tonumber(lineno), - location = location, - message = message - }) - end +---@param exp_lines ExpLine[] +local function detect_missing_expect_lines(exp_fname, exp_lines, s, e) + for i = s, e do + local exp_line = exp_lines[i] + if exp_line.filename then + print_error("error: %s:%d requires in %s:%d: # expect+1: %s", + exp_fname, i, exp_line.filename, exp_line.lineno, exp_line.text) end end - table.sort(missing_expectations, function(a, b) - if a.filename ~= b.filename then - return a.filename < b.filename - end - return a.lineno < b.lineno - end) - return missing_expectations end - local function check_mk(mk_fname) local exp_fname = mk_fname:gsub("%.mk$", ".exp") local mk_lines = load_lines(mk_fname) - local exp_lines = load_lines(exp_fname) - if exp_lines == nil then return end - local by_location = collect_lineno_diagnostics(exp_lines) - local prev_expect_line = 0 + local exp_raw_lines = load_lines(exp_fname) + if exp_raw_lines == nil then + return + end + local exp_lines = parse_exp(exp_raw_lines) + + local exp_it = 1 for mk_lineno, mk_line in ipairs(mk_lines) do - for text in mk_line:gmatch("#%s*expect%-not:%s*(.*)") do - local i = 1 - while i <= #exp_lines and not exp_lines[i]:find(text, 1, true) do - i = i + 1 - end - if i <= #exp_lines then - print_error("error: %s:%d: %s must not contain '%s'", - mk_fname, mk_lineno, exp_fname, text) + local function match(pattern, action) + local _, n = mk_line:gsub(pattern, action) + if n > 0 then + match = function() end end end - for text in mk_line:gmatch("#%s*expect%-not%-matches:%s*(.*)") do - local i = 1 - while i <= #exp_lines and not exp_lines[i]:find(text) do - i = i + 1 + match("^#%s+expect%-not:%s*(.*)", function(text) + for exp_lineno, exp_line in ipairs(exp_lines) do + if exp_line.text:find(text, 1, true) then + print_error("error: %s:%d: %s:%d must not contain '%s'", + mk_fname, mk_lineno, exp_fname, exp_lineno, text) + end end - if i <= #exp_lines then - print_error("error: %s:%d: %s must not match '%s'", - mk_fname, mk_lineno, exp_fname, text) + end) + + match("^#%s+expect%-not%-matches:%s*(.*)", function(pattern) + for exp_lineno, exp_line in ipairs(exp_lines) do + if exp_line.text:find(pattern) then + print_error("error: %s:%d: %s:%d must not match '%s'", + mk_fname, mk_lineno, exp_fname, exp_lineno, pattern) + end end - end + end) - for text in mk_line:gmatch("#%s*expect:%s*(.*)") do - local i = prev_expect_line - -- As of 2022-04-15, some lines in the .exp files contain trailing - -- whitespace. If possible, this should be avoided by rewriting the - -- debug logging. When done, the trailing gsub can be removed. - -- See deptgt-phony.exp lines 14 and 15. - while i < #exp_lines and text ~= exp_lines[i + 1]:gsub("^%s*", ""):gsub("%s*$", "") do + match("^#%s+expect:%s*(.*)", function(text) + local i = exp_it + while i <= #exp_lines and text ~= exp_lines[i].text do i = i + 1 end - if i < #exp_lines then - prev_expect_line = i + 1 + if i <= #exp_lines then + detect_missing_expect_lines(exp_fname, exp_lines, exp_it, i - 1) + exp_lines[i].text = "" + exp_it = i + 1 else print_error("error: %s:%d: '%s:%d+' must contain '%s'", - mk_fname, mk_lineno, exp_fname, prev_expect_line + 1, text) + mk_fname, mk_lineno, exp_fname, exp_it, text) end - end - if mk_line:match("^#%s*expect%-reset$") then - prev_expect_line = 0 - end + end) - ---@param text string - for offset, text in mk_line:gmatch("#%s*expect([+%-]%d+):%s*(.*)") do - local location = ("%s:%d"):format(mk_fname, mk_lineno + tonumber(offset)) - - local found = false - if by_location[location] ~= nil then - for i, message in ipairs(by_location[location]) do - if message == text then - by_location[location][i] = "" - found = true - break - elseif message ~= "" then - print_error("error: %s:%d: out-of-order '%s'", - mk_fname, mk_lineno, message) - end - end + match("^#%s+expect%-reset$", function() + exp_it = 1 + end) + + match("^#%s+expect([+%-]%d+):%s*(.*)", function(offset, text) + local msg_lineno = mk_lineno + tonumber(offset) + + local i = exp_it + while i <= #exp_lines and text ~= exp_lines[i].text do + i = i + 1 end - if not found then - print_error("error: %s:%d: %s must contain '%s'", - mk_fname, mk_lineno, exp_fname, text) + if i <= #exp_lines and exp_lines[i].lineno == msg_lineno then + detect_missing_expect_lines(exp_fname, exp_lines, exp_it, i - 1) + exp_lines[i].text = "" + exp_it = i + 1 + elseif i <= #exp_lines then + print_error("error: %s:%d: expect%+d must be expect%+d", + mk_fname, mk_lineno, tonumber(offset), + exp_lines[i].lineno - mk_lineno) + else + print_error("error: %s:%d: %s:%d+ must contain '%s'", + mk_fname, mk_lineno, exp_fname, exp_it, text) end - end - end + end) + + match("^#%s+expect[+%-:]", function() + print_error("error: %s:%d: invalid \"expect\" line: %s", + mk_fname, mk_lineno, mk_line) + end) - for _, m in ipairs(missing(by_location)) do - print_error("missing: %s: # expect+1: %s", m.location, m.message) end + detect_missing_expect_lines(exp_fname, exp_lines, exp_it, #exp_lines) end for _, fname in ipairs(arg) do diff --git a/contrib/bmake/unit-tests/cmd-errors-jobs.exp b/contrib/bmake/unit-tests/cmd-errors-jobs.exp index bd3ae1e51332..3be1bb9b0773 100644 --- a/contrib/bmake/unit-tests/cmd-errors-jobs.exp +++ b/contrib/bmake/unit-tests/cmd-errors-jobs.exp @@ -11,7 +11,7 @@ make: Unclosed variable "UNCLOSED" in command ": unexpected $@-${UNCLOSED" in target "parse-error-unclosed-expression" in make[1] in directory "<curdir>" -make: Unclosed expression, expecting '}' +make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": unexpected $@-${UNCLOSED:" in target "parse-error-unclosed-modifier" @@ -28,7 +28,7 @@ make: Unclosed variable "UNCLOSED" in command ": unexpected $@-${UNCLOSED" in target "parse-error-unclosed-expression" in make[1] in directory "<curdir>" -make: Unclosed expression, expecting '}' +make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": unexpected $@-${UNCLOSED:" in target "parse-error-unclosed-modifier" diff --git a/contrib/bmake/unit-tests/cmd-errors-jobs.mk b/contrib/bmake/unit-tests/cmd-errors-jobs.mk index a29883fc6676..f6261d6ad1a8 100644 --- a/contrib/bmake/unit-tests/cmd-errors-jobs.mk +++ b/contrib/bmake/unit-tests/cmd-errors-jobs.mk @@ -1,4 +1,4 @@ -# $NetBSD: cmd-errors-jobs.mk,v 1.15 2025/03/29 19:08:52 rillig Exp $ +# $NetBSD: cmd-errors-jobs.mk,v 1.16 2025/06/28 22:39:28 rillig Exp $ # # Demonstrate how errors in expressions affect whether the commands # are actually executed in jobs mode. @@ -50,11 +50,11 @@ parse-error-unknown-modifier: # expect-not-matches: ^: unexpected # expect: make: Unclosed variable "UNCLOSED" # expect: in command ": unexpected $@-${UNCLOSED" -# expect: make: Unclosed expression, expecting '}' +# expect: make: Unclosed expression, expecting "}" # expect: make: Unknown modifier ":Z" # expect: end parse-error-direct with status 2 # expect: make: Unclosed variable "UNCLOSED" -# expect: make: Unclosed expression, expecting '}' +# expect: make: Unclosed expression, expecting "}" # expect: make: Unknown modifier ":Z" # expect: end parse-error-indirect with status 2 diff --git a/contrib/bmake/unit-tests/cmd-errors-lint.exp b/contrib/bmake/unit-tests/cmd-errors-lint.exp index ec7336f618b8..b08a65ff96dc 100644 --- a/contrib/bmake/unit-tests/cmd-errors-lint.exp +++ b/contrib/bmake/unit-tests/cmd-errors-lint.exp @@ -2,7 +2,7 @@ make: Unclosed variable "UNCLOSED" in command ": $@ ${UNCLOSED" in target "unclosed-expression" -make: Unclosed expression, expecting '}' +make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": $@ ${UNCLOSED:" in target "unclosed-modifier" diff --git a/contrib/bmake/unit-tests/cmd-errors-lint.mk b/contrib/bmake/unit-tests/cmd-errors-lint.mk index eb2ec1171545..455ef2c0cfe7 100644 --- a/contrib/bmake/unit-tests/cmd-errors-lint.mk +++ b/contrib/bmake/unit-tests/cmd-errors-lint.mk @@ -1,4 +1,4 @@ -# $NetBSD: cmd-errors-lint.mk,v 1.7 2025/03/29 19:08:52 rillig Exp $ +# $NetBSD: cmd-errors-lint.mk,v 1.8 2025/06/28 22:39:28 rillig Exp $ # # Demonstrate how errors in expressions affect whether the commands # are actually executed. @@ -19,7 +19,7 @@ unclosed-expression: : $@ ${UNCLOSED unclosed-modifier: -# expect: make: Unclosed expression, expecting '}' +# expect: make: Unclosed expression, expecting "}" # expect-not: : unclosed-modifier : $@ ${UNCLOSED: diff --git a/contrib/bmake/unit-tests/cmd-errors.exp b/contrib/bmake/unit-tests/cmd-errors.exp index 62da47ff42c5..2916d423029e 100644 --- a/contrib/bmake/unit-tests/cmd-errors.exp +++ b/contrib/bmake/unit-tests/cmd-errors.exp @@ -2,7 +2,7 @@ make: Unclosed variable "UNCLOSED" in command ": $@-${UNCLOSED" in target "unclosed-expression" -make: Unclosed expression, expecting '}' +make: Unclosed expression, expecting "}" while evaluating variable "UNCLOSED" with value "" in command ": $@-${UNCLOSED:" in target "unclosed-modifier" diff --git a/contrib/bmake/unit-tests/cmd-errors.mk b/contrib/bmake/unit-tests/cmd-errors.mk index 8766b6a856c7..52e314c5bd38 100644 --- a/contrib/bmake/unit-tests/cmd-errors.mk +++ b/contrib/bmake/unit-tests/cmd-errors.mk @@ -1,4 +1,4 @@ -# $NetBSD: cmd-errors.mk,v 1.12 2025/03/29 19:08:52 rillig Exp $ +# $NetBSD: cmd-errors.mk,v 1.13 2025/06/28 22:39:28 rillig Exp $ # # Demonstrate how errors in expressions affect whether the commands # are actually executed in compat mode. @@ -17,7 +17,7 @@ unclosed-expression: : $@-${UNCLOSED unclosed-modifier: -# expect: make: Unclosed expression, expecting '}' +# expect: make: Unclosed expression, expecting "}" # expect-not: : unclosed-modifier- : $@-${UNCLOSED: diff --git a/contrib/bmake/unit-tests/cmdline-undefined.exp b/contrib/bmake/unit-tests/cmdline-undefined.exp index 12fc45e50822..ae0b35dac420 100644 --- a/contrib/bmake/unit-tests/cmdline-undefined.exp +++ b/contrib/bmake/unit-tests/cmdline-undefined.exp @@ -1,17 +1,17 @@ The = assignment operator -make: cmdline-undefined.mk:31: From the command line: Undefined is . -make: cmdline-undefined.mk:34: From .MAKEFLAGS '=': Undefined is . -make: cmdline-undefined.mk:37: From .MAKEFLAGS ':=': Undefined is . -make: cmdline-undefined.mk:43: From the command line: Undefined is now defined. -make: cmdline-undefined.mk:46: From .MAKEFLAGS '=': Undefined is now defined. +make: cmdline-undefined.mk:41: From the command line: Undefined is . +make: cmdline-undefined.mk:42: From .MAKEFLAGS '=': Undefined is . +make: cmdline-undefined.mk:43: From .MAKEFLAGS ':=': Undefined is . +make: cmdline-undefined.mk:47: From the command line: Undefined is now defined. +make: cmdline-undefined.mk:48: From .MAKEFLAGS '=': Undefined is now defined. make: cmdline-undefined.mk:49: From .MAKEFLAGS ':=': Undefined is now defined. The := assignment operator -make: cmdline-undefined.mk:31: From the command line: Undefined is . -make: cmdline-undefined.mk:34: From .MAKEFLAGS '=': Undefined is . -make: cmdline-undefined.mk:37: From .MAKEFLAGS ':=': Undefined is . -make: cmdline-undefined.mk:43: From the command line: Undefined is now defined. -make: cmdline-undefined.mk:46: From .MAKEFLAGS '=': Undefined is now defined. +make: cmdline-undefined.mk:41: From the command line: Undefined is . +make: cmdline-undefined.mk:42: From .MAKEFLAGS '=': Undefined is . +make: cmdline-undefined.mk:43: From .MAKEFLAGS ':=': Undefined is . +make: cmdline-undefined.mk:47: From the command line: Undefined is now defined. +make: cmdline-undefined.mk:48: From .MAKEFLAGS '=': Undefined is now defined. make: cmdline-undefined.mk:49: From .MAKEFLAGS ':=': Undefined is now defined. exit status 0 diff --git a/contrib/bmake/unit-tests/cmdline-undefined.mk b/contrib/bmake/unit-tests/cmdline-undefined.mk index e7c0400ad1e1..2deb944b1fab 100644 --- a/contrib/bmake/unit-tests/cmdline-undefined.mk +++ b/contrib/bmake/unit-tests/cmdline-undefined.mk @@ -1,4 +1,4 @@ -# $NetBSD: cmdline-undefined.mk,v 1.5 2024/04/23 22:51:28 rillig Exp $ +# $NetBSD: cmdline-undefined.mk,v 1.6 2025/06/30 21:44:39 rillig Exp $ # # Tests for undefined variables in expressions in the command line. @@ -8,6 +8,12 @@ all: # (which probably occurs rarely in practice, if at all), but their # variable value is not expanded, as usual. # +# expect+30: From the command line: Undefined is . +# expect+30: From .MAKEFLAGS '=': Undefined is . +# expect+30: From .MAKEFLAGS ':=': Undefined is . +# expect+33: From the command line: Undefined is now defined. +# expect+33: From .MAKEFLAGS '=': Undefined is now defined. +# expect+33: From .MAKEFLAGS ':=': Undefined is now defined. @echo 'The = assignment operator' @${.MAKE} -f ${MAKEFILE} print-undefined \ CMDLINE='Undefined is $${UNDEFINED}.' @@ -16,6 +22,12 @@ all: # The interesting case is using the ':=' assignment operator, which # expands its right-hand side. But only those variables that are # defined. +# expect+16: From the command line: Undefined is . +# expect+16: From .MAKEFLAGS '=': Undefined is . +# expect+16: From .MAKEFLAGS ':=': Undefined is . +# expect+19: From the command line: Undefined is now defined. +# expect+19: From .MAKEFLAGS '=': Undefined is now defined. +# expect+19: From .MAKEFLAGS ':=': Undefined is now defined. @echo 'The := assignment operator' @${.MAKE} -f ${MAKEFILE} print-undefined \ CMDLINE:='Undefined is $${UNDEFINED}.' @@ -26,26 +38,14 @@ all: .MAKEFLAGS: MAKEFLAGS_ASSIGN='Undefined is $${UNDEFINED}.' .MAKEFLAGS: MAKEFLAGS_SUBST:='Undefined is $${UNDEFINED}.' -# expect+2: From the command line: Undefined is . -# expect+1: From the command line: Undefined is . .info From the command line: ${CMDLINE} -# expect+2: From .MAKEFLAGS '=': Undefined is . -# expect+1: From .MAKEFLAGS '=': Undefined is . .info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN} -# expect+2: From .MAKEFLAGS ':=': Undefined is . -# expect+1: From .MAKEFLAGS ':=': Undefined is . .info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST} UNDEFINED?= now defined -# expect+2: From the command line: Undefined is now defined. -# expect+1: From the command line: Undefined is now defined. .info From the command line: ${CMDLINE} -# expect+2: From .MAKEFLAGS '=': Undefined is now defined. -# expect+1: From .MAKEFLAGS '=': Undefined is now defined. .info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN} -# expect+2: From .MAKEFLAGS ':=': Undefined is now defined. -# expect+1: From .MAKEFLAGS ':=': Undefined is now defined. .info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST} print-undefined: diff --git a/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp index 1a386d53dbef..81c73d887c18 100644 --- a/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp +++ b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp @@ -1,5 +1,5 @@ -make: cond-cmp-numeric-eq.mk:68: Malformed conditional '!(12345 = 12345)' -make: cond-cmp-numeric-eq.mk:76: Malformed conditional '!(12345 === 12345)' +make: cond-cmp-numeric-eq.mk:68: Malformed conditional "!(12345 = 12345)" +make: cond-cmp-numeric-eq.mk:76: Malformed conditional "!(12345 === 12345)" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk index a8630cb37f1f..ea60f6f7b18d 100755 --- a/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk +++ b/contrib/bmake/unit-tests/cond-cmp-numeric-eq.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-cmp-numeric-eq.mk,v 1.8 2024/08/06 18:00:16 rillig Exp $ +# $NetBSD: cond-cmp-numeric-eq.mk,v 1.9 2025/06/28 22:39:28 rillig Exp $ # # Tests for numeric comparisons with the == operator in .if conditions. @@ -64,7 +64,7 @@ .endif # There is no = operator for numbers. -# expect+1: Malformed conditional '!(12345 = 12345)' +# expect+1: Malformed conditional "!(12345 = 12345)" .if !(12345 = 12345) . error .else @@ -72,7 +72,7 @@ .endif # There is no === operator for numbers either. -# expect+1: Malformed conditional '!(12345 === 12345)' +# expect+1: Malformed conditional "!(12345 === 12345)" .if !(12345 === 12345) . error .else diff --git a/contrib/bmake/unit-tests/cond-cmp-numeric.exp b/contrib/bmake/unit-tests/cond-cmp-numeric.exp index 0945bef72300..2959ad99716c 100644 --- a/contrib/bmake/unit-tests/cond-cmp-numeric.exp +++ b/contrib/bmake/unit-tests/cond-cmp-numeric.exp @@ -1,15 +1,15 @@ CondParser_Eval: !(${:UINF} > 1e100) -make: cond-cmp-numeric.mk:15: Comparison with '>' requires both operands 'INF' and '1e100' to be numeric +make: cond-cmp-numeric.mk:15: Comparison with ">" requires both operands "INF" and "1e100" to be numeric CondParser_Eval: ${:UNaN} > NaN -make: cond-cmp-numeric.mk:21: Comparison with '>' requires both operands 'NaN' and 'NaN' to be numeric +make: cond-cmp-numeric.mk:21: Comparison with ">" requires both operands "NaN" and "NaN" to be numeric CondParser_Eval: !(${:UNaN} == NaN) Comparing "NaN" == "NaN" CondParser_Eval: 123 ! 123 -make: cond-cmp-numeric.mk:38: Malformed conditional '123 ! 123' +make: cond-cmp-numeric.mk:38: Malformed conditional "123 ! 123" CondParser_Eval: ${:U 123} < 124 Comparing 123.000000 < 124.000000 CondParser_Eval: ${:U123 } < 124 -make: cond-cmp-numeric.mk:54: Comparison with '<' requires both operands '123 ' and '124' to be numeric +make: cond-cmp-numeric.mk:54: Comparison with "<" requires both operands "123 " and "124" to be numeric make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-cmp-numeric.mk b/contrib/bmake/unit-tests/cond-cmp-numeric.mk index 63a3bff8d560..abe5cc4cce9c 100644 --- a/contrib/bmake/unit-tests/cond-cmp-numeric.mk +++ b/contrib/bmake/unit-tests/cond-cmp-numeric.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-cmp-numeric.mk,v 1.8 2024/08/06 18:00:16 rillig Exp $ +# $NetBSD: cond-cmp-numeric.mk,v 1.9 2025/06/28 22:39:28 rillig Exp $ # # Tests for numeric comparisons in .if conditions. # @@ -11,13 +11,13 @@ # Even if strtod(3) parses "INF" as +Infinity, make does not accept this # since it is not really a number; see TryParseNumber. -# expect+1: Comparison with '>' requires both operands 'INF' and '1e100' to be numeric +# expect+1: Comparison with ">" requires both operands "INF" and "1e100" to be numeric .if !(${:UINF} > 1e100) . error .endif # Neither is NaN a number; see TryParseNumber. -# expect+1: Comparison with '>' requires both operands 'NaN' and 'NaN' to be numeric +# expect+1: Comparison with ">" requires both operands "NaN" and "NaN" to be numeric .if ${:UNaN} > NaN . error .endif @@ -34,7 +34,7 @@ # whether the operator is valid, leaving the rest of the work to the # evaluation functions EvalCompareNum and EvalCompareStr. Ensure that this # parse error is properly reported. -# expect+1: Malformed conditional '123 ! 123' +# expect+1: Malformed conditional "123 ! 123" .if 123 ! 123 . error .else @@ -50,7 +50,7 @@ # Trailing spaces are NOT allowed for numbers. # See EvalCompare and TryParseNumber. -# expect+1: Comparison with '<' requires both operands '123 ' and '124' to be numeric +# expect+1: Comparison with "<" requires both operands "123 " and "124" to be numeric .if ${:U123 } < 124 . error .else diff --git a/contrib/bmake/unit-tests/cond-cmp-string.exp b/contrib/bmake/unit-tests/cond-cmp-string.exp index b55f30182442..8291d5300c3b 100644 --- a/contrib/bmake/unit-tests/cond-cmp-string.exp +++ b/contrib/bmake/unit-tests/cond-cmp-string.exp @@ -1,11 +1,11 @@ -make: cond-cmp-string.mk:19: Malformed conditional 'str != str' -make: cond-cmp-string.mk:44: Malformed conditional '"string" != "str""ing"' -make: cond-cmp-string.mk:52: Malformed conditional '!("value" = "value")' -make: cond-cmp-string.mk:60: Malformed conditional '!("value" === "value")' -make: cond-cmp-string.mk:118: Comparison with '<' requires both operands 'string' and 'string' to be numeric -make: cond-cmp-string.mk:126: Comparison with '<=' requires both operands 'string' and 'string' to be numeric -make: cond-cmp-string.mk:134: Comparison with '>' requires both operands 'string' and 'string' to be numeric -make: cond-cmp-string.mk:142: Comparison with '>=' requires both operands 'string' and 'string' to be numeric +make: cond-cmp-string.mk:19: Malformed conditional "str != str" +make: cond-cmp-string.mk:44: Malformed conditional ""string" != "str""ing"" +make: cond-cmp-string.mk:52: Malformed conditional "!("value" = "value")" +make: cond-cmp-string.mk:60: Malformed conditional "!("value" === "value")" +make: cond-cmp-string.mk:118: Comparison with "<" requires both operands "string" and "string" to be numeric +make: cond-cmp-string.mk:126: Comparison with "<=" requires both operands "string" and "string" to be numeric +make: cond-cmp-string.mk:134: Comparison with ">" requires both operands "string" and "string" to be numeric +make: cond-cmp-string.mk:142: Comparison with ">=" requires both operands "string" and "string" to be numeric make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-cmp-string.mk b/contrib/bmake/unit-tests/cond-cmp-string.mk index a913750a017f..56427bda11d0 100644 --- a/contrib/bmake/unit-tests/cond-cmp-string.mk +++ b/contrib/bmake/unit-tests/cond-cmp-string.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-cmp-string.mk,v 1.20 2024/08/06 18:00:16 rillig Exp $ +# $NetBSD: cond-cmp-string.mk,v 1.21 2025/06/28 22:39:28 rillig Exp $ # # Tests for string comparisons in .if conditions. @@ -15,7 +15,7 @@ # The left-hand side of the comparison must be enclosed in quotes. # This one is not enclosed in quotes and thus generates an error message. -# expect+1: Malformed conditional 'str != str' +# expect+1: Malformed conditional "str != str" .if str != str . error .endif @@ -40,7 +40,7 @@ # It is not possible to concatenate two string literals to form a single # string. In C, Python and the shell this is possible, but not in make. -# expect+1: Malformed conditional '"string" != "str""ing"' +# expect+1: Malformed conditional ""string" != "str""ing"" .if "string" != "str""ing" . error .else @@ -48,7 +48,7 @@ .endif # There is no = operator for strings. -# expect+1: Malformed conditional '!("value" = "value")' +# expect+1: Malformed conditional "!("value" = "value")" .if !("value" = "value") . error .else @@ -56,7 +56,7 @@ .endif # There is no === operator for strings either. -# expect+1: Malformed conditional '!("value" === "value")' +# expect+1: Malformed conditional "!("value" === "value")" .if !("value" === "value") . error .else @@ -114,7 +114,7 @@ .endif # Strings cannot be compared relationally, only for equality. -# expect+1: Comparison with '<' requires both operands 'string' and 'string' to be numeric +# expect+1: Comparison with "<" requires both operands "string" and "string" to be numeric .if "string" < "string" . error .else @@ -122,7 +122,7 @@ .endif # Strings cannot be compared relationally, only for equality. -# expect+1: Comparison with '<=' requires both operands 'string' and 'string' to be numeric +# expect+1: Comparison with "<=" requires both operands "string" and "string" to be numeric .if "string" <= "string" . error .else @@ -130,7 +130,7 @@ .endif # Strings cannot be compared relationally, only for equality. -# expect+1: Comparison with '>' requires both operands 'string' and 'string' to be numeric +# expect+1: Comparison with ">" requires both operands "string" and "string" to be numeric .if "string" > "string" . error .else @@ -138,7 +138,7 @@ .endif # Strings cannot be compared relationally, only for equality. -# expect+1: Comparison with '>=' requires both operands 'string' and 'string' to be numeric +# expect+1: Comparison with ">=" requires both operands "string" and "string" to be numeric .if "string" >= "string" . error .else diff --git a/contrib/bmake/unit-tests/cond-eof.exp b/contrib/bmake/unit-tests/cond-eof.exp index 44e481745a24..fb23e248178e 100644 --- a/contrib/bmake/unit-tests/cond-eof.exp +++ b/contrib/bmake/unit-tests/cond-eof.exp @@ -1,6 +1,6 @@ -make: cond-eof.mk:17: Malformed conditional '0 ${SIDE_EFFECT} ${SIDE_EFFECT2}' -make: cond-eof.mk:20: Malformed conditional '1 ${SIDE_EFFECT} ${SIDE_EFFECT2}' -make: cond-eof.mk:23: Malformed conditional '(0) ${SIDE_EFFECT} ${SIDE_EFFECT2}' +make: cond-eof.mk:17: Malformed conditional "0 ${SIDE_EFFECT} ${SIDE_EFFECT2}" +make: cond-eof.mk:20: Malformed conditional "1 ${SIDE_EFFECT} ${SIDE_EFFECT2}" +make: cond-eof.mk:23: Malformed conditional "(0) ${SIDE_EFFECT} ${SIDE_EFFECT2}" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-eof.mk b/contrib/bmake/unit-tests/cond-eof.mk index 706a7deebd1a..04d79d0783ad 100644 --- a/contrib/bmake/unit-tests/cond-eof.mk +++ b/contrib/bmake/unit-tests/cond-eof.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-eof.mk,v 1.7 2024/08/06 18:00:16 rillig Exp $ +# $NetBSD: cond-eof.mk,v 1.8 2025/06/28 22:39:28 rillig Exp $ # # Tests for parsing the end of '.if' conditions, which are represented as the # token TOK_EOF. @@ -13,12 +13,12 @@ SIDE_EFFECT2= ${:!echo 'side effect 2' 1>&2!} # These syntax errors are an edge case that does not occur during normal # operation. Still, it is easy to avoid evaluating these expressions, just in # case they have side effects. -# expect+1: Malformed conditional '0 ${SIDE_EFFECT} ${SIDE_EFFECT2}' +# expect+1: Malformed conditional "0 ${SIDE_EFFECT} ${SIDE_EFFECT2}" .if 0 ${SIDE_EFFECT} ${SIDE_EFFECT2} .endif -# expect+1: Malformed conditional '1 ${SIDE_EFFECT} ${SIDE_EFFECT2}' +# expect+1: Malformed conditional "1 ${SIDE_EFFECT} ${SIDE_EFFECT2}" .if 1 ${SIDE_EFFECT} ${SIDE_EFFECT2} .endif -# expect+1: Malformed conditional '(0) ${SIDE_EFFECT} ${SIDE_EFFECT2}' +# expect+1: Malformed conditional "(0) ${SIDE_EFFECT} ${SIDE_EFFECT2}" .if (0) ${SIDE_EFFECT} ${SIDE_EFFECT2} .endif diff --git a/contrib/bmake/unit-tests/cond-func-defined.exp b/contrib/bmake/unit-tests/cond-func-defined.exp index ea3ced9398e8..04b57061f803 100644 --- a/contrib/bmake/unit-tests/cond-func-defined.exp +++ b/contrib/bmake/unit-tests/cond-func-defined.exp @@ -1,5 +1,5 @@ -make: cond-func-defined.mk:24: Missing ')' after argument 'A' for 'defined' -make: cond-func-defined.mk:34: Missing ')' after argument 'DEF' for 'defined' +make: cond-func-defined.mk:24: Missing ")" after argument "A" for "defined" +make: cond-func-defined.mk:34: Missing ")" after argument "DEF" for "defined" make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-func-defined.mk b/contrib/bmake/unit-tests/cond-func-defined.mk index 66f95f3380c1..52eeaec8ccfc 100644 --- a/contrib/bmake/unit-tests/cond-func-defined.mk +++ b/contrib/bmake/unit-tests/cond-func-defined.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-func-defined.mk,v 1.14 2025/01/10 23:00:38 rillig Exp $ +# $NetBSD: cond-func-defined.mk,v 1.15 2025/06/28 22:39:28 rillig Exp $ # # Tests for the defined() function in .if conditions. @@ -20,7 +20,7 @@ ${:UA B}= variable name with spaces .endif # The argument of a function must not directly contain whitespace. -# expect+1: Missing ')' after argument 'A' for 'defined' +# expect+1: Missing ")" after argument "A" for "defined" .if !defined(A B) . error .endif @@ -30,7 +30,7 @@ ${:UA B}= variable name with spaces . error .endif -# expect+1: Missing ')' after argument 'DEF' for 'defined' +# expect+1: Missing ")" after argument "DEF" for "defined" .if defined(DEF . error .else diff --git a/contrib/bmake/unit-tests/cond-func-make.exp b/contrib/bmake/unit-tests/cond-func-make.exp index 4d493b3c3ccb..ab25dfc5b553 100644 --- a/contrib/bmake/unit-tests/cond-func-make.exp +++ b/contrib/bmake/unit-tests/cond-func-make.exp @@ -1,4 +1,4 @@ -make: cond-func-make.mk:24: warning: Unfinished character list in pattern argument '[' to function 'make' +make: cond-func-make.mk:24: warning: Unfinished character list in pattern argument "[" to function "make" : via-cmdline : via-dot-makeflags exit status 0 diff --git a/contrib/bmake/unit-tests/cond-func-make.mk b/contrib/bmake/unit-tests/cond-func-make.mk index 1a14fd320a3c..8903f9c0e723 100644 --- a/contrib/bmake/unit-tests/cond-func-make.mk +++ b/contrib/bmake/unit-tests/cond-func-make.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-func-make.mk,v 1.6 2025/01/10 23:00:38 rillig Exp $ +# $NetBSD: cond-func-make.mk,v 1.7 2025/06/28 22:39:28 rillig Exp $ # # Tests for the make() function in .if conditions, which tests whether # the argument has been passed as a target via the command line or later @@ -20,7 +20,7 @@ . error .endif -# expect+1: warning: Unfinished character list in pattern argument '[' to function 'make' +# expect+1: warning: Unfinished character list in pattern argument "[" to function "make" .if make([) . error .endif diff --git a/contrib/bmake/unit-tests/cond-func.exp b/contrib/bmake/unit-tests/cond-func.exp index c80f95f39c0b..77f65e77d46c 100644 --- a/contrib/bmake/unit-tests/cond-func.exp +++ b/contrib/bmake/unit-tests/cond-func.exp @@ -1,13 +1,13 @@ -make: cond-func.mk:37: Missing ')' after argument 'A' for 'defined' -make: cond-func.mk:53: Missing ')' after argument 'A' for 'defined' -make: cond-func.mk:57: Missing ')' after argument 'A' for 'defined' -make: cond-func.mk:91: Unknown operator '&' +make: cond-func.mk:37: Missing ")" after argument "A" for "defined" +make: cond-func.mk:53: Missing ")" after argument "A" for "defined" +make: cond-func.mk:57: Missing ")" after argument "A" for "defined" +make: cond-func.mk:91: Unknown operator "&" make: cond-func.mk:107: A plain function name is parsed as defined(...). make: cond-func.mk:115: A plain function name is parsed as defined(...). make: cond-func.mk:126: Symbols may start with a function name. make: cond-func.mk:132: Symbols may start with a function name. -make: cond-func.mk:138: Missing ')' after argument '' for 'defined' -make: cond-func.mk:145: Missing ')' after argument '${:UVARNAME}.param' for 'defined' +make: cond-func.mk:138: Missing ")" after argument "" for "defined" +make: cond-func.mk:145: Missing ")" after argument "${:UVARNAME}.param" for "defined" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-func.mk b/contrib/bmake/unit-tests/cond-func.mk index 3e4f8a9f151f..50b3f83cd4cb 100644 --- a/contrib/bmake/unit-tests/cond-func.mk +++ b/contrib/bmake/unit-tests/cond-func.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-func.mk,v 1.18 2024/08/07 05:48:45 rillig Exp $ +# $NetBSD: cond-func.mk,v 1.19 2025/06/28 22:39:28 rillig Exp $ # # Tests for those parts of the functions in .if conditions that are common # among several functions. @@ -33,7 +33,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces .endif # The argument of a function must not directly contain whitespace. -# expect+1: Missing ')' after argument 'A' for 'defined' +# expect+1: Missing ")" after argument "A" for "defined" .if !defined(A B) . error .endif @@ -49,11 +49,11 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces # # It's not entirely clear why these characters are forbidden. # The most plausible reason seems to be typo detection. -# expect+1: Missing ')' after argument 'A' for 'defined' +# expect+1: Missing ")" after argument "A" for "defined" .if !defined(A&B) . error .endif -# expect+1: Missing ')' after argument 'A' for 'defined' +# expect+1: Missing ")" after argument "A" for "defined" .if !defined(A|B) . error .endif @@ -87,7 +87,7 @@ ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces # interpreted as defined(A) && defined(B). Each kind of .if directive has a # default function that is called when a bare word is parsed. For the plain # .if directive, this function is 'defined'; see "struct If ifs" in cond.c. -# expect+1: Unknown operator '&' +# expect+1: Unknown operator "&" .if A&B . error .endif @@ -134,14 +134,14 @@ defined-var= # defined but empty . error .endif -# expect+1: Missing ')' after argument '' for 'defined' +# expect+1: Missing ")" after argument "" for "defined" .if defined( . error .else . error .endif -# expect+1: Missing ')' after argument '${:UVARNAME}.param' for 'defined' +# expect+1: Missing ")" after argument "${:UVARNAME}.param" for "defined" .if defined(${:UVARNAME}.param extra) . error .else diff --git a/contrib/bmake/unit-tests/cond-late.exp b/contrib/bmake/unit-tests/cond-late.exp index 13846e8c822a..e4b3fdac85f4 100644 --- a/contrib/bmake/unit-tests/cond-late.exp +++ b/contrib/bmake/unit-tests/cond-late.exp @@ -1,4 +1,4 @@ -make: cond-late.mk:38: Bad condition +make: cond-late.mk:29: Bad condition while evaluating condition " != "no"" while evaluating variable "VAR" with value "${${UNDEF} != "no":?:}" in make[1] in directory "<curdir>" diff --git a/contrib/bmake/unit-tests/cond-late.mk b/contrib/bmake/unit-tests/cond-late.mk index a8f381590a6e..154617f4f2b2 100644 --- a/contrib/bmake/unit-tests/cond-late.mk +++ b/contrib/bmake/unit-tests/cond-late.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-late.mk,v 1.9 2024/08/29 20:20:35 rillig Exp $ +# $NetBSD: cond-late.mk,v 1.10 2025/06/30 21:44:39 rillig Exp $ # # Using the :? modifier, expressions can contain conditional # expressions that are evaluated late, at expansion time. @@ -23,6 +23,13 @@ parse-time: .PHONY COND.true= "yes" == "yes" COND.false= "yes" != "yes" +.if make(do-parse-time) +VAR= ${${UNDEF} != "no":?:} +# expect+1: Bad condition +. if empty(VAR:Mpattern) +. endif +.endif + # If the order of evaluation were to change to first parse the condition # and then expand the variables, the output would change from the # current "yes no" to "yes yes", since both variables are non-empty. @@ -31,10 +38,3 @@ COND.false= "yes" != "yes" cond-literal: @echo ${ ${COND.true} :?yes:no} @echo ${ ${COND.false} :?yes:no} - -.if make(do-parse-time) -VAR= ${${UNDEF} != "no":?:} -# expect+1: Bad condition -. if empty(VAR:Mpattern) -. endif -.endif diff --git a/contrib/bmake/unit-tests/cond-op-and-lint.exp b/contrib/bmake/unit-tests/cond-op-and-lint.exp index 8896fea5c9b6..74ac32e205e6 100644 --- a/contrib/bmake/unit-tests/cond-op-and-lint.exp +++ b/contrib/bmake/unit-tests/cond-op-and-lint.exp @@ -1,4 +1,4 @@ -make: cond-op-and-lint.mk:10: Unknown operator '&' +make: cond-op-and-lint.mk:10: Unknown operator "&" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-op-and-lint.mk b/contrib/bmake/unit-tests/cond-op-and-lint.mk index bac4566314b0..0daa3a728f86 100644 --- a/contrib/bmake/unit-tests/cond-op-and-lint.mk +++ b/contrib/bmake/unit-tests/cond-op-and-lint.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-and-lint.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: cond-op-and-lint.mk,v 1.3 2025/06/28 22:39:28 rillig Exp $ # # Tests for the && operator in .if conditions, in lint mode. @@ -6,7 +6,7 @@ # The '&' operator is not allowed in lint mode. # It is not used in practice anyway. -# expect+1: Unknown operator '&' +# expect+1: Unknown operator "&" .if 0 & 0 . error .else diff --git a/contrib/bmake/unit-tests/cond-op-and.exp b/contrib/bmake/unit-tests/cond-op-and.exp index 1ada96a00bdd..b3e45ea1767e 100644 --- a/contrib/bmake/unit-tests/cond-op-and.exp +++ b/contrib/bmake/unit-tests/cond-op-and.exp @@ -1,11 +1,11 @@ make: cond-op-and.mk:36: Variable "UNDEF" is undefined make: cond-op-and.mk:41: Variable "UNDEF" is undefined make: cond-op-and.mk:44: Variable "UNDEF" is undefined -make: cond-op-and.mk:60: Unknown operator '&' -make: cond-op-and.mk:66: Unknown operator '&' -make: cond-op-and.mk:72: Unknown operator '&' -make: cond-op-and.mk:78: Unknown operator '&' -make: cond-op-and.mk:87: Unknown operator '&' +make: cond-op-and.mk:60: Unknown operator "&" +make: cond-op-and.mk:66: Unknown operator "&" +make: cond-op-and.mk:72: Unknown operator "&" +make: cond-op-and.mk:78: Unknown operator "&" +make: cond-op-and.mk:87: Unknown operator "&" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-op-and.mk b/contrib/bmake/unit-tests/cond-op-and.mk index 5d7f8a06800a..cb84e39e9217 100644 --- a/contrib/bmake/unit-tests/cond-op-and.mk +++ b/contrib/bmake/unit-tests/cond-op-and.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-and.mk,v 1.12 2025/01/11 21:21:33 rillig Exp $ +# $NetBSD: cond-op-and.mk,v 1.13 2025/06/28 22:39:28 rillig Exp $ # # Tests for the && operator in .if conditions. @@ -56,25 +56,25 @@ DEF= defined # The && operator may be abbreviated as &. This is not widely known though # and is also not documented in the manual page. -# expect+1: Unknown operator '&' +# expect+1: Unknown operator "&" .if 0 & 0 . error .else . error .endif -# expect+1: Unknown operator '&' +# expect+1: Unknown operator "&" .if 1 & 0 . error .else . error .endif -# expect+1: Unknown operator '&' +# expect+1: Unknown operator "&" .if 0 & 1 . error .else . error .endif -# expect+1: Unknown operator '&' +# expect+1: Unknown operator "&" .if !(1 & 1) . error .else @@ -83,7 +83,7 @@ DEF= defined # There is no operator '&&&'. The first two '&&' form an operator, the third # '&' forms the next (incomplete) token. -# expect+1: Unknown operator '&' +# expect+1: Unknown operator "&" .if 0 &&& 0 . error .else diff --git a/contrib/bmake/unit-tests/cond-op-not.exp b/contrib/bmake/unit-tests/cond-op-not.exp index 63aa928eabc3..f0dfb3b757b1 100644 --- a/contrib/bmake/unit-tests/cond-op-not.exp +++ b/contrib/bmake/unit-tests/cond-op-not.exp @@ -3,7 +3,7 @@ make: cond-op-not.mk:39: Not space evaluates to false. make: cond-op-not.mk:44: Not 0 evaluates to true. make: cond-op-not.mk:53: Not 1 evaluates to false. make: cond-op-not.mk:60: Not word evaluates to false. -make: cond-op-not.mk:65: Malformed conditional '!' +make: cond-op-not.mk:65: Malformed conditional "!" make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-op-not.mk b/contrib/bmake/unit-tests/cond-op-not.mk index 4565b60b115d..393d68675fca 100644 --- a/contrib/bmake/unit-tests/cond-op-not.mk +++ b/contrib/bmake/unit-tests/cond-op-not.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-not.mk,v 1.9 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: cond-op-not.mk,v 1.10 2025/06/28 22:39:28 rillig Exp $ # # Tests for the ! operator in .if conditions, which negates its argument. @@ -61,7 +61,7 @@ .endif # A single exclamation mark is a parse error. -# expect+1: Malformed conditional '!' +# expect+1: Malformed conditional "!" .if ! . error .else diff --git a/contrib/bmake/unit-tests/cond-op-or-lint.exp b/contrib/bmake/unit-tests/cond-op-or-lint.exp index 1c5837a9aca6..32d39dead9a1 100644 --- a/contrib/bmake/unit-tests/cond-op-or-lint.exp +++ b/contrib/bmake/unit-tests/cond-op-or-lint.exp @@ -1,4 +1,4 @@ -make: cond-op-or-lint.mk:10: Unknown operator '|' +make: cond-op-or-lint.mk:10: Unknown operator "|" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-op-or-lint.mk b/contrib/bmake/unit-tests/cond-op-or-lint.mk index 9ece9d5c9af6..1efc5d94cbf2 100644 --- a/contrib/bmake/unit-tests/cond-op-or-lint.mk +++ b/contrib/bmake/unit-tests/cond-op-or-lint.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-or-lint.mk,v 1.2 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: cond-op-or-lint.mk,v 1.3 2025/06/28 22:39:28 rillig Exp $ # # Tests for the || operator in .if conditions, in lint mode. @@ -6,7 +6,7 @@ # The '|' operator is not allowed in lint mode. # It is not used in practice anyway. -# expect+1: Unknown operator '|' +# expect+1: Unknown operator "|" .if 0 | 0 . error .else diff --git a/contrib/bmake/unit-tests/cond-op-or.exp b/contrib/bmake/unit-tests/cond-op-or.exp index 6213759c24f7..fe42ffd6b310 100644 --- a/contrib/bmake/unit-tests/cond-op-or.exp +++ b/contrib/bmake/unit-tests/cond-op-or.exp @@ -1,11 +1,11 @@ make: cond-op-or.mk:36: Variable "UNDEF" is undefined make: cond-op-or.mk:41: Variable "UNDEF" is undefined make: cond-op-or.mk:44: Variable "UNDEF" is undefined -make: cond-op-or.mk:60: Unknown operator '|' -make: cond-op-or.mk:66: Unknown operator '|' -make: cond-op-or.mk:72: Unknown operator '|' -make: cond-op-or.mk:78: Unknown operator '|' -make: cond-op-or.mk:87: Unknown operator '|' +make: cond-op-or.mk:60: Unknown operator "|" +make: cond-op-or.mk:66: Unknown operator "|" +make: cond-op-or.mk:72: Unknown operator "|" +make: cond-op-or.mk:78: Unknown operator "|" +make: cond-op-or.mk:87: Unknown operator "|" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-op-or.mk b/contrib/bmake/unit-tests/cond-op-or.mk index 381516499093..1c6e081dcac1 100644 --- a/contrib/bmake/unit-tests/cond-op-or.mk +++ b/contrib/bmake/unit-tests/cond-op-or.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-or.mk,v 1.14 2025/01/11 21:21:33 rillig Exp $ +# $NetBSD: cond-op-or.mk,v 1.15 2025/06/28 22:39:28 rillig Exp $ # # Tests for the || operator in .if conditions. @@ -56,25 +56,25 @@ DEF= defined # The || operator may be abbreviated as |. This is not widely known though # and is also not documented in the manual page. -# expect+1: Unknown operator '|' +# expect+1: Unknown operator "|" .if 0 | 0 . error .else . error .endif -# expect+1: Unknown operator '|' +# expect+1: Unknown operator "|" .if !(1 | 0) . error .else . error .endif -# expect+1: Unknown operator '|' +# expect+1: Unknown operator "|" .if !(0 | 1) . error .else . error .endif -# expect+1: Unknown operator '|' +# expect+1: Unknown operator "|" .if !(1 | 1) . error .else @@ -83,7 +83,7 @@ DEF= defined # There is no operator '|||'. The first two '||' form an operator, the third # '|' forms the next (incomplete) token. -# expect+1: Unknown operator '|' +# expect+1: Unknown operator "|" .if 0 ||| 0 . error .else diff --git a/contrib/bmake/unit-tests/cond-op-parentheses.exp b/contrib/bmake/unit-tests/cond-op-parentheses.exp index a4091226ec34..f8f9efc00772 100644 --- a/contrib/bmake/unit-tests/cond-op-parentheses.exp +++ b/contrib/bmake/unit-tests/cond-op-parentheses.exp @@ -1,7 +1,7 @@ -make: cond-op-parentheses.mk:22: Comparison with '>' requires both operands '3' and '(2' to be numeric -make: cond-op-parentheses.mk:25: Malformed conditional '(3) > 2' -make: cond-op-parentheses.mk:44: Malformed conditional '(' -make: cond-op-parentheses.mk:58: Malformed conditional ')' +make: cond-op-parentheses.mk:22: Comparison with ">" requires both operands "3" and "(2" to be numeric +make: cond-op-parentheses.mk:25: Malformed conditional "(3) > 2" +make: cond-op-parentheses.mk:44: Malformed conditional "(" +make: cond-op-parentheses.mk:58: Malformed conditional ")" make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-op-parentheses.mk b/contrib/bmake/unit-tests/cond-op-parentheses.mk index 17d5d767cd41..17d6504ede9e 100644 --- a/contrib/bmake/unit-tests/cond-op-parentheses.mk +++ b/contrib/bmake/unit-tests/cond-op-parentheses.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-op-parentheses.mk,v 1.8 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: cond-op-parentheses.mk,v 1.9 2025/06/28 22:39:28 rillig Exp $ # # Tests for parentheses in .if conditions, which group expressions to override # the precedence of the operators '!', '&&' and '||'. Parentheses cannot be @@ -18,10 +18,10 @@ # # XXX: It's inconsistent that the right operand has unbalanced parentheses. # -# expect+1: Comparison with '>' requires both operands '3' and '(2' to be numeric +# expect+1: Comparison with ">" requires both operands "3" and "(2" to be numeric .if 3 > (2) .endif -# expect+1: Malformed conditional '(3) > 2' +# expect+1: Malformed conditional "(3) > 2" .if (3) > 2 .endif @@ -40,7 +40,7 @@ .endif # An unbalanced opening parenthesis is a parse error. -# expect+1: Malformed conditional '(' +# expect+1: Malformed conditional "(" .if ( . error .else @@ -54,7 +54,7 @@ # TOK_TRUE, TOK_FALSE or TOK_ERROR. In cond.c 1.241, the return type of that # function was changed to a properly restricted enum type, to prevent this bug # from occurring again. -# expect+1: Malformed conditional ')' +# expect+1: Malformed conditional ")" .if ) . error .else diff --git a/contrib/bmake/unit-tests/cond-op.exp b/contrib/bmake/unit-tests/cond-op.exp index 1125a35fa3b3..692698b91a96 100644 --- a/contrib/bmake/unit-tests/cond-op.exp +++ b/contrib/bmake/unit-tests/cond-op.exp @@ -1,7 +1,7 @@ -make: cond-op.mk:51: Malformed conditional '"!word" == !word' -make: cond-op.mk:72: Malformed conditional '0 ${ERR::=evaluated}' +make: cond-op.mk:51: Malformed conditional ""!word" == !word" +make: cond-op.mk:72: Malformed conditional "0 ${ERR::=evaluated}" make: cond-op.mk:77: A misplaced expression after 0 is not evaluated. -make: cond-op.mk:82: Malformed conditional '1 ${ERR::=evaluated}' +make: cond-op.mk:82: Malformed conditional "1 ${ERR::=evaluated}" make: cond-op.mk:87: A misplaced expression after 1 is not evaluated. make: cond-op.mk:93: A B C => (A || B) && C A || B && C A || (B && C) make: cond-op.mk:108: 0 0 0 => 0 0 0 @@ -12,10 +12,10 @@ make: cond-op.mk:108: 1 0 0 => 0 1 1 make: cond-op.mk:108: 1 0 1 => 1 1 1 make: cond-op.mk:108: 1 1 0 => 0 1 1 make: cond-op.mk:108: 1 1 1 => 1 1 1 -make: cond-op.mk:120: Malformed conditional '1 &&' -make: cond-op.mk:129: Malformed conditional '0 &&' -make: cond-op.mk:138: Malformed conditional '1 ||' -make: cond-op.mk:148: Malformed conditional '0 ||' +make: cond-op.mk:120: Malformed conditional "1 &&" +make: cond-op.mk:129: Malformed conditional "0 &&" +make: cond-op.mk:138: Malformed conditional "1 ||" +make: cond-op.mk:148: Malformed conditional "0 ||" make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-op.mk b/contrib/bmake/unit-tests/cond-op.mk index 6493d887c806..974cb938065c 100644 --- a/contrib/bmake/unit-tests/cond-op.mk +++ b/contrib/bmake/unit-tests/cond-op.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-op.mk,v 1.17 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: cond-op.mk,v 1.18 2025/06/28 22:39:28 rillig Exp $ # # Tests for operators like &&, ||, ! in .if conditions. # @@ -47,7 +47,7 @@ # appear unquoted. If any, it must be enclosed in quotes. # In any case, it is not interpreted as a negation of an unquoted string. # See CondParser_String. -# expect+1: Malformed conditional '"!word" == !word' +# expect+1: Malformed conditional ""!word" == !word" .if "!word" == !word . error .endif @@ -68,7 +68,7 @@ # next token, even though in this position of the condition, only comparison # operators, TOK_AND, TOK_OR or TOK_RPAREN are allowed. .undef ERR -# expect+1: Malformed conditional '0 ${ERR::=evaluated}' +# expect+1: Malformed conditional "0 ${ERR::=evaluated}" .if 0 ${ERR::=evaluated} . error .endif @@ -78,7 +78,7 @@ .endif .undef ERR -# expect+1: Malformed conditional '1 ${ERR::=evaluated}' +# expect+1: Malformed conditional "1 ${ERR::=evaluated}" .if 1 ${ERR::=evaluated} . error .endif @@ -116,7 +116,7 @@ # This condition is obviously malformed. It is properly detected and also # was properly detected before 2021-01-19, but only because the left hand # side of the '&&' evaluated to true. -# expect+1: Malformed conditional '1 &&' +# expect+1: Malformed conditional "1 &&" .if 1 && . error .else @@ -125,7 +125,7 @@ # This obviously malformed condition was not detected as such before cond.c # 1.238 from 2021-01-19. -# expect+1: Malformed conditional '0 &&' +# expect+1: Malformed conditional "0 &&" .if 0 && . error .else @@ -134,7 +134,7 @@ # This obviously malformed condition was not detected as such before cond.c # 1.238 from 2021-01-19. -# expect+1: Malformed conditional '1 ||' +# expect+1: Malformed conditional "1 ||" .if 1 || . error .else @@ -144,7 +144,7 @@ # This condition is obviously malformed. It is properly detected and also # was properly detected before 2021-01-19, but only because the left hand # side of the '||' evaluated to false. -# expect+1: Malformed conditional '0 ||' +# expect+1: Malformed conditional "0 ||" .if 0 || . error .else diff --git a/contrib/bmake/unit-tests/cond-short.exp b/contrib/bmake/unit-tests/cond-short.exp index 19c7ef3d0b89..4100e6e5ef2b 100644 --- a/contrib/bmake/unit-tests/cond-short.exp +++ b/contrib/bmake/unit-tests/cond-short.exp @@ -7,7 +7,7 @@ expected M pattern expected or expected or exists expected or empty -make: cond-short.mk:231: Comparison with '<' requires both operands '' and '42' to be numeric +make: cond-short.mk:231: Comparison with "<" requires both operands "" and "42" to be numeric make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-short.mk b/contrib/bmake/unit-tests/cond-short.mk index bcdf372ca6e6..8c4c4140596e 100644 --- a/contrib/bmake/unit-tests/cond-short.mk +++ b/contrib/bmake/unit-tests/cond-short.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-short.mk,v 1.23 2023/11/19 22:32:44 rillig Exp $ +# $NetBSD: cond-short.mk,v 1.24 2025/06/28 22:39:28 rillig Exp $ # # Demonstrates that in conditions, the right-hand side of an && or || # is only evaluated if it can actually influence the result. @@ -227,7 +227,7 @@ VAR= ${VAR${:U1}} # Due to the quotes around the left-hand side of the '<', the operand is # marked as a string, thus preventing a numerical comparison. # -# expect+1: Comparison with '<' requires both operands '' and '42' to be numeric +# expect+1: Comparison with "<" requires both operands "" and "42" to be numeric .if "${INDIR_UNDEF}" < ${NUMBER} . info yes .else diff --git a/contrib/bmake/unit-tests/cond-token-number.exp b/contrib/bmake/unit-tests/cond-token-number.exp index 401f8a2364b7..a3b53c2dcd44 100644 --- a/contrib/bmake/unit-tests/cond-token-number.exp +++ b/contrib/bmake/unit-tests/cond-token-number.exp @@ -1,7 +1,7 @@ -make: cond-token-number.mk:16: Malformed conditional '-0' -make: cond-token-number.mk:27: Malformed conditional '+0' -make: cond-token-number.mk:38: Malformed conditional '!-1' -make: cond-token-number.mk:49: Malformed conditional '!+1' +make: cond-token-number.mk:16: Malformed conditional "-0" +make: cond-token-number.mk:27: Malformed conditional "+0" +make: cond-token-number.mk:38: Malformed conditional "!-1" +make: cond-token-number.mk:49: Malformed conditional "!+1" make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-token-number.mk b/contrib/bmake/unit-tests/cond-token-number.mk index 329a51d73b2a..1d0f8d20287e 100644 --- a/contrib/bmake/unit-tests/cond-token-number.mk +++ b/contrib/bmake/unit-tests/cond-token-number.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-token-number.mk,v 1.11 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: cond-token-number.mk,v 1.12 2025/06/28 22:39:28 rillig Exp $ # # Tests for number tokens in .if conditions. # @@ -12,7 +12,7 @@ # accepted by the condition parser. # # See the ch_isdigit call in CondParser_String. -# expect+1: Malformed conditional '-0' +# expect+1: Malformed conditional "-0" .if -0 . error .else @@ -23,7 +23,7 @@ # accepted by the condition parser. # # See the ch_isdigit call in CondParser_String. -# expect+1: Malformed conditional '+0' +# expect+1: Malformed conditional "+0" .if +0 . error .else @@ -34,7 +34,7 @@ # accepted by the condition parser. # # See the ch_isdigit call in CondParser_String. -# expect+1: Malformed conditional '!-1' +# expect+1: Malformed conditional "!-1" .if !-1 . error .else @@ -45,7 +45,7 @@ # accepted by the condition parser. # # See the ch_isdigit call in CondParser_String. -# expect+1: Malformed conditional '!+1' +# expect+1: Malformed conditional "!+1" .if !+1 . error .else diff --git a/contrib/bmake/unit-tests/cond-token-plain.exp b/contrib/bmake/unit-tests/cond-token-plain.exp index 52d7e6fcddaa..0b430eba7d39 100644 --- a/contrib/bmake/unit-tests/cond-token-plain.exp +++ b/contrib/bmake/unit-tests/cond-token-plain.exp @@ -1,10 +1,12 @@ CondParser_Eval: ${:Uvalue} != value Comparing "value" != "value" CondParser_Eval: ${:U} != " +make: cond-token-plain.mk:19: Unfinished string literal """ Comparing "" != "" CondParser_Eval: ${:U#hash} != "#hash" Comparing "#hash" != "#hash" CondParser_Eval: ${:U\\} != "\\ +make: cond-token-plain.mk:43: Unfinished string literal ""\\" Comparing "\" != "\" CondParser_Eval: ${:U#hash} != #hash Comparing "#hash" != "#hash" @@ -39,9 +41,9 @@ make: cond-token-plain.mk:139: Numbers can be composed from literals and express CondParser_Eval: 0${:Ux01} make: cond-token-plain.mk:144: Numbers can be composed from literals and expressions. CondParser_Eval: "" == -make: cond-token-plain.mk:151: Missing right-hand side of operator '==' +make: cond-token-plain.mk:151: Missing right-hand side of operator "==" CondParser_Eval: == "" -make: cond-token-plain.mk:160: Malformed conditional '== ""' +make: cond-token-plain.mk:160: Malformed conditional "== """ CondParser_Eval: \\ make: cond-token-plain.mk:176: The variable '\\' is not defined. CondParser_Eval: \\ @@ -49,15 +51,23 @@ make: cond-token-plain.mk:182: Now the variable '\\' is defined. CondParser_Eval: "unquoted\"quoted" != unquoted"quoted Comparing "unquoted"quoted" != "unquoted"quoted" CondParser_Eval: $$$$$$$$ != "" -make: cond-token-plain.mk:197: Malformed conditional '$$$$$$$$ != ""' +make: cond-token-plain.mk:197: Malformed conditional "$$$$$$$$ != """ CondParser_Eval: left == right -make: cond-token-plain.mk:206: Malformed conditional 'left == right' +make: cond-token-plain.mk:206: Malformed conditional "left == right" CondParser_Eval: ${0:?:} || left == right CondParser_Eval: 0 -make: cond-token-plain.mk:212: Malformed conditional '${0:?:} || left == right' +make: cond-token-plain.mk:212: Malformed conditional "${0:?:} || left == right" CondParser_Eval: left == right || ${0:?:} -make: cond-token-plain.mk:217: Malformed conditional 'left == right || ${0:?:}' -make: cond-token-plain.mk:236: Malformed conditional 'VAR.${IF_COUNT::+=1} != ""' +make: cond-token-plain.mk:217: Malformed conditional "left == right || ${0:?:}" +make: cond-token-plain.mk:236: Malformed conditional "VAR.${IF_COUNT::+=1} != """ +make: cond-token-plain.mk:272: Unfinished backslash escape sequence + while evaluating condition " str == str\" +make: cond-token-plain.mk:282: Unfinished backslash escape sequence + while evaluating condition " str == "str\" +make: cond-token-plain.mk:282: Unfinished string literal ""str\" + while evaluating condition " str == "str\" +make: cond-token-plain.mk:289: Unfinished string literal ""str" + while evaluating condition " str == "str" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-token-plain.mk b/contrib/bmake/unit-tests/cond-token-plain.mk index 4509c1feca80..400af22f92d7 100644 --- a/contrib/bmake/unit-tests/cond-token-plain.mk +++ b/contrib/bmake/unit-tests/cond-token-plain.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-token-plain.mk,v 1.20 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: cond-token-plain.mk,v 1.23 2025/07/06 07:56:16 rillig Exp $ # # Tests for plain tokens (that is, string literals without quotes) # in .if conditions. These are also called bare words. @@ -14,8 +14,8 @@ # condition since comment parsing is done in an early phase and removes the # '#' and everything after it long before the condition parser gets to see it. # -# XXX: The error message is missing for this malformed condition. -# The right-hand side of the comparison is just a '"', before unescaping. +# +# expect+1: Unfinished string literal """ .if ${:U} != "#hash" . error .endif @@ -38,8 +38,8 @@ # comments are stripped in an earlier phase. See "case '#'" in # CondParser_Token. # -# XXX: Missing error message for the malformed condition. The right-hand -# side before unescaping is double-quotes, backslash, backslash. +# +# expect+1: Unfinished string literal ""\\" .if ${:U\\} != "\\#hash" . error .endif @@ -147,7 +147,7 @@ VAR= defined .endif # If the right-hand side is missing, it's a parse error. -# expect+1: Missing right-hand side of operator '==' +# expect+1: Missing right-hand side of operator "==" .if "" == . error .else @@ -156,7 +156,7 @@ VAR= defined # If the left-hand side is missing, it's a parse error as well, but without # a specific error message. -# expect+1: Malformed conditional '== ""' +# expect+1: Malformed conditional "== """ .if == "" . error .else @@ -193,7 +193,7 @@ ${:U\\\\}= backslash # FIXME: In CondParser_String, Var_Parse returns var_Error without a # corresponding error message. -# expect+1: Malformed conditional '$$$$$$$$ != ""' +# expect+1: Malformed conditional "$$$$$$$$ != """ .if $$$$$$$$ != "" . error .else @@ -202,18 +202,18 @@ ${:U\\\\}= backslash # In a condition in an .if directive, the left-hand side must not be an # unquoted string literal. -# expect+1: Malformed conditional 'left == right' +# expect+1: Malformed conditional "left == right" .if left == right .endif # Before cond.c 1.276 from 2021-09-21, an expression containing the # modifier ':?:' allowed unquoted string literals for the rest of the # condition. This was an unintended implementation mistake. -# expect+1: Malformed conditional '${0:?:} || left == right' +# expect+1: Malformed conditional "${0:?:} || left == right" .if ${0:?:} || left == right .endif # This affected only the comparisons after the expression, so the following # was still a syntax error. -# expect+1: Malformed conditional 'left == right || ${0:?:}' +# expect+1: Malformed conditional "left == right || ${0:?:}" .if left == right || ${0:?:} .endif @@ -232,7 +232,7 @@ ${:U\\\\}= backslash # for the second time. The right-hand side of a comparison may be a bare # word, but that side has no risk of being parsed more than once. # -# expect+1: Malformed conditional 'VAR.${IF_COUNT::+=1} != ""' +# expect+1: Malformed conditional "VAR.${IF_COUNT::+=1} != """ .if VAR.${IF_COUNT::+=1} != "" . error .else @@ -265,3 +265,29 @@ COND= VAR.$${MOD_COUNT::+=1} . error .endif #.MAKEFLAGS: -d0 + + +# A trailing backslash in a bare word does not escape anything. +# expect+1: Unfinished backslash escape sequence +.if ${${:U str == str\\}:?yes:no} +. error +.else +. error +.endif + +# A trailing backslash in an unfinished string literal word does not escape +# anything. +# expect+2: Unfinished backslash escape sequence +# expect+1: Unfinished string literal ""str\" +.if ${${:U str == "str\\}:?yes:no} +. error +.else +. error +.endif + +# expect+1: Unfinished string literal ""str" +.if ${${:U str == "str}:?yes:no} +. error +.else +. error +.endif diff --git a/contrib/bmake/unit-tests/cond-token-string.exp b/contrib/bmake/unit-tests/cond-token-string.exp index d0a5a25f2aa4..d31c0abda17d 100644 --- a/contrib/bmake/unit-tests/cond-token-string.exp +++ b/contrib/bmake/unit-tests/cond-token-string.exp @@ -1,7 +1,7 @@ make: cond-token-string.mk:14: Unknown modifier ":Z" while evaluating "${:Uvalue:Z}"" with value "value" make: cond-token-string.mk:24: xvalue is not defined. -make: cond-token-string.mk:31: Malformed conditional 'x${:Uvalue} == ""' +make: cond-token-string.mk:31: Malformed conditional "x${:Uvalue} == """ make: cond-token-string.mk:41: Expected. CondParser_Eval: "UNDEF" make: cond-token-string.mk:51: The string literal "UNDEF" is not empty. diff --git a/contrib/bmake/unit-tests/cond-token-string.mk b/contrib/bmake/unit-tests/cond-token-string.mk index fb069f830582..9afe64dca821 100644 --- a/contrib/bmake/unit-tests/cond-token-string.mk +++ b/contrib/bmake/unit-tests/cond-token-string.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-token-string.mk,v 1.16 2025/03/29 19:08:52 rillig Exp $ +# $NetBSD: cond-token-string.mk,v 1.17 2025/06/28 22:39:28 rillig Exp $ # # Tests for quoted string literals in .if conditions. # @@ -27,7 +27,7 @@ # The 'x' produces a "Malformed conditional" since the left-hand side of a # comparison in an .if directive must be either an expression, a # quoted string literal or a number that starts with a digit. -# expect+1: Malformed conditional 'x${:Uvalue} == ""' +# expect+1: Malformed conditional "x${:Uvalue} == """ .if x${:Uvalue} == "" . error .else diff --git a/contrib/bmake/unit-tests/cond-token-var.exp b/contrib/bmake/unit-tests/cond-token-var.exp index 1bf61e79ca61..b63d606c7e5a 100644 --- a/contrib/bmake/unit-tests/cond-token-var.exp +++ b/contrib/bmake/unit-tests/cond-token-var.exp @@ -6,11 +6,11 @@ make: cond-token-var.mk:64: Variable "U" is undefined make: cond-token-var.mk:69: Variable "U" is undefined make: cond-token-var.mk:78: Variable "U" is undefined Var_Parse: ${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3} (eval) -make: cond-token-var.mk:106: Malformed conditional 'x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3}' +make: cond-token-var.mk:106: Malformed conditional "x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3}" Var_Parse: ${DEF}y == "${UNDEF2}" || 0x${UNDEF3} (eval) -make: cond-token-var.mk:111: Malformed conditional 'x${DEF}y == "${UNDEF2}" || 0x${UNDEF3}' +make: cond-token-var.mk:111: Malformed conditional "x${DEF}y == "${UNDEF2}" || 0x${UNDEF3}" Var_Parse: ${DEF}y == "${DEF}" || 0x${UNDEF3} (eval) -make: cond-token-var.mk:116: Malformed conditional 'x${DEF}y == "${DEF}" || 0x${UNDEF3}' +make: cond-token-var.mk:116: Malformed conditional "x${DEF}y == "${DEF}" || 0x${UNDEF3}" Global: VAR.param = value of VAR.param Var_Parse: ${VAR.param$U} (eval-defined-loud) Var_Parse: $U} (eval) diff --git a/contrib/bmake/unit-tests/cond-token-var.mk b/contrib/bmake/unit-tests/cond-token-var.mk index 8da8a2436390..842ca4d2cb12 100644 --- a/contrib/bmake/unit-tests/cond-token-var.mk +++ b/contrib/bmake/unit-tests/cond-token-var.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-token-var.mk,v 1.13 2025/04/04 18:57:01 rillig Exp $ +# $NetBSD: cond-token-var.mk,v 1.14 2025/06/28 22:39:28 rillig Exp $ # # Tests for expressions in .if conditions. # @@ -102,17 +102,17 @@ DEF= defined .MAKEFLAGS: -dv # The left-hand side of a comparison must not be an unquoted word. -# expect+1: Malformed conditional 'x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3}' +# expect+1: Malformed conditional "x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3}" .if x${UNDEF1}y == "${UNDEF2}" || 0x${UNDEF3} .endif # The left-hand side of a comparison must not be an unquoted word. -# expect+1: Malformed conditional 'x${DEF}y == "${UNDEF2}" || 0x${UNDEF3}' +# expect+1: Malformed conditional "x${DEF}y == "${UNDEF2}" || 0x${UNDEF3}" .if x${DEF}y == "${UNDEF2}" || 0x${UNDEF3} .endif # The left-hand side of a comparison must not be an unquoted word. -# expect+1: Malformed conditional 'x${DEF}y == "${DEF}" || 0x${UNDEF3}' +# expect+1: Malformed conditional "x${DEF}y == "${DEF}" || 0x${UNDEF3}" .if x${DEF}y == "${DEF}" || 0x${UNDEF3} .endif diff --git a/contrib/bmake/unit-tests/dep-op-missing.exp b/contrib/bmake/unit-tests/dep-op-missing.exp index 8521dbf79792..7c03092e09be 100644 --- a/contrib/bmake/unit-tests/dep-op-missing.exp +++ b/contrib/bmake/unit-tests/dep-op-missing.exp @@ -1,4 +1,4 @@ -make: dep-op-missing.tmp:1: Invalid line 'target' +make: dep-op-missing.tmp:1: Invalid line "target" in make[1] in directory "<curdir>" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/deptgt-begin.exp b/contrib/bmake/unit-tests/deptgt-begin.exp index bf6f61a51e72..5aa673e33d30 100644 --- a/contrib/bmake/unit-tests/deptgt-begin.exp +++ b/contrib/bmake/unit-tests/deptgt-begin.exp @@ -1,5 +1,5 @@ make: deptgt-begin.mk:19: warning: duplicate script for target ".BEGIN" ignored -make: deptgt-begin.mk:9: warning: using previous script for ".BEGIN" defined here +make: deptgt-begin.mk:8: warning: using previous script for ".BEGIN" defined here : parse time : Making before-begin before .BEGIN. : .BEGIN diff --git a/contrib/bmake/unit-tests/deptgt-begin.mk b/contrib/bmake/unit-tests/deptgt-begin.mk index 8b9842641a2d..a29155cb5fc2 100644 --- a/contrib/bmake/unit-tests/deptgt-begin.mk +++ b/contrib/bmake/unit-tests/deptgt-begin.mk @@ -1,10 +1,9 @@ -# $NetBSD: deptgt-begin.mk,v 1.7 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: deptgt-begin.mk,v 1.8 2025/06/30 21:44:39 rillig Exp $ # # Tests for the special target .BEGIN in dependency declarations, # which is a container for commands that are run before any other # commands from the shell lines. -# expect+2: warning: using previous script for ".BEGIN" defined here .BEGIN: : $@ @@ -14,7 +13,8 @@ # add its commands after this. # # There are several ways to resolve this situation, which are detailed below. -# expect+2: warning: duplicate script for target ".BEGIN" ignored +# expect+3: warning: duplicate script for target ".BEGIN" ignored +# expect-9: warning: using previous script for ".BEGIN" defined here .BEGIN: : Making another $@. diff --git a/contrib/bmake/unit-tests/deptgt-path-suffix.exp b/contrib/bmake/unit-tests/deptgt-path-suffix.exp index 6294d8a39dc0..e1c67daa8787 100644 --- a/contrib/bmake/unit-tests/deptgt-path-suffix.exp +++ b/contrib/bmake/unit-tests/deptgt-path-suffix.exp @@ -1,4 +1,4 @@ -make: deptgt-path-suffix.mk:8: Suffix '.c' not defined (yet) +make: deptgt-path-suffix.mk:8: Suffix ".c" not defined (yet) make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/deptgt-path-suffix.mk b/contrib/bmake/unit-tests/deptgt-path-suffix.mk index 494a076a5520..68bb27036b68 100644 --- a/contrib/bmake/unit-tests/deptgt-path-suffix.mk +++ b/contrib/bmake/unit-tests/deptgt-path-suffix.mk @@ -1,10 +1,10 @@ -# $NetBSD: deptgt-path-suffix.mk,v 1.3 2021/12/13 23:38:54 rillig Exp $ +# $NetBSD: deptgt-path-suffix.mk,v 1.4 2025/06/28 22:39:28 rillig Exp $ # # Tests for the special target .PATH.suffix in dependency declarations. # TODO: Implementation -# expect+1: Suffix '.c' not defined (yet) +# expect+1: Suffix ".c" not defined (yet) .PATH.c: .. .SUFFIXES: .c diff --git a/contrib/bmake/unit-tests/deptgt.exp b/contrib/bmake/unit-tests/deptgt.exp index 4c7cb4e50ddc..230fa497fcbd 100644 --- a/contrib/bmake/unit-tests/deptgt.exp +++ b/contrib/bmake/unit-tests/deptgt.exp @@ -1,4 +1,4 @@ -make: deptgt.mk:11: warning: Extra target '.PHONY' ignored +make: deptgt.mk:11: warning: Extra target ".PHONY" ignored make: deptgt.mk:30: Unassociated shell command ": command3 # parse error, since targets == NULL" Parsing deptgt.mk:36: ${:U}: empty-source ParseDependency(: empty-source) @@ -18,8 +18,8 @@ make: deptgt.mk:51: Unknown modifier ":Z" while evaluating "${:U:Z}:" with value "" make: deptgt.mk:55: Unknown modifier ":Z" while parsing "${:U:Z}:" -make: deptgt.mk:58: warning: Extra target 'ordinary' ignored -make: deptgt.mk:61: warning: Extra target (ordinary) ignored +make: deptgt.mk:58: warning: Extra target "ordinary" ignored +make: deptgt.mk:61: warning: Extra target "ordinary" ignored make: deptgt.mk:64: warning: Special and mundane targets don't mix. Mundane ones ignored make: Fatal errors encountered -- cannot continue make: stopped making "target1" in unit-tests diff --git a/contrib/bmake/unit-tests/deptgt.mk b/contrib/bmake/unit-tests/deptgt.mk index 779a1faf7115..fd7a716e3ebc 100644 --- a/contrib/bmake/unit-tests/deptgt.mk +++ b/contrib/bmake/unit-tests/deptgt.mk @@ -1,4 +1,4 @@ -# $NetBSD: deptgt.mk,v 1.23 2025/03/29 19:08:52 rillig Exp $ +# $NetBSD: deptgt.mk,v 1.24 2025/06/28 22:39:28 rillig Exp $ # # Tests for special targets like .BEGIN or .SUFFIXES in dependency # declarations. @@ -7,7 +7,7 @@ # Just in case anyone tries to compile several special targets in a single # dependency line: That doesn't work, and make immediately rejects it. -# expect+1: warning: Extra target '.PHONY' ignored +# expect+1: warning: Extra target ".PHONY" ignored .SUFFIXES .PHONY: .c.o # The following lines demonstrate how 'targets' is set and reset during @@ -54,10 +54,10 @@ ${:U:Z}: # expect+1: Unknown modifier ":Z" $${:U:Z}: -# expect+1: warning: Extra target 'ordinary' ignored +# expect+1: warning: Extra target "ordinary" ignored .END ordinary: -# expect+1: warning: Extra target (ordinary) ignored +# expect+1: warning: Extra target "ordinary" ignored .PATH ordinary: # expect+1: warning: Special and mundane targets don't mix. Mundane ones ignored diff --git a/contrib/bmake/unit-tests/directive-dinclude.exp b/contrib/bmake/unit-tests/directive-dinclude.exp index 5f5fec4d403e..55f1f77fbfde 100755 --- a/contrib/bmake/unit-tests/directive-dinclude.exp +++ b/contrib/bmake/unit-tests/directive-dinclude.exp @@ -1,4 +1,4 @@ -make: directive-dinclude-error.inc:1: Invalid line 'syntax error' +make: directive-dinclude-error.inc:1: Invalid line "syntax error" in directive-dinclude.mk:21 make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests diff --git a/contrib/bmake/unit-tests/directive-dinclude.mk b/contrib/bmake/unit-tests/directive-dinclude.mk index c363209579ad..da063083235f 100755 --- a/contrib/bmake/unit-tests/directive-dinclude.mk +++ b/contrib/bmake/unit-tests/directive-dinclude.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-dinclude.mk,v 1.4 2025/03/30 09:51:50 rillig Exp $ +# $NetBSD: directive-dinclude.mk,v 1.5 2025/06/28 22:39:28 rillig Exp $ # # Tests for the .dinclude directive, which includes another file, # silently skipping it if it cannot be opened. This is primarily used for @@ -16,7 +16,7 @@ .dinclude "${MAKEFILE}/subdir" # Errors that are not related to opening the file are still reported. -# expect: make: directive-dinclude-error.inc:1: Invalid line 'syntax error' +# expect: make: directive-dinclude-error.inc:1: Invalid line "syntax error" _!= echo 'syntax error' > directive-dinclude-error.inc .dinclude "${.CURDIR}/directive-dinclude-error.inc" _!= rm directive-dinclude-error.inc diff --git a/contrib/bmake/unit-tests/directive-export-gmake.exp b/contrib/bmake/unit-tests/directive-export-gmake.exp index f7bb07ab9da2..2c2875d669d2 100644 --- a/contrib/bmake/unit-tests/directive-export-gmake.exp +++ b/contrib/bmake/unit-tests/directive-export-gmake.exp @@ -1,4 +1,4 @@ -make: directive-export-gmake.mk:71: Invalid line 'export VAR=${:U1}', expanded to 'export VAR=1' +make: directive-export-gmake.mk:71: Invalid line "export VAR=${:U1}", expanded to "export VAR=1" in .for loop from directive-export-gmake.mk:67 with value = 1 make: directive-export-gmake.mk:85: 16:00:00 make: directive-export-gmake.mk:92: Variable/Value missing from "export" diff --git a/contrib/bmake/unit-tests/directive-export-gmake.mk b/contrib/bmake/unit-tests/directive-export-gmake.mk index de79470bf305..6e1d57c6a62d 100644 --- a/contrib/bmake/unit-tests/directive-export-gmake.mk +++ b/contrib/bmake/unit-tests/directive-export-gmake.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-export-gmake.mk,v 1.9 2023/12/17 09:44:00 rillig Exp $ +# $NetBSD: directive-export-gmake.mk,v 1.10 2025/06/28 22:39:28 rillig Exp $ # # Tests for the export directive (without leading dot), as in GNU make. @@ -67,7 +67,7 @@ export VAR=an ${UNDEF} variable .for value in 1 # XXX: The ':' in this line is inside an expression and should thus not be # interpreted as a dependency operator. -# expect+1: Invalid line 'export VAR=${:U1}', expanded to 'export VAR=1' +# expect+1: Invalid line "export VAR=${:U1}", expanded to "export VAR=1" export VAR=${value} .endfor diff --git a/contrib/bmake/unit-tests/directive-for-errors.exp b/contrib/bmake/unit-tests/directive-for-errors.exp index 39929864314d..1bae631b967a 100644 --- a/contrib/bmake/unit-tests/directive-for-errors.exp +++ b/contrib/bmake/unit-tests/directive-for-errors.exp @@ -4,10 +4,10 @@ make: directive-for-errors.mk:13: for-less endfor make: directive-for-errors.mk:25: Unknown directive "for" make: directive-for-errors.mk:27: warning: <> make: directive-for-errors.mk:29: for-less endfor -make: directive-for-errors.mk:44: invalid character '$' in .for loop variable name -make: directive-for-errors.mk:52: no iteration variables in for +make: directive-for-errors.mk:44: Invalid character "$" in .for loop variable name +make: directive-for-errors.mk:52: Missing iteration variables in .for loop make: directive-for-errors.mk:64: Wrong number of words (5) in .for substitution list with 3 variables -make: directive-for-errors.mk:78: missing `in' in for +make: directive-for-errors.mk:78: Missing "in" in .for loop make: directive-for-errors.mk:85: Unknown modifier ":Z" while evaluating "${:U3:Z} 4" with value "3" make: Fatal errors encountered -- cannot continue diff --git a/contrib/bmake/unit-tests/directive-for-errors.mk b/contrib/bmake/unit-tests/directive-for-errors.mk index a58b8294289b..2571b600bf38 100644 --- a/contrib/bmake/unit-tests/directive-for-errors.mk +++ b/contrib/bmake/unit-tests/directive-for-errors.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-for-errors.mk,v 1.17 2025/05/03 08:18:33 rillig Exp $ +# $NetBSD: directive-for-errors.mk,v 1.18 2025/06/28 22:39:28 rillig Exp $ # # Tests for error handling in .for loops. @@ -40,7 +40,7 @@ # error everywhere outside a .for loop. ${:U\$}= dollar # see whether the "variable" '$' is local ${:U\\}= backslash # see whether the "variable" '\' is local -# expect+1: invalid character '$' in .for loop variable name +# expect+1: Invalid character "$" in .for loop variable name .for a b $ \ in 1 2 3 4 . info Dollar $$ ${$} $($) and backslash $\ ${\} $(\). .endfor @@ -48,7 +48,7 @@ ${:U\\}= backslash # see whether the "variable" '\' is local # If there are no variables, there is no point in expanding the .for loop # since this would end up in an endless loop, consuming 0 of the 3 values in # each iteration. -# expect+1: no iteration variables in for +# expect+1: Missing iteration variables in .for loop .for in 1 2 3 # XXX: This should not be reached. It should be skipped, as already done # when the number of values is not a multiple of the number of variables, @@ -74,7 +74,7 @@ ${:U\\}= backslash # see whether the "variable" '\' is local # A missing 'in' parses the .for loop but skips the body. -# expect+1: missing `in' in for +# expect+1: Missing "in" in .for loop .for i over k . error .endfor diff --git a/contrib/bmake/unit-tests/directive-for-escape.exp b/contrib/bmake/unit-tests/directive-for-escape.exp index 6ab8a333a10f..78cc57a738a2 100644 --- a/contrib/bmake/unit-tests/directive-for-escape.exp +++ b/contrib/bmake/unit-tests/directive-for-escape.exp @@ -1,14 +1,14 @@ For: end for 1 For: loop body with chars = !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~: . info ${:U!"#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~} -make: directive-for-escape.mk:21: Unclosed expression, expecting '}' for modifier "U!"" +make: directive-for-escape.mk:21: Unclosed expression, expecting "}" for modifier "U!"" while evaluating "${:U!"" with value "!"" in .for loop from directive-for-escape.mk:20 with chars = !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~ make: directive-for-escape.mk:21: !" For: end for 1 For: loop body with chars = !"\\#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~: . info ${:U!"\\\\#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~} -make: directive-for-escape.mk:33: Unclosed expression, expecting '}' for modifier "U!"\\\\" +make: directive-for-escape.mk:33: Unclosed expression, expecting "}" for modifier "U!"\\\\" while evaluating "${:U!"\\\\" with value "!"\\" in .for loop from directive-for-escape.mk:32 with chars = !"\\#$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~ make: directive-for-escape.mk:33: !"\\ @@ -69,9 +69,9 @@ For: end for 1 For: loop body with i = $: . info ${:U\$} make: directive-for-escape.mk:147: $ -make: directive-for-escape.mk:155: invalid character ':' in .for loop variable name +make: directive-for-escape.mk:155: Invalid character ":" in .for loop variable name For: end for 1 -make: directive-for-escape.mk:165: invalid character '}' in .for loop variable name +make: directive-for-escape.mk:165: Invalid character "}" in .for loop variable name For: end for 1 For: end for 1 For: loop body with i = inner: @@ -89,7 +89,7 @@ For: end for 1 For: loop body with i = inner: . info ${i2} ${i,} ${:Uinner}${:Uinner}${:Uinner:M*}${:Uinner} make: directive-for-escape.mk:187: two comma innerinnerinnerinner -make: directive-for-escape.mk:196: invalid character '$' in .for loop variable name +make: directive-for-escape.mk:196: Invalid character "$" in .for loop variable name For: end for 1 make: directive-for-escape.mk:208: eight and no cents. For: end for 1 diff --git a/contrib/bmake/unit-tests/directive-for-escape.mk b/contrib/bmake/unit-tests/directive-for-escape.mk index e688ce98f258..913d61831c46 100644 --- a/contrib/bmake/unit-tests/directive-for-escape.mk +++ b/contrib/bmake/unit-tests/directive-for-escape.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-for-escape.mk,v 1.29 2024/08/29 20:20:36 rillig Exp $ +# $NetBSD: directive-for-escape.mk,v 1.30 2025/06/28 22:39:28 rillig Exp $ # # Test escaping of special characters in the iteration values of a .for loop. # These values get expanded later using the :U variable modifier, and this @@ -15,7 +15,7 @@ ASCII= !"\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~ # XXX: As of 2020-12-31, the '#' is not preserved in the expanded body of # the loop. Not only would it need the escaping for the variable modifier # ':U' but also the escaping for the line-end comment. -# expect+3: Unclosed expression, expecting '}' for modifier "U!"" +# expect+3: Unclosed expression, expecting "}" for modifier "U!"" # expect+2: !" .for chars in ${ASCII} . info ${chars} @@ -27,7 +27,7 @@ ASCII= !"\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~ # This means that a '#' sign cannot be passed in the value of a .for loop # at all. ASCII.2020-12-31= !"\\\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~ -# expect+3: Unclosed expression, expecting '}' for modifier "U!"\\\\" +# expect+3: Unclosed expression, expecting "}" for modifier "U!"\\\\" # expect+2: !"\\ .for chars in ${ASCII.2020-12-31} . info ${chars} @@ -151,7 +151,7 @@ VALUES= begin<$${UNDEF:Ufallback:N{{{}}}}>end # could contain colons, which affected expressions having this exact # modifier. This possibility was neither intended nor documented. NUMBERS= one two three -# expect+1: invalid character ':' in .for loop variable name +# expect+1: Invalid character ":" in .for loop variable name .for NUMBERS:M*e in replaced . info ${NUMBERS} ${NUMBERS:M*e} .endfor @@ -161,7 +161,7 @@ NUMBERS= one two three # expressions. This possibility was neither intended nor documented. BASENAME= one EXT= .c -# expect+1: invalid character '}' in .for loop variable name +# expect+1: Invalid character "}" in .for loop variable name .for BASENAME}${EXT in replaced . info ${BASENAME}${EXT} .endfor @@ -192,7 +192,7 @@ i,= comma # skipped "stupid" variable names though, but ForLoop_SubstVarLong naively # parsed the body of the loop, substituting each '${$}' with an actual # '${:Udollar}'. -# expect+1: invalid character '$' in .for loop variable name +# expect+1: Invalid character "$" in .for loop variable name .for $ in dollar . info eight $$$$$$$$ and no cents. . info eight ${$}${$}${$}${$} and no cents. diff --git a/contrib/bmake/unit-tests/directive-for-lines.exp b/contrib/bmake/unit-tests/directive-for-lines.exp index bf5b2b8b1209..23227122ffd3 100644 --- a/contrib/bmake/unit-tests/directive-for-lines.exp +++ b/contrib/bmake/unit-tests/directive-for-lines.exp @@ -1,9 +1,9 @@ -make: directive-for-lines.mk:27: expect 23 -make: directive-for-lines.mk:27: expect 23 -make: directive-for-lines.mk:36: expect 30 -make: directive-for-lines.mk:27: expect 23 -make: directive-for-lines.mk:27: expect 23 -make: directive-for-lines.mk:36: expect 30 +make: directive-for-lines.mk:31: This is line 31. +make: directive-for-lines.mk:31: This is line 31. +make: directive-for-lines.mk:38: This is line 38. +make: directive-for-lines.mk:31: This is line 31. +make: directive-for-lines.mk:31: This is line 31. +make: directive-for-lines.mk:38: This is line 38. make: no target to make. make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/directive-for-lines.mk b/contrib/bmake/unit-tests/directive-for-lines.mk index cae4e0a38897..898a1960e76a 100644 --- a/contrib/bmake/unit-tests/directive-for-lines.mk +++ b/contrib/bmake/unit-tests/directive-for-lines.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-for-lines.mk,v 1.5 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: directive-for-lines.mk,v 1.6 2025/06/30 21:44:39 rillig Exp $ # # Tests for the line numbers that are reported in .for loops. # @@ -7,6 +7,14 @@ # messages inside .for loops had been wrong since ParseGetLine skipped empty # lines, even when collecting the lines for the .for loop body. +# expect+21: This is line 31. +# expect+20: This is line 31. +# expect+26: This is line 38. + +# expect+17: This is line 31. +# expect+16: This is line 31. +# expect+22: This is line 38. + .for outer in a b # comment \ @@ -20,19 +28,13 @@ VAR= \ multi-line -# expect+4: expect 23 -# expect+3: expect 23 -# expect+2: expect 23 -# expect+1: expect 23 -.info expect 23 +.info This is line 31. .endfor # comment \ # continued comment -# expect+2: expect 30 -# expect+1: expect 30 -.info expect 30 +.info This is line 38. .endfor diff --git a/contrib/bmake/unit-tests/directive-for.exp b/contrib/bmake/unit-tests/directive-for.exp index cf87e6ea8569..d1c1064f0ef5 100755 --- a/contrib/bmake/unit-tests/directive-for.exp +++ b/contrib/bmake/unit-tests/directive-for.exp @@ -14,16 +14,16 @@ make: directive-for.mk:158: {{}} {{}} {{}} make: directive-for.mk:158: )( )( )( make: directive-for.mk:158: ][ ][ ][ make: directive-for.mk:158: }{ }{ }{ -make: directive-for.mk:166: invalid character ':' in .for loop variable name -make: directive-for.mk:173: invalid character '$' in .for loop variable name -make: directive-for.mk:185: invalid character '$' in .for loop variable name -make: directive-for.mk:207: no iteration variables in for -make: directive-for.mk:233: 1 open conditional - in .for loop from directive-for.mk:231 with var = value -make: directive-for.mk:249: for-less endfor -make: directive-for.mk:250: if-less endif -make: directive-for.mk:258: if-less endif - in .for loop from directive-for.mk:257 with var = value +make: directive-for.mk:166: Invalid character ":" in .for loop variable name +make: directive-for.mk:173: Invalid character "$" in .for loop variable name +make: directive-for.mk:185: Invalid character "$" in .for loop variable name +make: directive-for.mk:208: Missing iteration variables in .for loop +make: directive-for.mk:234: 1 open conditional + in .for loop from directive-for.mk:232 with var = value +make: directive-for.mk:252: for-less endfor +make: directive-for.mk:254: if-less endif +make: directive-for.mk:263: if-less endif + in .for loop from directive-for.mk:261 with var = value For: new loop 2 For: end for 2 For: end for 1 @@ -34,7 +34,7 @@ For: loop body with outer = o: endfor For: end for 1 For: loop body with inner = i: -make: directive-for.mk:307: newline-item=(a) +make: directive-for.mk:312: newline-item=(a) make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/directive-for.mk b/contrib/bmake/unit-tests/directive-for.mk index 2f989f54f228..72ffaa142ad6 100755 --- a/contrib/bmake/unit-tests/directive-for.mk +++ b/contrib/bmake/unit-tests/directive-for.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-for.mk,v 1.30 2025/03/30 16:43:10 rillig Exp $ +# $NetBSD: directive-for.mk,v 1.32 2025/07/01 04:24:20 rillig Exp $ # # Tests for the .for directive. # @@ -162,14 +162,14 @@ EXPANSION${plus}= value # except for whitespace, allowing for creative side effects, as usual for # arbitrary code injection. var= outer -# expect+1: invalid character ':' in .for loop variable name +# expect+1: Invalid character ":" in .for loop variable name .for var:Q in value "quoted" . info <${var}> <${var:Q}> <${var:Q:Q}> .endfor # Before 2023-05-09, when variable names could contain '$', the short # expression '$$' was preserved, the long expressions were substituted. -# expect+1: invalid character '$' in .for loop variable name +# expect+1: Invalid character "$" in .for loop variable name .for $ in value . info <$$> <${$}> <$($)> .endfor @@ -181,7 +181,7 @@ var= outer # possibility, therefore the variable names are restricted to using harmless # characters only. INDIRECT= direct -# expect+1: invalid character '$' in .for loop variable name +# expect+1: Invalid character "$" in .for loop variable name .for $(INDIRECT) in value # If the variable name could be chosen dynamically, the iteration variable # might have been 'direct', thereby expanding the expression '${direct}'. @@ -204,7 +204,8 @@ INDIRECT= ${DIRECT} # An empty list of variables to the left of the 'in' is a parse error. -.for in value # expect+0: no iteration variables in for +# expect+1: Missing iteration variables in .for loop +.for in value . error .endfor @@ -230,7 +231,8 @@ INDIRECT= ${DIRECT} # is processed. .for var in value . if 0 -.endfor # expect+0: 1 open conditional +.endfor +# expect-1: 1 open conditional # If there are no iteration values, the loop body is not processed, and the # check for mismatched conditionals is not performed. @@ -246,8 +248,10 @@ INDIRECT= ${DIRECT} .if 0 . for var in value # does not need a corresponding .endfor .endif -.endfor # expect+0: for-less endfor -.endif # expect+0: if-less endif +# expect+1: for-less endfor +.endfor +# expect+1: if-less endif +.endif # When a .for without the corresponding .endfor occurs in an active branch of @@ -255,7 +259,8 @@ INDIRECT= ${DIRECT} # without looking at any other directives. .if 1 . for var in value -. endif # expect+0: if-less endif +# expect+1: if-less endif +. endif . endfor # no 'for-less endfor' .endif # no 'if-less endif' diff --git a/contrib/bmake/unit-tests/directive-hyphen-include.exp b/contrib/bmake/unit-tests/directive-hyphen-include.exp index 3f17f0c41f0b..d1d37e783ca9 100755 --- a/contrib/bmake/unit-tests/directive-hyphen-include.exp +++ b/contrib/bmake/unit-tests/directive-hyphen-include.exp @@ -1,4 +1,4 @@ -make: directive-hyphen-include-error.inc:1: Invalid line 'syntax error' +make: directive-hyphen-include-error.inc:1: Invalid line "syntax error" in directive-hyphen-include.mk:20 make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests diff --git a/contrib/bmake/unit-tests/directive-hyphen-include.mk b/contrib/bmake/unit-tests/directive-hyphen-include.mk index ad596f4c47db..de438dfaffac 100755 --- a/contrib/bmake/unit-tests/directive-hyphen-include.mk +++ b/contrib/bmake/unit-tests/directive-hyphen-include.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-hyphen-include.mk,v 1.4 2025/03/30 09:51:50 rillig Exp $ +# $NetBSD: directive-hyphen-include.mk,v 1.5 2025/06/28 22:39:28 rillig Exp $ # # Tests for the .-include directive, which includes another file, # silently skipping it if it cannot be opened. @@ -15,7 +15,7 @@ .-include "${MAKEFILE}/subdir" # Errors that are not related to opening the file are still reported. -# expect: make: directive-hyphen-include-error.inc:1: Invalid line 'syntax error' +# expect: make: directive-hyphen-include-error.inc:1: Invalid line "syntax error" _!= echo 'syntax error' > directive-hyphen-include-error.inc .-include "${.CURDIR}/directive-hyphen-include-error.inc" _!= rm directive-hyphen-include-error.inc diff --git a/contrib/bmake/unit-tests/directive-if.exp b/contrib/bmake/unit-tests/directive-if.exp index 0d4a7ea16d34..634c9ee6b1df 100644 --- a/contrib/bmake/unit-tests/directive-if.exp +++ b/contrib/bmake/unit-tests/directive-if.exp @@ -5,7 +5,7 @@ make: directive-if.mk:45: This is not conditional. make: directive-if.mk:47: if-less else make: directive-if.mk:49: This is not conditional. make: directive-if.mk:51: if-less endif -make: directive-if.mk:55: Malformed conditional '' +make: directive-if.mk:55: Malformed conditional "" make: directive-if.mk:66: Quotes in plain words are probably a mistake. make: directive-if.mk:76: Don't do this, always put a space after a directive. make: directive-if.mk:81: Don't do this, always put a space after a directive. diff --git a/contrib/bmake/unit-tests/directive-if.mk b/contrib/bmake/unit-tests/directive-if.mk index 7ff04da0755b..5d1232d245a9 100644 --- a/contrib/bmake/unit-tests/directive-if.mk +++ b/contrib/bmake/unit-tests/directive-if.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-if.mk,v 1.13 2024/08/06 18:00:17 rillig Exp $ +# $NetBSD: directive-if.mk,v 1.14 2025/06/28 22:39:28 rillig Exp $ # # Tests for the .if directive. # @@ -51,7 +51,7 @@ .endif # Missing condition. -# expect+1: Malformed conditional '' +# expect+1: Malformed conditional "" .if . error .else diff --git a/contrib/bmake/unit-tests/directive-include.exp b/contrib/bmake/unit-tests/directive-include.exp index 71f39c57e807..361389cf1cad 100755 --- a/contrib/bmake/unit-tests/directive-include.exp +++ b/contrib/bmake/unit-tests/directive-include.exp @@ -8,7 +8,7 @@ make: directive-include.mk:56: Unknown modifier ":Z" while evaluating "${:U123:Z}.mk" with value "123" make: directive-include.mk:56: Could not find nonexistent.mk make: directive-include.mk:61: Cannot open /nonexistent -make: directive-include.mk:66: Invalid line 'include' +make: directive-include.mk:66: Invalid line "include" make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/directive-include.mk b/contrib/bmake/unit-tests/directive-include.mk index 42cdd97c43c7..ad6936ab2f3c 100755 --- a/contrib/bmake/unit-tests/directive-include.mk +++ b/contrib/bmake/unit-tests/directive-include.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-include.mk,v 1.19 2025/03/30 09:51:50 rillig Exp $ +# $NetBSD: directive-include.mk,v 1.20 2025/06/28 22:39:28 rillig Exp $ # # Tests for the .include directive, which includes another file. @@ -62,7 +62,7 @@ include /nonexistent # comment sinclude /nonexistent # comment include ${:U/dev/null} # comment include /dev/null /dev/null -# expect+1: Invalid line 'include' +# expect+1: Invalid line "include" include # XXX: trailing whitespace in diagnostic, missing quotes around filename diff --git a/contrib/bmake/unit-tests/directive-misspellings.exp b/contrib/bmake/unit-tests/directive-misspellings.exp index b918d05a2683..c551d73d5f98 100644 --- a/contrib/bmake/unit-tests/directive-misspellings.exp +++ b/contrib/bmake/unit-tests/directive-misspellings.exp @@ -1,6 +1,6 @@ make: directive-misspellings.mk:13: Unknown directive "dinclud" make: directive-misspellings.mk:16: Unknown directive "dincludx" -make: directive-misspellings.mk:18: .include filename must be delimited by '"' or '<' +make: directive-misspellings.mk:18: .include filename must be delimited by "" or <> make: directive-misspellings.mk:21: Unknown directive "erro" make: directive-misspellings.mk:23: Unknown directive "errox" make: directive-misspellings.mk:28: Unknown directive "expor" @@ -13,18 +13,18 @@ make: directive-misspellings.mk:46: Unknown directive "export-literax" make: directive-misspellings.mk:48: Unknown directive "export-literally" make: directive-misspellings.mk:51: Unknown directive "-includ" make: directive-misspellings.mk:54: Unknown directive "-includx" -make: directive-misspellings.mk:56: .include filename must be delimited by '"' or '<' +make: directive-misspellings.mk:56: .include filename must be delimited by "" or <> make: directive-misspellings.mk:59: Unknown directive "includ" make: directive-misspellings.mk:61: Could not find file make: directive-misspellings.mk:63: Unknown directive "includx" -make: directive-misspellings.mk:65: .include filename must be delimited by '"' or '<' +make: directive-misspellings.mk:65: .include filename must be delimited by "" or <> make: directive-misspellings.mk:68: Unknown directive "inf" make: directive-misspellings.mk:70: msg make: directive-misspellings.mk:72: Unknown directive "infx" make: directive-misspellings.mk:74: Unknown directive "infos" make: directive-misspellings.mk:77: Unknown directive "sinclud" make: directive-misspellings.mk:80: Unknown directive "sincludx" -make: directive-misspellings.mk:82: .include filename must be delimited by '"' or '<' +make: directive-misspellings.mk:82: .include filename must be delimited by "" or <> make: directive-misspellings.mk:85: Unknown directive "unde" make: directive-misspellings.mk:88: Unknown directive "undex" make: directive-misspellings.mk:90: Unknown directive "undefs" diff --git a/contrib/bmake/unit-tests/directive-misspellings.mk b/contrib/bmake/unit-tests/directive-misspellings.mk index 0014076d041f..cd6222b378f5 100644 --- a/contrib/bmake/unit-tests/directive-misspellings.mk +++ b/contrib/bmake/unit-tests/directive-misspellings.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-misspellings.mk,v 1.4 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: directive-misspellings.mk,v 1.5 2025/06/28 22:39:28 rillig Exp $ # # Tests for misspelled directives. # @@ -14,7 +14,7 @@ .dinclude "file" # expect+1: Unknown directive "dincludx" .dincludx "file" -# expect+1: .include filename must be delimited by '"' or '<' +# expect+1: .include filename must be delimited by "" or <> .dincludes "file" # XXX: the 's' is not meant to be a filename # expect+1: Unknown directive "erro" @@ -52,7 +52,7 @@ .-include "file" # expect+1: Unknown directive "-includx" .-includx "file" -# expect+1: .include filename must be delimited by '"' or '<' +# expect+1: .include filename must be delimited by "" or <> .-includes "file" # XXX: the 's' is not meant to be a filename # expect+1: Unknown directive "includ" @@ -61,7 +61,7 @@ .include "file" # expect+1: Unknown directive "includx" .includx "file" -# expect+1: .include filename must be delimited by '"' or '<' +# expect+1: .include filename must be delimited by "" or <> .includex "file" # XXX: the 's' is not meant to be a filename # expect+1: Unknown directive "inf" @@ -78,7 +78,7 @@ .sinclude "file" # expect+1: Unknown directive "sincludx" .sincludx "file" -# expect+1: .include filename must be delimited by '"' or '<' +# expect+1: .include filename must be delimited by "" or <> .sincludes "file" # XXX: the 's' is not meant to be a filename # expect+1: Unknown directive "unde" diff --git a/contrib/bmake/unit-tests/directive-sinclude.exp b/contrib/bmake/unit-tests/directive-sinclude.exp index b7503e18c9b5..74db51227f07 100755 --- a/contrib/bmake/unit-tests/directive-sinclude.exp +++ b/contrib/bmake/unit-tests/directive-sinclude.exp @@ -1,4 +1,4 @@ -make: directive-include-error.inc:1: Invalid line 'syntax error' +make: directive-include-error.inc:1: Invalid line "syntax error" in directive-sinclude.mk:20 make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests diff --git a/contrib/bmake/unit-tests/directive-sinclude.mk b/contrib/bmake/unit-tests/directive-sinclude.mk index d40915fa86d5..4c856d22be4f 100755 --- a/contrib/bmake/unit-tests/directive-sinclude.mk +++ b/contrib/bmake/unit-tests/directive-sinclude.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-sinclude.mk,v 1.6 2025/03/30 09:51:50 rillig Exp $ +# $NetBSD: directive-sinclude.mk,v 1.7 2025/06/28 22:39:28 rillig Exp $ # # Tests for the .sinclude directive, which includes another file, # silently skipping it if it cannot be opened. @@ -15,7 +15,7 @@ .sinclude "${MAKEFILE}/subdir" # Errors that are not related to opening the file are still reported. -# expect: make: directive-include-error.inc:1: Invalid line 'syntax error' +# expect: make: directive-include-error.inc:1: Invalid line "syntax error" _!= echo 'syntax error' > directive-include-error.inc .sinclude "${.CURDIR}/directive-include-error.inc" _!= rm directive-include-error.inc diff --git a/contrib/bmake/unit-tests/directive-unexport.exp b/contrib/bmake/unit-tests/directive-unexport.exp index 1be4b03e3874..25bab7d7fd35 100644 --- a/contrib/bmake/unit-tests/directive-unexport.exp +++ b/contrib/bmake/unit-tests/directive-unexport.exp @@ -1,5 +1,5 @@ make: directive-unexport.mk:19: UT_A=a UT_B=b UT_C=c make: directive-unexport.mk:21: UT_A UT_B UT_C make: directive-unexport.mk:30: UT_A=a UT_B=b UT_C=c -make: directive-unexport.mk:31: +make: directive-unexport.mk:32: exit status 0 diff --git a/contrib/bmake/unit-tests/directive-unexport.mk b/contrib/bmake/unit-tests/directive-unexport.mk index e759fe3e35f2..3c10ffa07d6a 100644 --- a/contrib/bmake/unit-tests/directive-unexport.mk +++ b/contrib/bmake/unit-tests/directive-unexport.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-unexport.mk,v 1.8 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: directive-unexport.mk,v 1.9 2025/06/30 21:44:39 rillig Exp $ # # Tests for the .unexport directive. # @@ -28,6 +28,7 @@ UT_C= c # expect+1: UT_A=a UT_B=b UT_C=c .info ${:!env|sort|grep '^UT_'!} +# expect+1: .info ${.MAKE.EXPORTED} .unexport # oops: missing argument diff --git a/contrib/bmake/unit-tests/directive-warning.exp b/contrib/bmake/unit-tests/directive-warning.exp index 2dd4e8ceb7f9..250e32583847 100644 --- a/contrib/bmake/unit-tests/directive-warning.exp +++ b/contrib/bmake/unit-tests/directive-warning.exp @@ -3,9 +3,9 @@ make: directive-warning.mk:12: Unknown directive "warn" make: directive-warning.mk:14: Unknown directive "warnin" make: directive-warning.mk:16: Unknown directive "warnin" make: directive-warning.mk:18: Missing argument for ".warning" -make: directive-warning.mk:19: warning: message -make: directive-warning.mk:21: Unknown directive "warnings" -make: directive-warning.mk:23: Unknown directive "warnings" +make: directive-warning.mk:20: warning: message +make: directive-warning.mk:22: Unknown directive "warnings" +make: directive-warning.mk:24: Unknown directive "warnings" make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/directive-warning.mk b/contrib/bmake/unit-tests/directive-warning.mk index bf0683f8911f..50666487c13f 100644 --- a/contrib/bmake/unit-tests/directive-warning.mk +++ b/contrib/bmake/unit-tests/directive-warning.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-warning.mk,v 1.9 2023/12/17 09:44:00 rillig Exp $ +# $NetBSD: directive-warning.mk,v 1.10 2025/07/01 04:24:20 rillig Exp $ # # Tests for the .warning directive. # @@ -16,7 +16,8 @@ .warnin message # misspelled # expect+1: Missing argument for ".warning" .warning # "Missing argument" -.warning message # expect+0: warning: message +# expect+1: warning: message +.warning message # expect+1: Unknown directive "warnings" .warnings # misspelled # expect+1: Unknown directive "warnings" diff --git a/contrib/bmake/unit-tests/directive.exp b/contrib/bmake/unit-tests/directive.exp index 2f1da18cdbb5..dce759abfe52 100644 --- a/contrib/bmake/unit-tests/directive.exp +++ b/contrib/bmake/unit-tests/directive.exp @@ -7,8 +7,8 @@ Global: .info = value make: directive.mk:31: := value Global: .MAKEFLAGS = -r -k -d v -d Global: .MAKEFLAGS = -r -k -d v -d 0 -make: directive.mk:40: Invalid line 'target-without-colon' -make: directive.mk:43: Invalid line 'target-without-colon another-target' +make: directive.mk:40: Invalid line "target-without-colon" +make: directive.mk:43: Invalid line "target-without-colon another-target" make: Fatal errors encountered -- cannot continue make: stopped making ".target" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/directive.mk b/contrib/bmake/unit-tests/directive.mk index 61938360dfc7..5f5be5aa0fab 100644 --- a/contrib/bmake/unit-tests/directive.mk +++ b/contrib/bmake/unit-tests/directive.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive.mk,v 1.9 2023/11/19 22:32:44 rillig Exp $ +# $NetBSD: directive.mk,v 1.10 2025/06/28 22:39:28 rillig Exp $ # # Tests for the preprocessing directives, such as .if or .info. @@ -36,8 +36,8 @@ # Not even the space after the '.info' can change anything about this. .${:Uinfo} : source -# expect+1: Invalid line 'target-without-colon' +# expect+1: Invalid line "target-without-colon" target-without-colon -# expect+1: Invalid line 'target-without-colon another-target' +# expect+1: Invalid line "target-without-colon another-target" target-without-colon another-target diff --git a/contrib/bmake/unit-tests/moderrs.exp b/contrib/bmake/unit-tests/moderrs.exp index 08aa2582f6be..4758294f0993 100644 --- a/contrib/bmake/unit-tests/moderrs.exp +++ b/contrib/bmake/unit-tests/moderrs.exp @@ -7,11 +7,11 @@ make: Unknown modifier ":Z" while evaluating variable "VAR" with value "TheVariable" in command "@echo 'VAR:${MOD_UNKN}=before-${VAR:${MOD_UNKN}:inner}-after'" in target "mod-unknown-indirect" -make: Unclosed expression, expecting '}' for modifier "S,V,v," +make: Unclosed expression, expecting "}" for modifier "S,V,v," while evaluating variable "VAR" with value "Thevariable" in command "@echo VAR:S,V,v,=${VAR:S,V,v," in target "unclosed-direct" -make: Unclosed expression after indirect modifier, expecting '}' +make: Unclosed expression after indirect modifier, expecting "}" while evaluating variable "VAR" with value "Thevariable" in command "@echo VAR:${MOD_TERM},=${VAR:${MOD_S}" in target "unclosed-indirect" @@ -29,7 +29,7 @@ make: Unfinished modifier after "...}", expecting "@" in command "@echo ${UNDEF:U1 2 3:@var@...}" in target "unfinished-loop-2" 1 2 3 -make: Unclosed expression, expecting '}' for modifier "@var@${var}}...@" +make: Unclosed expression, expecting "}" for modifier "@var@${var}}...@" while evaluating variable "UNDEF" with value "1}... 2}... 3}..." in command "@echo ${UNDEF:U1 2 3:@var@${var}}...@" in target "loop-close-1" @@ -55,7 +55,7 @@ make: Unfinished modifier after "=exclam}", expecting "!" while evaluating variable "!" with value "!" in command "@echo ${!:L:!=exclam}" in target "exclam-2" -make: Missing delimiter for modifier ':S' +make: Missing delimiter for modifier ":S" while evaluating variable "VAR" with value "TheVariable" in command "@echo 1: ${VAR:S" in target "mod-subst-delimiter-1" @@ -75,12 +75,12 @@ make: Unfinished modifier after "to", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 5: ${VAR:S,from,to" in target "mod-subst-delimiter-5" -make: Unclosed expression, expecting '}' for modifier "S,from,to," +make: Unclosed expression, expecting "}" for modifier "S,from,to," while evaluating variable "VAR" with value "TheVariable" in command "@echo 6: ${VAR:S,from,to," in target "mod-subst-delimiter-6" 7: TheVariable -make: Missing delimiter for modifier ':C' +make: Missing delimiter for modifier ":C" while evaluating variable "VAR" with value "TheVariable" in command "@echo 1: ${VAR:C" in target "mod-regex-delimiter-1" @@ -100,7 +100,7 @@ make: Unfinished modifier after "to", expecting "," while evaluating variable "VAR" with value "TheVariable" in command "@echo 5: ${VAR:C,from,to" in target "mod-regex-delimiter-5" -make: Unclosed expression, expecting '}' for modifier "C,from,to," +make: Unclosed expression, expecting "}" for modifier "C,from,to," while evaluating variable "VAR" with value "TheVariable" in command "@echo 6: ${VAR:C,from,to," in target "mod-regex-delimiter-6" diff --git a/contrib/bmake/unit-tests/moderrs.mk b/contrib/bmake/unit-tests/moderrs.mk index ca5cc082e6b8..c2ee320e2df2 100644 --- a/contrib/bmake/unit-tests/moderrs.mk +++ b/contrib/bmake/unit-tests/moderrs.mk @@ -1,4 +1,4 @@ -# $NetBSD: moderrs.mk,v 1.46 2025/03/30 00:35:52 rillig Exp $ +# $NetBSD: moderrs.mk,v 1.47 2025/06/28 22:39:29 rillig Exp $ # # various modifier error tests @@ -33,11 +33,11 @@ mod-unknown-indirect: @echo 'VAR:${MOD_UNKN}=before-${VAR:${MOD_UNKN}:inner}-after' unclosed-direct: -# expect: make: Unclosed expression, expecting '}' for modifier "S,V,v," +# expect: make: Unclosed expression, expecting "}" for modifier "S,V,v," @echo VAR:S,V,v,=${VAR:S,V,v, unclosed-indirect: -# expect: make: Unclosed expression after indirect modifier, expecting '}' +# expect: make: Unclosed expression after indirect modifier, expecting "}" @echo VAR:${MOD_TERM},=${VAR:${MOD_S} unfinished-indirect: @@ -60,7 +60,7 @@ unfinished-loop-3: # This is also contrary to the SysV modifier, where only the actually # used delimiter (either braces or parentheses) must be balanced. loop-close-1: -# expect: make: Unclosed expression, expecting '}' for modifier "@var@${var}}...@" +# expect: make: Unclosed expression, expecting "}" for modifier "@var@${var}}...@" @echo ${UNDEF:U1 2 3:@var@${var}}...@ loop-close-2: @echo ${UNDEF:U1 2 3:@var@${var}}...@} @@ -107,7 +107,7 @@ exclam-2: @echo ${!:L:!=exclam} mod-subst-delimiter-1: -# expect: make: Missing delimiter for modifier ':S' +# expect: make: Missing delimiter for modifier ":S" @echo 1: ${VAR:S mod-subst-delimiter-2: # expect: make: Unfinished modifier after "", expecting "," @@ -122,13 +122,13 @@ mod-subst-delimiter-5: # expect: make: Unfinished modifier after "to", expecting "," @echo 5: ${VAR:S,from,to mod-subst-delimiter-6: -# expect: make: Unclosed expression, expecting '}' for modifier "S,from,to," +# expect: make: Unclosed expression, expecting "}" for modifier "S,from,to," @echo 6: ${VAR:S,from,to, mod-subst-delimiter-7: @echo 7: ${VAR:S,from,to,} mod-regex-delimiter-1: -# expect: make: Missing delimiter for modifier ':C' +# expect: make: Missing delimiter for modifier ":C" @echo 1: ${VAR:C mod-regex-delimiter-2: # expect: make: Unfinished modifier after "", expecting "," @@ -143,7 +143,7 @@ mod-regex-delimiter-5: # expect: make: Unfinished modifier after "to", expecting "," @echo 5: ${VAR:C,from,to mod-regex-delimiter-6: -# expect: make: Unclosed expression, expecting '}' for modifier "C,from,to," +# expect: make: Unclosed expression, expecting "}" for modifier "C,from,to," @echo 6: ${VAR:C,from,to, mod-regex-delimiter-7: @echo 7: ${VAR:C,from,to,} diff --git a/contrib/bmake/unit-tests/opt-debug-file.exp b/contrib/bmake/unit-tests/opt-debug-file.exp index 1059351188e4..4a497f3011d9 100644 --- a/contrib/bmake/unit-tests/opt-debug-file.exp +++ b/contrib/bmake/unit-tests/opt-debug-file.exp @@ -1,6 +1,6 @@ -make: opt-debug-file.mk:44: This goes to stderr only, once. -make: opt-debug-file.mk:47: This goes to stderr only, once. -make: opt-debug-file.mk:50: This goes to stderr, and in addition to the debug log. +make: opt-debug-file.mk:54: This goes to stderr only, once. +make: opt-debug-file.mk:57: This goes to stderr only, once. +make: opt-debug-file.mk:60: This goes to stderr, and in addition to the debug log. CondParser_Eval: ${:!cat opt-debug-file.debuglog!:Maddition:[#]} != 1 Comparing 1.000000 != 1.000000 make: Unterminated quoted string [make 'This goes to stdout only, once.] diff --git a/contrib/bmake/unit-tests/opt-debug-file.mk b/contrib/bmake/unit-tests/opt-debug-file.mk index 33a35e0a458a..d107f177dae3 100644 --- a/contrib/bmake/unit-tests/opt-debug-file.mk +++ b/contrib/bmake/unit-tests/opt-debug-file.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-debug-file.mk,v 1.11 2024/06/30 15:21:24 rillig Exp $ +# $NetBSD: opt-debug-file.mk,v 1.12 2025/07/06 08:48:34 rillig Exp $ # # Tests for the -dF command line option, which redirects the debug log # to a file instead of writing it to stderr. @@ -27,7 +27,9 @@ DEBUG_OUTPUT:= ${:!cat opt-debug-file.debuglog!} .endif # To get the unexpanded text that was actually written to the debug log -# file, the content of that log file must not be stored in a variable. +# file, the content of that log file must not be stored in a variable +# directly. Instead, it can be processed in a single expression by a chain +# of modifiers. # # XXX: In the :M modifier, a dollar is escaped using '$$', not '\$'. This # escaping scheme unnecessarily differs from all other modifiers. @@ -35,6 +37,14 @@ DEBUG_OUTPUT:= ${:!cat opt-debug-file.debuglog!} . error .endif +# To get the unexpanded text that was actually written to the debug log +# file, the content of that log file must not be stored in a variable +# directly. Instead, each dollar sign must be escaped first. +DEBUG_OUTPUT:= ${:!cat opt-debug-file.debuglog!:S,\$,\$\$,g} +.if ${DEBUG_OUTPUT:M*Uexpanded*} != "\${:Uexpanded}" +. error +.endif + .MAKEFLAGS: -d0 diff --git a/contrib/bmake/unit-tests/opt-debug-lint.exp b/contrib/bmake/unit-tests/opt-debug-lint.exp index 8e7339fcd2e9..7173ec476ec5 100644 --- a/contrib/bmake/unit-tests/opt-debug-lint.exp +++ b/contrib/bmake/unit-tests/opt-debug-lint.exp @@ -1,8 +1,8 @@ make: opt-debug-lint.mk:20: Variable "X" is undefined make: opt-debug-lint.mk:43: Variable "UNDEF" is undefined -make: opt-debug-lint.mk:65: Missing delimiter ':' after modifier "L" +make: opt-debug-lint.mk:65: Missing delimiter ":" after modifier "L" while evaluating variable "value" with value "value" -make: opt-debug-lint.mk:65: Missing delimiter ':' after modifier "P" +make: opt-debug-lint.mk:65: Missing delimiter ":" after modifier "P" while evaluating variable "value" with value "value" make: opt-debug-lint.mk:74: Unknown modifier ":${" while evaluating variable "value" with value "" diff --git a/contrib/bmake/unit-tests/opt-debug-lint.mk b/contrib/bmake/unit-tests/opt-debug-lint.mk index 59cd36fb05e9..2f73c9bf645c 100644 --- a/contrib/bmake/unit-tests/opt-debug-lint.mk +++ b/contrib/bmake/unit-tests/opt-debug-lint.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-debug-lint.mk,v 1.24 2025/04/04 18:57:01 rillig Exp $ +# $NetBSD: opt-debug-lint.mk,v 1.25 2025/06/28 22:39:29 rillig Exp $ # # Tests for the -dL command line option, which runs additional checks # to catch common mistakes, such as unclosed expressions. @@ -60,8 +60,8 @@ ${UNDEF}: ${UNDEF} # Since 2020-10-03, in lint mode the variable modifier must be separated # by colons. See varparse-mod.mk. -# expect+2: Missing delimiter ':' after modifier "L" -# expect+1: Missing delimiter ':' after modifier "P" +# expect+2: Missing delimiter ":" after modifier "L" +# expect+1: Missing delimiter ":" after modifier "P" .if ${value:LPL} != "value" . error .endif diff --git a/contrib/bmake/unit-tests/opt-jobs-internal.exp b/contrib/bmake/unit-tests/opt-jobs-internal.exp index e3e8ee498224..61c96256a2e4 100644 --- a/contrib/bmake/unit-tests/opt-jobs-internal.exp +++ b/contrib/bmake/unit-tests/opt-jobs-internal.exp @@ -1,25 +1,13 @@ direct: mode=parallel make: error: invalid internal option "-J garbage" in "<curdir>" -make: warning: internal option "-J" in "<curdir>" refers to unopened file descriptors; falling back to compat mode. - To run the target even in -n mode, add the .MAKE pseudo-source to the target. - To run the target in default mode only, add a ${:D make} marker to a target's command. (This marker expression expands to an empty string.) - To make the sub-make run in compat mode, add -B to its invocation. - To make the sub-make independent from the parent make, unset the MAKEFLAGS environment variable in the target's commands. +make: warning: Invalid internal option "-J" in "<curdir>"; see the manual page in make[2] in directory "<curdir>" direct-open: mode=compat -make: warning: internal option "-J" in "<curdir>" refers to unopened file descriptors; falling back to compat mode. - To run the target even in -n mode, add the .MAKE pseudo-source to the target. - To run the target in default mode only, add a ${:D make} marker to a target's command. (This marker expression expands to an empty string.) - To make the sub-make run in compat mode, add -B to its invocation. - To make the sub-make independent from the parent make, unset the MAKEFLAGS environment variable in the target's commands. +make: warning: Invalid internal option "-J" in "<curdir>"; see the manual page in make[2] in directory "<curdir>" indirect-open: mode=compat indirect-expr: mode=parallel -make: warning: internal option "-J" in "<curdir>" refers to unopened file descriptors; falling back to compat mode. - To run the target even in -n mode, add the .MAKE pseudo-source to the target. - To run the target in default mode only, add a ${:D make} marker to a target's command. (This marker expression expands to an empty string.) - To make the sub-make run in compat mode, add -B to its invocation. - To make the sub-make independent from the parent make, unset the MAKEFLAGS environment variable in the target's commands. +make: warning: Invalid internal option "-J" in "<curdir>"; see the manual page in make[2] in directory "<curdir>" indirect-comment: mode=compat indirect-silent-comment: mode=parallel diff --git a/contrib/bmake/unit-tests/parse.exp b/contrib/bmake/unit-tests/parse.exp index 86d12effb5c7..4f97a9350550 100644 --- a/contrib/bmake/unit-tests/parse.exp +++ b/contrib/bmake/unit-tests/parse.exp @@ -1,6 +1,6 @@ -make: parse.mk:7: Invalid line '<<<<<< old' -make: parse.mk:14: Invalid line '>>>>>> new' -make: parse.mk:25: Invalid line 'one-target ${:U }', expanded to 'one-target ' +make: parse.mk:7: Invalid line "<<<<<< old" +make: parse.mk:14: Invalid line ">>>>>> new" +make: parse.mk:25: Invalid line "one-target ${:U }", expanded to "one-target " make: Fatal errors encountered -- cannot continue make: stopped making "Try_to_crash_FreeBSD.xxxxxxxxxxxxxxxxxx" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/parse.mk b/contrib/bmake/unit-tests/parse.mk index 80a51f2de11e..fb959a4a5e1b 100644 --- a/contrib/bmake/unit-tests/parse.mk +++ b/contrib/bmake/unit-tests/parse.mk @@ -1,16 +1,16 @@ -# $NetBSD: parse.mk,v 1.7 2023/08/19 11:09:02 rillig Exp $ +# $NetBSD: parse.mk,v 1.8 2025/06/28 22:39:29 rillig Exp $ # # Test those parts of the parsing that do not belong in any of the other # categories. -# expect+1: Invalid line '<<<<<< old' +# expect+1: Invalid line "<<<<<< old" <<<<<< old # No diagnostic since the following line is parsed as a variable assignment, # even though the variable name is empty. See also varname-empty.mk. ====== middle -# expect+1: Invalid line '>>>>>> new' +# expect+1: Invalid line ">>>>>> new" >>>>>> new @@ -21,7 +21,7 @@ # the expanded line's terminating '\0'. # # https://bugs.freebsd.org/265119 -# expect+1: Invalid line 'one-target ${:U }', expanded to 'one-target ' +# expect+1: Invalid line "one-target ${:U }", expanded to "one-target " one-target ${:U } diff --git a/contrib/bmake/unit-tests/var-op-assign.exp b/contrib/bmake/unit-tests/var-op-assign.exp index 4e287e518eb7..83459de4184d 100644 --- a/contrib/bmake/unit-tests/var-op-assign.exp +++ b/contrib/bmake/unit-tests/var-op-assign.exp @@ -1,5 +1,5 @@ this will be evaluated later -make: var-op-assign.mk:60: Invalid line 'VARIABLE NAME= variable value' +make: var-op-assign.mk:60: Invalid line "VARIABLE NAME= variable value" make: var-op-assign.mk:95: Parsing still continues until here. make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests diff --git a/contrib/bmake/unit-tests/var-op-assign.mk b/contrib/bmake/unit-tests/var-op-assign.mk index a900c28a918d..a218dbfdac0a 100644 --- a/contrib/bmake/unit-tests/var-op-assign.mk +++ b/contrib/bmake/unit-tests/var-op-assign.mk @@ -1,4 +1,4 @@ -# $NetBSD: var-op-assign.mk,v 1.11 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: var-op-assign.mk,v 1.12 2025/06/28 22:39:29 rillig Exp $ # # Tests for the = variable assignment operator, which overwrites an existing # variable or creates it. @@ -56,7 +56,7 @@ VAR= ${:! echo 'this will be evaluated later' 1>&2 !} # In a variable assignment, the variable name must consist of a single word. # The following line therefore generates a parse error. -# expect+1: Invalid line 'VARIABLE NAME= variable value' +# expect+1: Invalid line "VARIABLE NAME= variable value" VARIABLE NAME= variable value # But if the whitespace appears inside parentheses or braces, everything is diff --git a/contrib/bmake/unit-tests/var-op-expand.exp b/contrib/bmake/unit-tests/var-op-expand.exp index 105d2f50acc8..5e2c3d1936d7 100644 --- a/contrib/bmake/unit-tests/var-op-expand.exp +++ b/contrib/bmake/unit-tests/var-op-expand.exp @@ -1,22 +1,20 @@ make: var-op-expand.mk:274: Unknown modifier ":s,value,replaced," while evaluating variable "later" with value "" while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}" -make: var-op-expand.mk:278: warning: XXX Neither branch should be taken. -make: var-op-expand.mk:283: Unknown modifier ":s,value,replaced," +make: var-op-expand.mk:282: Unknown modifier ":s,value,replaced," while evaluating variable "later" with value "lowercase-value" while evaluating variable "indirect" with value "${later:s,value,replaced,} ok ${later:value=sysv}" -make: var-op-expand.mk:285: warning: XXX Neither branch should be taken. -make: var-op-expand.mk:297: Bad condition +make: var-op-expand.mk:295: Bad condition while evaluating condition " < 0 " -make: var-op-expand.mk:297: Unknown modifier ":Z1" +make: var-op-expand.mk:295: Unknown modifier ":Z1" while parsing "${:Z1}:${:Z2}}" while evaluating then-branch of condition " < 0 " -make: var-op-expand.mk:297: Unknown modifier ":Z2" +make: var-op-expand.mk:295: Unknown modifier ":Z2" while parsing "${:Z2}}" while evaluating else-branch of condition " < 0 " -make: var-op-expand.mk:297: Unknown modifier ":Z1" +make: var-op-expand.mk:295: Unknown modifier ":Z1" while evaluating "${:Z1}:${:Z2}}" with value "" -make: var-op-expand.mk:297: Unknown modifier ":Z2" +make: var-op-expand.mk:295: Unknown modifier ":Z2" while evaluating "${:Z2}}" with value "" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/var-op-expand.mk b/contrib/bmake/unit-tests/var-op-expand.mk index 6a49648f0618..fb9e1713438b 100644 --- a/contrib/bmake/unit-tests/var-op-expand.mk +++ b/contrib/bmake/unit-tests/var-op-expand.mk @@ -1,4 +1,4 @@ -# $NetBSD: var-op-expand.mk,v 1.24 2025/04/30 06:01:07 rillig Exp $ +# $NetBSD: var-op-expand.mk,v 1.25 2025/06/29 11:27:21 rillig Exp $ # # Tests for the := variable assignment operator, which expands its # right-hand side. @@ -274,15 +274,13 @@ indirect:= ${INDIRECT:tl} .if ${indirect} != " ok " . error .else -# expect+1: warning: XXX Neither branch should be taken. -. warning XXX Neither branch should be taken. +. error .endif LATER= uppercase-value later= lowercase-value # expect+1: Unknown modifier ":s,value,replaced," .if ${indirect} != "uppercase-replaced ok uppercase-sysv" -# expect+1: warning: XXX Neither branch should be taken. -. warning XXX Neither branch should be taken. +. error .else . error .endif diff --git a/contrib/bmake/unit-tests/varmisc.exp b/contrib/bmake/unit-tests/varmisc.exp index 509dbcc5e689..44b3c8e759cb 100644 --- a/contrib/bmake/unit-tests/varmisc.exp +++ b/contrib/bmake/unit-tests/varmisc.exp @@ -57,7 +57,7 @@ make: Unclosed variable "PATTERN" while evaluating variable "UNCLOSED" with value "" in command "@echo ${UNCLOSED:M${PATTERN" in target "varerror-unclosed-5" -make: Unclosed expression, expecting '}' for modifier "M${PATTERN" +make: Unclosed expression, expecting "}" for modifier "M${PATTERN" while evaluating variable "UNCLOSED" with value "" in command "@echo ${UNCLOSED:M${PATTERN" in target "varerror-unclosed-5" diff --git a/contrib/bmake/unit-tests/varmisc.mk b/contrib/bmake/unit-tests/varmisc.mk index b067742e9ac4..e36396633dc2 100644 --- a/contrib/bmake/unit-tests/varmisc.mk +++ b/contrib/bmake/unit-tests/varmisc.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmisc.mk,v 1.37 2024/08/29 20:20:36 rillig Exp $ +# $NetBSD: varmisc.mk,v 1.38 2025/06/28 22:39:29 rillig Exp $ # # Miscellaneous variable tests. @@ -200,7 +200,7 @@ varerror-unclosed-4: # expect: make: Unclosed variable "UNCLOSED" @echo ${UNCLOSED varerror-unclosed-5: -# expect: make: Unclosed expression, expecting '}' for modifier "M${PATTERN" +# expect: make: Unclosed expression, expecting "}" for modifier "M${PATTERN" @echo ${UNCLOSED:M${PATTERN varerror-unclosed-6: # expect: make: Unclosed variable "param" diff --git a/contrib/bmake/unit-tests/varmod-edge.exp b/contrib/bmake/unit-tests/varmod-edge.exp index 2b41623bb66c..b80380fb702c 100644 --- a/contrib/bmake/unit-tests/varmod-edge.exp +++ b/contrib/bmake/unit-tests/varmod-edge.exp @@ -1,8 +1,8 @@ -make: varmod-edge.mk:60: Unclosed expression, expecting '}' for modifier "U*)" +make: varmod-edge.mk:60: Unclosed expression, expecting "}" for modifier "U*)" while evaluating "${:U*)" with value "*)" while evaluating variable "INP" with value "(parentheses)" while evaluating variable "MOD" with value "${INP:M${:U*)}}" -make: varmod-edge.mk:88: Unfinished character list in pattern '[[' of modifier ':M' +make: varmod-edge.mk:88: Unfinished character list in pattern "[[" of modifier ":M" while evaluating variable "INP" with value "[ [[ [[[" while evaluating variable "MOD" with value "${INP:M${:U[[}}" make: varmod-edge.mk:178: Unfinished modifier after "a\=b}", expecting "=" diff --git a/contrib/bmake/unit-tests/varmod-edge.mk b/contrib/bmake/unit-tests/varmod-edge.mk index 473c7ad171e5..b5f879372afd 100644 --- a/contrib/bmake/unit-tests/varmod-edge.mk +++ b/contrib/bmake/unit-tests/varmod-edge.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-edge.mk,v 1.36 2025/03/29 19:08:52 rillig Exp $ +# $NetBSD: varmod-edge.mk,v 1.37 2025/06/28 22:39:29 rillig Exp $ # # Tests for edge cases in variable modifiers. # @@ -56,7 +56,7 @@ EXP= \(\{}\): INP= (parentheses) MOD= ${INP:M${:U*)}} EXP= (parentheses)} -# expect+1: Unclosed expression, expecting '}' for modifier "U*)" +# expect+1: Unclosed expression, expecting "}" for modifier "U*)" .if ${MOD} != ${EXP} . warning expected "${EXP}", got "${MOD}" .endif @@ -84,7 +84,7 @@ EXP= [ INP= [ [[ [[[ MOD= ${INP:M${:U[[}} EXP= [ -# expect+1: Unfinished character list in pattern '[[' of modifier ':M' +# expect+1: Unfinished character list in pattern "[[" of modifier ":M" .if ${MOD} != ${EXP} . warning expected "${EXP}", got "${MOD}" .endif diff --git a/contrib/bmake/unit-tests/varmod-ifelse.exp b/contrib/bmake/unit-tests/varmod-ifelse.exp index 039f0fd0b9a7..bf642c86fc8c 100644 --- a/contrib/bmake/unit-tests/varmod-ifelse.exp +++ b/contrib/bmake/unit-tests/varmod-ifelse.exp @@ -12,26 +12,25 @@ Comparing 1.000000 == 0.000000 make: varmod-ifelse.mk:94: Bad condition while evaluating condition "1 == == 2" Comparing "" != "" -make: varmod-ifelse.mk:98: warning: Oops, the parse error should have been propagated. CondParser_Eval: ${ ${:U\$}{VAR} == value:?ok:bad} != "ok" CondParser_Eval: ${VAR} == value Comparing "value" == "value" Comparing "ok" != "ok" -make: varmod-ifelse.mk:160: no. -make: varmod-ifelse.mk:163: Comparison with '>=' requires both operands 'no' and '10' to be numeric +make: varmod-ifelse.mk:159: no. +make: varmod-ifelse.mk:162: Comparison with ">=" requires both operands "no" and "10" to be numeric while evaluating condition "string == "literal" || no >= 10" -make: varmod-ifelse.mk:163: . -make: varmod-ifelse.mk:170: Bad condition +make: varmod-ifelse.mk:162: . +make: varmod-ifelse.mk:169: Bad condition while evaluating condition "string == "literal" && >= 10" -make: varmod-ifelse.mk:170: . -make: varmod-ifelse.mk:173: Bad condition +make: varmod-ifelse.mk:169: . +make: varmod-ifelse.mk:172: Bad condition while evaluating condition "string == "literal" || >= 10" -make: varmod-ifelse.mk:173: . -make: varmod-ifelse.mk:181: <true> -make: varmod-ifelse.mk:184: <false> -make: varmod-ifelse.mk:188: Bad condition +make: varmod-ifelse.mk:172: . +make: varmod-ifelse.mk:180: <true> +make: varmod-ifelse.mk:183: <false> +make: varmod-ifelse.mk:187: Bad condition while evaluating condition " " -make: varmod-ifelse.mk:188: <> +make: varmod-ifelse.mk:187: <> CondParser_Eval: 0 && ${1:?${:Uthen0:S,}},,}:${:Uelse0:S,}},,}} != "not evaluated" CondParser_Eval: 1 && ${0:?${:Uthen1:S,}},,}:${:Uelse1:S,}},,}} != "else1" CondParser_Eval: 0 @@ -41,31 +40,31 @@ CondParser_Eval: 1 Comparing "then2" != "then2" CondParser_Eval: ${DELAYED} == "one" Comparing "two" == "one" -make: varmod-ifelse.mk:284: no +make: varmod-ifelse.mk:283: no CondParser_Eval: ${DELAYED} == "two" Comparing "two" == "two" -make: varmod-ifelse.mk:286: yes +make: varmod-ifelse.mk:285: yes CondParser_Eval: ${DELAYED} == "one" Comparing "two" == "one" -make: varmod-ifelse.mk:289: no +make: varmod-ifelse.mk:288: no CondParser_Eval: ${DELAYED} == "two" Comparing "two" == "two" -make: varmod-ifelse.mk:292: yes -make: varmod-ifelse.mk:314: Unknown modifier ":X-then" +make: varmod-ifelse.mk:291: yes +make: varmod-ifelse.mk:313: Unknown modifier ":X-then" while evaluating "${:X-then}:${:X-else}}" with value "" while evaluating then-branch of condition "1" -make: varmod-ifelse.mk:314: Unknown modifier ":X-else" +make: varmod-ifelse.mk:313: Unknown modifier ":X-else" while parsing "${:X-else}}" while evaluating else-branch of condition "1" -make: varmod-ifelse.mk:322: Bad condition +make: varmod-ifelse.mk:321: Bad condition while evaluating condition " < 0 " -make: varmod-ifelse.mk:322: Unknown modifier ":Z1" +make: varmod-ifelse.mk:321: Unknown modifier ":Z1" while parsing "${:Z1}:${:Z2}}>" while evaluating then-branch of condition " < 0 " -make: varmod-ifelse.mk:322: Unknown modifier ":Z2" +make: varmod-ifelse.mk:321: Unknown modifier ":Z2" while parsing "${:Z2}}>" while evaluating else-branch of condition " < 0 " -make: varmod-ifelse.mk:322: <> +make: varmod-ifelse.mk:321: <> make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/varmod-ifelse.mk b/contrib/bmake/unit-tests/varmod-ifelse.mk index 986524330a97..fcd483d0c497 100644 --- a/contrib/bmake/unit-tests/varmod-ifelse.mk +++ b/contrib/bmake/unit-tests/varmod-ifelse.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-ifelse.mk,v 1.39 2025/04/30 06:01:07 rillig Exp $ +# $NetBSD: varmod-ifelse.mk,v 1.41 2025/06/29 11:27:21 rillig Exp $ # # Tests for the ${cond:?then:else} variable modifier, which evaluates either # the then-expression or the else-expression, depending on the condition. @@ -73,9 +73,9 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign} . error .endif -# If the "Bad conditional expression" appears in a quoted string literal, the +# If the "Bad condition" appears in a quoted string literal, the # error message "Malformed conditional" is not printed, leaving only the "Bad -# conditional expression". +# condition". # # XXX: The left-hand side is enclosed in quotes. This results in Var_Parse # being called without VARE_EVAL_DEFINED. When ApplyModifier_IfElse @@ -94,8 +94,7 @@ COND:= ${${UNDEF} == "":?bad-assign:bad-assign} .if "${1 == == 2:?yes:no}" != "" . error .else -# expect+1: warning: Oops, the parse error should have been propagated. -. warning Oops, the parse error should have been propagated. +. error .endif .MAKEFLAGS: -d0 @@ -158,7 +157,7 @@ STRING= string NUMBER= no # not really a number # expect+1: no. .info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}. -# expect+2: Comparison with '>=' requires both operands 'no' and '10' to be numeric +# expect+2: Comparison with ">=" requires both operands "no" and "10" to be numeric # expect+1: . .info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}. diff --git a/contrib/bmake/unit-tests/varmod-match-escape.exp b/contrib/bmake/unit-tests/varmod-match-escape.exp index 25d78226345c..42e470310d4c 100755 --- a/contrib/bmake/unit-tests/varmod-match-escape.exp +++ b/contrib/bmake/unit-tests/varmod-match-escape.exp @@ -33,14 +33,18 @@ Comparing ":" != "::" make: varmod-match-escape.mk:43: warning: XXX: Oops Global: .MAKEFLAGS = -r -k -d cv -d Global: .MAKEFLAGS = -r -k -d cv -d 0 -make: varmod-match-escape.mk:69: Dollar followed by nothing +make: varmod-match-escape.mk:63: Unfinished backslash at the end in pattern "\" of modifier ":M" while evaluating "${:U\$:M\$} != """ with value "$" -make: varmod-match-escape.mk:110: Unfinished character list in pattern '[A-]' of modifier ':M' +make: varmod-match-escape.mk:71: Dollar followed by nothing + while evaluating "${:U\$:M\$} != """ with value "$" +make: varmod-match-escape.mk:71: Unfinished backslash at the end in pattern "\" of modifier ":M" + while evaluating "${:U\$:M\$} != """ with value "$" +make: varmod-match-escape.mk:112: Unfinished character list in pattern "[A-]" of modifier ":M" while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]" - in .for loop from varmod-match-escape.mk:107 with pattern = [A-] -make: varmod-match-escape.mk:110: Unfinished character list in pattern '[^A-]' of modifier ':M' + in .for loop from varmod-match-escape.mk:109 with pattern = [A-] +make: varmod-match-escape.mk:112: Unfinished character list in pattern "[^A-]" of modifier ":M" while evaluating variable "WORDS" with value "A A] A]] B B] B]] ] ]] ]]] a a] a]]" - in .for loop from varmod-match-escape.mk:107 with pattern = [^A-] + in .for loop from varmod-match-escape.mk:109 with pattern = [^A-] make: Fatal errors encountered -- cannot continue make: stopped making "all" in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/varmod-match-escape.mk b/contrib/bmake/unit-tests/varmod-match-escape.mk index d9e2009f9b60..5c492d9d1f72 100755 --- a/contrib/bmake/unit-tests/varmod-match-escape.mk +++ b/contrib/bmake/unit-tests/varmod-match-escape.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-match-escape.mk,v 1.18 2024/08/29 20:20:36 rillig Exp $ +# $NetBSD: varmod-match-escape.mk,v 1.20 2025/06/28 22:39:29 rillig Exp $ # # As of 2020-08-01, the :M and :N modifiers interpret backslashes differently, # depending on whether there was an expression somewhere before the @@ -59,13 +59,15 @@ VALUES= : :: :\: # '\{' nor '\}'. But the text is expanded, and a lonely '$' at the end # is silently discarded. The resulting expanded pattern is thus '\', that # is a single backslash. +# expect+1: Unfinished backslash at the end in pattern "\" of modifier ":M" .if ${:U\$:M\$} != "" . error .endif # In lint mode, the case of a lonely '$' is covered with an error message. .MAKEFLAGS: -dL -# expect+1: Dollar followed by nothing +# expect+2: Dollar followed by nothing +# expect+1: Unfinished backslash at the end in pattern "\" of modifier ":M" .if ${:U\$:M\$} != "" . error .endif @@ -105,8 +107,8 @@ EXP.[^A-]]= a EXP.[^A-]]]= a] .for pattern in [A-] [A-]] [A-]]] [^A-] [^A-]] [^A-]]] -# expect+2: Unfinished character list in pattern '[A-]' of modifier ':M' -# expect+1: Unfinished character list in pattern '[^A-]' of modifier ':M' +# expect+2: Unfinished character list in pattern "[A-]" of modifier ":M" +# expect+1: Unfinished character list in pattern "[^A-]" of modifier ":M" . if ${WORDS:M${pattern}} != ${EXP.${pattern}} . warning ${pattern}: ${WORDS:M${pattern}} != ${EXP.${pattern}} . endif diff --git a/contrib/bmake/unit-tests/varmod-match.exp b/contrib/bmake/unit-tests/varmod-match.exp index 14eb7862d815..7bccc4283e32 100644 --- a/contrib/bmake/unit-tests/varmod-match.exp +++ b/contrib/bmake/unit-tests/varmod-match.exp @@ -1,22 +1,22 @@ -make: varmod-match.mk:289: Unfinished character list in pattern 'a[' of modifier ':M' +make: varmod-match.mk:293: Unfinished character list in pattern "a[" of modifier ":M" while evaluating variable "WORDS" with value "a a[" -make: varmod-match.mk:297: Unfinished character list in pattern 'a[^' of modifier ':M' +make: varmod-match.mk:301: Unfinished character list in pattern "a[^" of modifier ":M" while evaluating variable "WORDS" with value "a a[ aX" -make: varmod-match.mk:305: Unfinished character list in pattern '[-x1-3' of modifier ':M' +make: varmod-match.mk:309: Unfinished character list in pattern "[-x1-3" of modifier ":M" while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3" -make: varmod-match.mk:313: Unfinished character list in pattern '*[-x1-3' of modifier ':M' +make: varmod-match.mk:317: Unfinished character list in pattern "*[-x1-3" of modifier ":M" while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3" -make: varmod-match.mk:322: Unfinished character list in pattern '[^-x1-3' of modifier ':M' +make: varmod-match.mk:326: Unfinished character list in pattern "[^-x1-3" of modifier ":M" while evaluating variable "WORDS" with value "- + x xx 0 1 2 3 4 [x1-3" -make: varmod-match.mk:336: Unfinished character list in pattern '?[\' of modifier ':M' +make: varmod-match.mk:340: Unfinished character list in pattern "?[\" of modifier ":M" while evaluating variable "WORDS" with value "\\ \a x\" -make: varmod-match.mk:344: Unfinished character range in pattern '[x-' of modifier ':M' +make: varmod-match.mk:348: Unfinished character range in pattern "[x-" of modifier ":M" while evaluating variable "WORDS" with value "[x- x x- y" -make: varmod-match.mk:356: Unfinished character range in pattern '[^x-' of modifier ':M' +make: varmod-match.mk:360: Unfinished character range in pattern "[^x-" of modifier ":M" while evaluating variable "WORDS" with value "[x- x x- y yyyyy" -make: varmod-match.mk:363: Unfinished character list in pattern '[' of modifier ':M' +make: varmod-match.mk:367: Unfinished character list in pattern "[" of modifier ":M" while evaluating variable " : :: " with value " : :: " -make: varmod-match.mk:363: Unknown modifier ":]" +make: varmod-match.mk:367: Unknown modifier ":]" while evaluating variable " : :: " with value "" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod-match.mk b/contrib/bmake/unit-tests/varmod-match.mk index 99184989fb83..5894196c9cd5 100644 --- a/contrib/bmake/unit-tests/varmod-match.mk +++ b/contrib/bmake/unit-tests/varmod-match.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-match.mk,v 1.30 2025/03/29 19:08:52 rillig Exp $ +# $NetBSD: varmod-match.mk,v 1.32 2025/06/29 09:40:13 rillig Exp $ # # Tests for the ':M' modifier, which keeps only those words that match the # given pattern. @@ -13,8 +13,12 @@ # 6. Error handling # 7. Historical bugs # -# See ApplyModifier_Match, ParseModifier_Match, ModifyWord_Match and -# Str_Match. +# See also: +# char-005c-reverse-solidus.mk +# ApplyModifier_Match +# ParseModifier_Match +# ModifyWord_Match +# Str_Match # 1. Pattern characters '*', '?' and '\' @@ -285,7 +289,7 @@ ${:U*}= asterisk # [ Incomplete empty character list, never matches. WORDS= a a[ -# expect+1: Unfinished character list in pattern 'a[' of modifier ':M' +# expect+1: Unfinished character list in pattern "a[" of modifier ":M" .if ${WORDS:Ma[} != "" . error .endif @@ -293,7 +297,7 @@ WORDS= a a[ # [^ Incomplete negated empty character list, matches any single # character. WORDS= a a[ aX -# expect+1: Unfinished character list in pattern 'a[^' of modifier ':M' +# expect+1: Unfinished character list in pattern "a[^" of modifier ":M" .if ${WORDS:Ma[^} != "a[ aX" . error .endif @@ -301,7 +305,7 @@ WORDS= a a[ aX # [-x1-3 Incomplete character list, matches those elements that can be # parsed without lookahead. WORDS= - + x xx 0 1 2 3 4 [x1-3 -# expect+1: Unfinished character list in pattern '[-x1-3' of modifier ':M' +# expect+1: Unfinished character list in pattern "[-x1-3" of modifier ":M" .if ${WORDS:M[-x1-3} != "- x 1 2 3" . error .endif @@ -309,7 +313,7 @@ WORDS= - + x xx 0 1 2 3 4 [x1-3 # *[-x1-3 Incomplete character list after a wildcard, matches those # words that end with one of the characters from the list. WORDS= - + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3 -# expect+1: Unfinished character list in pattern '*[-x1-3' of modifier ':M' +# expect+1: Unfinished character list in pattern "*[-x1-3" of modifier ":M" .if ${WORDS:M*[-x1-3} != "- x xx 1 2 3 01 11 001 011 101 111 [x1-3" . warning ${WORDS:M*[-x1-3} .endif @@ -318,7 +322,7 @@ WORDS= - + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3 # Incomplete negated character list, matches any character # except those elements that can be parsed without lookahead. WORDS= - + x xx 0 1 2 3 4 [x1-3 -# expect+1: Unfinished character list in pattern '[^-x1-3' of modifier ':M' +# expect+1: Unfinished character list in pattern "[^-x1-3" of modifier ":M" .if ${WORDS:M[^-x1-3} != "+ 0 4" . error .endif @@ -332,7 +336,7 @@ WORDS= - + x xx 0 1 2 3 4 [x1-3 # '\', as there is no following space that could be escaped. WORDS= \\ \a ${:Ux\\} PATTERN= ${:U?[\\} -# expect+1: Unfinished character list in pattern '?[\' of modifier ':M' +# expect+1: Unfinished character list in pattern "?[\" of modifier ":M" .if ${WORDS:M${PATTERN}} != "\\\\ x\\" . error .endif @@ -340,7 +344,7 @@ PATTERN= ${:U?[\\} # [x- Incomplete character list containing an incomplete character # range, matches only the 'x'. WORDS= [x- x x- y -# expect+1: Unfinished character range in pattern '[x-' of modifier ':M' +# expect+1: Unfinished character range in pattern "[x-" of modifier ":M" .if ${WORDS:M[x-} != "x" . error .endif @@ -352,13 +356,13 @@ WORDS= [x- x x- y # XXX: Even matches strings that are longer than a single # character. WORDS= [x- x x- y yyyyy -# expect+1: Unfinished character range in pattern '[^x-' of modifier ':M' +# expect+1: Unfinished character range in pattern "[^x-" of modifier ":M" .if ${WORDS:M[^x-} != "[x- y yyyyy" . error .endif # [:] matches never since the ':' starts the next modifier -# expect+2: Unfinished character list in pattern '[' of modifier ':M' +# expect+2: Unfinished character list in pattern "[" of modifier ":M" # expect+1: Unknown modifier ":]" .if ${ ${:U\:} ${:U\:\:} :L:M[:]} != ":" . error diff --git a/contrib/bmake/unit-tests/varmod-mtime.exp b/contrib/bmake/unit-tests/varmod-mtime.exp index 9960dd877768..53b86b99b867 100644 --- a/contrib/bmake/unit-tests/varmod-mtime.exp +++ b/contrib/bmake/unit-tests/varmod-mtime.exp @@ -1,12 +1,12 @@ -make: varmod-mtime.mk:46: Invalid argument '123x' for modifier ':mtime' +make: varmod-mtime.mk:46: Invalid argument "123x" for modifier ":mtime" while evaluating variable "no/such/file" with value "no/such/file" make: varmod-mtime.mk:68: Cannot determine mtime for "no/such/file1": <ENOENT> while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2" make: varmod-mtime.mk:68: Cannot determine mtime for "no/such/file2": <ENOENT> while evaluating variable "no/such/file1 no/such/file2" with value "no/such/file1 no/such/file2" -make: varmod-mtime.mk:78: Invalid argument 'errorhandler-no' for modifier ':mtime' +make: varmod-mtime.mk:78: Invalid argument "errorhandler-no" for modifier ":mtime" while evaluating variable "MAKEFILE" with value "varmod-mtime.mk" -make: varmod-mtime.mk:86: Invalid argument 'warn' for modifier ':mtime' +make: varmod-mtime.mk:86: Invalid argument "warn" for modifier ":mtime" while evaluating variable "MAKEFILE" with value "varmod-mtime.mk" make: varmod-mtime.mk:110: Unknown modifier ":mtim" while evaluating variable "anything" with value "anything" diff --git a/contrib/bmake/unit-tests/varmod-mtime.mk b/contrib/bmake/unit-tests/varmod-mtime.mk index ec33cd698b41..aed7024efd6b 100644 --- a/contrib/bmake/unit-tests/varmod-mtime.mk +++ b/contrib/bmake/unit-tests/varmod-mtime.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-mtime.mk,v 1.16 2025/06/12 18:51:05 rillig Exp $ +# $NetBSD: varmod-mtime.mk,v 1.17 2025/06/28 22:39:29 rillig Exp $ # # Tests for the ':mtime' variable modifier, which maps each word of the # expression to that file's modification time. @@ -42,7 +42,7 @@ not_found_mtime:= ${no/such/file:L:mtime} # The fallback timestamp must only be an integer, without trailing characters. -# expect+1: Invalid argument '123x' for modifier ':mtime' +# expect+1: Invalid argument "123x" for modifier ":mtime" .if ${no/such/file:L:mtime=123x} . error .else @@ -74,7 +74,7 @@ _!= rm -f ${COOKIE} # Only the word 'error' is a special argument to the ':mtime' modifier, all # other words result in a parse error. -# expect+1: Invalid argument 'errorhandler-no' for modifier ':mtime' +# expect+1: Invalid argument "errorhandler-no" for modifier ":mtime" .if ${MAKEFILE:mtime=errorhandler-no} > 0 .else . error @@ -82,7 +82,7 @@ _!= rm -f ${COOKIE} # Only the word 'error' can be used as a fallback argument to the modifier. -# expect+1: Invalid argument 'warn' for modifier ':mtime' +# expect+1: Invalid argument "warn" for modifier ":mtime" .if ${MAKEFILE:mtime=warn} > 0 . error .else diff --git a/contrib/bmake/unit-tests/varmod-order.exp b/contrib/bmake/unit-tests/varmod-order.exp index f48256c6ae0e..fd18f0e11ee1 100644 --- a/contrib/bmake/unit-tests/varmod-order.exp +++ b/contrib/bmake/unit-tests/varmod-order.exp @@ -2,11 +2,11 @@ make: varmod-order.mk:14: Unknown modifier ":OX" while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten" make: varmod-order.mk:17: Unknown modifier ":OxXX" while evaluating variable "WORDS" with value "one two three four five six seven eight nine ten" -make: varmod-order.mk:20: Unclosed expression, expecting '}' for modifier "O" +make: varmod-order.mk:20: Unclosed expression, expecting "}" for modifier "O" while evaluating variable "WORDS" with value "eight five four nine one seven six ten three two" -make: varmod-order.mk:22: Unclosed expression, expecting '}' for modifier "On" +make: varmod-order.mk:22: Unclosed expression, expecting "}" for modifier "On" while evaluating variable "NUMBERS" with value "1 2 3 4 5 6 7 8 9 10" -make: varmod-order.mk:24: Unclosed expression, expecting '}' for modifier "Onr" +make: varmod-order.mk:24: Unclosed expression, expecting "}" for modifier "Onr" while evaluating variable "NUMBERS" with value "10 9 8 7 6 5 4 3 2 1" make: varmod-order.mk:30: Unknown modifier ":Oxn" while evaluating variable "NUMBERS" with value "8 5 4 9 1 7 6 10 3 2" diff --git a/contrib/bmake/unit-tests/varmod-order.mk b/contrib/bmake/unit-tests/varmod-order.mk index c8386ef951dc..f4fa5d10cdf8 100644 --- a/contrib/bmake/unit-tests/varmod-order.mk +++ b/contrib/bmake/unit-tests/varmod-order.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-order.mk,v 1.19 2025/03/29 23:50:07 rillig Exp $ +# $NetBSD: varmod-order.mk,v 1.20 2025/06/28 22:39:29 rillig Exp $ # # Tests for the :O variable modifier and its variants, which either sort the # words of the value or shuffle them. @@ -16,11 +16,11 @@ _:= ${WORDS:OX} # expect+1: Unknown modifier ":OxXX" _:= ${WORDS:OxXX} -# expect+1: Unclosed expression, expecting '}' for modifier "O" +# expect+1: Unclosed expression, expecting "}" for modifier "O" _:= ${WORDS:O -# expect+1: Unclosed expression, expecting '}' for modifier "On" +# expect+1: Unclosed expression, expecting "}" for modifier "On" _:= ${NUMBERS:On -# expect+1: Unclosed expression, expecting '}' for modifier "Onr" +# expect+1: Unclosed expression, expecting "}" for modifier "Onr" _:= ${NUMBERS:Onr # Shuffling numerically doesn't make sense, so don't allow 'x' and 'n' to be diff --git a/contrib/bmake/unit-tests/varmod-range.exp b/contrib/bmake/unit-tests/varmod-range.exp index 768ba9ac2f2d..b98865a4084a 100644 --- a/contrib/bmake/unit-tests/varmod-range.exp +++ b/contrib/bmake/unit-tests/varmod-range.exp @@ -1,6 +1,6 @@ make: varmod-range.mk:43: Variable "" is undefined while evaluating "${:range=5} != """ with value "1 2 3 4 5" -make: varmod-range.mk:66: Invalid number "x}Rest" != "Rest"" for ':range' modifier +make: varmod-range.mk:66: Invalid number "x}Rest" != "Rest"" for modifier ":range" while evaluating "${:U:range=x}Rest" != "Rest"" with value "" make: varmod-range.mk:76: Unknown modifier ":x0" while evaluating "${:U:range=0x0}Rest" != "Rest"" with value "1" diff --git a/contrib/bmake/unit-tests/varmod-range.mk b/contrib/bmake/unit-tests/varmod-range.mk index 7a60bcc23d86..69dcf6ad1a7d 100644 --- a/contrib/bmake/unit-tests/varmod-range.mk +++ b/contrib/bmake/unit-tests/varmod-range.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-range.mk,v 1.18 2025/04/04 18:57:01 rillig Exp $ +# $NetBSD: varmod-range.mk,v 1.19 2025/06/28 22:39:29 rillig Exp $ # # Tests for the :range variable modifier, which generates sequences # of integers from the given range. @@ -62,7 +62,7 @@ # # Since 2020-11-01, the parser issues a more precise "Invalid number" error # instead. -# expect+1: Invalid number "x}Rest" != "Rest"" for ':range' modifier +# expect+1: Invalid number "x}Rest" != "Rest"" for modifier ":range" .if "${:U:range=x}Rest" != "Rest" . error .else diff --git a/contrib/bmake/unit-tests/varmod.exp b/contrib/bmake/unit-tests/varmod.exp index 09c922aa16bd..022181d05cf1 100644 --- a/contrib/bmake/unit-tests/varmod.exp +++ b/contrib/bmake/unit-tests/varmod.exp @@ -1,47 +1,54 @@ make: varmod.mk:111: To escape a dollar, use \$, not $$, at "$$:L} != """ -make: varmod.mk:111: Invalid variable name ':', at "$:L} != """ +make: varmod.mk:111: Invalid variable name ":", at "$:L} != """ make: varmod.mk:117: Dollar followed by nothing while evaluating "${:Uword:@word@${word}$@} != "word"" with value "word" -make: varmod.mk:127: Missing delimiter ':' after modifier "P" +make: varmod.mk:125: Missing delimiter ":" after modifier "P" while evaluating variable "VAR" with value "VAR" -make: varmod.mk:129: Missing argument for ".error" -make: varmod.mk:135: Invalid modifier ":[99333000222000111000]" +make: varmod.mk:134: Invalid modifier ":[99333000222000111000]" while evaluating variable "word" with value "word" -make: varmod.mk:138: Invalid modifier ":[2147483648]" +make: varmod.mk:137: Invalid modifier ":[2147483648]" while evaluating variable "word" with value "word" -make: varmod.mk:144: Invalid number "99333000222000111000}" for ':range' modifier +make: varmod.mk:143: Invalid number "99333000222000111000}" for modifier ":range" while evaluating variable "word" with value "word" -make: varmod.mk:151: Invalid time value "\" +make: varmod.mk:150: Invalid time value "\" while evaluating indirect modifiers "gmtime=\" while evaluating "${:${:Ugmtime=\\}}" with value "" -make: varmod.mk:166: Dollar followed by nothing +make: varmod.mk:165: Dollar followed by nothing while evaluating variable "VAR" with value "value$" -make: varmod.mk:172: Dollar followed by nothing +make: varmod.mk:171: Dollar followed by nothing while evaluating variable "VAR" with value "value$" -make: varmod.mk:172: Dollar followed by nothing +make: varmod.mk:171: Dollar followed by nothing while evaluating variable "VAR" with value "value$ appended$" -make: varmod.mk:182: Dollar followed by nothing +make: varmod.mk:181: Dollar followed by nothing while evaluating variable "word" with value "word" -make: varmod.mk:186: Invalid modifier ":[$]" +make: varmod.mk:185: Invalid modifier ":[$]" while evaluating variable "word" with value "" -make: varmod.mk:203: Dollar followed by nothing +make: varmod.mk:202: Dollar followed by nothing while evaluating variable "VAR" with value "value$ appended$" -make: varmod.mk:203: Invalid variable name '}', at "$} != "set"" +make: varmod.mk:202: Invalid variable name "}", at "$} != "set"" while evaluating variable "VAR" with value "value<space>appended" -make: varmod.mk:207: Invalid variable name '}', at "$} != "fallback"" +make: varmod.mk:206: Invalid variable name "}", at "$} != "fallback"" while evaluating "${:Ufallback$} != "fallback"" with value "" -make: varmod.mk:211: Invalid time value "1000$" +make: varmod.mk:210: Invalid time value "1000$" while evaluating variable "%y" with value "%y" -make: varmod.mk:217: Invalid time value "1000$" +make: varmod.mk:216: Invalid time value "1000$" while evaluating variable "%y" with value "%y" -make: varmod.mk:223: Dollar followed by nothing +make: varmod.mk:222: Dollar followed by nothing while evaluating variable "word" with value "word" -make: varmod.mk:227: Dollar followed by nothing +make: varmod.mk:226: Dollar followed by nothing while evaluating variable "word" with value "word" -make: varmod.mk:231: Invalid argument 'fallback$' for modifier ':mtime' +make: varmod.mk:230: Invalid argument "fallback$" for modifier ":mtime" while evaluating variable "." with value "." -make: varmod.mk:245: Missing delimiter ':' after modifier "L" +make: varmod.mk:244: Missing delimiter ":" after modifier "L" while evaluating variable "VAR" with value "VAR" +make: varmod.mk:256: Invalid time value " : } \ $ ) \) ( " + while evaluating variable "%Y" with value "%Y" +make: varmod.mk:263: Invalid time value " : \) \ $ " + while evaluating variable "%Y" with value "%Y" +make: varmod.mk:268: Invalid time value " : } \ $ ) \) ( " + while evaluating variable "%Y" with value "%Y" +make: varmod.mk:273: Invalid time value " : \) \ $ " + while evaluating variable "%Y" with value "%Y" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/varmod.mk b/contrib/bmake/unit-tests/varmod.mk index cc7b08c447e9..af976f9d0086 100644 --- a/contrib/bmake/unit-tests/varmod.mk +++ b/contrib/bmake/unit-tests/varmod.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod.mk,v 1.26 2025/03/30 01:27:13 rillig Exp $ +# $NetBSD: varmod.mk,v 1.30 2025/06/29 11:27:21 rillig Exp $ # # Tests for variable modifiers, such as :Q, :S,from,to or :Ufallback. # @@ -107,7 +107,7 @@ DOLLAR2= ${:U\$} # Should it? .MAKEFLAGS: -dL # expect+2: To escape a dollar, use \$, not $$, at "$$:L} != """ -# expect+1: Invalid variable name ':', at "$:L} != """ +# expect+1: Invalid variable name ":", at "$:L} != """ .if ${$$:L} != "" . error .endif @@ -118,14 +118,13 @@ DOLLAR2= ${:U\$} . error .endif -# The variable modifier :P does not fall back to the SysV modifier. +# The modifier :P does not fall back to the SysV modifier. # Therefore the modifier :P=RE generates a parse error. -# XXX: The .error should not be reached since the expression is -# malformed, and this error should be propagated up to Cond_EvalLine. VAR= STOP -# expect+1: Missing delimiter ':' after modifier "P" +# expect+1: Missing delimiter ":" after modifier "P" .if ${VAR:P=RE} != "STORE" -# expect+1: Missing argument for ".error" +. error +.else . error .endif @@ -140,7 +139,7 @@ VAR= STOP # Test the range generation modifier ':range=n' with a very large number that # is larger than SIZE_MAX for any supported platform. -# expect+1: Invalid number "99333000222000111000}" for ':range' modifier +# expect+1: Invalid number "99333000222000111000}" for modifier ":range" .if ${word:L:range=99333000222000111000} .endif @@ -199,11 +198,11 @@ VAR_DOLLAR= VAR$$ . error .endif # expect+2: Dollar followed by nothing -# expect+1: Invalid variable name '}', at "$} != "set"" +# expect+1: Invalid variable name "}", at "$} != "set"" .if ${VAR:Dset$} != "set" . error .endif -# expect+1: Invalid variable name '}', at "$} != "fallback"" +# expect+1: Invalid variable name "}", at "$} != "fallback"" .if ${:Ufallback$} != "fallback" . error .endif @@ -227,7 +226,7 @@ VAR_DOLLAR= VAR$$ .if ${word:L:NX*$} != "word" . error .endif -# expect+1: Invalid argument 'fallback$' for modifier ':mtime' +# expect+1: Invalid argument "fallback$" for modifier ":mtime" .if ${.:L:mtime=fallback$} . error .else @@ -241,10 +240,36 @@ VAR_DOLLAR= VAR$$ .endif .undef VAR -# expect+1: Missing delimiter ':' after modifier "L" +# expect+1: Missing delimiter ":" after modifier "L" .if ${VAR:LAR=ALUE} != "VALUE" . error .endif .if ${VAR:L:AR=ALUE} != "VALUE" . error .endif + + +# When an expression has the usual form ${...} with braces, +# in the part of a modifier, ":}\$" can be escaped using a backslash. +# All other characters are passed through unmodified. +# expect+1: Invalid time value " : } \ $ ) \) ( " +.if ${%Y:L:localtime= \: \} \\ \$ ) \) ( :M*} != ": } \\ \$ ) \\) (" +. error +.endif +# When an expression has the unusual form $(...) with parentheses, +# in the part of a modifier, ":)\$" can be escaped using a backslash. +# All other characters are passed through unmodified. +# expect+1: Invalid time value " : \) \ $ " +.if ${%Y:L:localtime= \: \) \\ \$ } \} { :M*} != ": ) \\ \$ } \\} {" +. error +.endif +# Same when the modifier is the last modifier in an expression. +# expect+1: Invalid time value " : } \ $ ) \) ( " +.if ${%Y:L:localtime= \: \} \\ \$ ) \) ( } != " : } \\ \$ ) \\) ( " +. error +.endif +# Same when the modifier is the last modifier in an expression. +# expect+1: Invalid time value " : \) \ $ " +.if ${%Y:L:localtime= \: \) \\ \$ } \} { } != " : ) \\ \$ } \\} { " +. error +.endif diff --git a/contrib/bmake/unit-tests/varname-circumflex.exp b/contrib/bmake/unit-tests/varname-circumflex.exp new file mode 100644 index 000000000000..184b021fd5e5 --- /dev/null +++ b/contrib/bmake/unit-tests/varname-circumflex.exp @@ -0,0 +1,9 @@ +no_prerequisites: +prerequisite: file1.o +unique: file1.o file2.o file3.o +duplicate: file1.o file2.o file3.o +dir_part: /usr/include /usr/include . +file_part: stdio.h unistd.h foo.h +implicit.tout: implicit.tin +wait: file1.o .WAIT_1 file2.o +exit status 0 diff --git a/contrib/bmake/unit-tests/varname-circumflex.mk b/contrib/bmake/unit-tests/varname-circumflex.mk new file mode 100644 index 000000000000..270f7123781b --- /dev/null +++ b/contrib/bmake/unit-tests/varname-circumflex.mk @@ -0,0 +1,47 @@ +# $NetBSD: varname-circumflex.mk,v 1.1 2025/06/27 20:20:56 rillig Exp $ +# +# Tests for the target-local variable "^", which is required by POSIX 2024 +# and provided by GNU make. + +# TODO: Support $^. + +all: .PHONY +all: no_prerequisites prerequisite +all: unique duplicate +all: dir_part file_part +all: implicit.tout +all: wait + +.if defined(^) +. error +.endif + +no_prerequisites: + @echo $@: $^ + +prerequisite: file1.o + @echo $@: $^ + +unique: file1.o file2.o file3.o + @echo $@: $^ + +duplicate: file1.o file2.o file3.o file3.o + @echo $@: $^ + +dir_part: /usr/include/stdio.h /usr/include/unistd.h foo.h + @echo $@: $(^D) + +file_part: /usr/include/stdio.h /usr/include/unistd.h foo.h + @echo $@: ${^F} + +wait: file1.o .WAIT file2.o + @echo $@: $^ + +.SUFFIXES: +.SUFFIXES: .tin .tout + +.tin.tout: + @echo $@: $^ + +file1.o file2.o file3.o: +/usr/include/stdio.h /usr/include/unistd.h foo.h implicit.tin: diff --git a/contrib/bmake/unit-tests/varname-vpath.exp b/contrib/bmake/unit-tests/varname-vpath.exp index bf7a3036e99d..a750957b92ac 100644 --- a/contrib/bmake/unit-tests/varname-vpath.exp +++ b/contrib/bmake/unit-tests/varname-vpath.exp @@ -1,12 +1,12 @@ CondParser_Eval: !defined(TEST_MAIN) CondParser_Eval: exists(file-in-subdirectory) -exists(file-in-subdirectory) result is "" +"file-in-subdirectory" does not exist CondParser_Eval: exists(file2-in-subdirectory) -exists(file2-in-subdirectory) result is "" +"file2-in-subdirectory" does not exist CondParser_Eval: exists(file-in-subdirectory) -exists(file-in-subdirectory) result is "varname-vpath.dir/file-in-subdirectory" +"file-in-subdirectory" exists in "varname-vpath.dir/file-in-subdirectory" : yes 1 CondParser_Eval: exists(file2-in-subdirectory) -exists(file2-in-subdirectory) result is "varname-vpath.dir2/file2-in-subdirectory" +"file2-in-subdirectory" exists in "varname-vpath.dir2/file2-in-subdirectory" : yes 2 exit status 0 diff --git a/contrib/bmake/unit-tests/varname.exp b/contrib/bmake/unit-tests/varname.exp index d173d2025e9f..454e40cdf9cf 100644 --- a/contrib/bmake/unit-tests/varname.exp +++ b/contrib/bmake/unit-tests/varname.exp @@ -5,13 +5,13 @@ Var_Parse: ${VARNAME} (eval) Global: VAR((( = 3 open parentheses Var_Parse: ${VAR(((}}}}" != "3 open parentheses}}}" (eval) Global: .ALLTARGETS = VAR(((=) -make: varname.mk:31: Missing ')' in archive specification +make: varname.mk:31: Missing ")" in archive specification make: varname.mk:31: Error in archive specification: "VAR" Var_Parse: ${:UVAR\(\(\(}= try2 (eval) Evaluating modifier ${:U...} on value "" (eval, undefined) Result of ${:UVAR\(\(\(} is "VAR\(\(\(" (eval, defined) Global: .ALLTARGETS = VAR(((=) VAR\(\(\(= -make: varname.mk:37: Invalid line '${:UVAR\(\(\(}= try2', expanded to 'VAR\(\(\(= try2' +make: varname.mk:37: Invalid line "${:UVAR\(\(\(}= try2", expanded to "VAR\(\(\(= try2" Var_Parse: ${VARNAME} (eval) Global: VAR((( = try3 Global: .MAKEFLAGS = -r -k -d v -d diff --git a/contrib/bmake/unit-tests/varname.mk b/contrib/bmake/unit-tests/varname.mk index ae18819aa19e..17f29da7ef4c 100644 --- a/contrib/bmake/unit-tests/varname.mk +++ b/contrib/bmake/unit-tests/varname.mk @@ -1,4 +1,4 @@ -# $NetBSD: varname.mk,v 1.17 2025/06/12 04:33:00 rillig Exp $ +# $NetBSD: varname.mk,v 1.18 2025/06/28 22:39:29 rillig Exp $ # # Tests for variable names. @@ -26,14 +26,14 @@ ${VARNAME}= 3 open parentheses # This is not a variable assignment since the parentheses and braces are not # balanced. At the end of the line, there are still 3 levels open, which # means the variable name is not finished. -# expect+2: Missing ')' in archive specification +# expect+2: Missing ")" in archive specification # expect+1: Error in archive specification: "VAR" ${:UVAR(((}= try1 # On the left-hand side of a variable assignments, the backslash is not parsed # as an escape character, therefore the parentheses still count to the nesting # level, which at the end of the line is still 3. Therefore this is not a # variable assignment as well. -# expect+1: Invalid line '${:UVAR\(\(\(}= try2', expanded to 'VAR\(\(\(= try2' +# expect+1: Invalid line "${:UVAR\(\(\(}= try2", expanded to "VAR\(\(\(= try2" ${:UVAR\(\(\(}= try2 # To assign to a variable with an arbitrary name, the variable name has to # come from an external source, not the text that is parsed in the assignment diff --git a/contrib/bmake/unit-tests/varparse-errors.exp b/contrib/bmake/unit-tests/varparse-errors.exp index d4d01c96627e..2a9be069075f 100644 --- a/contrib/bmake/unit-tests/varparse-errors.exp +++ b/contrib/bmake/unit-tests/varparse-errors.exp @@ -12,33 +12,33 @@ make: varparse-errors.mk:73: Unknown modifier ":OX" make: varparse-errors.mk:73: Unknown modifier ":OX" while evaluating "${:OX}" with value "" while evaluating variable "IND" with value "${:OX}" -make: varparse-errors.mk:81: Unclosed expression, expecting '}' for modifier "Q" +make: varparse-errors.mk:81: Unclosed expression, expecting "}" for modifier "Q" while evaluating "${:U:Q" with value "" -make: varparse-errors.mk:83: Unclosed expression, expecting '}' for modifier "sh" +make: varparse-errors.mk:83: Unclosed expression, expecting "}" for modifier "sh" while evaluating "${:U:sh" with value "" -make: varparse-errors.mk:85: Unclosed expression, expecting '}' for modifier "tA" +make: varparse-errors.mk:85: Unclosed expression, expecting "}" for modifier "tA" while evaluating "${:U:tA" with value "" -make: varparse-errors.mk:87: Unclosed expression, expecting '}' for modifier "tsX" +make: varparse-errors.mk:87: Unclosed expression, expecting "}" for modifier "tsX" while evaluating "${:U:tsX" with value "" -make: varparse-errors.mk:89: Unclosed expression, expecting '}' for modifier "ts" +make: varparse-errors.mk:89: Unclosed expression, expecting "}" for modifier "ts" while evaluating "${:U:ts" with value "" -make: varparse-errors.mk:91: Unclosed expression, expecting '}' for modifier "ts\040" +make: varparse-errors.mk:91: Unclosed expression, expecting "}" for modifier "ts\040" while evaluating "${:U:ts\040" with value "" -make: varparse-errors.mk:93: Unclosed expression, expecting '}' for modifier "u" +make: varparse-errors.mk:93: Unclosed expression, expecting "}" for modifier "u" while evaluating "${:U:u" with value "" -make: varparse-errors.mk:95: Unclosed expression, expecting '}' for modifier "H" +make: varparse-errors.mk:95: Unclosed expression, expecting "}" for modifier "H" while evaluating "${:U:H" with value "." -make: varparse-errors.mk:97: Unclosed expression, expecting '}' for modifier "[1]" +make: varparse-errors.mk:97: Unclosed expression, expecting "}" for modifier "[1]" while evaluating "${:U:[1]" with value "" -make: varparse-errors.mk:99: Unclosed expression, expecting '}' for modifier "hash" +make: varparse-errors.mk:99: Unclosed expression, expecting "}" for modifier "hash" while evaluating "${:U:hash" with value "b2af338b" -make: varparse-errors.mk:101: Unclosed expression, expecting '}' for modifier "range" +make: varparse-errors.mk:101: Unclosed expression, expecting "}" for modifier "range" while evaluating "${:U:range" with value "1" -make: varparse-errors.mk:103: Unclosed expression, expecting '}' for modifier "_" +make: varparse-errors.mk:103: Unclosed expression, expecting "}" for modifier "_" while evaluating "${:U:_" with value "" -make: varparse-errors.mk:105: Unclosed expression, expecting '}' for modifier "gmtime" +make: varparse-errors.mk:105: Unclosed expression, expecting "}" for modifier "gmtime" while evaluating "${:U:gmtime" with value "<timestamp>" -make: varparse-errors.mk:107: Unclosed expression, expecting '}' for modifier "localtime" +make: varparse-errors.mk:107: Unclosed expression, expecting "}" for modifier "localtime" while evaluating "${:U:localtime" with value "<timestamp>" make: varparse-errors.tmp:1: Unknown modifier ":Z" while evaluating "${:Z}" with value "" diff --git a/contrib/bmake/unit-tests/varparse-errors.mk b/contrib/bmake/unit-tests/varparse-errors.mk index 2d1142fbb65c..bd74c442e789 100644 --- a/contrib/bmake/unit-tests/varparse-errors.mk +++ b/contrib/bmake/unit-tests/varparse-errors.mk @@ -1,4 +1,4 @@ -# $NetBSD: varparse-errors.mk,v 1.25 2025/05/03 08:18:33 rillig Exp $ +# $NetBSD: varparse-errors.mk,v 1.26 2025/06/28 22:39:29 rillig Exp $ # Tests for parsing and evaluating all kinds of expressions. # @@ -77,33 +77,33 @@ _:= ${:U:OX:U${IND}} ${:U:OX:U${IND}} # Before var.c 1.032 from 2022-08-24, make complained about 'Unknown modifier' # or 'Bad modifier' when in fact the modifier was entirely correct, it was # just not delimited by either ':' or '}' but instead by '\0'. -# expect+1: Unclosed expression, expecting '}' for modifier "Q" +# expect+1: Unclosed expression, expecting "}" for modifier "Q" UNCLOSED:= ${:U:Q -# expect+1: Unclosed expression, expecting '}' for modifier "sh" +# expect+1: Unclosed expression, expecting "}" for modifier "sh" UNCLOSED:= ${:U:sh -# expect+1: Unclosed expression, expecting '}' for modifier "tA" +# expect+1: Unclosed expression, expecting "}" for modifier "tA" UNCLOSED:= ${:U:tA -# expect+1: Unclosed expression, expecting '}' for modifier "tsX" +# expect+1: Unclosed expression, expecting "}" for modifier "tsX" UNCLOSED:= ${:U:tsX -# expect+1: Unclosed expression, expecting '}' for modifier "ts" +# expect+1: Unclosed expression, expecting "}" for modifier "ts" UNCLOSED:= ${:U:ts -# expect+1: Unclosed expression, expecting '}' for modifier "ts\040" +# expect+1: Unclosed expression, expecting "}" for modifier "ts\040" UNCLOSED:= ${:U:ts\040 -# expect+1: Unclosed expression, expecting '}' for modifier "u" +# expect+1: Unclosed expression, expecting "}" for modifier "u" UNCLOSED:= ${:U:u -# expect+1: Unclosed expression, expecting '}' for modifier "H" +# expect+1: Unclosed expression, expecting "}" for modifier "H" UNCLOSED:= ${:U:H -# expect+1: Unclosed expression, expecting '}' for modifier "[1]" +# expect+1: Unclosed expression, expecting "}" for modifier "[1]" UNCLOSED:= ${:U:[1] -# expect+1: Unclosed expression, expecting '}' for modifier "hash" +# expect+1: Unclosed expression, expecting "}" for modifier "hash" UNCLOSED:= ${:U:hash -# expect+1: Unclosed expression, expecting '}' for modifier "range" +# expect+1: Unclosed expression, expecting "}" for modifier "range" UNCLOSED:= ${:U:range -# expect+1: Unclosed expression, expecting '}' for modifier "_" +# expect+1: Unclosed expression, expecting "}" for modifier "_" UNCLOSED:= ${:U:_ -# expect+1: Unclosed expression, expecting '}' for modifier "gmtime" +# expect+1: Unclosed expression, expecting "}" for modifier "gmtime" UNCLOSED:= ${:U:gmtime -# expect+1: Unclosed expression, expecting '}' for modifier "localtime" +# expect+1: Unclosed expression, expecting "}" for modifier "localtime" UNCLOSED:= ${:U:localtime diff --git a/contrib/bmake/var.c b/contrib/bmake/var.c index 55d20bd324ac..66b18f769371 100644 --- a/contrib/bmake/var.c +++ b/contrib/bmake/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.1168 2025/06/13 18:31:08 rillig Exp $ */ +/* $NetBSD: var.c,v 1.1171 2025/06/29 11:02:17 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -143,7 +143,7 @@ #endif /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.1168 2025/06/13 18:31:08 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.1171 2025/06/29 11:02:17 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -452,6 +452,8 @@ VarNew(FStr name, const char *value, static Substring CanonicalVarname(Substring name) { + if (Substring_Equals(name, "^")) + return Substring_InitStr(ALLSRC); if (!(Substring_Length(name) > 0 && name.start[0] == '.')) return name; @@ -471,8 +473,6 @@ CanonicalVarname(Substring name) if (Substring_Equals(name, ".TARGET")) return Substring_InitStr(TARGET); - /* GNU make has an additional alias $^ == ${.ALLSRC}. */ - if (Substring_Equals(name, ".SHELL") && shellPath == NULL) Shell_Init(); @@ -2134,16 +2134,16 @@ typedef enum ApplyModifierResult { } ApplyModifierResult; /* - * Allow backslashes to escape the delimiter, $, and \, but don't touch other + * Allow backslashes to escape the delimiters, $, and \, but don't touch other * backslashes. */ static bool -IsEscapedModifierPart(const char *p, char delim, +IsEscapedModifierPart(const char *p, char end1, char end2, struct ModifyWord_SubstArgs *subst) { if (p[0] != '\\' || p[1] == '\0') return false; - if (p[1] == delim || p[1] == '\\' || p[1] == '$') + if (p[1] == end1 || p[1] == end2 || p[1] == '\\' || p[1] == '$') return true; return p[1] == '&' && subst != NULL; } @@ -2236,7 +2236,7 @@ ParseModifierPart( LazyBuf_Init(part, p); while (*p != '\0' && *p != end1 && *p != end2) { - if (IsEscapedModifierPart(p, end2, subst)) { + if (IsEscapedModifierPart(p, end1, end2, subst)) { LazyBuf_Add(part, p[1]); p += 2; } else if (*p != '$') { /* Unescaped, simple text */ @@ -2703,7 +2703,7 @@ ApplyModifier_Range(const char **pp, ModChain *ch) const char *p = mod + 6; if (!TryParseSize(&p, &n)) { Parse_Error(PARSE_FATAL, - "Invalid number \"%s\" for ':range' modifier", + "Invalid number \"%s\" for modifier \":range\"", mod + 6); return AMR_CLEANUP; } @@ -2834,7 +2834,7 @@ ModifyWord_Match(Substring word, SepBuf *buf, void *data) if (res.error != NULL && !args->error_reported) { args->error_reported = true; Parse_Error(PARSE_FATAL, - "%s in pattern '%s' of modifier '%s'", + "%s in pattern \"%s\" of modifier \"%s\"", res.error, args->pattern, args->neg ? ":N" : ":M"); } if (res.matched != args->neg) @@ -2927,7 +2927,7 @@ ApplyModifier_Mtime(const char **pp, ModChain *ch) invalid_argument: Parse_Error(PARSE_FATAL, - "Invalid argument '%.*s' for modifier ':mtime'", + "Invalid argument \"%.*s\" for modifier \":mtime\"", (int)strcspn(*pp + 1, ":{}()"), *pp + 1); return AMR_CLEANUP; } @@ -2965,7 +2965,7 @@ ApplyModifier_Subst(const char **pp, ModChain *ch) char delim = (*pp)[1]; if (delim == '\0') { Parse_Error(PARSE_FATAL, - "Missing delimiter for modifier ':S'"); + "Missing delimiter for modifier \":S\""); (*pp)++; return AMR_CLEANUP; } @@ -3017,7 +3017,7 @@ ApplyModifier_Regex(const char **pp, ModChain *ch) char delim = (*pp)[1]; if (delim == '\0') { Parse_Error(PARSE_FATAL, - "Missing delimiter for modifier ':C'"); + "Missing delimiter for modifier \":C\""); (*pp)++; return AMR_CLEANUP; } @@ -3995,7 +3995,7 @@ ApplyModifiersIndirect(ModChain *ch, const char **pp) else if (*p == '\0' && ch->endc != '\0') { Parse_Error(PARSE_FATAL, "Unclosed expression after indirect modifier, " - "expecting '%c'", + "expecting \"%c\"", ch->endc); *pp = p; return AMIR_OUT; @@ -4051,14 +4051,14 @@ ApplySingleModifier(const char **pp, ModChain *ch) if (*p == '\0' && ch->endc != '\0') { Parse_Error(PARSE_FATAL, - "Unclosed expression, expecting '%c' for " + "Unclosed expression, expecting \"%c\" for " "modifier \"%.*s\"", ch->endc, (int)(p - mod), mod); } else if (*p == ':') { p++; } else if (opts.strict && *p != '\0' && *p != ch->endc) { Parse_Error(PARSE_FATAL, - "Missing delimiter ':' after modifier \"%.*s\"", + "Missing delimiter \":\" after modifier \"%.*s\"", (int)(p - mod), mod); /* * TODO: propagate parse error to the enclosing @@ -4106,7 +4106,7 @@ ApplyModifiers( if (*p == '\0' && endc != '\0') { Parse_Error(PARSE_FATAL, - "Unclosed expression, expecting '%c'", ch.endc); + "Unclosed expression, expecting \"%c\"", ch.endc); goto cleanup; } @@ -4263,7 +4263,7 @@ IsShortVarnameValid(char varname, const char *start) Parse_Error(PARSE_FATAL, "Dollar followed by nothing"); else if (save_dollars) Parse_Error(PARSE_FATAL, - "Invalid variable name '%c', at \"%s\"", varname, start); + "Invalid variable name \"%c\", at \"%s\"", varname, start); return false; } @@ -4330,7 +4330,7 @@ FindLocalLegacyVar(Substring varname, GNode *scope, return NULL; if (varname.start[1] != 'F' && varname.start[1] != 'D') return NULL; - if (strchr("@%?*!<>", varname.start[0]) == NULL) + if (strchr("@%?*!<>^", varname.start[0]) == NULL) return NULL; v = VarFindSubstring(Substring_Init(varname.start, varname.start + 1), diff --git a/contrib/less/NEWS b/contrib/less/NEWS index 5767ded21a00..cdc8196a5f16 100644 --- a/contrib/less/NEWS +++ b/contrib/less/NEWS @@ -11,6 +11,16 @@ ====================================================================== + Major changes between "less" versions 678 and 679 + +* Fix bad parsing of lesskey file an env var is a prefix of another + env var (github #626). + +* Fix unexpected exit using -K if a key press is received while reading + the input file (github #628). + +====================================================================== + Major changes between "less" versions 668 and 678 * Treat -r in LESS environment variable as -R. diff --git a/contrib/less/decode.c b/contrib/less/decode.c index 2942a30863cb..8e451d1810c9 100644 --- a/contrib/less/decode.c +++ b/contrib/less/decode.c @@ -750,7 +750,7 @@ static int cmd_search(constant char *cmd, constant unsigned char *table, constan { action = taction; *extra = textra; - } else if (match > 0) /* cmd is a prefix of this table entry */ + } else if (match > 0 && action == A_INVALID) /* cmd is a prefix of this table entry */ { action = A_PREFIX; } diff --git a/contrib/less/help.c b/contrib/less/help.c index 81e0943fe4e2..5d8ba9a1b0fe 100644 --- a/contrib/less/help.c +++ b/contrib/less/help.c @@ -1,4 +1,4 @@ -/* This file was generated by mkhelp.pl from less.hlp at 20:41 on 2025/5/1 */ +/* This file was generated by mkhelp.pl from less.hlp at 19:46 on 2025/5/28 */ #include "less.h" constant char helpdata[] = { '\n', diff --git a/contrib/less/less.h b/contrib/less/less.h index 94a3e2235906..7b2d2c25bfc6 100644 --- a/contrib/less/less.h +++ b/contrib/less/less.h @@ -575,10 +575,11 @@ typedef enum { #endif #endif -#define S_INTERRUPT 01 -#define S_STOP 02 -#define S_WINCH 04 -#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP)) +#define S_INTERRUPT (1<<0) +#define S_SWINTERRUPT (1<<1) +#define S_STOP (1<<2) +#define S_WINCH (1<<3) +#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_SWINTERRUPT|S_STOP)) #ifdef EXIT_SUCCESS #define QUIT_OK EXIT_SUCCESS diff --git a/contrib/less/less.nro b/contrib/less/less.nro index 6b74ec5f161b..25a9869a9c59 100644 --- a/contrib/less/less.nro +++ b/contrib/less/less.nro @@ -1,5 +1,5 @@ '\" t -.TH LESS 1 "Version 678: 01 May 2025" +.TH LESS 1 "Version 679: 28 May 2025" .SH NAME less \- display the contents of a file in a terminal .SH SYNOPSIS diff --git a/contrib/less/lessecho.nro b/contrib/less/lessecho.nro index 696fcb13b214..f0cccc4de6da 100644 --- a/contrib/less/lessecho.nro +++ b/contrib/less/lessecho.nro @@ -1,4 +1,4 @@ -.TH LESSECHO 1 "Version 678: 01 May 2025" +.TH LESSECHO 1 "Version 679: 28 May 2025" .SH NAME lessecho \- expand metacharacters .SH SYNOPSIS diff --git a/contrib/less/lesskey.nro b/contrib/less/lesskey.nro index 61ba056b04c6..0a17c9deff71 100644 --- a/contrib/less/lesskey.nro +++ b/contrib/less/lesskey.nro @@ -1,5 +1,5 @@ '\" t -.TH LESSKEY 1 "Version 678: 01 May 2025" +.TH LESSKEY 1 "Version 679: 28 May 2025" .SH NAME lesskey \- customize key bindings for less .SH "SYNOPSIS (deprecated)" diff --git a/contrib/less/os.c b/contrib/less/os.c index 98a7ecf70c3c..357cbb356a16 100644 --- a/contrib/less/os.c +++ b/contrib/less/os.c @@ -275,7 +275,7 @@ start: if (ret != 0) { if (ret == READ_INTR) - sigs |= S_INTERRUPT; + sigs |= S_SWINTERRUPT; reading = FALSE; return (ret); } @@ -287,7 +287,7 @@ start: int c; c = WIN32getch(); - sigs |= S_INTERRUPT; + sigs |= S_SWINTERRUPT; reading = FALSE; if (c != CONTROL('C') && c != intr_char) WIN32ungetch((char) c); @@ -348,7 +348,7 @@ public int iopen(constant char *filename, int flags) while (!opening && SET_JUMP(open_label)) { opening = FALSE; - if (sigs & S_INTERRUPT) + if (sigs & (S_INTERRUPT|S_SWINTERRUPT)) { sigs = 0; #if HAVE_SETTABLE_ERRNO diff --git a/contrib/less/version.c b/contrib/less/version.c index 9a97f1658940..68a42a6272fa 100644 --- a/contrib/less/version.c +++ b/contrib/less/version.c @@ -1047,6 +1047,8 @@ v675 4/3/25 Add ESC-b. v676 4/16/25 Fix two OSC 8 display bugs. v677 4/27/25 Fix & filtering bug. v678 5/1/25 Don't change stty tab setting. +v679 5/28/25 Fix lesskey parsing bug when env var is prefix of another; + fix unexpected exit when using -K. */ -char version[] = "678"; +char version[] = "679"; diff --git a/contrib/tzcode/localtime.c b/contrib/tzcode/localtime.c index 5c3ef7ed47af..a6ec3d8e4e21 100644 --- a/contrib/tzcode/localtime.c +++ b/contrib/tzcode/localtime.c @@ -514,6 +514,8 @@ tzloadbody(char const *name, struct state *sp, bool doextend, return errno; case 0: return 0; + case 1: + break; } } fid = _open(name, O_RDONLY | O_BINARY); diff --git a/lib/libsys/fhopen.2 b/lib/libsys/fhopen.2 index aba53f1dd907..b281ac3d8949 100644 --- a/lib/libsys/fhopen.2 +++ b/lib/libsys/fhopen.2 @@ -31,7 +31,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd April 6, 2025 +.Dd July 20, 2025 .Dt FHOPEN 2 .Os .Sh NAME @@ -140,7 +140,7 @@ is no longer valid. .Xr fstatfs 2 , .Xr getfh 2 , .Xr open 2 , -.Xr named_attribute 9 +.Xr named_attribute 7 .Sh HISTORY The .Fn fhopen , diff --git a/lib/libsys/statfs.2 b/lib/libsys/statfs.2 index 49e8b5120558..ab65def11ebb 100644 --- a/lib/libsys/statfs.2 +++ b/lib/libsys/statfs.2 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 7, 2025 +.Dd July 20, 2025 .Dt STATFS 2 .Os .Sh NAME @@ -127,7 +127,7 @@ Mandatory Access Control (MAC) support for individual objects .Xr mac 4 ) . .It Dv MNT_NAMEDATTR The file system supports named attributes as described in -.Xr named_attribute 9 . +.Xr named_attribute 7 . .It Dv MNT_NFS4ACLS ACLs in NFSv4 variant are supported. .It Dv MNT_NOATIME @@ -264,7 +264,7 @@ each file or directory name or disk label .Sh SEE ALSO .Xr fhstatfs 2 , .Xr getfsstat 2 , -.Xr named_attribute 9 +.Xr named_attribute 7 .Sh HISTORY The .Fn statfs diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3 index 74b85d4aa17e..9dc752f0fd7b 100644 --- a/lib/libusb/libusb.3 +++ b/lib/libusb/libusb.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 13, 2025 +.Dd July 9, 2025 .Dt LIBUSB 3 .Os .Sh NAME @@ -366,6 +366,23 @@ argument is non-zero the feature is enabled. Else disabled. Returns 0 on success and a LIBUSB_ERROR code on failure. +.Pp +.Ft unsigned char * +.Fn libusb_dev_mem_alloc "libusb_device_handle *devh" +This function attempts to allocate a DMA memory block from the given +.Fa devh +so that we can enjoy the zero-copy transfer from kernel. +This function is provided for compatibility and is currently unimplemented and always returns NULL. +.Pp +.Ft int +.Fn libusb_dev_mem_free "libusb_device_handle *devh" "unsigned char *buffer" "size_t size" +This function frees the DMA memory in +.Fa devh +from the given +.Fa buffer +with +.Fa size . +This function is unimplemented and always returns LIBUSB_ERROR_NOT_SUPPORTED. .Sh USB DESCRIPTORS .Ft int .Fn libusb_get_device_descriptor "libusb_device *dev" "libusb_device_descriptor *desc" @@ -775,6 +792,17 @@ argument can be either of LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED or LIBUSB_HOTPLUG_ .Ft void .Fn libusb_hotplug_deregister_callback "libusb_context *ctx" "libusb_hotplug_callback_handle handle" This function unregisters a hotplug filter. +.Pp +.Ft void +.Fn libusb_free_pollfds "const struct libusb_pollfd **pollfds" +This function releases the memory storage in +.Fa pollfds , +and is safe to call when the argument is NULL. +.Pp void * +.Fn libusb_hotplug_get_user_data "struct libusb_context *ctx" "libusb_hotplug_callback_handle callback_handle" +This function returns the user data from the opaque +.Fa callback_handle , +or returns NULL if no matching handle is found. .Sh LIBUSB VERSION 0.1 COMPATIBILITY The library is also compliant with LibUSB version 0.1.12. .Pp diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h index 6fb1c19fad13..1803ff637738 100644 --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -122,6 +122,7 @@ enum libusb_transfer_type { LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1, LIBUSB_TRANSFER_TYPE_BULK = 2, LIBUSB_TRANSFER_TYPE_INTERRUPT = 3, + LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4, }; enum libusb_standard_request { @@ -513,6 +514,9 @@ int libusb_detach_kernel_driver(libusb_device_handle * devh, int interface); int libusb_attach_kernel_driver(libusb_device_handle * devh, int interface); int libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev, int enable); int libusb_set_interface_alt_setting(libusb_device_handle * devh, int interface_number, int alternate_setting); +unsigned char *libusb_dev_mem_alloc(libusb_device_handle *devh); +int libusb_dev_mem_free(libusb_device_handle *devh, unsigned char *buffer, + size_t size); /* USB Descriptors */ @@ -573,7 +577,8 @@ int libusb_handle_events(libusb_context * ctx); int libusb_handle_events_locked(libusb_context * ctx, struct timeval *tv); int libusb_get_next_timeout(libusb_context * ctx, struct timeval *tv); void libusb_set_pollfd_notifiers(libusb_context * ctx, libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, void *user_data); -const struct libusb_pollfd **libusb_get_pollfds(libusb_context * ctx); +const struct libusb_pollfd **libusb_get_pollfds(libusb_context *ctx); +void libusb_free_pollfds(const struct libusb_pollfd **pollfds); /* Synchronous device I/O */ @@ -593,6 +598,8 @@ typedef int (*libusb_hotplug_callback_fn)(libusb_context *ctx, int libusb_hotplug_register_callback(libusb_context *ctx, libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *handle); void libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle handle); +void *libusb_hotplug_get_user_data(struct libusb_context *ctx, + libusb_hotplug_callback_handle callback_handle); /* Streams support */ diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c index 6f1ca877fc28..5c116b39ea17 100644 --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -1530,6 +1530,7 @@ found: libusb20_tr_set_callback(pxfer0, libusb10_isoc_proxy); break; case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: case LIBUSB_TRANSFER_TYPE_INTERRUPT: libusb20_tr_set_callback(pxfer0, libusb10_bulk_intr_proxy); break; @@ -1904,3 +1905,16 @@ libusb_setlocale(const char *locale) return (LIBUSB_ERROR_INVALID_PARAM); } + +unsigned char * +libusb_dev_mem_alloc(libusb_device_handle *devh) +{ + return (NULL); +} + +int +libusb_dev_mem_free(libusb_device_handle *devh, unsigned char *buffer, + size_t size) +{ + return (LIBUSB_ERROR_NOT_SUPPORTED); +} diff --git a/lib/libusb/libusb10_hotplug.c b/lib/libusb/libusb10_hotplug.c index 369539d4512e..9c46d4926bfa 100644 --- a/lib/libusb/libusb10_hotplug.c +++ b/lib/libusb/libusb10_hotplug.c @@ -414,3 +414,21 @@ void libusb_hotplug_deregister_callback(libusb_context *ctx, free(handle); } + +void * +libusb_hotplug_get_user_data(struct libusb_context *ctx, + libusb_hotplug_callback_handle callback_handle) +{ + libusb_hotplug_callback_handle handle; + + ctx = GET_CONTEXT(ctx); + + HOTPLUG_LOCK(ctx); + TAILQ_FOREACH(handle, &ctx->hotplug_cbh, entry) { + if (handle == callback_handle) + break; + } + HOTPLUG_UNLOCK(ctx); + + return (handle); +} diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c index dd541b09caa6..c99586ff650d 100644 --- a/lib/libusb/libusb10_io.c +++ b/lib/libusb/libusb10_io.c @@ -781,6 +781,19 @@ libusb_fill_interrupt_transfer(struct libusb_transfer *transfer, } void +libusb_fill_bulk_stream_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + uint32_t stream_id, unsigned char *buffer, int length, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, + length, callback, user_data, timeout); + transfer->type = LIBUSB_TRANSFER_TYPE_BULK_STREAM; + + libusb_transfer_set_stream_id(transfer, stream_id); +} + +void libusb_fill_iso_transfer(struct libusb_transfer *transfer, libusb_device_handle *devh, uint8_t endpoint, uint8_t *buf, int length, int npacket, libusb_transfer_cb_fn callback, @@ -842,3 +855,12 @@ libusb_transfer_get_stream_id(struct libusb_transfer *transfer) /* get stream ID */ return (sxfer->stream_id); } + +void +libusb_free_pollfds(const struct libusb_pollfd **pollfds) +{ + if (pollfds == NULL) + return; + + free(pollfds); +} diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf index 00f4b718bfad..d502361eca37 100644 --- a/libexec/rc/rc.conf +++ b/libexec/rc/rc.conf @@ -694,7 +694,7 @@ entropy_file="/entropy" # Set to NO to disable late (used when going multi-user) entropy_dir="/var/db/entropy" # Set to NO to disable caching entropy via cron. entropy_save_sz="4096" # Size of the entropy cache files. entropy_save_num="8" # Number of entropy cache files to save. -harvest_mask="511" # Entropy device harvests all but the very invasive sources. +harvest_mask="4607" # Entropy device harvests all but the very invasive sources. # (See 'sysctl kern.random.harvest' and random(4)) osrelease_enable="YES" # Update /var/run/os-release on boot (or NO). osrelease_file="/var/run/os-release" # File to update for os-release. diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 04d17072af77..c6a98b50a165 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -337,7 +337,7 @@ map_object(int fd, const char *path, const struct stat *sb, bool ismain) obj->tlsalign = phtls->p_align; obj->tlspoffset = phtls->p_offset; obj->tlsinitsize = phtls->p_filesz; - obj->tlsinit = mapbase + phtls->p_vaddr; + obj->tlsinit = obj->relocbase + phtls->p_vaddr; } obj->stack_flags = stack_flags; if (note_start < note_end) diff --git a/release/packages/ucl/krb5-all.ucl b/release/packages/ucl/krb5-all.ucl new file mode 100644 index 000000000000..e269aabe1e85 --- /dev/null +++ b/release/packages/ucl/krb5-all.ucl @@ -0,0 +1,4 @@ +comment = "KRB5 Utilities" +desc = <<EOD +KRB5 Utilities +EOD diff --git a/release/packages/ucl/krb5-lib-all.ucl b/release/packages/ucl/krb5-lib-all.ucl new file mode 100644 index 000000000000..854b8a9f85df --- /dev/null +++ b/release/packages/ucl/krb5-lib-all.ucl @@ -0,0 +1,4 @@ +comment = "KRB5 Libraries" +desc = <<EOD +KRB5 Libraries +EOD diff --git a/share/man/man4/sa.4 b/share/man/man4/sa.4 index 96b11ebe5360..699a940a34d1 100644 --- a/share/man/man4/sa.4 +++ b/share/man/man4/sa.4 @@ -457,7 +457,8 @@ One EOM notification will be sent, BPEW status will be set for one position query, and then the driver state will be reset to normal. .Sh SEE ALSO .Xr mt 1 , -.Xr cam 4 +.Xr cam 4 , +.Xr mtio 4 .Sh AUTHORS .An -nosplit The diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index 313f40ad8e51..0f9f8242c5c2 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -299,6 +299,7 @@ nork [label="Norikatsu Shigemura\nnork@FreeBSD.org\n2009/06/09"] np [label="Navdeep Parhar\nnp@FreeBSD.org\n2009/06/05"] nwhitehorn [label="Nathan Whitehorn\nnwhitehorn@FreeBSD.org\n2008/07/03"] n_hibma [label="Nick Hibma\nn_hibma@FreeBSD.org\n1998/11/26"] +obiwac [label="Aymeric Wibo\nobiwac@FreeBSD.org\n2025/07/15"] obrien [label="David E. O'Brien\nobrien@FreeBSD.org\n1996/10/29"] oh [label="Oskar Holmlund\noh@FreeBSD.org\n2021/04/21"] olce [label="Olivier Certner\nolce@FreeBSD.org\n2023/12/01"] @@ -711,6 +712,8 @@ joerg -> schweikh jtl -> ngie jtl -> thj +jrm -> obiwac + julian -> glebius julian -> davidxu julian -> archie @@ -799,6 +802,8 @@ mav -> eugen mav -> freqlabs mav -> ram +mckusick -> obiwac + mdf -> gleb mdodd -> jake diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 14f57ca94ba7..b2bfe633adcc 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -497,8 +497,8 @@ struct kva_layout_s kva_layout_la57 = { .kva_min = KV5ADDR(NPML5EPG / 2, 0, 0, 0, 0), /* == rec_pt */ .dmap_low = KV5ADDR(DMPML5I, 0, 0, 0, 0), .dmap_high = KV5ADDR(DMPML5I + NDMPML5E, 0, 0, 0, 0), - .lm_low = KV4ADDR(LMSPML4I, 0, 0, 0), - .lm_high = KV4ADDR(LMEPML4I + 1, 0, 0, 0), + .lm_low = KV5ADDR(LMSPML5I, 0, 0, 0, 0), + .lm_high = KV5ADDR(LMEPML5I + 1, 0, 0, 0, 0), .km_low = KV4ADDR(KPML4BASE, 0, 0, 0), .km_high = KV4ADDR(KPML4BASE + NKPML4E - 1, NPDPEPG - 1, NPDEPG - 1, NPTEPG - 1), @@ -2475,6 +2475,7 @@ pmap_init(void) struct pmap_preinit_mapping *ppim; vm_page_t m, mpte; pml4_entry_t *pml4e; + unsigned long lm_max; int error, i, ret, skz63; /* L1TF, reserve page @0 unconditionally */ @@ -2600,10 +2601,15 @@ pmap_init(void) lm_ents = 8; TUNABLE_INT_FETCH("vm.pmap.large_map_pml4_entries", &lm_ents); - if (lm_ents > LMEPML4I - LMSPML4I + 1) - lm_ents = LMEPML4I - LMSPML4I + 1; + lm_max = (kva_layout.lm_high - kva_layout.lm_low) / NBPML4; + if (lm_ents > lm_max) { + printf( + "pmap: shrinking large map from requested %d slots to %ld slots\n", + lm_ents, lm_max); + lm_ents = lm_max; + } #ifdef KMSAN - if (lm_ents > KMSANORIGPML4I - LMSPML4I) { + if (!la57 && lm_ents > KMSANORIGPML4I - LMSPML4I) { printf( "pmap: shrinking large map for KMSAN (%d slots to %ld slots)\n", lm_ents, KMSANORIGPML4I - LMSPML4I); @@ -2615,12 +2621,20 @@ pmap_init(void) lm_ents, (u_long)lm_ents * (NBPML4 / 1024 / 1024 / 1024)); if (lm_ents != 0) { large_vmem = vmem_create("large", kva_layout.lm_low, - (vmem_size_t)kva_layout.lm_high - kva_layout.lm_low, - PAGE_SIZE, 0, M_WAITOK); + (vmem_size_t)lm_ents * NBPML4, PAGE_SIZE, 0, M_WAITOK); if (large_vmem == NULL) { printf("pmap: cannot create large map\n"); lm_ents = 0; } + if (la57) { + for (i = 0; i < howmany((vm_offset_t)NBPML4 * + lm_ents, NBPML5); i++) { + m = pmap_large_map_getptp_unlocked(); + kernel_pmap->pm_pmltop[LMSPML5I + i] = X86_PG_V | + X86_PG_RW | X86_PG_A | X86_PG_M | + pg_nx | VM_PAGE_TO_PHYS(m); + } + } for (i = 0; i < lm_ents; i++) { m = pmap_large_map_getptp_unlocked(); pml4e = pmap_pml4e(kernel_pmap, kva_layout.lm_low + @@ -10763,19 +10777,28 @@ pmap_large_map_getptp(void) static pdp_entry_t * pmap_large_map_pdpe(vm_offset_t va) { + pml4_entry_t *pml4; vm_pindex_t pml4_idx; vm_paddr_t mphys; - pml4_idx = pmap_pml4e_index(va); - KASSERT(LMSPML4I <= pml4_idx && pml4_idx < LMSPML4I + lm_ents, - ("pmap_large_map_pdpe: va %#jx out of range idx %#jx LMSPML4I " - "%#jx lm_ents %d", - (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); - KASSERT((kernel_pml4[pml4_idx] & X86_PG_V) != 0, - ("pmap_large_map_pdpe: invalid pml4 for va %#jx idx %#jx " - "LMSPML4I %#jx lm_ents %d", - (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); - mphys = kernel_pml4[pml4_idx] & PG_FRAME; + KASSERT(va >= kva_layout.lm_low && va < kva_layout.lm_low + + (vm_offset_t)NBPML4 * lm_ents, ("va %#lx not in large map", va)); + if (la57) { + pml4 = pmap_pml4e(kernel_pmap, va); + mphys = *pml4 & PG_FRAME; + } else { + pml4_idx = pmap_pml4e_index(va); + + KASSERT(LMSPML4I <= pml4_idx && pml4_idx < LMSPML4I + lm_ents, + ("pmap_large_map_pdpe: va %#jx out of range idx %#jx " + "LMSPML4I %#jx lm_ents %d", + (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); + KASSERT((kernel_pml4[pml4_idx] & X86_PG_V) != 0, + ("pmap_large_map_pdpe: invalid pml4 for va %#jx idx %#jx " + "LMSPML4I %#jx lm_ents %d", + (uintmax_t)va, (uintmax_t)pml4_idx, LMSPML4I, lm_ents)); + mphys = kernel_pml4[pml4_idx] & PG_FRAME; + } return ((pdp_entry_t *)PHYS_TO_DMAP(mphys) + pmap_pdpe_index(va)); } @@ -12144,10 +12167,12 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS) for (sva = 0, i = pmap_pml4e_index(sva); i < NPML4EPG; i++) { switch (i) { case PML4PML4I: - sbuf_printf(sb, "\nRecursive map:\n"); + if (!la57) + sbuf_printf(sb, "\nRecursive map:\n"); break; case DMPML4I: - sbuf_printf(sb, "\nDirect map:\n"); + if (!la57) + sbuf_printf(sb, "\nDirect map:\n"); break; #ifdef KASAN case KASANPML4I: @@ -12166,7 +12191,8 @@ sysctl_kmaps(SYSCTL_HANDLER_ARGS) sbuf_printf(sb, "\nKernel map:\n"); break; case LMSPML4I: - sbuf_printf(sb, "\nLarge map:\n"); + if (!la57) + sbuf_printf(sb, "\nLarge map:\n"); break; } diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index 08e96027a5ed..a0ca97f2d5a0 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -202,9 +202,14 @@ #define KMSANSHADPML4I (KPML4BASE - NKMSANSHADPML4E) #define KMSANORIGPML4I (DMPML4I - NKMSANORIGPML4E) -/* Large map: index of the first and max last pml4 entry */ +/* + * Large map: index of the first and max last pml4/la48 and pml5/la57 + * entry. + */ #define LMSPML4I (PML4PML4I + 1) #define LMEPML4I (KASANPML4I - 1) +#define LMSPML5I (DMPML5I + NDMPML5E) +#define LMEPML5I (LMSPML5I + 32 - 1) /* 32 slots for large map */ /* * XXX doesn't really belong here I guess... diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index e4cc05cbb889..ef352e776af6 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -181,9 +181,9 @@ * 0x0100000000000000 - 0xf0ffffffffffffff does not exist (hole) * 0xff00000000000000 - 0xff00ffffffffffff recursive page table (2048TB slot) * 0xff01000000000000 - 0xff20ffffffffffff direct map (32 x 2048TB slots) - * 0xff21000000000000 - 0xffff807fffffffff unused - * 0xffff808000000000 - 0xffff847fffffffff large map (can be tuned up) - * 0xffff848000000000 - 0xfffff77fffffffff unused (large map extends there) + * 0xff21000000000000 - 0xff40ffffffffffff large map + * 0xff41000000000000 - 0xffff7fffffffffff unused + * 0xffff800000000000 - 0xfffff5ffffffffff unused (start of kernel pml4 entry) * 0xfffff60000000000 - 0xfffff7ffffffffff 2TB KMSAN origin map, optional * 0xfffff78000000000 - 0xfffff7bfffffffff 512GB KASAN shadow map, optional * 0xfffff80000000000 - 0xfffffbffffffffff 4TB unused diff --git a/sys/arm64/broadcom/genet/if_genet.c b/sys/arm64/broadcom/genet/if_genet.c index 0602f076b257..182b5582fb7c 100644 --- a/sys/arm64/broadcom/genet/if_genet.c +++ b/sys/arm64/broadcom/genet/if_genet.c @@ -349,7 +349,7 @@ gen_attach(device_t dev) } /* If address was not found, create one based on the hostid and name. */ - if (eaddr_found == 0) + if (!eaddr_found) ether_gen_addr(sc->ifp, &eaddr); /* Attach ethernet interface */ ether_ifattach(sc->ifp, eaddr.octet); @@ -653,7 +653,7 @@ gen_bus_dma_teardown(struct gen_softc *sc) error); } - if (sc->tx_buf_tag != NULL) { + if (sc->rx_buf_tag != NULL) { for (i = 0; i < RX_DESC_COUNT; i++) { error = bus_dmamap_destroy(sc->rx_buf_tag, sc->rx_ring_ent[i].map); diff --git a/sys/dev/ice/ice_iov.c b/sys/dev/ice/ice_iov.c index e06c7eb56f7a..c5a3e1060e44 100644 --- a/sys/dev/ice/ice_iov.c +++ b/sys/dev/ice/ice_iov.c @@ -345,7 +345,7 @@ ice_iov_add_vf(struct ice_softc *sc, uint16_t vfnum, const nvlist_t *params) if (nvlist_exists_binary(params, "mac-addr")) { mac = nvlist_get_binary(params, "mac-addr", &size); - bcopy(mac, vf->mac, ETHER_ADDR_LEN); + memcpy(vf->mac, mac, ETHER_ADDR_LEN); if (nvlist_get_bool(params, "allow-set-mac")) vf->vf_flags |= VF_FLAG_SET_MAC_CAP; @@ -617,12 +617,14 @@ ice_vc_get_vf_res_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf) { struct ice_hw *hw = &sc->hw; struct virtchnl_vf_resource *vf_res; + struct virtchnl_vsi_resource *vsi_res; u16 vf_res_len; u32 vf_caps; /* XXX: Only support one VSI per VF, so this size doesn't need adjusting */ vf_res_len = sizeof(struct virtchnl_vf_resource); - vf_res = (struct virtchnl_vf_resource *)malloc(vf_res_len, M_ICE, M_WAITOK | M_ZERO); + vf_res = (struct virtchnl_vf_resource *)malloc(vf_res_len, M_ICE, + M_WAITOK | M_ZERO); vf_res->num_vsis = 1; vf_res->num_queue_pairs = vf->vsi->num_tx_queues; @@ -643,10 +645,13 @@ ice_vc_get_vf_res_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf) vf_res->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_WB_ON_ITR; } - vf_res->vsi_res[0].vsi_id = vf->vsi->idx; - vf_res->vsi_res[0].num_queue_pairs = vf->vsi->num_tx_queues; - vf_res->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV; - vf_res->vsi_res[0].qset_handle = 0; + vsi_res = &vf_res->vsi_res[0]; + vsi_res->vsi_id = vf->vsi->idx; + vsi_res->num_queue_pairs = vf->vsi->num_tx_queues; + vsi_res->vsi_type = VIRTCHNL_VSI_SRIOV; + vsi_res->qset_handle = 0; + if (!ETHER_IS_ZERO(vf->mac)) + memcpy(vsi_res->default_mac_addr, vf->mac, ETHER_ADDR_LEN); ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_GET_VF_RESOURCES, VIRTCHNL_STATUS_SUCCESS, (u8 *)vf_res, vf_res_len, NULL); diff --git a/sys/dev/random/fortuna.c b/sys/dev/random/fortuna.c index c4282c723a44..8363de99a60a 100644 --- a/sys/dev/random/fortuna.c +++ b/sys/dev/random/fortuna.c @@ -341,6 +341,13 @@ random_fortuna_process_event(struct harvest_event *event) u_int pl; RANDOM_RESEED_LOCK(); + /* + * Run SP 800-90B health tests on the source if so configured. + */ + if (!random_harvest_healthtest(event)) { + RANDOM_RESEED_UNLOCK(); + return; + } /*- * FS&K - P_i = P_i|<harvested stuff> * Accumulate the event into the appropriate pool diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c index 395310b115fb..c7762967c4fb 100644 --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -88,6 +88,8 @@ static void random_sources_feed(void); static __read_mostly bool epoch_inited; static __read_mostly epoch_t rs_epoch; +static const char *random_source_descr[ENTROPYSOURCE]; + /* * How many events to queue up. We create this many items in * an 'empty' queue, then transfer them to the 'harvest' queue with @@ -299,6 +301,230 @@ random_sources_feed(void) explicit_bzero(entropy, sizeof(entropy)); } +/* + * State used for conducting NIST SP 800-90B health tests on entropy sources. + */ +static struct health_test_softc { + uint32_t ht_rct_value[HARVESTSIZE + 1]; + u_int ht_rct_count; /* number of samples with the same value */ + u_int ht_rct_limit; /* constant after init */ + + uint32_t ht_apt_value[HARVESTSIZE + 1]; + u_int ht_apt_count; /* number of samples with the same value */ + u_int ht_apt_seq; /* sequence number of the last sample */ + u_int ht_apt_cutoff; /* constant after init */ + + uint64_t ht_total_samples; + bool ondemand; /* Set to true to restart the state machine */ + enum { + INIT = 0, /* initial state */ + DISABLED, /* health checking is disabled */ + STARTUP, /* doing startup tests, samples are discarded */ + STEADY, /* steady-state operation */ + FAILED, /* health check failed, discard samples */ + } ht_state; +} healthtest[ENTROPYSOURCE]; + +#define RANDOM_SELFTEST_STARTUP_SAMPLES 1024 /* 4.3, requirement 4 */ +#define RANDOM_SELFTEST_APT_WINDOW 512 /* 4.4.2 */ + +static void +copy_event(uint32_t dst[static HARVESTSIZE + 1], + const struct harvest_event *event) +{ + memset(dst, 0, sizeof(uint32_t) * (HARVESTSIZE + 1)); + memcpy(dst, event->he_entropy, event->he_size); + dst[HARVESTSIZE] = event->he_somecounter; +} + +static void +random_healthtest_rct_init(struct health_test_softc *ht, + const struct harvest_event *event) +{ + ht->ht_rct_count = 1; + copy_event(ht->ht_rct_value, event); +} + +/* + * Apply the repitition count test to a sample. + * + * Return false if the test failed, i.e., we observed >= C consecutive samples + * with the same value, and true otherwise. + */ +static bool +random_healthtest_rct_next(struct health_test_softc *ht, + const struct harvest_event *event) +{ + uint32_t val[HARVESTSIZE + 1]; + + copy_event(val, event); + if (memcmp(val, ht->ht_rct_value, sizeof(ht->ht_rct_value)) != 0) { + ht->ht_rct_count = 1; + memcpy(ht->ht_rct_value, val, sizeof(ht->ht_rct_value)); + return (true); + } else { + ht->ht_rct_count++; + return (ht->ht_rct_count < ht->ht_rct_limit); + } +} + +static void +random_healthtest_apt_init(struct health_test_softc *ht, + const struct harvest_event *event) +{ + ht->ht_apt_count = 1; + ht->ht_apt_seq = 1; + copy_event(ht->ht_apt_value, event); +} + +static bool +random_healthtest_apt_next(struct health_test_softc *ht, + const struct harvest_event *event) +{ + uint32_t val[HARVESTSIZE + 1]; + + if (ht->ht_apt_seq == 0) { + random_healthtest_apt_init(ht, event); + return (true); + } + + copy_event(val, event); + if (memcmp(val, ht->ht_apt_value, sizeof(ht->ht_apt_value)) == 0) { + ht->ht_apt_count++; + if (ht->ht_apt_count >= ht->ht_apt_cutoff) + return (false); + } + + ht->ht_apt_seq++; + if (ht->ht_apt_seq == RANDOM_SELFTEST_APT_WINDOW) + ht->ht_apt_seq = 0; + + return (true); +} + +/* + * Run the health tests for the given event. This is assumed to be called from + * a serialized context. + */ +bool +random_harvest_healthtest(const struct harvest_event *event) +{ + struct health_test_softc *ht; + + ht = &healthtest[event->he_source]; + + /* + * Was on-demand testing requested? Restart the state machine if so, + * restarting the startup tests. + */ + if (atomic_load_bool(&ht->ondemand)) { + atomic_store_bool(&ht->ondemand, false); + ht->ht_state = INIT; + } + + switch (ht->ht_state) { + case __predict_false(INIT): + /* Store the first sample and initialize test state. */ + random_healthtest_rct_init(ht, event); + random_healthtest_apt_init(ht, event); + ht->ht_total_samples = 0; + ht->ht_state = STARTUP; + return (false); + case DISABLED: + /* No health testing for this source. */ + return (true); + case STEADY: + case STARTUP: + ht->ht_total_samples++; + if (random_healthtest_rct_next(ht, event) && + random_healthtest_apt_next(ht, event)) { + if (ht->ht_state == STARTUP && + ht->ht_total_samples >= + RANDOM_SELFTEST_STARTUP_SAMPLES) { + printf( + "random: health test passed for source %s\n", + random_source_descr[event->he_source]); + ht->ht_state = STEADY; + } + return (ht->ht_state == STEADY); + } + ht->ht_state = FAILED; + printf( + "random: health test failed for source %s, discarding samples\n", + random_source_descr[event->he_source]); + /* FALLTHROUGH */ + case FAILED: + return (false); + } +} + +static bool nist_healthtest_enabled = false; +SYSCTL_BOOL(_kern_random, OID_AUTO, nist_healthtest_enabled, + CTLFLAG_RDTUN, &nist_healthtest_enabled, 0, + "Enable NIST SP 800-90B health tests for noise sources"); + +static void +random_healthtest_init(enum random_entropy_source source) +{ + struct health_test_softc *ht; + + ht = &healthtest[source]; + KASSERT(ht->ht_state == INIT, + ("%s: health test state is %d for source %d", + __func__, ht->ht_state, source)); + + /* + * If health-testing is enabled, validate all sources except CACHED and + * VMGENID: they are deterministic sources used only a small, fixed + * number of times, so statistical testing is not applicable. + */ + if (!nist_healthtest_enabled || + source == RANDOM_CACHED || source == RANDOM_PURE_VMGENID) { + ht->ht_state = DISABLED; + return; + } + + /* + * Set cutoff values for the two tests, assuming that each sample has + * min-entropy of 1 bit and allowing for an error rate of 1 in 2^{34}. + * With a sample rate of RANDOM_KTHREAD_HZ, we expect to see an false + * positive once in ~54.5 years. + * + * The RCT limit comes from the formula in section 4.4.1. + * + * The APT cutoff is calculated using the formula in section 4.4.2 + * footnote 10 with the window size changed from 512 to 511, since the + * test as written counts the number of samples equal to the first + * sample in the window, and thus tests W-1 samples. + */ + ht->ht_rct_limit = 35; + ht->ht_apt_cutoff = 330; +} + +static int +random_healthtest_ondemand(SYSCTL_HANDLER_ARGS) +{ + u_int mask, source; + int error; + + mask = 0; + error = sysctl_handle_int(oidp, &mask, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + while (mask != 0) { + source = ffs(mask) - 1; + if (source < nitems(healthtest)) + atomic_store_bool(&healthtest[source].ondemand, true); + mask &= ~(1u << source); + } + return (0); +} +SYSCTL_PROC(_kern_random, OID_AUTO, nist_healthtest_ondemand, + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, + random_healthtest_ondemand, "I", + "Re-run NIST SP 800-90B startup health tests for a noise source"); + static int random_check_uint_harvestmask(SYSCTL_HANDLER_ARGS) { @@ -362,7 +588,8 @@ static const char *random_source_descr[ENTROPYSOURCE] = { [RANDOM_SWI] = "SWI", [RANDOM_FS_ATIME] = "FS_ATIME", [RANDOM_UMA] = "UMA", - [RANDOM_CALLOUT] = "CALLOUT", /* ENVIRONMENTAL_END */ + [RANDOM_CALLOUT] = "CALLOUT", + [RANDOM_RANDOMDEV] = "RANDOMDEV", /* ENVIRONMENTAL_END */ [RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */ [RANDOM_PURE_SAFE] = "PURE_SAFE", [RANDOM_PURE_GLXSB] = "PURE_GLXSB", @@ -424,6 +651,9 @@ random_harvestq_init(void *unused __unused) hc_source_mask = almost_everything_mask; RANDOM_HARVEST_INIT_LOCK(); harvest_context.hc_active_buf = 0; + + for (int i = 0; i < ENTROPYSOURCE; i++) + random_healthtest_init(i); } SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_THIRD, random_harvestq_init, NULL); diff --git a/sys/dev/random/random_harvestq.h b/sys/dev/random/random_harvestq.h index 7804bf52aa4f..1d462500df85 100644 --- a/sys/dev/random/random_harvestq.h +++ b/sys/dev/random/random_harvestq.h @@ -49,4 +49,6 @@ random_get_cyclecount(void) return ((uint32_t)get_cyclecount()); } +bool random_harvest_healthtest(const struct harvest_event *event); + #endif /* SYS_DEV_RANDOM_RANDOM_HARVESTQ_H_INCLUDED */ diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index 9d1c7b1167c8..ced4dd8067d9 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -312,7 +312,7 @@ randomdev_accumulate(uint8_t *buf, u_int count) for (i = 0; i < RANDOM_KEYSIZE_WORDS; i += sizeof(event.he_entropy)/sizeof(event.he_entropy[0])) { event.he_somecounter = random_get_cyclecount(); event.he_size = sizeof(event.he_entropy); - event.he_source = RANDOM_CACHED; + event.he_source = RANDOM_RANDOMDEV; event.he_destination = destination++; /* Harmless cheating */ memcpy(event.he_entropy, entropy_data + i, sizeof(event.he_entropy)); p_random_alg_context->ra_event_processor(&event); diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 4c498e96a3c0..a957315aaa12 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -647,7 +647,8 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap, NFSATTRBIT_TIMECREATE)) NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE); (void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0, - &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL); + &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL, + false, false, false); break; } } @@ -2646,7 +2647,8 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, NFSACL_T *saclp, struct vattr *vap, fhandle_t *fhp, int rderror, nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram, int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno, - struct statfs *pnfssf) + struct statfs *pnfssf, bool xattrsupp, bool has_hiddensystem, + bool has_namedattr) { int bitpos, retnum = 0; u_int32_t *tl; @@ -2660,10 +2662,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, struct nfsfsinfo fsinf; struct timespec temptime; NFSACL_T *aclp, *naclp = NULL; - size_t atsiz; - bool xattrsupp; short irflag; - long has_pathconf; #ifdef QUOTA struct dqblk dqb; uid_t savuid; @@ -2747,18 +2746,6 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, } } - /* Check to see if Extended Attributes are supported. */ - xattrsupp = false; - if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_XATTRSUPPORT)) { - if (NFSVOPLOCK(vp, LK_SHARED) == 0) { - error = VOP_GETEXTATTR(vp, EXTATTR_NAMESPACE_USER, - "xxx", NULL, &atsiz, cred, p); - NFSVOPUNLOCK(vp); - if (error != EOPNOTSUPP) - xattrsupp = true; - } - } - /* * Put out the attribute bitmap for the ones being filled in * and get the field for the number of attributes returned. @@ -2780,11 +2767,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACLSUPPORT); NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACL); } - if (cred == NULL || p == NULL || vp == NULL || - VOP_PATHCONF(vp, _PC_HAS_HIDDENSYSTEM, - &has_pathconf) != 0) - has_pathconf = 0; - if (has_pathconf == 0) { + if (!has_hiddensystem) { NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN); NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM); } @@ -2828,10 +2811,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, break; case NFSATTRBIT_NAMEDATTR: NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - if (VOP_PATHCONF(vp, _PC_HAS_NAMEDATTR, - &has_pathconf) != 0) - has_pathconf = 0; - if (has_pathconf != 0) + if (has_namedattr) *tl = newnfs_true; else *tl = newnfs_false; diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 3b6c1ec90c06..54f60a753c50 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -395,8 +395,9 @@ int nfsrv_putopbit(struct nfsrv_descript *, nfsopbit_t *); void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int, struct nfsvattr *); int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *, - struct vattr *, fhandle_t *, int, nfsattrbit_t *, - struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, struct statfs *); + struct vattr *, fhandle_t *, int, nfsattrbit_t *, struct ucred *, + NFSPROC_T *, int, int, int, int, uint64_t, struct statfs *, bool, bool, + bool); void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *); struct mbuf *nfsrv_adj(struct mbuf *, int, int); void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *); @@ -735,7 +736,8 @@ int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct nfsrv_descript *, NFSPROC_T *); int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *, - struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t); + struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, bool, bool, + bool); int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, NFSACL_T *, NFSPROC_T *); int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index e0e66baca44d..2f3c59b68518 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -5436,7 +5436,8 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucred *cred, NFSPROC_T *p, NFSZERO_ATTRBIT(&attrbits); NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL); (void) nfsv4_fillattr(nd, vp->v_mount, vp, aclp, NULL, NULL, 0, - &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL); + &attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL, false, false, + false); error = nfscl_request(nd, vp, p, cred); if (error) return (error); diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 1ae5ed1a75ca..99a781640c53 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -3701,7 +3701,7 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p) if (!error) (void) nfsv4_fillattr(nd, NULL, NULL, NULL, &va, NULL, 0, &rattrbits, NULL, p, 0, 0, 0, 0, - (uint64_t)0, NULL); + (uint64_t)0, NULL, false, false, false); break; case NFSV4OP_CBRECALL: NFSCL_DEBUG(4, "cbrecall\n"); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 43ee0383669f..4f0d5946d6b9 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2112,7 +2112,8 @@ int nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp, struct nfsvattr *nvap, fhandle_t *fhp, int rderror, nfsattrbit_t *attrbitp, struct ucred *cred, struct thread *p, int isdgram, int reterr, - int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno) + int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno, + bool xattrsupp, bool has_hiddensystem, bool has_namedattr) { struct statfs *sf; int error; @@ -2131,7 +2132,7 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp, } error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror, attrbitp, cred, p, isdgram, reterr, supports_nfsv4acls, at_root, - mounted_on_fileno, sf); + mounted_on_fileno, sf, xattrsupp, has_hiddensystem, has_namedattr); free(sf, M_TEMP); NFSEXITCODE2(0, nd); return (error); @@ -2448,7 +2449,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, struct nfsvattr nva, at, *nvap = &nva; struct mbuf *mb0, *mb1; struct nfsreferral *refp; - int nlen, r, error = 0, getret = 1, usevget = 1; + int nlen, r, error = 0, getret = 1, ret, usevget = 1; int siz, cnt, fullsiz, eofflag, ncookies, entrycnt; caddr_t bpos0, bpos1; u_int64_t off, toff, verf __unused; @@ -2462,6 +2463,9 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, uint64_t mounted_on_fileno; struct thread *p = curthread; int bextpg0, bextpg1, bextpgsiz0, bextpgsiz1; + size_t atsiz; + long pathval; + bool has_hiddensystem, has_namedattr, xattrsupp; if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); @@ -2936,9 +2940,32 @@ again: *tl++ = newnfs_true; txdr_hyper(*cookiep, tl); dirlen += nfsm_strtom(nd, dp->d_name, nlen); + xattrsupp = false; + has_hiddensystem = false; + has_namedattr = false; if (nvp != NULL) { supports_nfsv4acls = nfs_supportsnfsv4acls(nvp); + if (NFSISSET_ATTRBIT(&attrbits, + NFSATTRBIT_XATTRSUPPORT)) { + ret = VOP_GETEXTATTR(nvp, + EXTATTR_NAMESPACE_USER, + "xxx", NULL, &atsiz, + nd->nd_cred, p); + xattrsupp = ret != EOPNOTSUPP; + } + if (VOP_PATHCONF(nvp, + _PC_HAS_HIDDENSYSTEM, &pathval) != + 0) + pathval = 0; + has_hiddensystem = pathval > 0; + pathval = 0; + if (NFSISSET_ATTRBIT(&attrbits, + NFSATTRBIT_NAMEDATTR) && + VOP_PATHCONF(nvp, _PC_HAS_NAMEDATTR, + &pathval) != 0) + pathval = 0; + has_namedattr = pathval > 0; NFSVOPUNLOCK(nvp); } else supports_nfsv4acls = 0; @@ -2958,13 +2985,15 @@ again: nvp, nvap, &nfh, r, &rderrbits, nd->nd_cred, p, isdgram, 0, supports_nfsv4acls, at_root, - mounted_on_fileno); + mounted_on_fileno, xattrsupp, + has_hiddensystem, has_namedattr); } else { dirlen += nfsvno_fillattr(nd, new_mp, nvp, nvap, &nfh, r, &attrbits, nd->nd_cred, p, isdgram, 0, supports_nfsv4acls, at_root, - mounted_on_fileno); + mounted_on_fileno, xattrsupp, + has_hiddensystem, has_namedattr); } if (nvp != NULL) vrele(nvp); @@ -6356,7 +6385,7 @@ nfsrv_setacldsdorpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p, * the same type (VREG). */ nfsv4_fillattr(nd, NULL, vp, aclp, NULL, NULL, 0, &attrbits, NULL, - NULL, 0, 0, 0, 0, 0, NULL); + NULL, 0, 0, 0, 0, 0, NULL, false, false, false); error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); if (error != 0) { diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 3acf07d5253b..9eebcda548c6 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -241,7 +241,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, { struct nfsvattr nva; fhandle_t fh; - int at_root = 0, error = 0, supports_nfsv4acls; + int at_root = 0, error = 0, ret, supports_nfsv4acls; struct nfsreferral *refp; nfsattrbit_t attrbits, tmpbits; struct mount *mp; @@ -250,6 +250,9 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, uint64_t mounted_on_fileno = 0; accmode_t accmode; struct thread *p = curthread; + size_t atsiz; + long pathval; + bool has_hiddensystem, has_namedattr, xattrsupp; if (nd->nd_repstat) goto out; @@ -307,6 +310,26 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, &nva, &attrbits, p); if (nd->nd_repstat == 0) { supports_nfsv4acls = nfs_supportsnfsv4acls(vp); + xattrsupp = false; + if (NFSISSET_ATTRBIT(&attrbits, + NFSATTRBIT_XATTRSUPPORT)) { + ret = VOP_GETEXTATTR(vp, + EXTATTR_NAMESPACE_USER, + "xxx", NULL, &atsiz, nd->nd_cred, + p); + xattrsupp = ret != EOPNOTSUPP; + } + if (VOP_PATHCONF(vp, _PC_HAS_HIDDENSYSTEM, + &pathval) != 0) + pathval = 0; + has_hiddensystem = pathval > 0; + pathval = 0; + if (NFSISSET_ATTRBIT(&attrbits, + NFSATTRBIT_NAMEDATTR) && + VOP_PATHCONF(vp, _PC_HAS_NAMEDATTR, + &pathval) != 0) + pathval = 0; + has_namedattr = pathval > 0; mp = vp->v_mount; if (nfsrv_enable_crossmntpt != 0 && vp->v_type == VDIR && @@ -340,7 +363,9 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, (void)nfsvno_fillattr(nd, mp, vp, &nva, &fh, 0, &attrbits, nd->nd_cred, p, isdgram, 1, supports_nfsv4acls, - at_root, mounted_on_fileno); + at_root, mounted_on_fileno, + xattrsupp, has_hiddensystem, + has_namedattr); vfs_unbusy(mp); } vrele(vp); diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c index 91f8251589e4..b60cdf45af52 100644 --- a/sys/netinet/tcp_hpts.c +++ b/sys/netinet/tcp_hpts.c @@ -433,38 +433,40 @@ static void tcp_hpts_log(struct tcp_hpts_entry *hpts, struct tcpcb *tp, struct timeval *tv, int slots_to_run, int idx, bool from_callout) { - union tcp_log_stackspecific log; - /* - * Unused logs are - * 64 bit - delRate, rttProp, bw_inuse - * 16 bit - cwnd_gain - * 8 bit - bbr_state, bbr_substate, inhpts; - */ - memset(&log, 0, sizeof(log)); - log.u_bbr.flex1 = hpts->p_nxt_slot; - log.u_bbr.flex2 = hpts->p_cur_slot; - log.u_bbr.flex3 = hpts->p_prev_slot; - log.u_bbr.flex4 = idx; - log.u_bbr.flex5 = hpts->p_curtick; - log.u_bbr.flex6 = hpts->p_on_queue_cnt; - log.u_bbr.flex7 = hpts->p_cpu; - log.u_bbr.flex8 = (uint8_t)from_callout; - log.u_bbr.inflight = slots_to_run; - log.u_bbr.applimited = hpts->overidden_sleep; - log.u_bbr.delivered = hpts->saved_curtick; - log.u_bbr.timeStamp = tcp_tv_to_usectick(tv); - log.u_bbr.epoch = hpts->saved_curslot; - log.u_bbr.lt_epoch = hpts->saved_prev_slot; - log.u_bbr.pkts_out = hpts->p_delayed_by; - log.u_bbr.lost = hpts->p_hpts_sleep_time; - log.u_bbr.pacing_gain = hpts->p_cpu; - log.u_bbr.pkt_epoch = hpts->p_runningslot; - log.u_bbr.use_lt_bw = 1; - TCP_LOG_EVENTP(tp, NULL, - &tptosocket(tp)->so_rcv, - &tptosocket(tp)->so_snd, - BBR_LOG_HPTSDIAG, 0, - 0, &log, false, tv); + if (hpts_does_tp_logging && tcp_bblogging_on(tp)) { + union tcp_log_stackspecific log; + /* + * Unused logs are + * 64 bit - delRate, rttProp, bw_inuse + * 16 bit - cwnd_gain + * 8 bit - bbr_state, bbr_substate, inhpts; + */ + memset(&log, 0, sizeof(log)); + log.u_bbr.flex1 = hpts->p_nxt_slot; + log.u_bbr.flex2 = hpts->p_cur_slot; + log.u_bbr.flex3 = hpts->p_prev_slot; + log.u_bbr.flex4 = idx; + log.u_bbr.flex5 = hpts->p_curtick; + log.u_bbr.flex6 = hpts->p_on_queue_cnt; + log.u_bbr.flex7 = hpts->p_cpu; + log.u_bbr.flex8 = (uint8_t)from_callout; + log.u_bbr.inflight = slots_to_run; + log.u_bbr.applimited = hpts->overidden_sleep; + log.u_bbr.delivered = hpts->saved_curtick; + log.u_bbr.timeStamp = tcp_tv_to_usectick(tv); + log.u_bbr.epoch = hpts->saved_curslot; + log.u_bbr.lt_epoch = hpts->saved_prev_slot; + log.u_bbr.pkts_out = hpts->p_delayed_by; + log.u_bbr.lost = hpts->p_hpts_sleep_time; + log.u_bbr.pacing_gain = hpts->p_cpu; + log.u_bbr.pkt_epoch = hpts->p_runningslot; + log.u_bbr.use_lt_bw = 1; + TCP_LOG_EVENTP(tp, NULL, + &tptosocket(tp)->so_rcv, + &tptosocket(tp)->so_snd, + BBR_LOG_HPTSDIAG, 0, + 0, &log, false, tv); + } } static void @@ -1353,10 +1355,7 @@ again: } CURVNET_SET(inp->inp_vnet); /* Lets do any logging that we might want to */ - if (hpts_does_tp_logging && tcp_bblogging_on(tp)) { - tcp_hpts_log(hpts, tp, &tv, slots_to_run, i, - from_callout); - } + tcp_hpts_log(hpts, tp, &tv, slots_to_run, i, from_callout); if (tp->t_fb_ptr != NULL) { kern_prefetch(tp->t_fb_ptr, &did_prefetch); @@ -1487,7 +1486,7 @@ no_run: } void -__tcp_set_hpts(struct tcpcb *tp, int32_t line) +tcp_set_hpts(struct tcpcb *tp) { struct tcp_hpts_entry *hpts; int failed; diff --git a/sys/netinet/tcp_hpts.h b/sys/netinet/tcp_hpts.h index b097a2b98db9..f5856ed8e688 100644 --- a/sys/netinet/tcp_hpts.h +++ b/sys/netinet/tcp_hpts.h @@ -149,8 +149,7 @@ uint32_t tcp_hpts_insert_diag(struct tcpcb *tp, uint32_t slot, int32_t line, #define tcp_hpts_insert(inp, slot) \ tcp_hpts_insert_diag((inp), (slot), __LINE__, NULL) -void __tcp_set_hpts(struct tcpcb *tp, int32_t line); -#define tcp_set_hpts(a) __tcp_set_hpts(a, __LINE__) +void tcp_set_hpts(struct tcpcb *tp); void tcp_set_inp_to_drop(struct inpcb *inp, uint16_t reason); @@ -165,25 +164,25 @@ extern int32_t tcp_min_hptsi_time; * The following functions should also be available * to userspace as well. */ -static __inline uint32_t +static inline uint32_t tcp_tv_to_hptstick(const struct timeval *sv) { return ((sv->tv_sec * 100000) + (sv->tv_usec / HPTS_TICKS_PER_SLOT)); } -static __inline uint32_t +static inline uint32_t tcp_tv_to_usectick(const struct timeval *sv) { return ((uint32_t) ((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); } -static __inline uint32_t +static inline uint32_t tcp_tv_to_mssectick(const struct timeval *sv) { return ((uint32_t) ((sv->tv_sec * HPTS_MSEC_IN_SEC) + (sv->tv_usec/HPTS_USEC_IN_MSEC))); } -static __inline uint64_t +static inline uint64_t tcp_tv_to_lusectick(const struct timeval *sv) { return ((uint64_t)((sv->tv_sec * HPTS_USEC_IN_SEC) + sv->tv_usec)); @@ -199,7 +198,7 @@ get_hpts_min_sleep_time(void) return (tcp_min_hptsi_time + HPTS_TICKS_PER_SLOT); } -static __inline uint32_t +static inline uint32_t tcp_gethptstick(struct timeval *sv) { struct timeval tv; @@ -210,7 +209,7 @@ tcp_gethptstick(struct timeval *sv) return (tcp_tv_to_hptstick(sv)); } -static __inline uint64_t +static inline uint64_t tcp_get_u64_usecs(struct timeval *tv) { struct timeval tvd; @@ -221,7 +220,7 @@ tcp_get_u64_usecs(struct timeval *tv) return (tcp_tv_to_lusectick(tv)); } -static __inline uint32_t +static inline uint32_t tcp_get_usecs(struct timeval *tv) { struct timeval tvd; diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 7c032e13f37a..1f60c0e07b13 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1055,6 +1055,8 @@ findpcb: * socket appended to the listen queue in SYN_RECEIVED state. */ if ((thflags & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK) { + int result; + /* * Parse the TCP options here because * syncookies need access to the reflected @@ -1064,8 +1066,8 @@ findpcb: /* * NB: syncache_expand() doesn't unlock inp. */ - rstreason = syncache_expand(&inc, &to, th, &so, m, port); - if (rstreason < 0) { + result = syncache_expand(&inc, &to, th, &so, m, port); + if (result < 0) { /* * A failing TCP MD5 signature comparison * must result in the segment being dropped @@ -1073,7 +1075,7 @@ findpcb: * to the sender. */ goto dropunlock; - } else if (rstreason == 0) { + } else if (result == 0) { /* * No syncache entry, or ACK was not for our * SYN/ACK. Do our protection against double @@ -1515,7 +1517,9 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, struct tcpopt to; int tfo_syn; u_int maxseg = 0; + bool no_data; + no_data = (tlen == 0); thflags = tcp_get_flags(th); tp->sackhint.last_sack_ack = 0; sack_changed = SACK_NOCHANGE; @@ -1754,7 +1758,7 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, tp->ts_recent = to.to_tsval; } - if (tlen == 0) { + if (no_data) { if (SEQ_GT(th->th_ack, tp->snd_una) && SEQ_LEQ(th->th_ack, tp->snd_max) && !IN_RECOVERY(tp->t_flags) && @@ -2557,7 +2561,7 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th, if (SEQ_LEQ(th->th_ack, tp->snd_una)) { maxseg = tcp_maxseg(tp); - if (tlen == 0 && + if (no_data && (tiwin == tp->snd_wnd || (tp->t_flags & TF_SACK_PERMIT))) { /* @@ -3113,8 +3117,7 @@ step6: (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { /* keep track of pure window updates */ - if (tlen == 0 && - tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) + if (no_data && tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) TCPSTAT_INC(tcps_rcvwinupd); tp->snd_wnd = tiwin; tp->snd_wl1 = th->th_seq; diff --git a/sys/netinet/tcp_log_buf.c b/sys/netinet/tcp_log_buf.c index 75d693bc019b..e24790ece43d 100644 --- a/sys/netinet/tcp_log_buf.c +++ b/sys/netinet/tcp_log_buf.c @@ -2878,7 +2878,7 @@ tcp_log_sendfile(struct socket *so, off_t offset, size_t nbytes, int flags) /* double check log state now that we have the lock */ if (inp->inp_flags & INP_DROPPED) goto done; - if (tp->_t_logstate != TCP_LOG_STATE_OFF) { + if (tcp_bblogging_on(tp)) { struct timeval tv; tcp_log_eventspecific_t log; diff --git a/sys/netinet/tcp_log_buf.h b/sys/netinet/tcp_log_buf.h index fef32e16b2e4..3e7eef8a1cda 100644 --- a/sys/netinet/tcp_log_buf.h +++ b/sys/netinet/tcp_log_buf.h @@ -539,12 +539,12 @@ struct tcpcb; NULL, NULL, 0, NULL); \ } while (0) #endif /* TCP_LOG_FORCEVERBOSE */ +/* Assumes/requires the caller has already checked tcp_bblogging_on(tp). */ #define TCP_LOG_EVENTP(tp, th, rxbuf, txbuf, eventid, errornum, len, stackinfo, th_hostorder, tv) \ do { \ - if (tcp_bblogging_on(tp)) \ - tcp_log_event(tp, th, rxbuf, txbuf, eventid, \ - errornum, len, stackinfo, th_hostorder, \ - NULL, NULL, 0, tv); \ + KASSERT(tcp_bblogging_on(tp), ("bblogging is off")); \ + tcp_log_event(tp, th, rxbuf, txbuf, eventid, errornum, len, \ + stackinfo, th_hostorder, NULL, NULL, 0, tv); \ } while (0) #ifdef TCP_BLACKBOX diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index 8e05498863b9..f52e6fbddfef 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -198,7 +198,7 @@ static uint32_t rack_pcm_blast = 0; static uint32_t rack_pcm_is_enabled = 1; static uint8_t rack_ssthresh_rest_rto_rec = 0; /* Do we restore ssthresh when we have rec -> rto -> rec */ -static uint32_t rack_gp_gain_req = 1200; /* Amount percent wise required to gain to record a round has "gaining" */ +static uint32_t rack_gp_gain_req = 1200; /* Amount percent wise required to gain to record a round as "gaining" */ static uint32_t rack_rnd_cnt_req = 0x10005; /* Default number of rounds if we are below rack_gp_gain_req where we exit ss */ @@ -938,7 +938,7 @@ rack_init_sysctls(void) SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), OID_AUTO, "time_between", CTLFLAG_RW, - & rack_time_between_probertt, 96000000, + &rack_time_between_probertt, 96000000, "How many useconds between the lowest rtt falling must past before we enter probertt"); SYSCTL_ADD_U32(&rack_sysctl_ctx, SYSCTL_CHILDREN(rack_probertt), @@ -3554,8 +3554,7 @@ rack_get_measure_window(struct tcpcb *tp, struct tcp_rack *rack) * earlier. * * So lets calculate the BDP with the "known" b/w using - * the SRTT has our rtt and then multiply it by the - * goal. + * the SRTT as our rtt and then multiply it by the goal. */ bw = rack_get_bw(rack); srtt = (uint64_t)tp->t_srtt; @@ -5793,7 +5792,7 @@ rack_cong_signal(struct tcpcb *tp, uint32_t type, uint32_t ack, int line) tp->t_badrxtwin = 0; break; } - if ((CC_ALGO(tp)->cong_signal != NULL) && + if ((CC_ALGO(tp)->cong_signal != NULL) && (type != CC_RTO)){ tp->t_ccv.curack = ack; CC_ALGO(tp)->cong_signal(&tp->t_ccv, type); @@ -5904,7 +5903,7 @@ rack_calc_thresh_rack(struct tcp_rack *rack, uint32_t srtt, uint32_t cts, int li * * If reorder-fade is configured, then we track the last time we saw * re-ordering occur. If we reach the point where enough time as - * passed we no longer consider reordering has occuring. + * passed we no longer consider reordering as occurring. * * Or if reorder-face is 0, then once we see reordering we consider * the connection to alway be subject to reordering and just set lro @@ -7096,7 +7095,7 @@ rack_merge_rsm(struct tcp_rack *rack, l_rsm->r_flags |= RACK_TLP; if (r_rsm->r_flags & RACK_RWND_COLLAPSED) l_rsm->r_flags |= RACK_RWND_COLLAPSED; - if ((r_rsm->r_flags & RACK_APP_LIMITED) && + if ((r_rsm->r_flags & RACK_APP_LIMITED) && ((l_rsm->r_flags & RACK_APP_LIMITED) == 0)) { /* * If both are app-limited then let the @@ -8137,7 +8136,7 @@ rack_update_rsm(struct tcpcb *tp, struct tcp_rack *rack, * remove the lost desgination and reduce the * bytes considered lost. */ - rsm->r_flags &= ~RACK_WAS_LOST; + rsm->r_flags &= ~RACK_WAS_LOST; KASSERT((rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start)), ("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack)); if (rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start)) @@ -8832,7 +8831,7 @@ rack_apply_updated_usrtt(struct tcp_rack *rack, uint32_t us_rtt, uint32_t us_cts val = rack_probertt_lower_within * rack_time_between_probertt; val /= 100; - if ((rack->in_probe_rtt == 0) && + if ((rack->in_probe_rtt == 0) && (rack->rc_skip_timely == 0) && ((us_cts - rack->r_ctl.rc_lower_rtt_us_cts) >= (rack_time_between_probertt - val))) { rack_enter_probertt(rack, us_cts); @@ -10369,7 +10368,7 @@ more: * and yet before retransmitting we get an ack * which can happen due to reordering. */ - rsm->r_flags &= ~RACK_WAS_LOST; + rsm->r_flags &= ~RACK_WAS_LOST; KASSERT((rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start)), ("rsm:%p rack:%p rc_considered_lost goes negative", rsm, rack)); if (rack->r_ctl.rc_considered_lost >= (rsm->r_end - rsm->r_start)) @@ -11065,7 +11064,7 @@ rack_strike_dupack(struct tcp_rack *rack, tcp_seq th_ack) * We need to skip anything already set * to be retransmitted. */ - if ((rsm->r_dupack >= DUP_ACK_THRESHOLD) || + if ((rsm->r_dupack >= DUP_ACK_THRESHOLD) || (rsm->r_flags & RACK_MUST_RXT)) { rsm = TAILQ_NEXT(rsm, r_tnext); continue; @@ -16919,7 +16918,7 @@ do_output_now: } else if ((nxt_pkt == 0) && (tp->t_flags & TF_ACKNOW)) { goto do_output_now; } else if ((no_output == 1) && - (nxt_pkt == 0) && + (nxt_pkt == 0) && (tcp_in_hpts(rack->rc_tp) == 0)) { /* * We are not in hpts and we had a pacing timer up. Use @@ -17546,7 +17545,7 @@ rack_get_pacing_delay(struct tcp_rack *rack, struct tcpcb *tp, uint32_t len, str rack->r_ctl.rc_last_us_rtt, 88, __LINE__, NULL, gain); } - if (((bw_est == 0) || (rate_wanted == 0) || (rack->gp_ready == 0)) && + if (((bw_est == 0) || (rate_wanted == 0) || (rack->gp_ready == 0)) && (rack->use_fixed_rate == 0)) { /* * No way yet to make a b/w estimate or @@ -20043,7 +20042,7 @@ again: rack->r_ctl.pcm_max_seg = ctf_fixed_maxseg(tp) * 10; } } - if ((rack->r_ctl.pcm_max_seg != 0) && (rack->pcm_needed == 1)) { + if ((rack->r_ctl.pcm_max_seg != 0) && (rack->pcm_needed == 1)) { uint32_t rw_avail, cwa; if (tp->snd_wnd > ctf_outstanding(tp)) @@ -21031,7 +21030,7 @@ just_return_nolock: } else log = 1; } - /* Mark the last packet has app limited */ + /* Mark the last packet as app limited */ rsm = tqhash_max(rack->r_ctl.tqh); if (rsm && ((rsm->r_flags & RACK_APP_LIMITED) == 0)) { if (rack->r_ctl.rc_app_limited_cnt == 0) diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index 06fe9e8820c9..a825658bd9ee 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -234,17 +234,20 @@ static SYSCTL_NODE(_net_inet6_mld, OID_AUTO, ifinfo, CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_mld_ifinfo, "Per-interface MLDv2 state"); -static int mld_v1enable = 1; -SYSCTL_INT(_net_inet6_mld, OID_AUTO, v1enable, CTLFLAG_RWTUN, - &mld_v1enable, 0, "Enable fallback to MLDv1"); +VNET_DEFINE_STATIC(bool, mld_v1enable) = true; +#define V_mld_v1enable VNET(mld_v1enable) +SYSCTL_BOOL(_net_inet6_mld, OID_AUTO, v1enable, CTLFLAG_VNET | CTLFLAG_RWTUN, + &VNET_NAME(mld_v1enable), 0, "Enable fallback to MLDv1"); -static int mld_v2enable = 1; -SYSCTL_INT(_net_inet6_mld, OID_AUTO, v2enable, CTLFLAG_RWTUN, - &mld_v2enable, 0, "Enable MLDv2"); +VNET_DEFINE_STATIC(bool, mld_v2enable) = true; +#define V_mld_v2enable VNET(mld_v2enable) +SYSCTL_BOOL(_net_inet6_mld, OID_AUTO, v2enable, CTLFLAG_VNET | CTLFLAG_RWTUN, + &VNET_NAME(mld_v2enable), 0, "Enable MLDv2"); -static int mld_use_allow = 1; -SYSCTL_INT(_net_inet6_mld, OID_AUTO, use_allow, CTLFLAG_RWTUN, - &mld_use_allow, 0, "Use ALLOW/BLOCK for RFC 4604 SSM joins/leaves"); +VNET_DEFINE_STATIC(bool, mld_use_allow) = true; +#define V_mld_use_allow VNET(mld_use_allow) +SYSCTL_BOOL(_net_inet6_mld, OID_AUTO, use_allow, CTLFLAG_VNET | CTLFLAG_RWTUN, + &VNET_NAME(mld_use_allow), 0, "Use ALLOW/BLOCK for RFC 4604 SSM joins/leaves"); /* * Packed Router Alert option structure declaration. @@ -481,7 +484,7 @@ mld_domifattach(struct ifnet *ifp) mbufq_init(&mli->mli_gq, MLD_MAX_RESPONSE_PACKETS); if ((ifp->if_flags & IFF_MULTICAST) == 0) mli->mli_flags |= MLIF_SILENT; - if (mld_use_allow) + if (V_mld_use_allow) mli->mli_flags |= MLIF_USEALLOW; MLD_LOCK(); @@ -614,7 +617,7 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, is_general_query = 0; - if (!mld_v1enable) { + if (!V_mld_v1enable) { CTR3(KTR_MLD, "ignore v1 query %s on ifp %p(%s)", ip6_sprintf(ip6tbuf, &mld->mld_addr), ifp, if_name(ifp)); @@ -790,7 +793,7 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, NET_EPOCH_ASSERT(); - if (!mld_v2enable) { + if (!V_mld_v2enable) { CTR3(KTR_MLD, "ignore v2 query src %s on ifp %p(%s)", ip6_sprintf(ip6tbuf, &ip6->ip6_src), ifp, if_name(ifp)); @@ -1076,7 +1079,7 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6, NET_EPOCH_ASSERT(); - if (!mld_v1enable) { + if (!V_mld_v1enable) { CTR3(KTR_MLD, "ignore v1 report %s on ifp %p(%s)", ip6_sprintf(ip6tbuf, &mld->mld_addr), ifp, if_name(ifp)); diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c index 9e87af578885..44b63e38a8e6 100644 --- a/sys/rpc/clnt_rc.c +++ b/sys/rpc/clnt_rc.c @@ -198,6 +198,12 @@ clnt_reconnect_connect(CLIENT *cl) newclient = clnt_vc_create(so, (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers, rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr); + /* + * CLSET_FD_CLOSE must be done now, in case rpctls_connect() + * fails just below. + */ + if (newclient != NULL) + CLNT_CONTROL(newclient, CLSET_FD_CLOSE, 0); if (rc->rc_tls && newclient != NULL) { CURVNET_SET(so->so_vnet); stat = rpctls_connect(newclient, rc->rc_tlscertname, so, @@ -236,7 +242,6 @@ clnt_reconnect_connect(CLIENT *cl) goto out; } - CLNT_CONTROL(newclient, CLSET_FD_CLOSE, 0); CLNT_CONTROL(newclient, CLSET_CONNECT, &one); CLNT_CONTROL(newclient, CLSET_TIMEOUT, &rc->rc_timeout); CLNT_CONTROL(newclient, CLSET_RETRY_TIMEOUT, &rc->rc_retry); diff --git a/sys/rpc/rpcsec_gss/rpcsec_gss.c b/sys/rpc/rpcsec_gss/rpcsec_gss.c index 62c71937a185..983dd251f81f 100644 --- a/sys/rpc/rpcsec_gss/rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/rpcsec_gss.c @@ -67,6 +67,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/hash.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/kobj.h> #include <sys/lock.h> @@ -772,6 +773,17 @@ rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret) gd->gd_cred.gc_seq = 0; /* + * XXX Threads from inside jails can get here via calls + * to clnt_vc_call()->AUTH_REFRESH()->rpc_gss_refresh() + * but the NFS mount is always done outside of the + * jails in vnet0. Since the thread credentials won't + * necessarily have cr_prison == vnet0 and this function + * has no access to the socket, using vnet0 seems the + * only option. This is broken if NFS mounts are enabled + * within vnet prisons. + */ + KGSS_CURVNET_SET_QUIET(vnet0); + /* * For KerberosV, if there is a client principal name, that implies * that this is a host based initiator credential in the default * keytab file. For this case, it is necessary to do a @@ -994,12 +1006,14 @@ out: gss_delete_sec_context(&min_stat, &gd->gd_ctx, GSS_C_NO_BUFFER); } + KGSS_CURVNET_RESTORE(); mtx_lock(&gd->gd_lock); gd->gd_state = RPCSEC_GSS_START; wakeup(gd); mtx_unlock(&gd->gd_lock); return (FALSE); } + KGSS_CURVNET_RESTORE(); mtx_lock(&gd->gd_lock); gd->gd_state = RPCSEC_GSS_ESTABLISHED; diff --git a/sys/sys/param.h b/sys/sys/param.h index a8e9635242dd..bd739eacae6f 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -74,7 +74,7 @@ * cannot include sys/param.h and should only be updated here. */ #undef __FreeBSD_version -#define __FreeBSD_version 1500052 +#define __FreeBSD_version 1500053 /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/random.h b/sys/sys/random.h index 254ba9451d0a..5abf762cd200 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -85,7 +85,8 @@ enum random_entropy_source { RANDOM_FS_ATIME, RANDOM_UMA, /* Special!! UMA/SLAB Allocator */ RANDOM_CALLOUT, - RANDOM_ENVIRONMENTAL_END = RANDOM_CALLOUT, + RANDOM_RANDOMDEV, + RANDOM_ENVIRONMENTAL_END = RANDOM_RANDOMDEV, /* Fast hardware random-number sources from here on. */ RANDOM_PURE_START, RANDOM_PURE_OCTEON = RANDOM_PURE_START, diff --git a/tools/test/stress2/misc/fullpath2.sh b/tools/test/stress2/misc/fullpath2.sh index f0037851482d..413f832420d4 100755 --- a/tools/test/stress2/misc/fullpath2.sh +++ b/tools/test/stress2/misc/fullpath2.sh @@ -123,7 +123,7 @@ static volatile u_int *share; #define NB 1024 #define RUNTIME 300 -/* dtrace -w -n 'fbt::*vn_fullpath:entry {@rw[execname,probefunc] = count(); }' */ +/* dtrace -n 'fbt::vn_fullpath:entry {@rw[execname,probefunc] = count(); }' */ static void getfiles(pid_t pid) diff --git a/usr.bin/bmake/Makefile.config b/usr.bin/bmake/Makefile.config index 78babc2f1382..8ff6c81b8c78 100644 --- a/usr.bin/bmake/Makefile.config +++ b/usr.bin/bmake/Makefile.config @@ -6,7 +6,7 @@ SRCTOP?= ${.CURDIR:H:H} # things set by configure -_MAKE_VERSION?=20250618 +_MAKE_VERSION?=20250707 prefix?= /usr srcdir= ${SRCTOP}/contrib/bmake diff --git a/usr.bin/bmake/unit-tests/Makefile b/usr.bin/bmake/unit-tests/Makefile index 1b9a47febe11..d4ee6f33f862 100644 --- a/usr.bin/bmake/unit-tests/Makefile +++ b/usr.bin/bmake/unit-tests/Makefile @@ -1,9 +1,9 @@ # This is a generated file, do NOT edit! # See contrib/bmake/bsd.after-import.mk # -# $Id: Makefile,v 1.239 2025/06/15 21:32:16 sjg Exp $ +# $Id: Makefile,v 1.240 2025/06/30 18:40:54 sjg Exp $ # -# $NetBSD: Makefile,v 1.367 2025/06/13 20:23:16 rillig Exp $ +# $NetBSD: Makefile,v 1.369 2025/06/29 09:40:13 rillig Exp $ # # Unit tests for make(1) # @@ -61,6 +61,7 @@ rm-tmpdir: .NOMETA # src/tests/usr.bin/make/t_make.sh as well. #TESTS+= archive #TESTS+= archive-suffix +TESTS+= char-005c-reverse-solidus TESTS+= cmd-errors TESTS+= cmd-errors-jobs TESTS+= cmd-errors-lint @@ -416,6 +417,7 @@ TESTS+= varmod-to-upper TESTS+= varmod-undefined TESTS+= varmod-unique TESTS+= varname +TESTS+= varname-circumflex TESTS+= varname-dollar TESTS+= varname-dot-alltargets TESTS+= varname-dot-curdir @@ -544,7 +546,6 @@ TESTS:= ${TESTS:${BROKEN_TESTS:S,^,N,:ts:}} # Ideas for more tests: # char-0020-space.mk -# char-005C-backslash.mk # escape-cond-str.mk # escape-cond-func-arg.mk # escape-varmod.mk diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index 0b1a37f43723..1ca63b371f65 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -259,6 +259,7 @@ 06/11 Alonso Cardenas Marquez <acm@FreeBSD.org> born in Arequipa, Peru, 1979 06/14 Josh Paetzel <jpaetzel@FreeBSD.org> born in Minneapolis, Minnesota, United States, 1973 06/15 Second quarterly status reports are due on 06/30 +06/15 Aymeric Wibo <obiwac@FreeBSD.org> born in Plaistow, London, United Kingdom, 2004 06/17 Tilman Linneweh <arved@FreeBSD.org> born in Weinheim, Baden-Wuerttemberg, Germany, 1978 06/18 Li-Wen Hsu <lwhsu@FreeBSD.org> born in Taipei, Taiwan, Republic of China, 1984 06/18 Roman Bogorodskiy <novel@FreeBSD.org> born in Saratov, Russian Federation, 1986 diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh index ec20fc813bf4..18595042da5f 100755 --- a/usr.bin/man/man.sh +++ b/usr.bin/man/man.sh @@ -313,6 +313,8 @@ manpath_warnings() { # redirected to another source file. man_check_for_so() { local IFS line tstr + local counter_so=0 + local counter_so_limit=32 unset IFS if [ -n "$catpage" ]; then @@ -320,13 +322,16 @@ man_check_for_so() { fi # We need to loop to accommodate multiple .so directives. - while true + while [ $counter_so -lt $counter_so_limit ] do + counter_so=$((counter_so + 1)) + line=$($cattool "$manpage" 2>/dev/null | grep -E -m1 -v '^\.\\"[ ]*|^[ ]*$') case "$line" in '.so /'*) break ;; # ignore absolute path '.so '*) trim "${line#.so}" - decho "$manpage includes $tstr" + decho "$manpage includes $tstri level=$counter_so" + # Glob and check for the file. if ! check_man "$1/$tstr" ""; then decho " Unable to find $tstr" @@ -337,6 +342,10 @@ man_check_for_so() { esac done + if [ $counter_so -ge $counter_so_limit ]; then + decho ".so include limit of $counter_so_limit reached, stop" + fi + return 0 } diff --git a/usr.sbin/trim/trim.8 b/usr.sbin/trim/trim.8 index 1ac10d7e3d46..a4874c54c183 100644 --- a/usr.sbin/trim/trim.8 +++ b/usr.sbin/trim/trim.8 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd January 18, 2019 +.Dd July 20, 2025 .Dt TRIM 8 .Os .Sh NAME @@ -36,7 +36,7 @@ .Bk -words .Sm off .Ar offset -.Op Cm K | k | M | m | G | g | T | t ] +.Op Cm K | k | M | m | G | g | T | t | P | p | E | e ] .Sm on .Xc .Ek @@ -68,13 +68,13 @@ Overrides .It Fl l Xo .Sm off .Ar offset -.Op Cm K | k | M | m | G | g | T | t +.Op Cm K | k | M | m | G | g | T | t | P | p | E | e .Sm on .Xc .It Fl o Xo .Sm off .Ar offset -.Op Cm K | k | M | m | G | g | T | t +.Op Cm K | k | M | m | G | g | T | t | P | p | E | e .Sm on .Xc Specify the length @@ -88,12 +88,14 @@ unless one or both of these options are presented. The argument may be suffixed with one of .Cm K , .Cm M , -.Cm G +.Cm G , +.Cm T , +.Cm P or -.Cm T +.Cm E (either upper or lower case) to indicate a multiple of -Kilobytes, Megabytes, Gigabytes or Terabytes -respectively. +Kilobytes, Megabytes, Gigabytes, Terabytes, Petabytes or +Exabytes, respectively. .It Fl q Do not output anything except of possible error messages (quiet mode). Overrides diff --git a/usr.sbin/trim/trim.c b/usr.sbin/trim/trim.c index 3e187faa0fb3..27f57ac2fb72 100644 --- a/usr.sbin/trim/trim.c +++ b/usr.sbin/trim/trim.c @@ -114,7 +114,7 @@ main(int argc, char **argv) * * trim -f -- /dev/da0 -r rfile */ - + if (strcmp(argv[optind-1], "--") != 0) { for (ch = optind; ch < argc; ch++) if (argv[ch][0] == '-') @@ -127,6 +127,9 @@ main(int argc, char **argv) if (argc < 1) usage(name); + if (dryrun) + printf("dry run: add -f to actually perform the operation\n"); + while ((fname = *argv++) != NULL) if (trim(fname, offset, length, dryrun, verbose) < 0) error++; @@ -213,10 +216,8 @@ trim(const char *path, off_t offset, off_t length, bool dryrun, bool verbose) printf("trim %s offset %ju length %ju\n", path, (uintmax_t)offset, (uintmax_t)length); - if (dryrun) { - printf("dry run: add -f to actually perform the operation\n"); + if (dryrun) return (0); - } fd = opendev(path, O_RDWR | O_DIRECT); arg[0] = offset; @@ -237,7 +238,7 @@ static void usage(const char *name) { (void)fprintf(stderr, - "usage: %s [-[lo] offset[K|k|M|m|G|g|T|t]] [-r rfile] [-Nfqv] device ...\n", + "usage: %s [-[lo] offset[K|k|M|m|G|g|T|t|P|p|E|e]] [-r rfile] [-Nfqv] device ...\n", name); exit(EX_USAGE); } |