blob: 6689214d521424e313fb202b00cd1edc06a0bfa1 [file] [log] [blame]
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00001#
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
Patrik Stridvall5b3b6d91999-10-24 21:45:39 +000019package preprocessor;
20
21use strict;
22
23sub 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}};
Alexandre Julliard7cae5582002-06-01 02:55:48 +000033
Patrik Stridvall5b3b6d91999-10-24 21:45:39 +000034 $$include_found = shift;
35 $$conditional_found = shift;
36
37 return $self;
38}
39
40sub include {
41 my $self = shift;
42 my $include_found = \${$self->{INCLUDE_FOUND}};
43
44 my $argument = shift;
45
46 &$$include_found($argument);
47}
48
49sub 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
61sub 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
73sub 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 $_ = $';
Patrik Stridvall20ca0012001-06-19 03:34:52 +000099 } elsif(/^(!)?(\w+)\s*$/) {
Patrik Stridvall5b3b6d91999-10-24 21:45:39 +0000100 $_ = $';
101 } elsif(/^\(|\)/) {
102 $_ = $';
103 } else {
104 print "*** Can't parse '#$directive $_' ***\n";
105 $_ = "";
106 }
107 }
108}
109
110sub 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
124sub 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
133sub 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
160sub is_def {
161 my $self = shift;
162 my $state = \%{$self->{STATE}};
163
164 my $name = shift;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000165
Patrik Stridvall5b3b6d91999-10-24 21:45:39 +0000166 my $status = $$state{$name};
167
168 return defined($status) && $status eq "def";
169}
170
171sub is_undef {
172 my $self = shift;
173 my $state = \%{$self->{STATE}};
174
175 my $name = shift;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000176
Patrik Stridvall5b3b6d91999-10-24 21:45:39 +0000177 my $status = $$state{$name};
178
179 return defined($status) && $status eq "undef";
180}
181
182sub is_unknown {
183 my $self = shift;
184 my $state = \%{$self->{STATE}};
185
186 my $name = shift;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000187
Patrik Stridvall5b3b6d91999-10-24 21:45:39 +0000188 my $status = $$state{$name};
189
190 return !defined($status);
191}
192
1931;