@@ -25,43 +25,51 @@ class DependencyGrapher
2525
2626 class ExpressionEvaluator
2727 def initialize ( expression )
28- @expression = expression . strip
28+ @expression = expression
2929 end
3030
3131 def evaluate ( defines )
32+ # Stage0: eliminate comments
33+ @expression . gsub! ( /(\/ \/ .*)$/ , "" )
34+ @expression . gsub! ( /(\/ \* .*\* \/ )/ , "" )
35+
3236 # Stage1: find 'defined's and evaluate
3337 # replace defined with boolean evaluation value
34- @expression . gsub! ( /(defined\( .+?\) )/ ) { |expr |
35- defkey = expr . match ( /\( (.+?)\) / ) [ 1 ]
36- if defines . include? ( defkey )
37- 'true'
38- else
39- 'false'
40- end
41- }
38+ re = /((!|\s *)?defined((\( |\s +)(\s *[^) ]+)(\) |\s |$)))/o
39+ @expression . gsub! ( re ) do |expr |
40+ m = expr . match ( re )
41+ negate = m [ 2 ] == "!"
42+ key = m [ 5 ] . strip
43+
44+ value = defines . include? key
45+ value = !value if negate
46+ value ? "true" : "false"
47+ end
48+
4249 # Stage2: scan macro-defined keywords
4350 # replace with actual value (true or false)
4451 # this covers patterns like __clang__ and __x86_64__
45- @expression . gsub! ( /__[A-Za-z0-9_]+__/ ) { |expr |
52+ @expression . gsub! ( /__[A-Za-z0-9_]+__/ ) do |expr |
4653 if defines . include? ( expr )
4754 defines [ expr ] . to_s
4855 elsif integer? ( expr )
4956 expr
5057 else
5158 '0'
5259 end
53- }
60+ end
5461
5562 # this covers other patters.
56- @expression . gsub! ( /[A-Z0-9_]{4,}/ ) { |expr |
63+ @expression . gsub! ( /[A-Z0-9_]{4,}/ ) do |expr |
5764 if defines . include? ( expr )
5865 defines [ expr ] . to_s
5966 elsif integer? ( expr )
6067 expr
6168 else
6269 '0'
6370 end
64- }
71+ end
72+
6573 # Stage3: Evaluate with ruby eval()
6674 eval ( @expression )
6775 end
0 commit comments