2 ################################################################################
4 # apicheck.pl -- generate C source for automated API check
6 ################################################################################
8 # Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
9 # Version 2.x, Copyright (C) 2001, Paul Marquess.
10 # Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
12 # This program is free software; you can redistribute it and/or
13 # modify it under the same terms as Perl itself.
15 ################################################################################
18 require './parts/ppptools.pl';
22 open OUT, ">$file" or die "$file: $!\n";
28 my @f = parse_embed(qw( parts/embed.fnc parts/apidoc.fnc parts/ppport.fnc ));
30 my %todo = %{&parse_todo};
83 ORIGMARK => ['dORIGMARK;'],
84 POPpx => ['STRLEN n_a;'],
85 POPpbytex => ['STRLEN n_a;'],
94 UNDERBAR => ['dUNDERBAR;'],
95 XCPT_TRY_START => ['dXCPT;'],
96 XCPT_TRY_END => ['dXCPT;'],
97 XCPT_CATCH => ['dXCPT;'],
98 XCPT_RETHROW => ['dXCPT;'],
102 map { ($_ => 1) } qw(
117 * !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
118 * This file is built by $0.
119 * Any changes made here will be lost!
128 #ifdef DPPP_APICHECK_NO_PPPORT_H
130 /* This is just to avoid too many baseline failures with perls < 5.6.0 */
133 # define dTHX extern int Perl___notused
138 #define NEED_PL_signals
139 #define NEED_PL_parser
140 #define NEED_caller_cx
142 #define NEED_grok_bin
143 #define NEED_grok_hex
144 #define NEED_grok_number
145 #define NEED_grok_numeric_radix
146 #define NEED_grok_oct
147 #define NEED_gv_fetchpvn_flags
148 #define NEED_load_module
149 #define NEED_mg_findext
150 #define NEED_my_snprintf
151 #define NEED_my_sprintf
152 #define NEED_my_strlcat
153 #define NEED_my_strlcpy
154 #define NEED_newCONSTSUB
155 #define NEED_newRV_noinc
156 #define NEED_newSV_type
157 #define NEED_newSVpvn_flags
158 #define NEED_newSVpvn_share
159 #define NEED_pv_display
160 #define NEED_pv_escape
161 #define NEED_pv_pretty
162 #define NEED_sv_2pv_flags
163 #define NEED_sv_2pvbyte
164 #define NEED_sv_catpvf_mg
165 #define NEED_sv_catpvf_mg_nocontext
166 #define NEED_sv_pvn_force_flags
167 #define NEED_sv_setpvf_mg
168 #define NEED_sv_setpvf_mg_nocontext
169 #define NEED_sv_unmagicext
171 #define NEED_vload_module
172 #define NEED_vnewSVpvf
180 static char *VARarg2;
181 static double VARarg3;
183 #if defined(PERL_BCDVERSION) && (PERL_BCDVERSION < 0x5009005)
184 /* needed to make PL_parser apicheck work */
185 typedef void yy_parser;
191 my %want = map { ($_ => 0) } @ARGV;
192 @f = grep { exists $want{$_->{name}} } @f;
193 for (@f) { $want{$_->{name}}++ }
195 die "nothing found for '$_'\n" unless $want{$_};
201 $ignore{$f->{name}} and next;
202 $f->{flags}{A} or next; # only public API members
204 $ignore{$f->{name}} = 1; # ignore duplicates
206 my $Perl_ = $f->{flags}{p} ? 'Perl_' : '';
215 for $ca (@{$f->{args}}) {
219 push @arg, qw(VARarg1 VARarg2 VARarg3);
222 my($n, $p, $d) = $a =~ /^ (\w+(?:\s+\w+)*)\s* # type name => $n
223 (\**) # pointer => $p
224 (?:\s*const\s*)? # const
225 ((?:\[[^\]]*\])*) # dimension => $d
227 or die "$0 - cannot parse argument: [$a]\n";
228 if (exists $amap{$n}) {
229 push @arg, $amap{$n};
232 $n = $tmap{$n} || $n;
233 if ($n eq 'const char' and $p eq '*' and !$f->{flags}{f}) {
237 my $v = 'arg' . $i++;
239 $stack .= " static $n $p$v$d;\n";
243 unless ($f->{flags}{n} || $f->{flags}{'m'}) {
244 $stack = " dTHX;\n$stack";
245 $aTHX = @arg ? 'aTHX_ ' : 'aTHX';
248 if ($stack{$f->{name}}) {
250 for (@{$stack{$f->{name}}}) {
256 my $args = join ', ', @arg;
257 my $rvt = $f->{ret} || 'void';
260 $ret = $castvoid{$f->{name}} ? '(void) ' : '';
263 $stack .= " $rvt rval;\n";
264 $ret = $ignorerv{$f->{name}} ? '(void) ' : "rval = ";
266 my $aTHX_args = "$aTHX$args";
268 if (!$f->{flags}{'m'} or $f->{flags}{'b'} or @arg > 0) {
270 $aTHX_args = "($aTHX_args)";
274 /******************************************************************************
278 ******************************************************************************/
282 if ($todo{$f->{name}}) {
283 my($ver,$sub) = $todo{$f->{name}} =~ /^5\.(\d{3})(\d{3})$/ or die;
287 if ($ver < 6 && $sub > 0) {
288 $sub =~ s/0$// or die;
290 print OUT "#if PERL_VERSION > $ver || (PERL_VERSION == $ver && PERL_SUBVERSION >= $sub) /* TODO */\n";
294 ? "$Perl_$f->{name}$aTHX_args"
297 $f->{cond} and print OUT "#if $f->{cond}\n";
300 void _DPPP_test_$f->{name} (void)
314 $ret$Perl_$f->{name}$aTHX_args;
320 $f->{cond} and print OUT "#endif\n";
321 $todo{$f->{name}} and print OUT "#endif\n";