Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1518 lines
37 KiB

  1. #!./miniperl
  2. =head1 NAME
  3. xsubpp - compiler to convert Perl XS code into C code
  4. =head1 SYNOPSIS
  5. B<xsubpp> [B<-v>] [B<-C++>] [B<-except>] [B<-s pattern>] [B<-prototypes>] [B<-noversioncheck>] [B<-nolinenumbers>] [B<-typemap typemap>] [B<-object_capi>]... file.xs
  6. =head1 DESCRIPTION
  7. I<xsubpp> will compile XS code into C code by embedding the constructs
  8. necessary to let C functions manipulate Perl values and creates the glue
  9. necessary to let Perl access those functions. The compiler uses typemaps to
  10. determine how to map C function parameters and variables to Perl values.
  11. The compiler will search for typemap files called I<typemap>. It will use
  12. the following search path to find default typemaps, with the rightmost
  13. typemap taking precedence.
  14. ../../../typemap:../../typemap:../typemap:typemap
  15. =head1 OPTIONS
  16. =over 5
  17. =item B<-C++>
  18. Adds ``extern "C"'' to the C code.
  19. =item B<-except>
  20. Adds exception handling stubs to the C code.
  21. =item B<-typemap typemap>
  22. Indicates that a user-supplied typemap should take precedence over the
  23. default typemaps. This option may be used multiple times, with the last
  24. typemap having the highest precedence.
  25. =item B<-v>
  26. Prints the I<xsubpp> version number to standard output, then exits.
  27. =item B<-prototypes>
  28. By default I<xsubpp> will not automatically generate prototype code for
  29. all xsubs. This flag will enable prototypes.
  30. =item B<-noversioncheck>
  31. Disables the run time test that determines if the object file (derived
  32. from the C<.xs> file) and the C<.pm> files have the same version
  33. number.
  34. =item B<-nolinenumbers>
  35. Prevents the inclusion of `#line' directives in the output.
  36. =item B<-object_capi>
  37. Compile code as C in a PERL_OBJECT environment.
  38. back
  39. =head1 ENVIRONMENT
  40. No environment variables are used.
  41. =head1 AUTHOR
  42. Larry Wall
  43. =head1 MODIFICATION HISTORY
  44. See the file F<changes.pod>.
  45. =head1 SEE ALSO
  46. perl(1), perlxs(1), perlxstut(1)
  47. =cut
  48. require 5.002;
  49. use Cwd;
  50. use vars '$cplusplus';
  51. use vars '%v';
  52. use Config;
  53. sub Q ;
  54. # Global Constants
  55. $XSUBPP_version = "1.9507";
  56. my ($Is_VMS, $SymSet);
  57. if ($^O eq 'VMS') {
  58. $Is_VMS = 1;
  59. # Establish set of global symbols with max length 28, since xsubpp
  60. # will later add the 'XS_' prefix.
  61. require ExtUtils::XSSymSet;
  62. $SymSet = new ExtUtils::XSSymSet 28;
  63. }
  64. $FH = 'File0000' ;
  65. $usage = "Usage: xsubpp [-v] [-C++] [-except] [-prototypes] [-noversioncheck] [-nolinenumbers] [-s pattern] [-typemap typemap]... file.xs\n";
  66. $proto_re = "[" . quotemeta('\$%&*@;') . "]" ;
  67. # mjn
  68. $OBJ = 1 if $Config{'ccflags'} =~ /PERL_OBJECT/i;
  69. $except = "";
  70. $WantPrototypes = -1 ;
  71. $WantVersionChk = 1 ;
  72. $ProtoUsed = 0 ;
  73. $WantLineNumbers = 1 ;
  74. SWITCH: while (@ARGV and $ARGV[0] =~ /^-./) {
  75. $flag = shift @ARGV;
  76. $flag =~ s/^-// ;
  77. $spat = quotemeta shift, next SWITCH if $flag eq 's';
  78. $cplusplus = 1, next SWITCH if $flag eq 'C++';
  79. $WantPrototypes = 0, next SWITCH if $flag eq 'noprototypes';
  80. $WantPrototypes = 1, next SWITCH if $flag eq 'prototypes';
  81. $WantVersionChk = 0, next SWITCH if $flag eq 'noversioncheck';
  82. $WantVersionChk = 1, next SWITCH if $flag eq 'versioncheck';
  83. $WantCAPI = 1, next SWITCH if $flag eq 'object_capi';
  84. $except = " TRY", next SWITCH if $flag eq 'except';
  85. push(@tm,shift), next SWITCH if $flag eq 'typemap';
  86. $WantLineNumbers = 0, next SWITCH if $flag eq 'nolinenumbers';
  87. $WantLineNumbers = 1, next SWITCH if $flag eq 'linenumbers';
  88. (print "xsubpp version $XSUBPP_version\n"), exit
  89. if $flag eq 'v';
  90. die $usage;
  91. }
  92. if ($WantPrototypes == -1)
  93. { $WantPrototypes = 0}
  94. else
  95. { $ProtoUsed = 1 }
  96. @ARGV == 1 or die $usage;
  97. ($dir, $filename) = $ARGV[0] =~ m#(.*)/(.*)#
  98. or ($dir, $filename) = $ARGV[0] =~ m#(.*)\\(.*)#
  99. or ($dir, $filename) = $ARGV[0] =~ m#(.*[>\]])(.*)#
  100. or ($dir, $filename) = ('.', $ARGV[0]);
  101. chdir($dir);
  102. $pwd = cwd();
  103. ++ $IncludedFiles{$ARGV[0]} ;
  104. my(@XSStack) = ({type => 'none'}); # Stack of conditionals and INCLUDEs
  105. my($XSS_work_idx, $cpp_next_tmp) = (0, "XSubPPtmpAAAA");
  106. sub TrimWhitespace
  107. {
  108. $_[0] =~ s/^\s+|\s+$//go ;
  109. }
  110. sub TidyType
  111. {
  112. local ($_) = @_ ;
  113. # rationalise any '*' by joining them into bunches and removing whitespace
  114. s#\s*(\*+)\s*#$1#g;
  115. s#(\*+)# $1 #g ;
  116. # change multiple whitespace into a single space
  117. s/\s+/ /g ;
  118. # trim leading & trailing whitespace
  119. TrimWhitespace($_) ;
  120. $_ ;
  121. }
  122. $typemap = shift @ARGV;
  123. foreach $typemap (@tm) {
  124. die "Can't find $typemap in $pwd\n" unless -r $typemap;
  125. }
  126. unshift @tm, qw(../../../../lib/ExtUtils/typemap ../../../lib/ExtUtils/typemap
  127. ../../lib/ExtUtils/typemap ../../../typemap ../../typemap
  128. ../typemap typemap);
  129. foreach $typemap (@tm) {
  130. next unless -e $typemap ;
  131. # skip directories, binary files etc.
  132. warn("Warning: ignoring non-text typemap file '$typemap'\n"), next
  133. unless -T $typemap ;
  134. open(TYPEMAP, $typemap)
  135. or warn ("Warning: could not open typemap file '$typemap': $!\n"), next;
  136. $mode = 'Typemap';
  137. $junk = "" ;
  138. $current = \$junk;
  139. while (<TYPEMAP>) {
  140. next if /^\s*#/;
  141. my $line_no = $. + 1;
  142. if (/^INPUT\s*$/) { $mode = 'Input'; $current = \$junk; next; }
  143. if (/^OUTPUT\s*$/) { $mode = 'Output'; $current = \$junk; next; }
  144. if (/^TYPEMAP\s*$/) { $mode = 'Typemap'; $current = \$junk; next; }
  145. if ($mode eq 'Typemap') {
  146. chomp;
  147. my $line = $_ ;
  148. TrimWhitespace($_) ;
  149. # skip blank lines and comment lines
  150. next if /^$/ or /^#/ ;
  151. my($type,$kind, $proto) = /^\s*(.*?\S)\s+(\S+)\s*($proto_re*)\s*$/ or
  152. warn("Warning: File '$typemap' Line $. '$line' TYPEMAP entry needs 2 or 3 columns\n"), next;
  153. $type = TidyType($type) ;
  154. $type_kind{$type} = $kind ;
  155. # prototype defaults to '$'
  156. $proto = "\$" unless $proto ;
  157. warn("Warning: File '$typemap' Line $. '$line' Invalid prototype '$proto'\n")
  158. unless ValidProtoString($proto) ;
  159. $proto_letter{$type} = C_string($proto) ;
  160. }
  161. elsif (/^\s/) {
  162. $$current .= $_;
  163. }
  164. elsif ($mode eq 'Input') {
  165. s/\s+$//;
  166. $input_expr{$_} = '';
  167. $current = \$input_expr{$_};
  168. }
  169. else {
  170. s/\s+$//;
  171. $output_expr{$_} = '';
  172. $current = \$output_expr{$_};
  173. }
  174. }
  175. close(TYPEMAP);
  176. }
  177. foreach $key (keys %input_expr) {
  178. $input_expr{$key} =~ s/\n+$//;
  179. }
  180. $END = "!End!\n\n"; # "impossible" keyword (multiple newline)
  181. # Match an XS keyword
  182. $BLOCK_re= '\s*(' . join('|', qw(
  183. REQUIRE BOOT CASE PREINIT INPUT INIT CODE PPCODE OUTPUT
  184. CLEANUP ALIAS PROTOTYPES PROTOTYPE VERSIONCHECK INCLUDE
  185. SCOPE INTERFACE INTERFACE_MACRO C_ARGS
  186. )) . "|$END)\\s*:";
  187. # Input: ($_, @line) == unparsed input.
  188. # Output: ($_, @line) == (rest of line, following lines).
  189. # Return: the matched keyword if found, otherwise 0
  190. sub check_keyword {
  191. $_ = shift(@line) while !/\S/ && @line;
  192. s/^(\s*)($_[0])\s*:\s*(?:#.*)?/$1/s && $2;
  193. }
  194. if ($WantLineNumbers) {
  195. {
  196. package xsubpp::counter;
  197. sub TIEHANDLE {
  198. my ($class, $cfile) = @_;
  199. my $buf = "";
  200. $SECTION_END_MARKER = "#line --- \"$cfile\"";
  201. $line_no = 1;
  202. bless \$buf;
  203. }
  204. sub PRINT {
  205. my $self = shift;
  206. for (@_) {
  207. $$self .= $_;
  208. while ($$self =~ s/^([^\n]*\n)//) {
  209. my $line = $1;
  210. ++ $line_no;
  211. $line =~ s|^\#line\s+---(?=\s)|#line $line_no|;
  212. print STDOUT $line;
  213. }
  214. }
  215. }
  216. sub PRINTF {
  217. my $self = shift;
  218. my $fmt = shift;
  219. $self->PRINT(sprintf($fmt, @_));
  220. }
  221. sub DESTROY {
  222. # Not necessary if we're careful to end with a "\n"
  223. my $self = shift;
  224. print STDOUT $$self;
  225. }
  226. }
  227. my $cfile = $filename;
  228. $cfile =~ s/\.xs$/.c/i or $cfile .= ".c";
  229. tie(*PSEUDO_STDOUT, 'xsubpp::counter', $cfile);
  230. select PSEUDO_STDOUT;
  231. }
  232. sub print_section {
  233. # the "do" is required for right semantics
  234. do { $_ = shift(@line) } while !/\S/ && @line;
  235. print("#line ", $line_no[@line_no - @line -1], " \"$filename\"\n")
  236. if $WantLineNumbers && !/^\s*#\s*line\b/ && !/^#if XSubPPtmp/;
  237. for (; defined($_) && !/^$BLOCK_re/o; $_ = shift(@line)) {
  238. print "$_\n";
  239. }
  240. print "$xsubpp::counter::SECTION_END_MARKER\n" if $WantLineNumbers;
  241. }
  242. sub merge_section {
  243. my $in = '';
  244. while (!/\S/ && @line) {
  245. $_ = shift(@line);
  246. }
  247. for (; defined($_) && !/^$BLOCK_re/o; $_ = shift(@line)) {
  248. $in .= "$_\n";
  249. }
  250. chomp $in;
  251. return $in;
  252. }
  253. sub process_keyword($)
  254. {
  255. my($pattern) = @_ ;
  256. my $kwd ;
  257. &{"${kwd}_handler"}()
  258. while $kwd = check_keyword($pattern) ;
  259. }
  260. sub CASE_handler {
  261. blurt ("Error: `CASE:' after unconditional `CASE:'")
  262. if $condnum && $cond eq '';
  263. $cond = $_;
  264. TrimWhitespace($cond);
  265. print " ", ($condnum++ ? " else" : ""), ($cond ? " if ($cond)\n" : "\n");
  266. $_ = '' ;
  267. }
  268. sub INPUT_handler {
  269. for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
  270. last if /^\s*NOT_IMPLEMENTED_YET/;
  271. next unless /\S/; # skip blank lines
  272. TrimWhitespace($_) ;
  273. my $line = $_ ;
  274. # remove trailing semicolon if no initialisation
  275. s/\s*;$//g unless /[=;+].*\S/ ;
  276. # check for optional initialisation code
  277. my $var_init = '' ;
  278. $var_init = $1 if s/\s*([=;+].*)$//s ;
  279. $var_init =~ s/"/\\"/g;
  280. s/\s+/ /g;
  281. my ($var_type, $var_addr, $var_name) = /^(.*?[^& ]) *(\&?) *\b(\w+)$/s
  282. or blurt("Error: invalid argument declaration '$line'"), next;
  283. # Check for duplicate definitions
  284. blurt ("Error: duplicate definition of argument '$var_name' ignored"), next
  285. if $arg_list{$var_name} ++ ;
  286. $thisdone |= $var_name eq "THIS";
  287. $retvaldone |= $var_name eq "RETVAL";
  288. $var_types{$var_name} = $var_type;
  289. print "\t" . &map_type($var_type);
  290. $var_num = $args_match{$var_name};
  291. $proto_arg[$var_num] = ProtoString($var_type)
  292. if $var_num ;
  293. if ($var_addr) {
  294. $var_addr{$var_name} = 1;
  295. $func_args =~ s/\b($var_name)\b/&$1/;
  296. }
  297. if ($var_init =~ /^[=;]\s*NO_INIT\s*;?\s*$/) {
  298. print "\t$var_name;\n";
  299. } elsif ($var_init =~ /\S/) {
  300. &output_init($var_type, $var_num, $var_name, $var_init);
  301. } elsif ($var_num) {
  302. # generate initialization code
  303. &generate_init($var_type, $var_num, $var_name);
  304. } else {
  305. print ";\n";
  306. }
  307. }
  308. }
  309. sub OUTPUT_handler {
  310. for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
  311. next unless /\S/;
  312. if (/^\s*SETMAGIC\s*:\s*(ENABLE|DISABLE)\s*/) {
  313. $DoSetMagic = ($1 eq "ENABLE" ? 1 : 0);
  314. next;
  315. }
  316. my ($outarg, $outcode) = /^\s*(\S+)\s*(.*?)\s*$/s ;
  317. blurt ("Error: duplicate OUTPUT argument '$outarg' ignored"), next
  318. if $outargs{$outarg} ++ ;
  319. if (!$gotRETVAL and $outarg eq 'RETVAL') {
  320. # deal with RETVAL last
  321. $RETVAL_code = $outcode ;
  322. $gotRETVAL = 1 ;
  323. next ;
  324. }
  325. blurt ("Error: OUTPUT $outarg not an argument"), next
  326. unless defined($args_match{$outarg});
  327. blurt("Error: No input definition for OUTPUT argument '$outarg' - ignored"), next
  328. unless defined $var_types{$outarg} ;
  329. $var_num = $args_match{$outarg};
  330. if ($outcode) {
  331. print "\t$outcode\n";
  332. print "\tSvSETMAGIC(ST(" , $var_num-1 , "));\n" if $DoSetMagic;
  333. } else {
  334. &generate_output($var_types{$outarg}, $var_num, $outarg, $DoSetMagic);
  335. }
  336. }
  337. }
  338. sub C_ARGS_handler() {
  339. my $in = merge_section();
  340. TrimWhitespace($in);
  341. $func_args = $in;
  342. }
  343. sub INTERFACE_MACRO_handler() {
  344. my $in = merge_section();
  345. TrimWhitespace($in);
  346. if ($in =~ /\s/) { # two
  347. ($interface_macro, $interface_macro_set) = split ' ', $in;
  348. } else {
  349. $interface_macro = $in;
  350. $interface_macro_set = 'UNKNOWN_CVT'; # catch later
  351. }
  352. $interface = 1; # local
  353. $Interfaces = 1; # global
  354. }
  355. sub INTERFACE_handler() {
  356. my $in = merge_section();
  357. TrimWhitespace($in);
  358. foreach (split /[\s,]+/, $in) {
  359. $Interfaces{$_} = $_;
  360. }
  361. print Q<<"EOF";
  362. # XSFUNCTION = $interface_macro($ret_type,cv,XSANY.any_dptr);
  363. EOF
  364. $interface = 1; # local
  365. $Interfaces = 1; # global
  366. }
  367. sub CLEANUP_handler() { print_section() }
  368. sub PREINIT_handler() { print_section() }
  369. sub INIT_handler() { print_section() }
  370. sub GetAliases
  371. {
  372. my ($line) = @_ ;
  373. my ($orig) = $line ;
  374. my ($alias) ;
  375. my ($value) ;
  376. # Parse alias definitions
  377. # format is
  378. # alias = value alias = value ...
  379. while ($line =~ s/^\s*([\w:]+)\s*=\s*(\w+)\s*//) {
  380. $alias = $1 ;
  381. $orig_alias = $alias ;
  382. $value = $2 ;
  383. # check for optional package definition in the alias
  384. $alias = $Packprefix . $alias if $alias !~ /::/ ;
  385. # check for duplicate alias name & duplicate value
  386. Warn("Warning: Ignoring duplicate alias '$orig_alias'")
  387. if defined $XsubAliases{$alias} ;
  388. Warn("Warning: Aliases '$orig_alias' and '$XsubAliasValues{$value}' have identical values")
  389. if $XsubAliasValues{$value} ;
  390. $XsubAliases = 1;
  391. $XsubAliases{$alias} = $value ;
  392. $XsubAliasValues{$value} = $orig_alias ;
  393. }
  394. blurt("Error: Cannot parse ALIAS definitions from '$orig'")
  395. if $line ;
  396. }
  397. sub ALIAS_handler ()
  398. {
  399. for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
  400. next unless /\S/;
  401. TrimWhitespace($_) ;
  402. GetAliases($_) if $_ ;
  403. }
  404. }
  405. sub REQUIRE_handler ()
  406. {
  407. # the rest of the current line should contain a version number
  408. my ($Ver) = $_ ;
  409. TrimWhitespace($Ver) ;
  410. death ("Error: REQUIRE expects a version number")
  411. unless $Ver ;
  412. # check that the version number is of the form n.n
  413. death ("Error: REQUIRE: expected a number, got '$Ver'")
  414. unless $Ver =~ /^\d+(\.\d*)?/ ;
  415. death ("Error: xsubpp $Ver (or better) required--this is only $XSUBPP_version.")
  416. unless $XSUBPP_version >= $Ver ;
  417. }
  418. sub VERSIONCHECK_handler ()
  419. {
  420. # the rest of the current line should contain either ENABLE or
  421. # DISABLE
  422. TrimWhitespace($_) ;
  423. # check for ENABLE/DISABLE
  424. death ("Error: VERSIONCHECK: ENABLE/DISABLE")
  425. unless /^(ENABLE|DISABLE)/i ;
  426. $WantVersionChk = 1 if $1 eq 'ENABLE' ;
  427. $WantVersionChk = 0 if $1 eq 'DISABLE' ;
  428. }
  429. sub PROTOTYPE_handler ()
  430. {
  431. my $specified ;
  432. death("Error: Only 1 PROTOTYPE definition allowed per xsub")
  433. if $proto_in_this_xsub ++ ;
  434. for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
  435. next unless /\S/;
  436. $specified = 1 ;
  437. TrimWhitespace($_) ;
  438. if ($_ eq 'DISABLE') {
  439. $ProtoThisXSUB = 0
  440. }
  441. elsif ($_ eq 'ENABLE') {
  442. $ProtoThisXSUB = 1
  443. }
  444. else {
  445. # remove any whitespace
  446. s/\s+//g ;
  447. death("Error: Invalid prototype '$_'")
  448. unless ValidProtoString($_) ;
  449. $ProtoThisXSUB = C_string($_) ;
  450. }
  451. }
  452. # If no prototype specified, then assume empty prototype ""
  453. $ProtoThisXSUB = 2 unless $specified ;
  454. $ProtoUsed = 1 ;
  455. }
  456. sub SCOPE_handler ()
  457. {
  458. death("Error: Only 1 SCOPE declaration allowed per xsub")
  459. if $scope_in_this_xsub ++ ;
  460. for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
  461. next unless /\S/;
  462. TrimWhitespace($_) ;
  463. if ($_ =~ /^DISABLE/i) {
  464. $ScopeThisXSUB = 0
  465. }
  466. elsif ($_ =~ /^ENABLE/i) {
  467. $ScopeThisXSUB = 1
  468. }
  469. }
  470. }
  471. sub PROTOTYPES_handler ()
  472. {
  473. # the rest of the current line should contain either ENABLE or
  474. # DISABLE
  475. TrimWhitespace($_) ;
  476. # check for ENABLE/DISABLE
  477. death ("Error: PROTOTYPES: ENABLE/DISABLE")
  478. unless /^(ENABLE|DISABLE)/i ;
  479. $WantPrototypes = 1 if $1 eq 'ENABLE' ;
  480. $WantPrototypes = 0 if $1 eq 'DISABLE' ;
  481. $ProtoUsed = 1 ;
  482. }
  483. sub INCLUDE_handler ()
  484. {
  485. # the rest of the current line should contain a valid filename
  486. TrimWhitespace($_) ;
  487. death("INCLUDE: filename missing")
  488. unless $_ ;
  489. death("INCLUDE: output pipe is illegal")
  490. if /^\s*\|/ ;
  491. # simple minded recursion detector
  492. death("INCLUDE loop detected")
  493. if $IncludedFiles{$_} ;
  494. ++ $IncludedFiles{$_} unless /\|\s*$/ ;
  495. # Save the current file context.
  496. push(@XSStack, {
  497. type => 'file',
  498. LastLine => $lastline,
  499. LastLineNo => $lastline_no,
  500. Line => \@line,
  501. LineNo => \@line_no,
  502. Filename => $filename,
  503. Handle => $FH,
  504. }) ;
  505. ++ $FH ;
  506. # open the new file
  507. open ($FH, "$_") or death("Cannot open '$_': $!") ;
  508. print Q<<"EOF" ;
  509. #
  510. #/* INCLUDE: Including '$_' from '$filename' */
  511. #
  512. EOF
  513. $filename = $_ ;
  514. # Prime the pump by reading the first
  515. # non-blank line
  516. # skip leading blank lines
  517. while (<$FH>) {
  518. last unless /^\s*$/ ;
  519. }
  520. $lastline = $_ ;
  521. $lastline_no = $. ;
  522. }
  523. sub PopFile()
  524. {
  525. return 0 unless $XSStack[-1]{type} eq 'file' ;
  526. my $data = pop @XSStack ;
  527. my $ThisFile = $filename ;
  528. my $isPipe = ($filename =~ /\|\s*$/) ;
  529. -- $IncludedFiles{$filename}
  530. unless $isPipe ;
  531. close $FH ;
  532. $FH = $data->{Handle} ;
  533. $filename = $data->{Filename} ;
  534. $lastline = $data->{LastLine} ;
  535. $lastline_no = $data->{LastLineNo} ;
  536. @line = @{ $data->{Line} } ;
  537. @line_no = @{ $data->{LineNo} } ;
  538. if ($isPipe and $? ) {
  539. -- $lastline_no ;
  540. print STDERR "Error reading from pipe '$ThisFile': $! in $filename, line $lastline_no\n" ;
  541. exit 1 ;
  542. }
  543. print Q<<"EOF" ;
  544. #
  545. #/* INCLUDE: Returning to '$filename' from '$ThisFile' */
  546. #
  547. EOF
  548. return 1 ;
  549. }
  550. sub ValidProtoString ($)
  551. {
  552. my($string) = @_ ;
  553. if ( $string =~ /^$proto_re+$/ ) {
  554. return $string ;
  555. }
  556. return 0 ;
  557. }
  558. sub C_string ($)
  559. {
  560. my($string) = @_ ;
  561. $string =~ s[\\][\\\\]g ;
  562. $string ;
  563. }
  564. sub ProtoString ($)
  565. {
  566. my ($type) = @_ ;
  567. $proto_letter{$type} or "\$" ;
  568. }
  569. sub check_cpp {
  570. my @cpp = grep(/^\#\s*(?:if|e\w+)/, @line);
  571. if (@cpp) {
  572. my ($cpp, $cpplevel);
  573. for $cpp (@cpp) {
  574. if ($cpp =~ /^\#\s*if/) {
  575. $cpplevel++;
  576. } elsif (!$cpplevel) {
  577. Warn("Warning: #else/elif/endif without #if in this function");
  578. print STDERR " (precede it with a blank line if the matching #if is outside the function)\n"
  579. if $XSStack[-1]{type} eq 'if';
  580. return;
  581. } elsif ($cpp =~ /^\#\s*endif/) {
  582. $cpplevel--;
  583. }
  584. }
  585. Warn("Warning: #if without #endif in this function") if $cpplevel;
  586. }
  587. }
  588. sub Q {
  589. my($text) = @_;
  590. $text =~ s/^#//gm;
  591. $text =~ s/\[\[/{/g;
  592. $text =~ s/\]\]/}/g;
  593. $text;
  594. }
  595. open($FH, $filename) or die "cannot open $filename: $!\n";
  596. # Identify the version of xsubpp used
  597. print <<EOM ;
  598. /*
  599. * This file was generated automatically by xsubpp version $XSUBPP_version from the
  600. * contents of $filename. Do not edit this file, edit $filename instead.
  601. *
  602. * ANY CHANGES MADE HERE WILL BE LOST!
  603. *
  604. */
  605. EOM
  606. print("#line 1 \"$filename\"\n")
  607. if $WantLineNumbers;
  608. while (<$FH>) {
  609. last if ($Module, $Package, $Prefix) =
  610. /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/;
  611. if ($OBJ) {
  612. s/#if(?:def\s|\s+defined)\s*(\(__cplusplus\)|__cplusplus)/#if defined(__cplusplus) && !defined(PERL_OBJECT)/;
  613. }
  614. print $_;
  615. }
  616. &Exit unless defined $_;
  617. print "$xsubpp::counter::SECTION_END_MARKER\n" if $WantLineNumbers;
  618. $lastline = $_;
  619. $lastline_no = $.;
  620. # Read next xsub into @line from ($lastline, <$FH>).
  621. sub fetch_para {
  622. # parse paragraph
  623. death ("Error: Unterminated `#if/#ifdef/#ifndef'")
  624. if !defined $lastline && $XSStack[-1]{type} eq 'if';
  625. @line = ();
  626. @line_no = () ;
  627. return PopFile() if !defined $lastline;
  628. if ($lastline =~
  629. /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/) {
  630. $Module = $1;
  631. $Package = defined($2) ? $2 : ''; # keep -w happy
  632. $Prefix = defined($3) ? $3 : ''; # keep -w happy
  633. $Prefix = quotemeta $Prefix ;
  634. ($Module_cname = $Module) =~ s/\W/_/g;
  635. ($Packid = $Package) =~ tr/:/_/;
  636. $Packprefix = $Package;
  637. $Packprefix .= "::" if $Packprefix ne "";
  638. $lastline = "";
  639. }
  640. for(;;) {
  641. if ($lastline !~ /^\s*#/ ||
  642. # CPP directives:
  643. # ANSI: if ifdef ifndef elif else endif define undef
  644. # line error pragma
  645. # gcc: warning include_next
  646. # obj-c: import
  647. # others: ident (gcc notes that some cpps have this one)
  648. $lastline =~ /^#[ \t]*(?:(?:if|ifn?def|elif|else|endif|define|undef|pragma|error|warning|line\s+\d+|ident)\b|(?:include(?:_next)?|import)\s*["<].*[>"])/) {
  649. last if $lastline =~ /^\S/ && @line && $line[-1] eq "";
  650. push(@line, $lastline);
  651. push(@line_no, $lastline_no) ;
  652. }
  653. # Read next line and continuation lines
  654. last unless defined($lastline = <$FH>);
  655. $lastline_no = $.;
  656. my $tmp_line;
  657. $lastline .= $tmp_line
  658. while ($lastline =~ /\\$/ && defined($tmp_line = <$FH>));
  659. chomp $lastline;
  660. $lastline =~ s/^\s+$//;
  661. }
  662. pop(@line), pop(@line_no) while @line && $line[-1] eq "";
  663. 1;
  664. }
  665. PARAGRAPH:
  666. while (fetch_para()) {
  667. # Print initial preprocessor statements and blank lines
  668. while (@line && $line[0] !~ /^[^\#]/) {
  669. my $line = shift(@line);
  670. print $line, "\n";
  671. next unless $line =~ /^\#\s*((if)(?:n?def)?|elsif|else|endif)\b/;
  672. my $statement = $+;
  673. if ($statement eq 'if') {
  674. $XSS_work_idx = @XSStack;
  675. push(@XSStack, {type => 'if'});
  676. } else {
  677. death ("Error: `$statement' with no matching `if'")
  678. if $XSStack[-1]{type} ne 'if';
  679. if ($XSStack[-1]{varname}) {
  680. push(@InitFileCode, "#endif\n");
  681. push(@BootCode, "#endif");
  682. }
  683. my(@fns) = keys %{$XSStack[-1]{functions}};
  684. if ($statement ne 'endif') {
  685. # Hide the functions defined in other #if branches, and reset.
  686. @{$XSStack[-1]{other_functions}}{@fns} = (1) x @fns;
  687. @{$XSStack[-1]}{qw(varname functions)} = ('', {});
  688. } else {
  689. my($tmp) = pop(@XSStack);
  690. 0 while (--$XSS_work_idx
  691. && $XSStack[$XSS_work_idx]{type} ne 'if');
  692. # Keep all new defined functions
  693. push(@fns, keys %{$tmp->{other_functions}});
  694. @{$XSStack[$XSS_work_idx]{functions}}{@fns} = (1) x @fns;
  695. }
  696. }
  697. }
  698. next PARAGRAPH unless @line;
  699. if ($XSS_work_idx && !$XSStack[$XSS_work_idx]{varname}) {
  700. # We are inside an #if, but have not yet #defined its xsubpp variable.
  701. print "#define $cpp_next_tmp 1\n\n";
  702. push(@InitFileCode, "#if $cpp_next_tmp\n");
  703. push(@BootCode, "#if $cpp_next_tmp");
  704. $XSStack[$XSS_work_idx]{varname} = $cpp_next_tmp++;
  705. }
  706. death ("Code is not inside a function"
  707. ." (maybe last function was ended by a blank line "
  708. ." followed by a a statement on column one?)")
  709. if $line[0] =~ /^\s/;
  710. # initialize info arrays
  711. undef(%args_match);
  712. undef(%var_types);
  713. undef(%var_addr);
  714. undef(%defaults);
  715. undef($class);
  716. undef($static);
  717. undef($elipsis);
  718. undef($wantRETVAL) ;
  719. undef(%arg_list) ;
  720. undef(@proto_arg) ;
  721. undef($proto_in_this_xsub) ;
  722. undef($scope_in_this_xsub) ;
  723. undef($interface);
  724. $interface_macro = 'XSINTERFACE_FUNC' ;
  725. $interface_macro_set = 'XSINTERFACE_FUNC_SET' ;
  726. $ProtoThisXSUB = $WantPrototypes ;
  727. $ScopeThisXSUB = 0;
  728. $_ = shift(@line);
  729. while ($kwd = check_keyword("REQUIRE|PROTOTYPES|VERSIONCHECK|INCLUDE")) {
  730. &{"${kwd}_handler"}() ;
  731. next PARAGRAPH unless @line ;
  732. $_ = shift(@line);
  733. }
  734. if (check_keyword("BOOT")) {
  735. &check_cpp;
  736. push (@BootCode, "#line $line_no[@line_no - @line] \"$filename\"")
  737. if $WantLineNumbers && $line[0] !~ /^\s*#\s*line\b/;
  738. push (@BootCode, @line, "") ;
  739. next PARAGRAPH ;
  740. }
  741. # extract return type, function name and arguments
  742. ($ret_type) = TidyType($_);
  743. # a function definition needs at least 2 lines
  744. blurt ("Error: Function definition too short '$ret_type'"), next PARAGRAPH
  745. unless @line ;
  746. $static = 1 if $ret_type =~ s/^static\s+//;
  747. $func_header = shift(@line);
  748. blurt ("Error: Cannot parse function definition from '$func_header'"), next PARAGRAPH
  749. unless $func_header =~ /^(?:([\w:]*)::)?(\w+)\s*\(\s*(.*?)\s*\)\s*(const)?\s*$/s;
  750. ($class, $func_name, $orig_args) = ($1, $2, $3) ;
  751. $class = "$4 $class" if $4;
  752. ($pname = $func_name) =~ s/^($Prefix)?/$Packprefix/;
  753. ($clean_func_name = $func_name) =~ s/^$Prefix//;
  754. $Full_func_name = "${Packid}_$clean_func_name";
  755. if ($Is_VMS) { $Full_func_name = $SymSet->addsym($Full_func_name); }
  756. # Check for duplicate function definition
  757. for $tmp (@XSStack) {
  758. next unless defined $tmp->{functions}{$Full_func_name};
  759. Warn("Warning: duplicate function definition '$clean_func_name' detected");
  760. last;
  761. }
  762. $XSStack[$XSS_work_idx]{functions}{$Full_func_name} ++ ;
  763. %XsubAliases = %XsubAliasValues = %Interfaces = ();
  764. $DoSetMagic = 1;
  765. @args = split(/\s*,\s*/, $orig_args);
  766. if (defined($class)) {
  767. my $arg0 = ((defined($static) or $func_name eq 'new')
  768. ? "CLASS" : "THIS");
  769. unshift(@args, $arg0);
  770. ($orig_args = "$arg0, $orig_args") =~ s/^$arg0, $/$arg0/;
  771. }
  772. $orig_args =~ s/"/\\"/g;
  773. $min_args = $num_args = @args;
  774. foreach $i (0..$num_args-1) {
  775. if ($args[$i] =~ s/\.\.\.//) {
  776. $elipsis = 1;
  777. $min_args--;
  778. if ($args[$i] eq '' && $i == $num_args - 1) {
  779. pop(@args);
  780. last;
  781. }
  782. }
  783. if ($args[$i] =~ /^([^=]*[^\s=])\s*=\s*(.*)/s) {
  784. $min_args--;
  785. $args[$i] = $1;
  786. $defaults{$args[$i]} = $2;
  787. $defaults{$args[$i]} =~ s/"/\\"/g;
  788. }
  789. $proto_arg[$i+1] = "\$" ;
  790. }
  791. if (defined($class)) {
  792. $func_args = join(", ", @args[1..$#args]);
  793. } else {
  794. $func_args = join(", ", @args);
  795. }
  796. @args_match{@args} = 1..@args;
  797. $PPCODE = grep(/^\s*PPCODE\s*:/, @line);
  798. $CODE = grep(/^\s*CODE\s*:/, @line);
  799. # Detect CODE: blocks which use ST(n)= or XST_m*(n,v)
  800. # to set explicit return values.
  801. $EXPLICIT_RETURN = ($CODE &&
  802. ("@line" =~ /(\bST\s*\([^;]*=) | (\bXST_m\w+\s*\()/x ));
  803. $ALIAS = grep(/^\s*ALIAS\s*:/, @line);
  804. $INTERFACE = grep(/^\s*INTERFACE\s*:/, @line);
  805. # print function header
  806. print Q<<"EOF";
  807. #XS(XS_${Full_func_name})
  808. #[[
  809. # dXSARGS;
  810. EOF
  811. print Q<<"EOF" if $ALIAS ;
  812. # dXSI32;
  813. EOF
  814. print Q<<"EOF" if $INTERFACE ;
  815. # dXSFUNCTION($ret_type);
  816. EOF
  817. if ($elipsis) {
  818. $cond = ($min_args ? qq(items < $min_args) : 0);
  819. }
  820. elsif ($min_args == $num_args) {
  821. $cond = qq(items != $min_args);
  822. }
  823. else {
  824. $cond = qq(items < $min_args || items > $num_args);
  825. }
  826. print Q<<"EOF" if $except;
  827. # char errbuf[1024];
  828. # *errbuf = '\0';
  829. EOF
  830. if ($ALIAS)
  831. { print Q<<"EOF" if $cond }
  832. # if ($cond)
  833. # croak("Usage: %s($orig_args)", GvNAME(CvGV(cv)));
  834. EOF
  835. else
  836. { print Q<<"EOF" if $cond }
  837. # if ($cond)
  838. # croak("Usage: $pname($orig_args)");
  839. EOF
  840. print Q<<"EOF" if $PPCODE;
  841. # SP -= items;
  842. EOF
  843. # Now do a block of some sort.
  844. $condnum = 0;
  845. $cond = ''; # last CASE: condidional
  846. push(@line, "$END:");
  847. push(@line_no, $line_no[-1]);
  848. $_ = '';
  849. &check_cpp;
  850. while (@line) {
  851. &CASE_handler if check_keyword("CASE");
  852. print Q<<"EOF";
  853. # $except [[
  854. EOF
  855. # do initialization of input variables
  856. $thisdone = 0;
  857. $retvaldone = 0;
  858. $deferred = "";
  859. %arg_list = () ;
  860. $gotRETVAL = 0;
  861. INPUT_handler() ;
  862. process_keyword("INPUT|PREINIT|INTERFACE_MACRO|C_ARGS|ALIAS|PROTOTYPE|SCOPE") ;
  863. print Q<<"EOF" if $ScopeThisXSUB;
  864. # ENTER;
  865. # [[
  866. EOF
  867. if (!$thisdone && defined($class)) {
  868. if (defined($static) or $func_name eq 'new') {
  869. print "\tchar *";
  870. $var_types{"CLASS"} = "char *";
  871. &generate_init("char *", 1, "CLASS");
  872. }
  873. else {
  874. print "\t$class *";
  875. $var_types{"THIS"} = "$class *";
  876. &generate_init("$class *", 1, "THIS");
  877. }
  878. }
  879. # do code
  880. if (/^\s*NOT_IMPLEMENTED_YET/) {
  881. print "\n\tcroak(\"$pname: not implemented yet\");\n";
  882. $_ = '' ;
  883. } else {
  884. if ($ret_type ne "void") {
  885. print "\t" . &map_type($ret_type) . "\tRETVAL;\n"
  886. if !$retvaldone;
  887. $args_match{"RETVAL"} = 0;
  888. $var_types{"RETVAL"} = $ret_type;
  889. }
  890. print $deferred;
  891. process_keyword("INIT|ALIAS|PROTOTYPE|INTERFACE_MACRO|INTERFACE|C_ARGS") ;
  892. if (check_keyword("PPCODE")) {
  893. print_section();
  894. death ("PPCODE must be last thing") if @line;
  895. print "\tLEAVE;\n" if $ScopeThisXSUB;
  896. print "\tPUTBACK;\n\treturn;\n";
  897. } elsif (check_keyword("CODE")) {
  898. print_section() ;
  899. } elsif (defined($class) and $func_name eq "DESTROY") {
  900. print "\n\t";
  901. print "delete THIS;\n";
  902. } else {
  903. print "\n\t";
  904. if ($ret_type ne "void") {
  905. print "RETVAL = ";
  906. $wantRETVAL = 1;
  907. }
  908. if (defined($static)) {
  909. if ($func_name eq 'new') {
  910. $func_name = "$class";
  911. } else {
  912. print "${class}::";
  913. }
  914. } elsif (defined($class)) {
  915. if ($func_name eq 'new') {
  916. $func_name .= " $class";
  917. } else {
  918. print "THIS->";
  919. }
  920. }
  921. $func_name =~ s/^($spat)//
  922. if defined($spat);
  923. $func_name = 'XSFUNCTION' if $interface;
  924. print "$func_name($func_args);\n";
  925. }
  926. }
  927. # do output variables
  928. $gotRETVAL = 0;
  929. undef $RETVAL_code ;
  930. undef %outargs ;
  931. process_keyword("OUTPUT|ALIAS|PROTOTYPE");
  932. # all OUTPUT done, so now push the return value on the stack
  933. if ($gotRETVAL && $RETVAL_code) {
  934. print "\t$RETVAL_code\n";
  935. } elsif ($gotRETVAL || $wantRETVAL) {
  936. # RETVAL almost never needs SvSETMAGIC()
  937. &generate_output($ret_type, 0, 'RETVAL', 0);
  938. }
  939. # do cleanup
  940. process_keyword("CLEANUP|ALIAS|PROTOTYPE") ;
  941. print Q<<"EOF" if $ScopeThisXSUB;
  942. # ]]
  943. EOF
  944. print Q<<"EOF" if $ScopeThisXSUB and not $PPCODE;
  945. # LEAVE;
  946. EOF
  947. # print function trailer
  948. print Q<<EOF;
  949. # ]]
  950. EOF
  951. print Q<<EOF if $except;
  952. # BEGHANDLERS
  953. # CATCHALL
  954. # sprintf(errbuf, "%s: %s\\tpropagated", Xname, Xreason);
  955. # ENDHANDLERS
  956. EOF
  957. if (check_keyword("CASE")) {
  958. blurt ("Error: No `CASE:' at top of function")
  959. unless $condnum;
  960. $_ = "CASE: $_"; # Restore CASE: label
  961. next;
  962. }
  963. last if $_ eq "$END:";
  964. death(/^$BLOCK_re/o ? "Misplaced `$1:'" : "Junk at end of function");
  965. }
  966. print Q<<EOF if $except;
  967. # if (errbuf[0])
  968. # croak(errbuf);
  969. EOF
  970. if ($ret_type ne "void" or $EXPLICIT_RETURN) {
  971. print Q<<EOF unless $PPCODE;
  972. # XSRETURN(1);
  973. EOF
  974. } else {
  975. print Q<<EOF unless $PPCODE;
  976. # XSRETURN_EMPTY;
  977. EOF
  978. }
  979. print Q<<EOF;
  980. #]]
  981. #
  982. EOF
  983. my $newXS = "newXS" ;
  984. my $proto = "" ;
  985. # Build the prototype string for the xsub
  986. if ($ProtoThisXSUB) {
  987. $newXS = "newXSproto";
  988. if ($ProtoThisXSUB eq 2) {
  989. # User has specified empty prototype
  990. $proto = ', ""' ;
  991. }
  992. elsif ($ProtoThisXSUB ne 1) {
  993. # User has specified a prototype
  994. $proto = ', "' . $ProtoThisXSUB . '"';
  995. }
  996. else {
  997. my $s = ';';
  998. if ($min_args < $num_args) {
  999. $s = '';
  1000. $proto_arg[$min_args] .= ";" ;
  1001. }
  1002. push @proto_arg, "$s\@"
  1003. if $elipsis ;
  1004. $proto = ', "' . join ("", @proto_arg) . '"';
  1005. }
  1006. }
  1007. if (%XsubAliases) {
  1008. $XsubAliases{$pname} = 0
  1009. unless defined $XsubAliases{$pname} ;
  1010. while ( ($name, $value) = each %XsubAliases) {
  1011. push(@InitFileCode, Q<<"EOF");
  1012. # cv = newXS(\"$name\", XS_$Full_func_name, file);
  1013. # XSANY.any_i32 = $value ;
  1014. EOF
  1015. push(@InitFileCode, Q<<"EOF") if $proto;
  1016. # sv_setpv((SV*)cv$proto) ;
  1017. EOF
  1018. }
  1019. }
  1020. elsif ($interface) {
  1021. while ( ($name, $value) = each %Interfaces) {
  1022. $name = "$Package\::$name" unless $name =~ /::/;
  1023. push(@InitFileCode, Q<<"EOF");
  1024. # cv = newXS(\"$name\", XS_$Full_func_name, file);
  1025. # $interface_macro_set(cv,$value) ;
  1026. EOF
  1027. push(@InitFileCode, Q<<"EOF") if $proto;
  1028. # sv_setpv((SV*)cv$proto) ;
  1029. EOF
  1030. }
  1031. }
  1032. else {
  1033. push(@InitFileCode,
  1034. " ${newXS}(\"$pname\", XS_$Full_func_name, file$proto);\n");
  1035. }
  1036. }
  1037. # print initialization routine
  1038. print Q<<"EOF";
  1039. ##ifdef __cplusplus
  1040. #extern "C"
  1041. ##endif
  1042. EOF
  1043. if ($WantCAPI) {
  1044. print Q<<"EOF";
  1045. ##ifdef PERL_CAPI
  1046. #XS(boot__CAPI_entry)
  1047. ##else
  1048. EOF
  1049. }
  1050. print Q<<"EOF";
  1051. #XS(boot_$Module_cname)
  1052. EOF
  1053. if ($WantCAPI) {
  1054. print Q<<"EOF";
  1055. ##endif /* PERL_CAPI */
  1056. EOF
  1057. }
  1058. print Q<<"EOF";
  1059. #[[
  1060. # dXSARGS;
  1061. # char* file = __FILE__;
  1062. #
  1063. EOF
  1064. print Q<<"EOF" if $WantVersionChk ;
  1065. # XS_VERSION_BOOTCHECK ;
  1066. #
  1067. EOF
  1068. print Q<<"EOF" if defined $XsubAliases or defined $Interfaces ;
  1069. # {
  1070. # CV * cv ;
  1071. #
  1072. EOF
  1073. print @InitFileCode;
  1074. print Q<<"EOF" if defined $XsubAliases or defined $Interfaces ;
  1075. # }
  1076. EOF
  1077. if (@BootCode)
  1078. {
  1079. print "\n /* Initialisation Section */\n\n" ;
  1080. @line = @BootCode;
  1081. print_section();
  1082. print "\n /* End of Initialisation Section */\n\n" ;
  1083. }
  1084. print Q<<"EOF";;
  1085. # XSRETURN_YES;
  1086. #]]
  1087. #
  1088. EOF
  1089. if ($WantCAPI) {
  1090. print Q<<"EOF";
  1091. ##ifdef PERL_CAPI
  1092. ##define XSCAPI(name) void name(CV* cv, void* pPerl)
  1093. #
  1094. ##ifdef __cplusplus
  1095. #extern "C"
  1096. ##endif
  1097. #XSCAPI(boot_$Module_cname)
  1098. #[[
  1099. # boot_CAPI_handler(cv, boot__CAPI_entry, pPerl);
  1100. #]]
  1101. ##endif /* PERL_CAPI */
  1102. EOF
  1103. }
  1104. warn("Please specify prototyping behavior for $filename (see perlxs manual)\n")
  1105. unless $ProtoUsed ;
  1106. &Exit;
  1107. sub output_init {
  1108. local($type, $num, $var, $init) = @_;
  1109. local($arg) = "ST(" . ($num - 1) . ")";
  1110. if( $init =~ /^=/ ) {
  1111. eval qq/print "\\t$var $init\\n"/;
  1112. warn $@ if $@;
  1113. } else {
  1114. if( $init =~ s/^\+// && $num ) {
  1115. &generate_init($type, $num, $var);
  1116. } else {
  1117. eval qq/print "\\t$var;\\n"/;
  1118. warn $@ if $@;
  1119. $init =~ s/^;//;
  1120. }
  1121. $deferred .= eval qq/"\\n\\t$init\\n"/;
  1122. warn $@ if $@;
  1123. }
  1124. }
  1125. sub Warn
  1126. {
  1127. # work out the line number
  1128. my $line_no = $line_no[@line_no - @line -1] ;
  1129. print STDERR "@_ in $filename, line $line_no\n" ;
  1130. }
  1131. sub blurt
  1132. {
  1133. Warn @_ ;
  1134. $errors ++
  1135. }
  1136. sub death
  1137. {
  1138. Warn @_ ;
  1139. exit 1 ;
  1140. }
  1141. sub generate_init {
  1142. local($type, $num, $var) = @_;
  1143. local($arg) = "ST(" . ($num - 1) . ")";
  1144. local($argoff) = $num - 1;
  1145. local($ntype);
  1146. local($tk);
  1147. $type = TidyType($type) ;
  1148. blurt("Error: '$type' not in typemap"), return
  1149. unless defined($type_kind{$type});
  1150. ($ntype = $type) =~ s/\s*\*/Ptr/g;
  1151. ($subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
  1152. $tk = $type_kind{$type};
  1153. $tk =~ s/OBJ$/REF/ if $func_name =~ /DESTROY$/;
  1154. $type =~ tr/:/_/;
  1155. blurt("Error: No INPUT definition for type '$type' found"), return
  1156. unless defined $input_expr{$tk} ;
  1157. $expr = $input_expr{$tk};
  1158. if ($expr =~ /DO_ARRAY_ELEM/) {
  1159. blurt("Error: '$subtype' not in typemap"), return
  1160. unless defined($type_kind{$subtype});
  1161. blurt("Error: No INPUT definition for type '$subtype' found"), return
  1162. unless defined $input_expr{$type_kind{$subtype}} ;
  1163. $subexpr = $input_expr{$type_kind{$subtype}};
  1164. $subexpr =~ s/ntype/subtype/g;
  1165. $subexpr =~ s/\$arg/ST(ix_$var)/g;
  1166. $subexpr =~ s/\n\t/\n\t\t/g;
  1167. $subexpr =~ s/is not of (.*\")/[arg %d] is not of $1, ix_$var + 1/g;
  1168. $subexpr =~ s/\$var/${var}[ix_$var - $argoff]/;
  1169. $expr =~ s/DO_ARRAY_ELEM/$subexpr/;
  1170. }
  1171. if ($expr =~ m#/\*.*scope.*\*/#i) { # "scope" in C comments
  1172. $ScopeThisXSUB = 1;
  1173. }
  1174. if (defined($defaults{$var})) {
  1175. $expr =~ s/(\t+)/$1 /g;
  1176. $expr =~ s/ /\t/g;
  1177. eval qq/print "\\t$var;\\n"/;
  1178. warn $@ if $@;
  1179. $deferred .= eval qq/"\\n\\tif (items < $num)\\n\\t $var = $defaults{$var};\\n\\telse {\\n$expr;\\n\\t}\\n"/;
  1180. warn $@ if $@;
  1181. } elsif ($ScopeThisXSUB or $expr !~ /^\t\$var =/) {
  1182. eval qq/print "\\t$var;\\n"/;
  1183. warn $@ if $@;
  1184. $deferred .= eval qq/"\\n$expr;\\n"/;
  1185. warn $@ if $@;
  1186. } else {
  1187. eval qq/print "$expr;\\n"/;
  1188. warn $@ if $@;
  1189. }
  1190. }
  1191. sub generate_output {
  1192. local($type, $num, $var, $do_setmagic) = @_;
  1193. local($arg) = "ST(" . ($num - ($num != 0)) . ")";
  1194. local($argoff) = $num - 1;
  1195. local($ntype);
  1196. $type = TidyType($type) ;
  1197. if ($type =~ /^array\(([^,]*),(.*)\)/) {
  1198. print "\tsv_setpvn($arg, (char *)$var, $2 * sizeof($1)), XFree((char *)$var);\n";
  1199. print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
  1200. } else {
  1201. blurt("Error: '$type' not in typemap"), return
  1202. unless defined($type_kind{$type});
  1203. blurt("Error: No OUTPUT definition for type '$type' found"), return
  1204. unless defined $output_expr{$type_kind{$type}} ;
  1205. ($ntype = $type) =~ s/\s*\*/Ptr/g;
  1206. $ntype =~ s/\(\)//g;
  1207. ($subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
  1208. $expr = $output_expr{$type_kind{$type}};
  1209. if ($expr =~ /DO_ARRAY_ELEM/) {
  1210. blurt("Error: '$subtype' not in typemap"), return
  1211. unless defined($type_kind{$subtype});
  1212. blurt("Error: No OUTPUT definition for type '$subtype' found"), return
  1213. unless defined $output_expr{$type_kind{$subtype}} ;
  1214. $subexpr = $output_expr{$type_kind{$subtype}};
  1215. $subexpr =~ s/ntype/subtype/g;
  1216. $subexpr =~ s/\$arg/ST(ix_$var)/g;
  1217. $subexpr =~ s/\$var/${var}[ix_$var]/g;
  1218. $subexpr =~ s/\n\t/\n\t\t/g;
  1219. $expr =~ s/DO_ARRAY_ELEM\n/$subexpr/;
  1220. eval "print qq\a$expr\a";
  1221. warn $@ if $@;
  1222. print "\t\tSvSETMAGIC(ST(ix_$var));\n" if $do_setmagic;
  1223. }
  1224. elsif ($var eq 'RETVAL') {
  1225. if ($expr =~ /^\t\$arg = new/) {
  1226. # We expect that $arg has refcnt 1, so we need to
  1227. # mortalize it.
  1228. eval "print qq\a$expr\a";
  1229. warn $@ if $@;
  1230. print "\tsv_2mortal(ST(0));\n";
  1231. print "\tSvSETMAGIC(ST(0));\n" if $do_setmagic;
  1232. }
  1233. elsif ($expr =~ /^\s*\$arg\s*=/) {
  1234. # We expect that $arg has refcnt >=1, so we need
  1235. # to mortalize it!
  1236. eval "print qq\a$expr\a";
  1237. warn $@ if $@;
  1238. print "\tsv_2mortal(ST(0));\n";
  1239. print "\tSvSETMAGIC(ST(0));\n" if $do_setmagic;
  1240. }
  1241. else {
  1242. # Just hope that the entry would safely write it
  1243. # over an already mortalized value. By
  1244. # coincidence, something like $arg = &sv_undef
  1245. # works too.
  1246. print "\tST(0) = sv_newmortal();\n";
  1247. eval "print qq\a$expr\a";
  1248. warn $@ if $@;
  1249. # new mortals don't have set magic
  1250. }
  1251. }
  1252. elsif ($arg =~ /^ST\(\d+\)$/) {
  1253. eval "print qq\a$expr\a";
  1254. warn $@ if $@;
  1255. print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
  1256. }
  1257. }
  1258. }
  1259. sub map_type {
  1260. my($type) = @_;
  1261. $type =~ tr/:/_/;
  1262. $type =~ s/^array\(([^,]*),(.*)\).*/$1 */s;
  1263. $type;
  1264. }
  1265. sub Exit {
  1266. # If this is VMS, the exit status has meaning to the shell, so we
  1267. # use a predictable value (SS$_Normal or SS$_Abort) rather than an
  1268. # arbitrary number.
  1269. # exit ($Is_VMS ? ($errors ? 44 : 1) : $errors) ;
  1270. exit ($errors ? 1 : 0);
  1271. }