MSDN: "WM_NCHITTEST - Returns HTCLIENT if the control style is
[wine.git] / tools / winapi_check / preprocessor.pm
blobdd9fbd43b7b41e28d442c023c6b12953e1854cc0
1 package preprocessor;
3 use strict;
5 sub new {
6 my $proto = shift;
7 my $class = ref($proto) || $proto;
8 my $self = {};
9 bless ($self, $class);
11 my $state = \%{$self->{STATE}};
12 my $stack = \@{$self->{STACK}};
13 my $include_found = \${$self->{INCLUDE_FOUND}};
14 my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
16 $$include_found = shift;
17 $$conditional_found = shift;
19 return $self;
22 sub include {
23 my $self = shift;
24 my $include_found = \${$self->{INCLUDE_FOUND}};
26 my $argument = shift;
28 &$$include_found($argument);
31 sub define {
32 my $self = shift;
33 my $state = \%{$self->{STATE}};
34 my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
36 my $name = shift;
38 $$state{$name} = "def";
40 &$$conditional_found($name);
43 sub undefine {
44 my $self = shift;
45 my $state = \%{$self->{STATE}};
46 my $conditional_found = \${$self->{CONDITIONAL_FOUND}};
48 my $name = shift;
50 $$state{$name} = "undef";
52 &$$conditional_found($name);
55 sub begin_if {
56 my $self = shift;
57 my $state = \%{$self->{STATE}};
58 my $stack = \@{$self->{STACK}};
60 my $directive = shift;
61 local $_ = shift;
63 while(!/^$/) {
64 if(/^0\s*\&\&/) {
65 $_ = "0";
66 } elsif(/^1\s*\|\|/) {
67 $_ = "1";
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;
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 $_ = "";
92 sub else_if {
93 my $self = shift;
94 my $state = \%{$self->{STATE}};
95 my $stack = \@{$self->{STACK}};
97 my $argument = shift;
99 $self->end_if;
101 if(defined($argument)) {
102 $self->begin_if("elif", $argument);
106 sub end_if {
107 my $self = shift;
108 my $state = \%{$self->{STATE}};
109 my $stack = \@{$self->{STACK}};
111 my $macro = pop @$stack;
112 delete $$state{$macro} if defined($macro);
115 sub directive {
116 my $self = shift;
117 my $state = \%{$self->{STATE}};
118 my $stack = \@{$self->{STACK}};
120 my $directive = shift;
121 my $argument = shift;
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);
142 sub is_def {
143 my $self = shift;
144 my $state = \%{$self->{STATE}};
146 my $name = shift;
148 my $status = $$state{$name};
150 return defined($status) && $status eq "def";
153 sub is_undef {
154 my $self = shift;
155 my $state = \%{$self->{STATE}};
157 my $name = shift;
159 my $status = $$state{$name};
161 return defined($status) && $status eq "undef";
164 sub is_unknown {
165 my $self = shift;
166 my $state = \%{$self->{STATE}};
168 my $name = shift;
170 my $status = $$state{$name};
172 return !defined($status);