rc icon indicating copy to clipboard operation
rc copied to clipboard

if not doesn't handle multiple preceding ifs or nested if nots [PATCH]

Open ptommy opened this issue 3 years ago • 0 comments

Example:

if (false) echo FALSE    # This truth value will be used by ifnot
if (true) echo TRUE
if not echo NOT TRUE

This erroneously outputs NOT TRUE.

I should mention that this is a rather serious bug, if you're using if not. It can make the logic of a script completely wrong if you are using a simple if without else or if not early in the script, and later use if-if not, where the if not will use the truth value of the earlier if and not the preceding one.

Here's a patch that tests for this in trip.rc

diff --git a/trip.rc b/trip.rc
index 43af11b..6ac5fe0 100644
--- a/trip.rc
+++ b/trip.rc
@@ -713,6 +713,7 @@ submatch 'if (false) { echo foo } else echo qux; if not echo bar' 'rc: `if not''
 # if-not stack if_state regression
 s='
 L=()
+if (false) l=($L a0)
 if (true) {
     if (false) {
         L=($L  a1)

And here's a fix:

diff --git a/walk.c b/walk.c
index 314484b..50581a6 100644
--- a/walk.c
+++ b/walk.c
@@ -102,8 +102,8 @@ top:        sigchk();
                cond = TRUE;
                if_this = walk(n->u[0].p, TRUE);
                cond = oldcond;
-               if (if_last == if_nothing) if_last = if_this;
                walk(if_this ? true_cmd : false_cmd, parent);
+               if_last = false_cmd ? if_nothing : if_this;
                break;
        }
        case nIfnot: {

if_last should be updated after possibly nested if-ifnots are executed, and it should be set to the truth value of an else-less if, or to if_nothing if the if had an else.

This will trigger the error "if not must follow if" whenever ifnot is used after an else (or an ifnot), but it will not trigger an error for the following:

if (false) echo FALSE
echo ALWAYS
if not echo NOT FALSE

I don't think this necessarily should be considered an error. Right now however the parser does, although it only detects in in lines, so the following will trigger the "if not must follow if" error:

if (false) echo FALSE; echo ALWAYS; if not echo NOT FALSE

but should it...?

ptommy avatar Sep 27 '21 09:09 ptommy