mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Document all the non-constant tracking machinery.
This commit is contained in:
@@ -3649,6 +3649,14 @@ As an example, the following two expressions are equivalent:
|
||||
.fi
|
||||
.RE
|
||||
.TP
|
||||
.B isconst(x_any)
|
||||
Evaluates its argument and then \fIthrows away\fR the value, returning
|
||||
1 if the expression is constant or 0 if it is non-constant. Note that
|
||||
\fBisconst\fR does not take into account the context; if \fIarg\fR is
|
||||
a constant expression but evaluated in a non-constant context,
|
||||
\fBisconst\fR will still return 1. For details about constant vs.
|
||||
non-constant expressions, see the section "NON-CONSTANT EXPRESSIONS"
|
||||
.TP
|
||||
.B isdst([d_date [,t_time]]) \fRor\fB isdst(q_datetime)
|
||||
Returns a positive number if daylight saving time is in
|
||||
effect on the specified date and time. \fIDate\fR
|
||||
@@ -3951,6 +3959,11 @@ The second REM statement sets up the 14-day blue-box cycle with a similar
|
||||
adjustment made by AFTER in conjunction with _garbhol.
|
||||
.RE
|
||||
.TP
|
||||
.B nonconst(x_arg)
|
||||
Returns the argument \fIarg\fR unchanged, but forces the expression
|
||||
to be considered \fInon-constant\fR. For details, see the section
|
||||
"NON-CONSTANT EXPRESSIONS"
|
||||
.TP
|
||||
.B now()
|
||||
Returns the current system time, as a \fBTIME\fR type. This may be
|
||||
the actual time, or a time supplied on the command line.
|
||||
@@ -5691,7 +5704,9 @@ to consider it non-constant:
|
||||
.RS
|
||||
.TP
|
||||
.B o
|
||||
A global variable
|
||||
A global variable that has been assigned the result of a non-constant
|
||||
expression, or that has been assigned a value in a \fInon-constant
|
||||
context\fR (to be described later.)
|
||||
.TP
|
||||
.B o
|
||||
A system variable
|
||||
@@ -5713,19 +5728,36 @@ The use of an OMITFUNC
|
||||
The use of a relative SCANFROM
|
||||
.RE
|
||||
.PP
|
||||
Note that \fBRemind\fR checks expressions for non-constantness
|
||||
\fIin isolation\fR. It does not trace data flow. For example.
|
||||
a human can easily see that the expression in the REM command
|
||||
below is actually constant, but \fBRemind\fR does not look
|
||||
at the preceding assignment. It simply looks at the expression \fBd\fR
|
||||
in isolation and considers that the global variable \fBd\fR
|
||||
might not be constant.
|
||||
Whenever a variable is assigned a value, \fBRemind\fR tracks whether
|
||||
or not the expression whose value it was assigned is constant or
|
||||
non-constant. Additionally, variables that are assigned in a
|
||||
non-constant context are always assumed to be non-constant.
|
||||
A non-constant context is the code in the scope of an \fBIF\fR
|
||||
statement where the \fBIF\fR expression is non-constant.
|
||||
.PP
|
||||
Here are some examples that should make things clear:
|
||||
.PP
|
||||
.nf
|
||||
SET d '2025-06-01'
|
||||
REM [d] MSG Hello!
|
||||
SET d '2025-06-01' # d is constant
|
||||
REM [d] MSG Hello! # eligible for purging
|
||||
|
||||
SET d today() - 3 # d is non-constant
|
||||
REM [d] MSG Hello! # not eligible for purging
|
||||
|
||||
IF wkdaynum(today()) == 3
|
||||
set d '2025-06-01' # d is non-constant
|
||||
ELSE
|
||||
set d '2026-01-01' # d is non-constant
|
||||
ENDIF
|
||||
.fi
|
||||
.PP
|
||||
Note that within the \fBIF\fR...\fBENDIF\fR scope, any assignments
|
||||
are non-constant because the code flow depends on today's date, which
|
||||
could change in subsequent \fBRemind\fR runs.
|
||||
.PP
|
||||
Variables initialized on the command-line with the \fB\-i\fR flag are
|
||||
\fIalways\fR considered to be non-constant.
|
||||
.PP
|
||||
The \fBn\fR debugging flag prints a message to standard error whenever
|
||||
\fBRemind\fR decides that an expression is non-constant. This can produce
|
||||
a large amount of output, so if you want to find out why \fBRemind\fR considers
|
||||
|
||||
@@ -649,7 +649,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
strtolower(trig->omitfunc);
|
||||
/* An OMITFUNC counts as a nonconst_expr! */
|
||||
s->expr_happened = 1;
|
||||
nonconst_debug(s->nonconst_expr, "OMITFUNC counts as a non-constant expression");
|
||||
nonconst_debug(s->nonconst_expr, tr("OMITFUNC counts as a non-constant expression"));
|
||||
s->nonconst_expr = 1;
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
@@ -1071,7 +1071,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
FromDSE(DSEToday - tok.val, &y, &m, &d);
|
||||
/* Don't purge reminders with a relative scanfrom */
|
||||
s->expr_happened = 1;
|
||||
nonconst_debug(s->nonconst_expr, "Relative SCANFROM counts as a non-constant expression");
|
||||
nonconst_debug(s->nonconst_expr, tr("Relative SCANFROM counts as a non-constant expression"));
|
||||
s->nonconst_expr = 1;
|
||||
break;
|
||||
|
||||
|
||||
@@ -426,7 +426,7 @@ get_var(expr_node *node, Value *ans, int *nonconst)
|
||||
return E_NOSUCH_VAR;
|
||||
}
|
||||
if (v->nonconstant) {
|
||||
nonconst_debug(*nonconst, "Global variable `%s' makes expression non-constant", str);
|
||||
nonconst_debug(*nonconst, tr("Global variable `%s' makes expression non-constant"), str);
|
||||
*nonconst = 1;
|
||||
}
|
||||
return CopyValue(ans, &(v->v));
|
||||
@@ -883,7 +883,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
case N_SHORT_SYSVAR:
|
||||
/* System var? Return it and note non-constant expression */
|
||||
nonconst_debug(*nonconst, "System variable `$%s' makes expression non-constant", node->u.name);
|
||||
nonconst_debug(*nonconst, tr("System variable `$%s' makes expression non-constant"), node->u.name);
|
||||
*nonconst = 1;
|
||||
r = get_sysvar(node, ans);
|
||||
DBG(debug_evaluation(ans, r, "$%s", node->u.name));
|
||||
@@ -891,7 +891,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
|
||||
case N_SYSVAR:
|
||||
/* System var? Return it and note non-constant expression */
|
||||
nonconst_debug(*nonconst, "System variable `$%s' makes expression non-constant", node->u.value.v.str);
|
||||
nonconst_debug(*nonconst, tr("System variable `$%s' makes expression non-constant"), node->u.value.v.str);
|
||||
*nonconst = 1;
|
||||
r = get_sysvar(node, ans);
|
||||
DBG(debug_evaluation(ans, r, "$%s", node->u.value.v.str));
|
||||
@@ -900,7 +900,7 @@ evaluate_expr_node(expr_node *node, Value *locals, Value *ans, int *nonconst)
|
||||
case N_BUILTIN_FUNC:
|
||||
/* Built-in function? Evaluate and note non-constant where applicable */
|
||||
if (!node->u.builtin_func->is_constant) {
|
||||
nonconst_debug(*nonconst, "Non-constant builtin function `%s' makes expression non-constant", node->u.builtin_func->name);
|
||||
nonconst_debug(*nonconst, tr("Non-constant builtin function `%s' makes expression non-constant"), node->u.builtin_func->name);
|
||||
*nonconst = 1;
|
||||
}
|
||||
return eval_builtin(node, locals, ans, nonconst);
|
||||
|
||||
@@ -646,6 +646,11 @@ int DoSet (Parser *p)
|
||||
} else {
|
||||
r = SetVar(DBufValue(&buf), &v, 0);
|
||||
}
|
||||
if (DebugFlag & DB_NONCONST) {
|
||||
if (!in_constant_context() && !p->nonconst_expr) {
|
||||
Wprint(tr("Variable assignment considered non-constant because of context"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf.len > VAR_NAME_LEN) {
|
||||
Wprint(tr("Warning: Variable name `%.*s...' truncated to `%.*s'"),
|
||||
|
||||
@@ -24808,28 +24808,34 @@ 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 "GetValidHebDate: Bad adarbehave value %d" ""
|
||||
TRANSLATE "Global variable `%s' makes expression non-constant" ""
|
||||
TRANSLATE "In" ""
|
||||
TRANSLATE "Invalid INFO string: Must be of the form \"Header: Value\"" ""
|
||||
TRANSLATE "Invalid translation: Both original and translated must have the same printf-style formatting sequences in the same order." ""
|
||||
TRANSLATE "Missing REM type; assuming MSG" ""
|
||||
TRANSLATE "No Adar A in %d" ""
|
||||
TRANSLATE "No substition function `%s' defined" ""
|
||||
TRANSLATE "Non-constant builtin function `%s' makes expression non-constant" ""
|
||||
TRANSLATE "Not setting $OnceFile: Already processed a reminder with a ONCE clause" ""
|
||||
TRANSLATE "OMIT: UNTIL not allowed; did you mean THROUGH?" ""
|
||||
TRANSLATE "OMITFUNC counts as a non-constant expression" ""
|
||||
TRANSLATE "POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d" ""
|
||||
TRANSLATE "Reading `%s': Found in cache" ""
|
||||
TRANSLATE "Reading `%s': Opening file on disk" ""
|
||||
TRANSLATE "Reading `-': Reading stdin" ""
|
||||
TRANSLATE "Reading command `%s': Found in cache" ""
|
||||
TRANSLATE "Relative SCANFROM counts as a non-constant expression" ""
|
||||
TRANSLATE "SATISFY: constant 0 will never be true" ""
|
||||
TRANSLATE "SATISFY: constant \"\" will never be true" ""
|
||||
TRANSLATE "SATISFY: expression has no reference to trigdate() or $T..." ""
|
||||
TRANSLATE "SECURITY: Won't read non-root-owned file or directory when running as root!" ""
|
||||
TRANSLATE "SECURITY: Won't read world-writable file or directory!" ""
|
||||
TRANSLATE "Scanning directory `%s' for *.rem files" ""
|
||||
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 "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" ""
|
||||
TRANSLATE "Warning: SCANFROM is ignored in two-argument form of evaltrig()" ""
|
||||
|
||||
Reference in New Issue
Block a user