Subject: ash & POSIX 1003.2 q's
To: None <tech-userlevel@NetBSD.ORG>
From: VaX#n8 <vax@linkdead.paranoia.com>
List: tech-userlevel
Date: 01/27/1997 01:23:46
Hmm, wow.
There's more to this parsing business than meets the eye.
I started to fix some minor stuff; I got showtree working pretty well,
and started to fool with some minor sh bugs, when I realized what
I really needed was a functional definition like POSIX 1003.2.
If someone would loan me a copy, I'd fix up ash -- if people thought
it would be a worthwhile task.  I'm as much of a minimalist as the
next person, but maybe forgetting about it is better, I dunno.
Lunix is using bash for cryin' out loud :)
I'm a little disappointed that pdksh doesn't use something
like yacc, but perhaps there is a good reason (the tables get too big?
suboptimal generated parsers?)

Let's have some examples:

   true || echo hi && echo bye

Echoes "bye", but is not a bug; short-circuit ops are left-associative
and equal precedence.

As a little example, let's take the description of the "-e" option.

    If not interactive, exit immediately if any
    untested command fails.  The exit status of a
    command is considered to be explicitly tested if
    the command is used to control an if, elif, while,
    or until; or if the command is the left hand
    operand of an ``&&'' or ``||'' operator.

I noticed that this fails under ash but not bash with -e options:

	if false; true; then echo hi; fi

Apparently the "tested" attribute only applies to the last SIMPLE command.
In other words, if this is your parse tree (growing rightward, root on left):

		false
	;
		true
if
	echo hi

The "testedness" doesn't descend through the semicolon; it only applies
to the "true" command and not to the "false" command.  In the preorder
traversal of the parse tree, the "tested" flag is simply not passed to
the first child of the semicolon operator.  Let's assume this rather
strict definition of "controlling" an if statement.
All kinds of heck break loose.  What about this:

	false && true

No problem, false is tested.  But what about:

	false && true; echo here

Parse tree:

        echo here
; 
                false
         && 
                true


In this case, the call to evaluate the semicolon invokes itself recursively
on the AND operator, which fails, so the semi fails.  The problem is that
the "testedness" is not being returned up the ladder with the exit code.
In fact, each invocation has it's own copy of the flags, so the AND
operator can't (cleanly) modify the SEMI's copy.

Just in case anyone wants a copy... ask...
Things aren't fixed enough to file a formal bug report.