[PATCH] fixed stream->protect handling
commiteac4d539b83ef7a917ed74a4fbf49033de88206d
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 27 Nov 2005 07:33:00 +0000 (27 02:33 -0500)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 28 Nov 2005 01:40:51 +0000 (27 17:40 -0800)
tree1913de4b156014bc9c5aa254619147c9168027f1
parent7b894af8a590b9e20e81b6de605f3151f14e3410
[PATCH] fixed stream->protect handling

New mechanism: we introduce new fields of struct stream - ifndef and
dirty.  The former is the nesting level of ifndef that currently
protects us, or 0 if there's none.  The latter is a boolean - "do we
ignore new non-empty stuff shows up right now?".

There are five states, more or less matching the old ->constant ones:
 1) nothing - dirty = 0, ->protect = NULL, ->ifndef = 0.
 2) candidate - dirty = 0, ->protect = <ident>, ->ifndef > 0.
 3) checking - dirty = 0, ->protect = <ident>, ->ifndef = 0.
 4) maybe - dirty = 1, ->protect = <ident>, ->ifndef > 0.
 5) not - dirty = 1, ->protect = NULL, ->ifndef = 0.

Rules:
 - any directive except #ifdef, #ifndef, #else, #endif, #<newline> is
   considered dirty.
 - any non-directive (#<not a directive name>...) is considered dirty
 - any tokens in lines that do not begin with # are considered dirty
 - #if[n]def with syntax errors is considered dirty.
 - any nesting errors => stream is non-constant.
 - any dirty material not under ifndef => stream is non-constant.
 - the outermost ifndef at the first time we run into dirty material
   will be the candidate for stream protector.
 - any subsequent dirty material not under ifndef <protector> => stream
   is non-constant.

We start in "nothing".  Transitions:
 - "nothing": dirty material => "not", see ifndef => "candidate"
 - "candidate": dirty material => "maybe", leave that ifndef => "nothing"
 - "maybe": dirty material => "maybe", leave that ifndef => "checking"
 - "checking": dirty material => "not", same ifndef => "maybe
 - "not": they check in, but they don't check out...

Seeing a nesting error (#else/#elif/#endif out of place/order or
unclosed #if...  in the end) gets us to "not", no matter which state we
were in.

That's it.  Implementation is actually pretty simple and
straightforward; it's less scary than the description above.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
pre-process.c
token.h
validation/preprocessor20.c [new file with mode: 0644]
validation/preprocessor20.h [new file with mode: 0644]