1
# Copyright 2001-2004 The Apache Software Foundation
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
7
# http://www.apache.org/licenses/LICENSE-2.0
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
1
15
package Apache::ParseSource;
4
18
use Apache::Build ();
21
use File::Spec::Functions qw(catdir);
7
23
our $VERSION = '0.02';
54
70
'CORE_PRIVATE', #so we get all of apache
55
71
'MP_SOURCE_SCAN', #so we can avoid some c-scan barfing
56
72
'_NETINET_TCP_H', #c-scan chokes on netinet/tcp.h
57
'APR_OPTIONAL_H', #c-scan chokes on apr_optional.h
73
# 'APR_OPTIONAL_H', #c-scan chokes on apr_optional.h
58
74
'apr_table_do_callback_fn_t=void', #c-scan chokes on function pointers
78
# some types c-scan failing to resolve
79
push @c_scan_defines, map { "$_=void" }
80
qw(PPADDR_t PerlExitListEntry modperl_tipool_vtbl_t);
63
C::Scan->VERSION(0.75);
83
require ModPerl::CScan;
84
ModPerl::CScan->VERSION(0.75);
68
my $c = C::Scan->new(filename => $self->{scan_filename});
70
$c->set(includeDirs => $self->includes);
89
my $c = ModPerl::CScan->new(filename => $self->{scan_filename});
91
my $includes = $self->includes;
93
# where to find perl headers, but we don't want to parse them otherwise
94
my $perl_core_path = catdir $Config{installarchlib}, "CORE";
95
push @$includes, $perl_core_path;
97
$c->set(includeDirs => $includes);
72
99
my @defines = @c_scan_defines;
99
126
require File::Find;
101
my(@dirs) = $self->include_dirs;
103
unless (-d $dirs[0]) {
104
die "could not find include directory";
108
my $unwanted = join '|', qw(ap_listen internal version
109
apr_optional mod_include mod_cgi mod_proxy
110
mod_ssl ssl_ apr_anylock apr_rmm
111
ap_config mod_log_config);
129
# don't pick preinstalled mod_perl headers if any, but pick the rest
131
my @dirs = $self->include_dirs;
132
die "could not find include directory (build the project first)"
135
my $unwanted = join '|', qw(ap_listen internal version
136
apr_optional mod_include mod_cgi
137
mod_proxy mod_ssl ssl_ apr_anylock
138
apr_rmm ap_config mod_log_config
140
my $unwanted = qr|^$unwanted|;
143
push @includes, find_includes_wanted($wanted, $unwanted, @dirs);
146
# now add the live mod_perl headers (to make sure that we always
147
# work against the latest source)
149
my @dirs = map { catdir $self->config->{cwd}, $_ }
150
catdir(qw(src modules perl)), 'xs';
153
my $wanted = join '|', qw(mod_perl modperl_);
154
$wanted = qr|^$wanted|;
156
push @includes, find_includes_wanted($wanted, $unwanted, @dirs);
159
# now reorg the header files list, so the fragile scan won't choke
165
# mod_perl.h needs to be included before other mod_perl
169
elsif (/modperl_\w+.h$/) {
172
elsif (/apr_\w+\.h$/ ) {
173
# apr headers need to be included first
180
@includes = (@apr, @rest, @mp);
182
return $self->{includes} = \@includes;
185
sub find_includes_wanted {
186
my($wanted, $unwanted, @dirs) = @_;
113
188
for my $dir (@dirs) {
114
189
File::Find::finddepth({
116
191
return unless /\.h$/;
117
return if /^($unwanted)/o;
194
return unless /$wanted/;
197
return if /$unwanted/;
118
200
my $dir = $File::Find::dir;
119
201
push @includes, "$dir/$_";
125
#include apr_*.h before the others
126
my @wanted = grep { /apr_\w+\.h$/ } @includes;
127
push @wanted, grep { !/apr_\w+\.h$/ } @includes;
129
return $self->{includes} = \@wanted;
132
209
sub generate_cscan_file {
135
212
my $includes = $self->find_includes;
137
214
my $filename = '.apache_includes';
139
215
open my $fh, '>', $filename or die "can't open $filename: $!";
141
print $fh qq(\#include "$_"\n);
217
for my $path (@$includes) {
218
my $filename = basename $path;
219
print $fh qq(\#include "$path"\n);
145
224
return $filename;
151
230
my %defines_wanted = (
153
232
common => [qw{OK DECLINED DONE}],
233
config => [qw{DECLINE_CMD}],
154
236
methods => [qw{M_ METHODS}],
237
mpmq => [qw{AP_MPMQ_}],
155
238
options => [qw{OPT_}],
239
override => [qw{OR_ ACCESS_CONF RSRC_CONF}],
240
platform => [qw{CRLF CR LF}],
241
remotehost => [qw{REMOTE_}],
156
242
satisfy => [qw{SATISFY_}],
157
remotehost => [qw{REMOTE_}],
159
config => [qw{DECLINE_CMD}],
160
243
types => [qw{DIR_MAGIC_TYPE}],
161
override => [qw{OR_ ACCESS_CONF RSRC_CONF}],
163
platform => [qw{CRLF CR LF}],
166
table => [qw{APR_OVERLAP_TABLES_}],
167
poll => [qw{APR_POLL}],
168
246
common => [qw{APR_SUCCESS}],
169
247
error => [qw{APR_E}],
248
filemode => ["APR_($filemode)"],
249
filepath => [qw{APR_FILEPATH_}],
170
250
fileperms => [qw{APR_\w(READ|WRITE|EXECUTE)}],
171
251
finfo => [qw{APR_FINFO_}],
172
filepath => [qw{APR_FILEPATH_}],
173
filemode => ["APR_($filemode)"],
174
252
flock => [qw{APR_FLOCK_}],
253
hook => [qw{APR_HOOK_}],
254
limit => [qw{APR_LIMIT}],
255
poll => [qw{APR_POLL}],
175
256
socket => [qw{APR_SO_}],
176
limit => [qw{APR_LIMIT}],
177
hook => [qw{APR_HOOK_}],
257
status => [qw{APR_TIMEUP}],
258
table => [qw{APR_OVERLAP_TABLES_}],
178
259
uri => [qw{APR_URI_}],
262
common => [qw{MODPERL_RC_}],
182
266
my %defines_wanted_re;
190
274
my %enums_wanted = (
191
Apache => { map { $_, 1 } qw(cmd_how input_mode filter_type) },
192
APR => { map { $_, 1 } qw(apr_shutdown_how apr_read_type apr_lockmech) },
275
Apache => { map { $_, 1 } qw(cmd_how input_mode filter_type conn_keepalive) },
276
APR => { map { $_, 1 } qw(apr_shutdown_how apr_read_type apr_lockmech apr_filetype) },
195
279
my $defines_unwanted = join '|', qw{
196
HTTP_VERSION APR_EOL_STR APLOG_MARK APLOG_NOERRNO
280
HTTP_VERSION APR_EOL_STR APLOG_MARK APLOG_NOERRNO APR_SO_TIMEOUT
199
283
sub get_constants {