@@ -2043,13 +2043,20 @@ BEGIN { $build_subclass->('', # parent
2043
2043
sub parse {
2044
2044
my __PACKAGE__ $self = shift ;
2045
2045
my ExtUtils::ParseXS $pxs = shift ;
2046
+ my $do_notimplemented = shift ;
2046
2047
2047
2048
$self -> SUPER::parse($pxs ); # set file/line_no
2048
2049
2049
2050
# Consume and process lines until the next directive.
2050
2051
while ( @{$pxs -> {line }}
2051
2052
&& $pxs -> {line }[0] !~ / ^$ExtUtils::ParseXS::BLOCK_regexp /o )
2052
2053
{
2054
+ if ($do_notimplemented ) {
2055
+ # treat NOT_IMPLEMENTED_YET as another block separator, in
2056
+ # addition to $BLOCK_regexp.
2057
+ last if $pxs -> {line }[0] =~ / ^\s *NOT_IMPLEMENTED_YET/ ;
2058
+ }
2059
+
2053
2060
push @{$self -> {lines }}, $pxs -> {line }[0];
2054
2061
my $class = ref ($self ) . ' _line' ;
2055
2062
my $kid = $class -> new();
@@ -2062,6 +2069,20 @@ sub parse {
2062
2069
}
2063
2070
2064
2071
2072
+ # call as_code() on any kids which have that method
2073
+
2074
+ sub as_code {
2075
+ my __PACKAGE__ $self = shift ;
2076
+ my ExtUtils::ParseXS $pxs = shift ;
2077
+
2078
+ return unless $self -> {kids };
2079
+ for my $kid (@{$self -> {kids }}) {
2080
+ next unless $kid -> can(' as_code' );
2081
+ $kid -> as_code($pxs );
2082
+ }
2083
+ }
2084
+
2085
+
2065
2086
# ======================================================================
2066
2087
2067
2088
package ExtUtils::ParseXS::Node::keyline ;
@@ -2243,42 +2264,54 @@ sub parse {
2243
2264
2244
2265
# ======================================================================
2245
2266
2246
- package ExtUtils::ParseXS ; # XXX tmp
2267
+ package ExtUtils::ParseXS::Node::INPUT ;
2247
2268
2248
- # INPUT_handler(): handle an explicit INPUT: block, or any implicit INPUT
2269
+ # Handle an explicit INPUT: block, or any implicit INPUT
2249
2270
# block which can follow an xsub signature or CASE keyword.
2250
2271
2251
- sub INPUT_handler {
2252
- my ExtUtils::ParseXS $self = shift ;
2253
- my $line = shift ;
2272
+ BEGIN { $build_subclass -> (' keylines' , # parent
2273
+ )};
2254
2274
2255
- # In this loop: process each line until the next keyword or end of
2256
- # paragraph.
2275
+ # The inherited parse() method will call INPUT_line->parse() for each line
2257
2276
2258
- for (; $line !~ / ^$ExtUtils::ParseXS::BLOCK_regexp /o ; $line = shift (@{ $self -> {line } })) {
2259
- # treat NOT_IMPLEMENTED_YET as another block separator, in addition to
2260
- # $BLOCK_regexp.
2261
- last if $line =~ / ^\s *NOT_IMPLEMENTED_YET/ ;
2262
2277
2263
- $self -> INPUT_handler_line($line );
2264
- } # foreach line in INPUT block
2265
- $_ = $line ;
2278
+ sub parse {
2279
+ my __PACKAGE__ $self = shift ;
2280
+ my ExtUtils::ParseXS $pxs = shift ;
2281
+
2282
+ # Call the SUPER parse method, which will call INPUT_line->parse()
2283
+ # for each lINPUT line. The '1' bool arg indicates to treat
2284
+ # NOT_IMPLEMENTED_YET as another block separator, in addition to
2285
+ # $BLOCK_regexp.
2286
+ $self -> SUPER::parse($pxs , 1);
2266
2287
}
2267
2288
2268
2289
2269
2290
# ======================================================================
2270
2291
2271
- package ExtUtils::ParseXS ; # XXX tmp
2292
+ package ExtUtils::ParseXS::Node::INPUT_line ;
2293
+
2294
+ # Handle one line from an INPUT keyword block
2295
+
2296
+ BEGIN { $build_subclass -> (' keyline' , # parent
2297
+ ' param' , # the param object associated with this INPUT line.
2298
+ )};
2299
+
2300
+
2301
+ # Parse one line from an INPUT block
2302
+ #
2272
2303
2273
- # process a single line from an INPUT section
2304
+ sub parse {
2305
+ my __PACKAGE__ $self = shift ;
2306
+ my ExtUtils::ParseXS $pxs = shift ;
2307
+ my ExtUtils::ParseXS::Node::INPUT $parent = shift ; # parent INPUT node
2274
2308
2275
- sub INPUT_handler_line {
2276
- my ExtUtils::ParseXS $self = shift ;
2277
- my $line = shift ;
2309
+ $self -> SUPER::parse($pxs ); # set file/line_no/line
2310
+ my $line = $self -> {line }; # line of text to be processed
2278
2311
2279
2312
return unless $line =~ / \S / ; # skip blank lines
2280
2313
2281
- trim_whitespace($line );
2314
+ ExtUtils::ParseXS::Utilities:: trim_whitespace($line );
2282
2315
my $orig_line = $line ; # keep original line for error messages
2283
2316
2284
2317
# remove any trailing semicolon, except for initialisations
@@ -2318,18 +2351,18 @@ sub INPUT_handler_line {
2318
2351
(\w + | length\(\w +\) ) # name or length(name)
2319
2352
$
2320
2353
/xs
2321
- or $self -> blurt(" Error: invalid parameter declaration '$orig_line '" ), return ;
2354
+ or $pxs -> blurt(" Error: invalid parameter declaration '$orig_line '" ), return ;
2322
2355
2323
2356
# length(s) is only allowed in the XSUB's signature.
2324
2357
if ($var_name =~ / ^length\( (\w +)\) $ / ) {
2325
- $self -> blurt(" Error: length() not permitted in INPUT section" );
2358
+ $pxs -> blurt(" Error: length() not permitted in INPUT section" );
2326
2359
return ;
2327
2360
}
2328
2361
2329
2362
my ($var_num , $is_alien );
2330
2363
2331
2364
my ExtUtils::ParseXS::Node::Param $param
2332
- = $self -> {xsub_sig }{names }{$var_name };
2365
+ = $pxs -> {xsub_sig }{names }{$var_name };
2333
2366
2334
2367
2335
2368
if (defined $param ) {
@@ -2344,7 +2377,7 @@ sub INPUT_handler_line {
2344
2377
if ( $param -> {in_input }
2345
2378
or (!$param -> {is_synthetic } and defined $param -> {type })
2346
2379
) {
2347
- $self -> blurt(
2380
+ $pxs -> blurt(
2348
2381
" Error: duplicate definition of parameter '$var_name ' ignored" );
2349
2382
return ;
2350
2383
}
@@ -2358,9 +2391,9 @@ sub INPUT_handler_line {
2358
2391
# type, and has already been moved to the correct position;
2359
2392
# otherwise, it's an alien var that didn't appear in the
2360
2393
# signature; move to the correct position.
2361
- @{$self -> {xsub_sig }{params }} =
2362
- grep $_ != $param , @{$self -> {xsub_sig }{params }};
2363
- push @{$self -> {xsub_sig }{params }}, $param ;
2394
+ @{$pxs -> {xsub_sig }{params }} =
2395
+ grep $_ != $param , @{$pxs -> {xsub_sig }{params }};
2396
+ push @{$pxs -> {xsub_sig }{params }}, $param ;
2364
2397
$is_alien = 1;
2365
2398
$param -> {is_alien } = 1;
2366
2399
}
@@ -2379,8 +2412,8 @@ sub INPUT_handler_line {
2379
2412
is_alien => 1,
2380
2413
});
2381
2414
2382
- push @{$self -> {xsub_sig }{params }}, $param ;
2383
- $self -> {xsub_sig }{names }{$var_name } = $param ;
2415
+ push @{$pxs -> {xsub_sig }{params }}, $param ;
2416
+ $pxs -> {xsub_sig }{names }{$var_name } = $param ;
2384
2417
}
2385
2418
2386
2419
# Parse the initialisation part of the INPUT line (if any)
@@ -2407,7 +2440,7 @@ sub INPUT_handler_line {
2407
2440
# "; extra code" or "+ extra code" :
2408
2441
# append the extra code (after passing through eval) after all the
2409
2442
# INPUT and PREINIT blocks have been processed, indirectly using
2410
- # the $self ->{xsub_deferred_code_lines} mechanism.
2443
+ # the $pxs ->{xsub_deferred_code_lines} mechanism.
2411
2444
# In addition, for '+', also generate the normal initialisation
2412
2445
# code from the standard typemap - assuming that it's a real
2413
2446
# parameter that appears in the signature as well as the INPUT
@@ -2435,18 +2468,31 @@ sub INPUT_handler_line {
2435
2468
is_addr => !!$var_addr ,
2436
2469
);
2437
2470
2438
- $param -> check($self )
2471
+ $self -> {param } = $param ;
2472
+
2473
+ $param -> check($pxs )
2439
2474
or return ;
2475
+ }
2476
+
2477
+
2478
+ sub as_code {
2479
+ my __PACKAGE__ $self = shift ;
2480
+ my ExtUtils::ParseXS $pxs = shift ;
2440
2481
2441
2482
# Emit "type var" declaration and possibly various forms of
2442
2483
# initialiser code.
2443
2484
2485
+ my $param = $self -> {param };
2486
+ return unless $param ; # might be blank line
2487
+
2444
2488
# Synthetic params like THIS will be emitted later - they
2445
2489
# are treated like ANSI params, except the type can overridden
2446
2490
# within an INPUT statement
2447
2491
return if $param -> {is_synthetic };
2448
2492
2449
- $param -> as_code($self );
2493
+ # The param object contains data from both the INPUT line and
2494
+ # the XSUB signature.
2495
+ $param -> as_code($pxs );
2450
2496
}
2451
2497
2452
2498
0 commit comments