[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>