|
|
On 3/19/23 10:14, Kenneth wrote:
> William F Pokorny <ano### [at] anonymousorg> wrote:
>>
>> Alright.
>>
>> A long time ago I created a bunch of statically linked(a) versions of
>> POV-Ray going back through time. Anyhow. Used these to trace the
>> introduction of the str/num OK in #ifdef test bug.
>> [clip]
>> My BIG bet is on the following commit being the problem,
>> but I don't have a static compile of it or the one prior to it to
>> be sure.
>>
>
> Given the current mix of flaws, the use of a string literal still has me
> scratching my head...
> #ifdef("...string...")
>
> Alain's and JR's explanation of the expected behavior seems valid; but with a
> properly-working #ifdef, should the comparison fail outright (fatal error)? Or
> should it still be seen as defined? I'm mostly just curious ;-)
>
I'm a little further along in looking at this. It's looking messy.
I think we need to start with the fact #ifdef, #ifndef and #undef have
ALWAYS been #ifIdDefined, #ifIdNotDefined and #undefineId. Going back to
the v3.6 documentation we have:
---------------
2.2.2.6.2 The #ifdef and #ifndef Directives
The #ifdef and #ifndef directive are similar to the #if directive
however they are used to determine if an identifier has been previously
declared.
IFDEF_DIRECTIVE:
#ifdef ( IDENTIFIER ) TOKENS... [#else TOKENS...] #end
IFNDEF_DIRECTIVE:
#ifndef ( IDENTIFIER ) TOKENS... [#else TOKENS...] #end
If the IDENTIFIER exists then the first group of tokens is parsed
normally and the second set is skipped. If false, the first set is
skipped and the second set is parsed. ...
----------------
So... The up front, not so good, news is the behavior of at least the
#ifdef and #ifndef keywords was partly changed back in March of 2015.
Intentional or accidental? It's not mentioned as an intended change
anywhere I have seen - and I still don't understand how it happened even
with some time reviewing the changes when it happened.
Christoph went on to add a bunch of inbuilt keywords to be considered
'defined' sometime after late November 2018 - which makes me begin to
think he too might have been considering these *def keywords in the
c/c++ coding, macro test sense.
The few 'keywords' I've tested these generate a warning in at least some
versions of POV-Ray. But it's weird, keywords NOT returning immediate
numbers or strings are also considered 'defined' in these versions
though they are in fact arbitrary SDL keywords.
Even this worked in the pre-backed off v3.8 release parser:
#ifdef(#declare V=99;#undef V)
...
Though without some other mistake it would usually die with a later
unmatched something parsing fail. That said it's not hard to get it to
parse clean - say with an added #if(). I will always die if somebody
tries use the undef'd V.
So, much more was being supported as testing true in povr/v4.0, but
still not some things like raw vectors. Though things like x,y,z are OK.
Christoph backed up the v3.8 parser and again lost the inbuilt keywords
as "defined". I do not know the reasons for the parser backup, but
perhaps this issue it - or big part of it. I don't know.
I do know, I've got a mess with these in the povr parser given my branch
point... :-(
When I test v3.7, v3.8b2 and my povr(v4.0?) code I get:
v3.7
----------------------
GOOD_ID --> This is a valid ID. (ifdef returning true)
GOOD_ID --> This is a valid ID. (ifndef returning false)
BAD_ID --> This is NOT a valid ID. (ifdef returning false)
BAD_ID --> This is NOT a valid ID. (ifndef returning true)
"STRING" --> Other than an ID. (ifdef returning false)
"STRING" --> Other than an ID. (ifndef returning true)
"" --> Other than an ID. (ifdef returning false)
"" --> Other than an ID. (ifndef returning true)
1.23456 --> Other than an ID. (ifdef returning false)
1.23456 --> Other than an ID. (ifndef returning true)
0 --> Other than an ID. (ifdef returning false)
0 --> Other than an ID. (ifndef returning true)
pi --> Other than an ID. (ifdef returning false)
pi --> Other than an ID. (ifndef returning true)
--> Other than an ID. (ifdef returning true)
--> Other than an ID. (ifndef returning true)
v3.8b2
-----------------------
GOOD_ID --> This is a valid ID. (ifdef returning true)
GOOD_ID --> This is a valid ID. (ifndef returning false)
BAD_ID --> This is NOT a valid ID. (ifdef returning false)
BAD_ID --> This is NOT a valid ID. (ifndef returning true)
"STRING" --> Other than an ID. (ifdef returning true) ***
"STRING" --> Other than an ID. (ifndef returning false) ***
"" --> Other than an ID. (ifdef returning true) ***
"" --> Other than an ID. (ifndef returning false) ***
1.23456 --> Other than an ID. (ifdef returning true) ***
1.23456 --> Other than an ID. (ifndef returning false) ***
0 --> Other than an ID. (ifdef returning true) ***
0 --> Other than an ID. (ifndef returning false) ***
pi --> Other than an ID. (ifdef returning false)
pi --> Other than an ID. (ifndef returning true)
--> Other than an ID. (ifdef returning true)
--> Other than an ID. (ifndef returning true)
povr & likely v4.0 and other misc releases before parser backup
-------------------------
GOOD_ID --> This is a valid ID. (ifdef returning true)
GOOD_ID --> This is a valid ID. (ifndef returning false)
BAD_ID --> This is NOT a valid ID. (ifdef returning false)
BAD_ID --> This is NOT a valid ID. (ifndef returning true)
"STRING" --> Other than an ID. (ifdef returning true) ***
"STRING" --> Other than an ID. (ifndef returning false) ***
"" --> Other than an ID. (ifdef returning true) ***
"" --> Other than an ID. (ifndef returning false) ***
1.23456 --> Other than an ID. (ifdef returning true) ***
1.23456 --> Other than an ID. (ifndef returning false) ***
0 --> Other than an ID. (ifdef returning true) ***
0 --> Other than an ID. (ifndef returning false) ***
pi --> Other than an ID. (ifdef returning true) ###
pi --> Other than an ID. (ifndef returning false) ###
--> Other than an ID. (ifdef returning true)
--> Other than an ID. (ifndef returning true)
The last case with empty parens is an exposure back to v3.7. In a lot of
code the effective fall through at the #if____ will cause later parsing
problems, but the error are of the more unhelpful sort. It would be best
if the empty parens were themselves a parse error. I 'think' it's
probably also possible to fix the following parsing issues with another,
cleaning syntax (actual bad-syntax) sort of mistake.
My feeling is the right thing to do would be to take the behavior back
to what it has always been with the nearer term v3.8 release. If we want
the most backward compatibility this it. Further, the extra now being
changed currently in the v3.8 code is not consistent with respect to
things like pi - which to the parser is an immediate value of pi. And
datetime would be an example of an immediate string which would test
true, you'd think, if "string" does.
What to do... I could spend a lot of time trying to figure out the
history here, but I think the current state not completely tenable since
2015...
We need functionality which deals only with IDs.
We, perhaps, need some sort of what is in the parenthesis is 'defined'
functionality too, but the generic sort being allowed or not seems
questionable to me. Are people already using this functionality?
With povr I might do something drastic like create 'id' versions and and
'defined' versions - with all new keyword names so users would be forced
to look at potential problems with interpretation and behavior given the
old keywords wouldn't work!
Hmm... We do have new to v3.8 the local and global dictionaries. Could I
just dump the #ifdef and #ifndef keyword for something based on those. I
can't remember at the moment how they work.
Don't know... Whatever it is in povr, afraid at the moment it'll be a
lot of work - because I'll need to digest a lot of the parser code.
Guess it's time to do my taxes... :-)
Bill P.
Post a reply to this message
|
|