Take care of some corner-cases of non-const tracking.

This commit is contained in:
Dianne Skoll
2025-05-22 09:35:18 -04:00
parent 633812d961
commit 1d3c1f006f
8 changed files with 74 additions and 0 deletions

View File

@@ -1761,6 +1761,8 @@ static void GenerateCalEntries(int col)
tok.type != T_Else &&
tok.type != T_EndIf &&
tok.type != T_IfTrig &&
tok.type != T_Set &&
tok.type != T_Fset &&
should_ignore_line())
{
/* DO NOTHING */

View File

@@ -747,6 +747,10 @@ eval_userfunc(expr_node *node, Value *locals, Value *ans, int *nonconst)
FuncRecursionLevel++;
if (!f->is_constant) {
nonconst_debug(*nonconst, tr("User function `%s' defined in non-constant context makes expression non-constant"), f->name);
*nonconst = 1;
}
/* Add a call to the call stack for better error messages */
pushed = push_call(f->filename, f->name, f->lineno, f->lineno_start);

View File

@@ -287,6 +287,8 @@ static void DoReminders(void)
tok.type != T_Else &&
tok.type != T_EndIf &&
tok.type != T_IfTrig &&
tok.type != T_Set &&
tok.type != T_Fset &&
should_ignore_line())
{
/*** IGNORE THE LINE ***/

View File

@@ -296,6 +296,7 @@ typedef struct {
typedef struct udf_struct {
struct hash_link link;
char name[VAR_NAME_LEN+1];
char is_constant;
expr_node *node;
char **args;
int nargs;

View File

@@ -196,6 +196,20 @@ int DoFset(ParsePtr p)
/* Convert to lower-case */
strtolower(DBufValue(&buf));
/* If we're ignoring the line, just update is_constant flag if needed */
if (should_ignore_line()) {
if (in_constant_context()) {
DBufFree(&buf);
return OK;
}
existing = FindUserFunc(DBufValue(&buf));
if (existing) {
nonconst_debug(!existing->is_constant, tr("Function definition considered non-constant because of context"));
existing->is_constant = 0;
}
DBufFree(&buf);
return OK;
}
/* If the function exists and was defined at the same line of the same
file, do nothing */
existing = FindUserFunc(DBufValue(&buf));
@@ -240,6 +254,12 @@ int DoFset(ParsePtr p)
func->lineno = LineNo;
func->lineno_start = LineNoStart;
func->recurse_flag = 0;
if (in_constant_context()) {
func->is_constant = 1;
} else {
nonconst_debug(0, tr("Function definition considered non-constant because of context"));
func->is_constant = 0;
}
StrnCpy(func->name, DBufValue(&buf), VAR_NAME_LEN);
DBufFree(&buf);
if (!Hush) {

View File

@@ -604,14 +604,31 @@ int DoSet (Parser *p)
Value v;
int r;
int ch;
int ignoring = should_ignore_line();
DynamicBuffer buf;
DynamicBuffer buf2;
DBufInit(&buf);
DBufInit(&buf2);
Var *var;
r = ParseIdentifier(p, &buf);
if (r) return r;
if (ignoring) {
/* We're only here to mark a variable as non-const */
if (in_constant_context()) {
DBufFree(&buf);
return OK;
}
var = FindVar(DBufValue(&buf), 0);
if (var) {
nonconst_debug(var->nonconstant, tr("Variable assignment considered non-constant because of context"));
var->nonconstant = 1;
}
DBufFree(&buf);
return OK;
}
/* Allow optional equals-sign: SET var = value */
ch = ParseNonSpaceChar(p, &r, 1);
if (r) return r;

View File

@@ -24813,6 +24813,7 @@ TRANSLATE "Executing `%s' for INCLUDECMD and caching as `%s'" ""
TRANSLATE "Found cached directory listing for `%s'" ""
TRANSLATE "Function `%s' defined at %s(%s) should take %d argument%s, but actually takes %d" ""
TRANSLATE "Function `%s' redefined: previously defined at %s(%s)" ""
TRANSLATE "Function definition considered non-constant because of context" ""
TRANSLATE "GetValidHebDate: Bad adarbehave value %d" ""
TRANSLATE "Global variable `%s' makes expression non-constant" ""
TRANSLATE "In" ""
@@ -24841,6 +24842,7 @@ TRANSLATE "System variable `$%s' makes expression non-constant" ""
TRANSLATE "Undefined %s function: `%s'" ""
TRANSLATE "Unmatched PUSH-OMIT-CONTEXT at %s(%d)" ""
TRANSLATE "Unrecognized command; interpreting as REM" ""
TRANSLATE "User function `%s' defined in non-constant context makes expression non-constant" ""
TRANSLATE "Variable assignment considered non-constant because of context" ""
TRANSLATE "Warning: Function name `%s...' truncated to `%s'" ""
TRANSLATE "Warning: OMIT is ignored if you use OMITFUNC" ""

View File

@@ -1532,6 +1532,32 @@ REM SCANFROM -7 MSG foo
REM MSG [g(3)]
# Check user-functions for constant-ness
FUNSET f
IF today() > '1990-01-01'
FSET f(x) 2
ELSE
FSET f(x) 3
ENDIF
SET a f(1)
FUNSET f
FSET f(x) '1990-01-01'
IF today() < '1990-01-01'
FSET f(x) '2025-12-31'
ENDIF
set a f(1)
FUNSET F
SET a 1
IF today() < '1990-01-01'
SET a 2
ENDIF
dump -c a
DEBUG -n
DEBUG -e