Renamed libuuid.a to libwine_uuid.a
[wine] / tools / winapi_check / preprocessor.pm
1 package preprocessor;
2
3 use strict;
4
5 sub new {
6     my $proto = shift;
7     my $class = ref($proto) || $proto;
8     my $self  = {};
9     bless ($self, $class);
10
11     my $state = \%{$self->{STATE}};
12     my $stack = \@{$self->{STACK}};
13     my $include_found = \${$self->{INCLUDE_FOUND}};
14     my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
15   
16     $$include_found = shift;
17     $$conditional_found = shift;
18
19     return $self;
20 }
21
22 sub include {
23     my $self = shift;
24     my $include_found = \${$self->{INCLUDE_FOUND}};
25
26     my $argument = shift;
27
28     &$$include_found($argument);
29 }
30
31 sub define {
32     my $self = shift;
33     my $state = \%{$self->{STATE}};
34     my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
35
36     my $name = shift;
37
38     $$state{$name} = "def";
39
40     &$$conditional_found($name);
41 }
42
43 sub undefine {
44     my $self = shift;
45     my $state = \%{$self->{STATE}};
46     my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
47
48     my $name = shift;
49
50     $$state{$name} = "undef";
51
52     &$$conditional_found($name);
53 }
54
55 sub begin_if {
56     my $self = shift;
57     my $state = \%{$self->{STATE}};
58     my $stack = \@{$self->{STACK}};
59
60     my $directive = shift;
61     local $_ = shift;
62
63     while(!/^$/) {
64         if(/^0\s*\&\&/) {
65             $_ = "0";
66         } elsif(/^1\s*\|\|/) {
67             $_ = "1";
68         }
69
70         if(/^(!)?defined\s*\(\s*(.+?)\s*\)\s*((\&\&|\|\|)\s*)?/){
71             $_ = $';
72             if(defined($1) && $1 eq "!") {
73                 $self->undefine($2);
74                 push @$stack, $2;
75             } else {
76                 $self->define($2);
77                 push @$stack, $2;
78             }
79         } elsif(/^(\w+)\s*(<|<=|==|!=|>=|>)\s*(\w+)\s*((\&\&|\|\|)\s*)?/) {
80             $_ = $';
81         } elsif(/^(\w+)\s*$/) {
82             $_ = $';
83         } elsif(/^\(|\)/) {
84             $_ = $';
85         } else {
86             print "*** Can't parse '#$directive $_' ***\n";
87             $_ = "";
88         }
89     }
90 }
91
92 sub else_if {
93     my $self = shift;
94     my $state = \%{$self->{STATE}};
95     my $stack = \@{$self->{STACK}};
96
97     my $argument = shift;
98
99     $self->end_if;
100
101     if(defined($argument)) {
102         $self->begin_if("elif", $argument);
103     }
104 }
105
106 sub end_if {
107     my $self = shift;
108     my $state = \%{$self->{STATE}};
109     my $stack = \@{$self->{STACK}};
110
111     my $macro = pop @$stack;
112     delete $$state{$macro} if defined($macro);
113 }
114
115 sub directive {
116     my $self = shift;
117     my $state = \%{$self->{STATE}};
118     my $stack = \@{$self->{STACK}};
119
120     my $directive = shift;
121     my $argument = shift;
122
123     local $_ = $directive;
124     if(/^if$/) {
125         $self->begin_if("if",$argument);
126     } elsif(/^ifdef$/) {
127         $self->begin_if("if", "defined($argument)");
128     } elsif(/^ifndef$/) {
129         $self->begin_if("if", "!defined($argument)");
130         push @$stack, $argument;
131     } elsif(/^elif$/) {
132         $self->else_if($argument);
133     } elsif(/^else$/) {
134         $self->else_if;
135     } elsif(/^endif$/) {
136         $self->end_if;
137     } elsif(/^include/) {
138         $self->include($argument);
139     }
140 }
141
142 sub is_def {
143     my $self = shift;
144     my $state = \%{$self->{STATE}};
145
146     my $name = shift;
147     
148     my $status = $$state{$name};
149
150     return defined($status) && $status eq "def";
151 }
152
153 sub is_undef {
154     my $self = shift;
155     my $state = \%{$self->{STATE}};
156
157     my $name = shift;
158     
159     my $status = $$state{$name};
160
161     return defined($status) && $status eq "undef";
162 }
163
164 sub is_unknown {
165     my $self = shift;
166     my $state = \%{$self->{STATE}};
167
168     my $name = shift;
169     
170     my $status = $$state{$name};
171
172     return !defined($status);
173 }
174
175 1;