Update output for current build process.
[wine] / tools / winapi_check / preprocessor.pm
1 #
2 # Copyright 1999, 2000, 2001 Patrik Stridvall
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 #
18
19 package preprocessor;
20
21 use strict;
22
23 sub new {
24     my $proto = shift;
25     my $class = ref($proto) || $proto;
26     my $self  = {};
27     bless ($self, $class);
28
29     my $state = \%{$self->{STATE}};
30     my $stack = \@{$self->{STACK}};
31     my $include_found = \${$self->{INCLUDE_FOUND}};
32     my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
33
34     $$include_found = shift;
35     $$conditional_found = shift;
36
37     return $self;
38 }
39
40 sub include {
41     my $self = shift;
42     my $include_found = \${$self->{INCLUDE_FOUND}};
43
44     my $argument = shift;
45
46     &$$include_found($argument);
47 }
48
49 sub define {
50     my $self = shift;
51     my $state = \%{$self->{STATE}};
52     my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
53
54     my $name = shift;
55
56     $$state{$name} = "def";
57
58     &$$conditional_found($name);
59 }
60
61 sub undefine {
62     my $self = shift;
63     my $state = \%{$self->{STATE}};
64     my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
65
66     my $name = shift;
67
68     $$state{$name} = "undef";
69
70     &$$conditional_found($name);
71 }
72
73 sub begin_if {
74     my $self = shift;
75     my $state = \%{$self->{STATE}};
76     my $stack = \@{$self->{STACK}};
77
78     my $directive = shift;
79     local $_ = shift;
80
81     while(!/^$/) {
82         if(/^0\s*\&\&/) {
83             $_ = "0";
84         } elsif(/^1\s*\|\|/) {
85             $_ = "1";
86         }
87
88         if(/^(!)?defined\s*\(\s*(.+?)\s*\)\s*((\&\&|\|\|)\s*)?/){
89             $_ = $';
90             if(defined($1) && $1 eq "!") {
91                 $self->undefine($2);
92                 push @$stack, $2;
93             } else {
94                 $self->define($2);
95                 push @$stack, $2;
96             }
97         } elsif(/^(\w+)\s*(<|<=|==|!=|>=|>)\s*(\w+)\s*((\&\&|\|\|)\s*)?/) {
98             $_ = $';
99         } elsif(/^(!)?(\w+)\s*$/) {
100             $_ = $';
101         } elsif(/^\(|\)/) {
102             $_ = $';
103         } else {
104             print "*** Can't parse '#$directive $_' ***\n";
105             $_ = "";
106         }
107     }
108 }
109
110 sub else_if {
111     my $self = shift;
112     my $state = \%{$self->{STATE}};
113     my $stack = \@{$self->{STACK}};
114
115     my $argument = shift;
116
117     $self->end_if;
118
119     if(defined($argument)) {
120         $self->begin_if("elif", $argument);
121     }
122 }
123
124 sub end_if {
125     my $self = shift;
126     my $state = \%{$self->{STATE}};
127     my $stack = \@{$self->{STACK}};
128
129     my $macro = pop @$stack;
130     delete $$state{$macro} if defined($macro);
131 }
132
133 sub directive {
134     my $self = shift;
135     my $state = \%{$self->{STATE}};
136     my $stack = \@{$self->{STACK}};
137
138     my $directive = shift;
139     my $argument = shift;
140
141     local $_ = $directive;
142     if(/^if$/) {
143         $self->begin_if("if",$argument);
144     } elsif(/^ifdef$/) {
145         $self->begin_if("if", "defined($argument)");
146     } elsif(/^ifndef$/) {
147         $self->begin_if("if", "!defined($argument)");
148         push @$stack, $argument;
149     } elsif(/^elif$/) {
150         $self->else_if($argument);
151     } elsif(/^else$/) {
152         $self->else_if;
153     } elsif(/^endif$/) {
154         $self->end_if;
155     } elsif(/^include/) {
156         $self->include($argument);
157     }
158 }
159
160 sub is_def {
161     my $self = shift;
162     my $state = \%{$self->{STATE}};
163
164     my $name = shift;
165
166     my $status = $$state{$name};
167
168     return defined($status) && $status eq "def";
169 }
170
171 sub is_undef {
172     my $self = shift;
173     my $state = \%{$self->{STATE}};
174
175     my $name = shift;
176
177     my $status = $$state{$name};
178
179     return defined($status) && $status eq "undef";
180 }
181
182 sub is_unknown {
183     my $self = shift;
184     my $state = \%{$self->{STATE}};
185
186     my $name = shift;
187
188     my $status = $$state{$name};
189
190     return !defined($status);
191 }
192
193 1;