The caller has already provided daif state. No need to keep updating
daif via pic_set_priority if it's already in the state we need (interrupts
disabled).
That comment was useful when there was no function is_null_pointer.
Back then, the code for testing a null pointer was written in-line,
which made it really hard to see what's going on. This is no longer the
case.
In ModifyWords, there is no "passed string" anymore since that function
now directly operates on the expression value.
While here, improve the documentation of ModifyWordsCallback and rename
it to ModifyWordProc, focusing on its purpose instead of where it is
used.
The condition "st->newValue.str != val" in ApplySingleModifier made the
memory management look more complicated than it really was. Freeing an
object based on another object's value is harder to understand than
necessary.
To fix this, the "current value" of the expression is now stored in
ApplyModifiersState, and it gets updated in-place by the ApplyModifier
functions. This reduces the number of parameters for the ApplyModifier
functions.
Accessing the current value of the expression is now more verbose than
before (st->value.str instead of the simple val). To compensate for
this verbosity, ApplyModifiersIndirect is now much easier to understand
since there is no extra "current value" floating around.
There is still room for improvement. In ApplyModifiers, passing an FStr
in and returning another (or possibly the same) makes it difficult to
understand memory management. Adding a separate Expr type that outlives
the ApplyModifiersState will make this easier, in a follow-up commit.
- use a single macro to align pointers and expose the alignment, instead
of hard-coding 3 in 1/2 the macros.
- fix an issue in the ipv6 lt2p where it was aligning for ipv4 and pulling
for ipv6.
Memory management of the value of variable expressions is currently more
complicated than necessary. It is the responsibility of ApplyModifiers,
even though conceptually the value belongs to an expression, so it
should rather be in Expr. Right now, this is an alias for
ApplyModifiersState, but that will change soon.
When that is done, there will no longer be a "current value" and a "new
value", only a single "value" of an expression. At that point, before
Expr_SetValueOwn will overwrite the old value with the output of the
shell command, the error message needs to refer to the latter.
Single-character short variable expressions such as $V neither have a
starting character nor an ending character. The only interesting
character forms the complete variable name.
No functional change.
Unlike ':ts' and ':tW', the effects of ':U' are visible even after the
modifiers from the nested expression have been applied. These subtle
details, like many others, are not documented in the manual page.
As a preparation for refactoring the code around variable expressions,
there need to be a few tests for indirect variable modifiers since these
were not covered before.
Indirect modifiers may include ':ts' and ':tW', which change the
interpretation of the variable expression in small details. The scope
of these changes is limited to the indirect modifier, any evaluations
outside this indirect modifier are unaffected.
The changes to the .exp file are mostly line number changes, plus a
demonstration of a newly found bug, where an expression is evaluated
successfully despite producing a parse error.
The plan is to have only the "current value" of the expression as a
member, not the "new value". To do this consistently and get the memory
management right, there must be a single place (or two) where the value
of the expression is updated.
No functional change.
The type name ApplyModifiersState was only intended as a working draft,
its name is too long and its scope a little too narrow.
Applying the modifiers is the main part of evaluating a variable
expression, and the scope of that type will be extended to parsing the
name of the expression as well. This will hopefully reduce the number
of parameters, which is currently at 14.
No functional change.
Combining the assignment operator ':=' with the variable modifier ':U'
on the same variable does not work as intended. At the point where the
':U' is evaluated, the variable is guaranteed to be defined because the
code in VarAssign_EvalSubst says so.