procmail
[Top] [All Lists]

Re: "?" with "$"

1999-01-18 01:21:30
jari(_dot_)aalto(_at_)poboxes(_dot_)com (Jari Aalto+mail.procmail) writes:
* Sat 1999-01-16 David Tamkin <dattier(_at_)Mcs(_dot_)Net> list.procmail
| Sean Straw's suggestion to Jimmy Humphrey included code with these
| conditions:
| 
| | * $? test -s $AUTH_FILE
| | * $? echo $FROM | $FGREP -i -f $AUTH_FILE
| 
| It's been my experience that the "$" modifier is not needed to expand
| variables or command substitutions in exit code ("?"-type) conditions.  It
| might even hurt if the values of the variables or the output of backquoted
| commands includes dollar signs or backticks.
| 
| The "$" modifier is needed for command and variable substitutions in regular
| expressions.

But that's illogical then. The most important thing in programming
languages is that it behave in uniform way. While it may be currently
possible to write "?" lines without the dollar extrapolation, I hope you
make it mandatory in possible new release of procmail.

Procmail is consistent: it does variable expansion just the shell,
executes external commands as if they were executed via the shell, and
maintains the shell's separation of name vs use for variables.  What's
inconsistent about the following?

        FGREP = '/usr/local/bin/grep -F'
        output1= `$FGREP something $HOME/blah`
        :0
        * ?       $FGREP something $HOME/blah
        output2=| $FGREP something $HOME/blah

To _suppress_ variable expansion on '?' conditions would confuse a lot
of people, break a pile of scripts, be buggy and difficult to implement
(if the command is passed to the shell, how is procmail going to keep
the shell from expanding variables?) and generally make people
unhappy.



Procmail is already too full of other exceptions. Eg. I don't understand why
the ?? syntax was chosen as it is:

For backwards compatibility, when a new feature like variable matching
is added, it should not change currently valid rcfiles.  The technique
used here was to take a condition line which was not previously legal
and give it a meaning.  Before variable matching was added, it was
illegal for a condition to contain "??" as no valid regexp contains two
operators in a row.  That's also why '*' was chosen to lead conditions
in the new condition format (no valid regexp can begin with an
operator).


   #   something is _variable_, but "regexp" is literal

   *  something ?? regexp

You appear to equate naming a variable and using it.  In the shell and
procmail, a variable's name does not include the dollar sign.  You only
only prefix with a dollar sign when you want to 'expand' it (i.e.,
interpolate its value into the currently being read text).  Thus, you
don't use a dollar sign when assigning to a variable or when naming a
variable to match against.

The shell (and procmail from it) does it this way because it's a macro
language: all text is scanned for variable expansions.  To include the
dollar sign on the variable in an assignment would be ambigious: is it
an assignment or an attempt to execute a command named by the
variable?


   #   REGEXP is variable and needs "$" extrapolation command next to "*",
   #   but funny, something must not be typed "$something"

   *$  something ?? $regexp

Actually,
        * $something ?? $regexp
_does_ work -- when procmail sees the '$' it's looking for condition
specials, not doing variable expansion.  So, it strips the '$', does
variable expansion on the rest, then sees "something ?? ...", so it sets
up the regexp to be matched against variable something.  However, it
would be better to reorder the above condition into:

        * something ?? $ $regexp

That way, variable expansion is only done on the part that needs it.

When procmail is reading a condition and it encounters "variable ??",
it makes note that the condition should be matched against that
variable, then starts the reading the rest of the condition as if it
were at the start of the condition, so that you place a '!' or '$'
special after the "variable ??".  The same goes for the '!' special,
while the '$' special causes procmail to apply variable and command
expansion to the rest of the condition and then start looking for
special all over again on the result

For example, consider the following variable assignments and recipes:

        foo  = '! bar ?? $ $baz'
        bar  = 'something here'
        baz  = '! quux ??'
        quux = 'something here too'
        blip = 'but nothing here'

        :0
        * blip ?? $ ! $foo thing \/.*
        { LOG = "matched: " }
        :0 E
        { LOG = "failed: " }
        LOG = "$MATCH"

This will log "failed: here too".  Here's the steps of procmail's
parsing.  The lefthand column shows whether the condition is being
negated and what procmail is going to match against.

+-----Negated
|
|    +---Match target
|    |                  Condition to be parsed
V    V                  -------------------------------------------
no   message header     blip ?? $ ! $foo thing \/.*
no   variable blip      $ ! $foo thing \/.*
no   variable blip      ! ! bar ?? $ $baz thing \/.*
yes  variable blip      ! bar ?? $ $baz thing \/.*
no   variable blip      bar ?? $ $baz thing \/.*
no   variable bar       $ $baz thing \/.*
no   variable bar       ! quux ?? thing \/.*
yes  variable bar       quux ?? thing \/.*
yes  variable quux      thing \/.*

Ta dah: no more specials, so the regexp "thing \/.*" is matched against
the variable quux, and the condition is negated so it fails while MATCH
is set to "here to".


It would make much more sense to write $ always when it's question about 
variables:

Yeah, perl is nice language, but it's not the only one.


   *$  $something ?? $regexp

Sorry, that condition already has a useful meaning: match the regexp
stored in the 'regexp' variable against the value of variable whose
name is stored in the 'something' variable.


Even worse desicion, that you can move the extrapolation dollar in the line:

   *   something ?? $ $regexp

Worse?  You mean to say that you _dislike_ orthogonality?


Philip Guenther

<Prev in Thread] Current Thread [Next in Thread>