procmail
[Top] [All Lists]

Re: Syntax of scoring command negation

1997-02-06 09:33:54
Ken Marsh <kmarsh(_at_)charm(_dot_)net> writes:
Again, thanks to everyone whose helping me with this. Hopefully,
when we'er done, we'll update the man pages or other doc, as
Mr. Guenther suggests here.

suggested BNF:
condition_line ::= * condition
condition ::= w^x condition
      | ! condition
      | $ condition
      | var ?? condition
      | ? command
      | regexp
      | > number
      | < number


But if you think in BNF grammers, wouldn't the above seem obvious?

No. First of all, the BNF you just gave isn't in there. Second, if
it was, it is still missing:

condition ::= command

*Where* did this BNF rule come from???

It is my trial attempt to explain the grammer "correct" syntax
of:

w^x ! command

But that's not correct.  The correct syntax for a scored/weighted
negated program condition (where the exitcode is treated like the
number of matches to score) is:

* w^x ! ? command


OK, I could reverse the challenge, and ask you to find me where
the above syntax (w^x ! command) is found in your BNF or the man
page. This is not an accusation, just pointing out that it's sort
of undocumented.

It's undocumented beacause it doesn't work.


You're right about my suggesting allowing the ambiguity of regexp
vs. shell command. All that would be needed to cover this "new"
case is:

          | ! command

Huh?  Now you're mixing actions with conditions.  Are you trying to
describe procmail's current syntax, or are you trying to propose a
new syntax.  It is not clear which you think you're doing.

Let's back up to the beginning and look at what syntax procmail accepts
for recipes.  I'm not going to describe the obsolete and deprecated
syntax of putting the number of conditions in the line that starts the
recipe, partly because you can't put that in BNF, but mainly because
you shouldn't write any new recipes with that syntax.  Everything in
all caps is a token.  Continuation line and comment processing are
assumed to have already been done (note that it's actually parser state
dependent how the these are done, but it generally does what you
want).  Comments on the grammer are in parens on the right.


procmailrc ::=                  (nothing)
             | recipe procmailrc
             | assignment procmailrc

recipe ::= recipe_start_line conditions action

recipe_start_line ::= ":0" FLAGS opt_lockstuff "\n"

opt_lockstuff ::=               (nothing)
                | ":"
                | ":" LOCKFILE

conditions ::=                  (nothing)
             | condition_line conditions

condition_line ::= "*" condition "\n"

condition ::= NUMBER "^" NUMBER condition
            | "!" condition
            | "$" condition
            | VAR "??" condition
            | "?" COMMAND
            | REGEXP
            | ">" NUMBER
            | "<" NUMBER

action ::= BERKELEY_MAILBOX             (only one file type mailbox allowed)
         | maildirs                     (multiple directory style allowed)
         | "|" COMMAND
         | "!" addresses
         | VARIABLE "=" "|" COMMAND
         | VARIABLE "=" "!" addresses   (this works, but why you would do it...)
         | "{" procmailrc "}"

maildirs ::= MAILDIRECTORY
           | MAILDIRECTORY maildirs

addresses ::= ADDRESS
            | ADDRESS addresses

assignment ::= VARIABLE "=" WORD


Okay, given the above *you* have to 'program' procmail in a way that it
can parse with the above grammer.  Procmail accepts the above: are you
going to give it something that it can accept?


But wait! that's still ambiguous... so how does procmail disambiguate:

:0
* 1^2 ! /usr/kmarsh/bin/counat

from,

:0
* 1^2 ! countat # that's a RE

If there isn't a '?' marking it as a command, then it's a regexp.  Both
of the above would be parsed as weighted negated regexp matches.  Is it
that hard to understand?


I suppose that negating an RE match is not terribly useful, so
it's not used, but guess what? It's allowed by your BNF. 

Negated regexp conditions aren't usefull?!?!?!  Hello?!?!?!?  On the second
page of the procmailex(5) manpage we find:

          :0 hwc:
          * !^FROM_MAILER
          | uncompress headc.Z; cat >>headc; compress headc

*Many* recipes contain the condition

        * ! ^X-Loop: my(_at_)address(_dot_)here

Negated regexp condition are *very* useful.


 Okay, so the author of
procmail had to change the grammer to eliminate this ambiguity.  He did
so by requiring a command to be preceded by a '?'.  Then he documented
this on the manpage.

OK, but left the (w^x ! command) undocumented.

THAT SYNTAX IS WRONG.  IT DOESN'T WORK.


If you want to negate the return code of a command as a condition, you
must say:

* ! ? commmand

But that's not what Lars Kellogg-Stedman suggested (assuming that it
works, which I do):

:0
* 1^2 ! /usr/kmarsh/bin/counat

Did he get it wrong? Like I said, I tried the syntax you give here,
and it worked like procmailrc's man page says it would, and not
like the procmailsc man page said.

I don't have Lars's message on hand, but if he said that the above
would work, he was wrong.  It may have been a typo on his part -- I've
done the same myself, only to have David correct me.  If that was the
source of this entire confusion, then I'm sorry someone didn't catch it
and fire of a correction.

As for the procmailsc(5) manpage, where does it suggest the above syntax
would work?  It described how a weighted program condition is scored,
but nowhere does it say that just because you're using scoring you can
leave off the '?' that makes it a program condition to start with.


...
Granted, there's the source. I would expect one example, though.

It's true that there's a paucity of examples that contain program
conditions.  Indeed, I see only one on the procmailex(5) manpage.
Furthermore, there's a lack of really complicated examples to
demonstrate the heights (or depths) of procmailrc programming.  I'm
considering sending Stephen my count_items.rc as a demonstration of
recursive INCLUDERC usage, but I'll need to drop in a pile of
documentation describing why you can't do it without the recursive
call.

I suggest that further discussion be moved off the list, for the sanity
of the others.

Philip Guenther