Pre-YAPC consting fun
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / Constant / Base.pm
1 package ExtUtils::Constant::Base;
2
3 use strict;
4 use vars qw($VERSION $is_perl56);
5 use Carp;
6 use Text::Wrap;
7 use ExtUtils::Constant::Utils qw(C_stringify perl_stringify);
8
9 $VERSION = '0.01';
10
11 $is_perl56 = ($] < 5.007 && $] > 5.005_50);
12
13
14 =head1 NAME
15
16 ExtUtils::Constant::Base - base class for ExtUtils::Constant objects
17
18 =head1 SYNOPSIS
19
20     require ExtUtils::Constant::Base;
21     @ISA = 'ExtUtils::Constant::Base';
22
23 =head1 DESCRIPTION
24
25 ExtUtils::Constant::Base provides a base implementation of methods to
26 generate C code to give fast constant value lookup by named string. Currently
27 it's mostly used ExtUtils::Constant::XS, which generates the lookup code
28 for the constant() subroutine found in many XS modules.
29
30 =head1 USAGE
31
32 ExtUtils::Constant::Base exports no subroutines. The following methods are
33 available
34
35 =over 4
36
37 =cut
38
39 sub valid_type {
40   # Default to assuming that you don't need different types of return data.
41   1;
42 }
43 sub default_type {
44   '';
45 }
46
47 =item header
48
49 A method returning a scalar containing definitions needed, typically for a
50 C header file.
51
52 =cut
53
54 sub header {
55   ''
56 }
57
58 # This might actually be a return statement. Note that you are responsible
59 # for any space you might need before your value, as it lets to perform
60 # "tricks" such as "return KEY_" and have strings appended.
61 sub assignment_clause_for_type;
62 # In which case this might be an empty string
63 sub return_statement_for_type {undef};
64 sub return_statement_for_notdef;
65 sub return_statement_for_notfound;
66
67 # "#if 1" is true to a C pre-processor
68 sub macro_from_name {
69   1;
70 }
71
72 sub name_param {
73   'name';
74 }
75
76 # This is possibly buggy, in that it's not mandatory (below, in the main
77 # C_constant parameters, but is expected to exist here, if it's needed)
78 # Buggy because if you're definitely pure 8 bit only, and will never be
79 # presented with your constants in utf8, the default form of C_constant can't
80 # be told not to do the utf8 version.
81
82 sub is_utf8_param {
83   'utf8';
84 }
85
86 sub memEQ {
87   "!memcmp";
88 }
89
90 =item memEQ_clause args_hashref
91
92 A method to return a suitable C C<if> statement to check whether I<name>
93 is equal to the C variable C<name>. If I<checked_at> is defined, then it
94 is used to avoid C<memEQ> for short names, or to generate a comment to
95 highlight the position of the character in the C<switch> statement.
96
97 If i<checked_at> is a reference to a scalar, then instead it gives
98 the characters pre-checked at the beginning, (and the number of chars by
99 which the C variable name has been advanced. These need to be chopped from
100 the front of I<name>).
101
102 =cut
103
104 sub memEQ_clause {
105 #    if (memEQ(name, "thingy", 6)) {
106   # Which could actually be a character comparison or even ""
107   my ($self, $args) = @_;
108   my ($name, $checked_at, $indent) = @{$args}{qw(name checked_at indent)};
109   $indent = ' ' x ($indent || 4);
110   my $front_chop;
111   if (ref $checked_at) {
112     # regexp won't work on 5.6.1 without use utf8; in turn that won't work
113     # on 5.005_03.
114     substr ($name, 0, length $$checked_at,) = '';
115     $front_chop = C_stringify ($$checked_at);
116     undef $checked_at;
117   }
118   my $len = length $name;
119
120   if ($len < 2) {
121     return $indent . "{\n"
122         if (defined $checked_at and $checked_at == 0) or $len == 0;
123     # We didn't switch, drop through to the code for the 2 character string
124     $checked_at = 1;
125   }
126
127   my $name_param = $self->name_param;
128
129   if ($len < 3 and defined $checked_at) {
130     my $check;
131     if ($checked_at == 1) {
132       $check = 0;
133     } elsif ($checked_at == 0) {
134       $check = 1;
135     }
136     if (defined $check) {
137       my $char = C_stringify (substr $name, $check, 1);
138       # Placate 5.005 with a break in the string. I can't see a good way of
139       # getting it to not take [ as introducing an array lookup, even with
140       # ${name_param}[$check]
141       return $indent . "if ($name_param" . "[$check] == '$char') {\n";
142     }
143   }
144   if (($len == 2 and !defined $checked_at)
145      or ($len == 3 and defined ($checked_at) and $checked_at == 2)) {
146     my $char1 = C_stringify (substr $name, 0, 1);
147     my $char2 = C_stringify (substr $name, 1, 1);
148     return $indent .
149       "if ($name_param" . "[0] == '$char1' && $name_param" . "[1] == '$char2') {\n";
150   }
151   if (($len == 3 and defined ($checked_at) and $checked_at == 1)) {
152     my $char1 = C_stringify (substr $name, 0, 1);
153     my $char2 = C_stringify (substr $name, 2, 1);
154     return $indent .
155       "if ($name_param" . "[0] == '$char1' && $name_param" . "[2] == '$char2') {\n";
156   }
157
158   my $pointer = '^';
159   my $have_checked_last = defined ($checked_at) && $len == $checked_at + 1;
160   if ($have_checked_last) {
161     # Checked at the last character, so no need to memEQ it.
162     $pointer = C_stringify (chop $name);
163     $len--;
164   }
165
166   $name = C_stringify ($name);
167   my $memEQ = $self->memEQ();
168   my $body = $indent . "if ($memEQ($name_param, \"$name\", $len)) {\n";
169   # Put a little ^ under the letter we checked at
170   # Screws up for non printable and non-7 bit stuff, but that's too hard to
171   # get right.
172   if (defined $checked_at) {
173     $body .= $indent . "/*      " . (' ' x length $memEQ)
174       . (' ' x length $name_param)
175       . (' ' x $checked_at) . $pointer
176       . (' ' x ($len - $checked_at + length $len)) . "    */\n";
177   } elsif (defined $front_chop) {
178     $body .= $indent . "/*                $front_chop"
179       . (' ' x ($len + 1 + length $len)) . "    */\n";
180   }
181   return $body;
182 }
183
184 =item dump_names arg_hashref, ITEM...
185
186 An internal function to generate the embedded perl code that will regenerate
187 the constant subroutines.  I<default_type>, I<types> and I<ITEM>s are the
188 same as for C_constant.  I<indent> is treated as number of spaces to indent
189 by.  If C<declare_types> is true a C<$types> is always declared in the perl
190 code generated, if defined and false never declared, and if undefined C<$types>
191 is only declared if the values in I<types> as passed in cannot be inferred from
192 I<default_types> and the I<ITEM>s.
193
194 =cut
195
196 sub dump_names {
197   my ($self, $args, @items) = @_;
198   my ($default_type, $what, $indent, $declare_types)
199     = @{$args}{qw(default_type what indent declare_types)};
200   $indent = ' ' x ($indent || 0);
201
202   my $result;
203   my (@simple, @complex, %used_types);
204   foreach (@items) {
205     my $type;
206     if (ref $_) {
207       $type = $_->{type} || $default_type;
208       if ($_->{utf8}) {
209         # For simplicity always skip the bytes case, and reconstitute this entry
210         # from its utf8 twin.
211         next if $_->{utf8} eq 'no';
212         # Copy the hashref, as we don't want to mess with the caller's hashref.
213         $_ = {%$_};
214         unless ($is_perl56) {
215           utf8::decode ($_->{name});
216         } else {
217           $_->{name} = pack 'U*', unpack 'U0U*', $_->{name};
218         }
219         delete $_->{utf8};
220       }
221     } else {
222       $_ = {name=>$_};
223       $type = $default_type;
224     }
225     $used_types{$type}++;
226     if ($type eq $default_type
227         # grr 5.6.1
228         and length $_->{name}
229         and length $_->{name} == ($_->{name} =~ tr/A-Za-z0-9_//)
230         and !defined ($_->{macro}) and !defined ($_->{value})
231         and !defined ($_->{default}) and !defined ($_->{pre})
232         and !defined ($_->{post}) and !defined ($_->{def_pre})
233         and !defined ($_->{def_post}) and !defined ($_->{weight})) {
234       # It's the default type, and the name consists only of A-Za-z0-9_
235       push @simple, $_->{name};
236     } else {
237       push @complex, $_;
238     }
239   }
240
241   if (!defined $declare_types) {
242     # Do they pass in any types we weren't already using?
243     foreach (keys %$what) {
244       next if $used_types{$_};
245       $declare_types++; # Found one in $what that wasn't used.
246       last; # And one is enough to terminate this loop
247     }
248   }
249   if ($declare_types) {
250     $result = $indent . 'my $types = {map {($_, 1)} qw('
251       . join (" ", sort keys %$what) . ")};\n";
252   }
253   local $Text::Wrap::huge = 'overflow';
254   local $Text::Wrap::columns = 80;
255   $result .= wrap ($indent . "my \@names = (qw(",
256                    $indent . "               ", join (" ", sort @simple) . ")");
257   if (@complex) {
258     foreach my $item (sort {$a->{name} cmp $b->{name}} @complex) {
259       my $name = perl_stringify $item->{name};
260       my $line = ",\n$indent            {name=>\"$name\"";
261       $line .= ", type=>\"$item->{type}\"" if defined $item->{type};
262       foreach my $thing (qw (macro value default pre post def_pre def_post)) {
263         my $value = $item->{$thing};
264         if (defined $value) {
265           if (ref $value) {
266             $line .= ", $thing=>[\""
267               . join ('", "', map {perl_stringify $_} @$value) . '"]';
268           } else {
269             $line .= ", $thing=>\"" . perl_stringify($value) . "\"";
270           }
271         }
272       }
273       $line .= "}";
274       # Ensure that the enclosing C comment doesn't end
275       # by turning */  into *" . "/
276       $line =~ s!\*\/!\*" . "/!gs;
277       # gcc -Wall doesn't like finding /* inside a comment
278       $line =~ s!\/\*!/" . "\*!gs;
279       $result .= $line;
280     }
281   }
282   $result .= ");\n";
283
284   $result;
285 }
286
287 =item assign arg_hashref, VALUE...
288
289 A method to return a suitable assignment clause. If I<type> is aggregate
290 (eg I<PVN> expects both pointer and length) then there should be multiple
291 I<VALUE>s for the components. I<pre> and I<post> if defined give snippets
292 of C code to proceed and follow the assignment. I<pre> will be at the start
293 of a block, so variables may be defined in it.
294
295 =cut
296 # Hmm. value undef to to NOTDEF? value () to do NOTFOUND?
297
298 sub assign {
299   my $self = shift;
300   my $args = shift;
301   my ($indent, $type, $pre, $post, $item)
302       = @{$args}{qw(indent type pre post item)};
303   $post ||= '';
304   my $clause;
305   my $close;
306   if ($pre) {
307     chomp $pre;
308     $close = "$indent}\n";
309     $clause = $indent . "{\n";
310     $indent .= "  ";
311     $clause .= "$indent$pre";
312     $clause .= ";" unless $pre =~ /;$/;
313     $clause .= "\n";
314   }
315   confess "undef \$type" unless defined $type;
316   confess "Can't generate code for type $type"
317     unless $self->valid_type($type);
318
319   $clause .= join '', map {"$indent$_\n"}
320     $self->assignment_clause_for_type({type=>$type,item=>$item}, @_);
321   chomp $post;
322   if (length $post) {
323     $clause .= "$post";
324     $clause .= ";" unless $post =~ /;$/;
325     $clause .= "\n";
326   }
327   my $return = $self->return_statement_for_type($type);
328   $clause .= "$indent$return\n" if defined $return;
329   $clause .= $close if $close;
330   return $clause;
331 }
332
333 =item return_clause arg_hashref, ITEM
334
335 A method to return a suitable C<#ifdef> clause. I<ITEM> is a hashref
336 (as passed to C<C_constant> and C<match_clause>. I<indent> is the number
337 of spaces to indent, defaulting to 6.
338
339 =cut
340
341 sub return_clause {
342
343 ##ifdef thingy
344 #      *iv_return = thingy;
345 #      return PERL_constant_ISIV;
346 ##else
347 #      return PERL_constant_NOTDEF;
348 ##endif
349   my ($self, $args, $item) = @_;
350   my $indent = $args->{indent};
351
352   my ($name, $value, $macro, $default, $pre, $post, $def_pre, $def_post, $type)
353     = @$item{qw (name value macro default pre post def_pre def_post type)};
354   $value = $name unless defined $value;
355   $macro = $self->macro_from_name($item) unless defined $macro;
356   # "#if 1" is true to a C pre-processor
357   $macro = 1 if !defined $macro or $macro eq '';
358   $indent = ' ' x ($indent || 6);
359   unless (defined $type) {
360     # use Data::Dumper; print STDERR Dumper ($item);
361     confess "undef \$type";
362   }
363
364   my $clause;
365
366   ##ifdef thingy
367   if (ref $macro) {
368     $clause = $macro->[0];
369   } elsif ($macro ne "1") {
370     $clause = "#ifdef $macro\n";
371   }
372
373   #      *iv_return = thingy;
374   #      return PERL_constant_ISIV;
375   $clause
376     .= $self->assign ({indent=>$indent, type=>$type, pre=>$pre, post=>$post,
377                        item=>$item}, ref $value ? @$value : $value);
378
379   if (ref $macro or $macro ne "1") {
380     ##else
381     $clause .= "#else\n";
382
383     #      return PERL_constant_NOTDEF;
384     if (!defined $default) {
385       my $notdef = $self->return_statement_for_notdef();
386       $clause .= "$indent$notdef\n" if defined $notdef;
387     } else {
388       my @default = ref $default ? @$default : $default;
389       $type = shift @default;
390       $clause .= $self->assign ({indent=>$indent, type=>$type, pre=>$pre,
391                                  post=>$post, item=>$item}, @default);
392     }
393
394     ##endif
395     if (ref $macro) {
396       $clause .= $macro->[1];
397     } else {
398       $clause .= "#endif\n";
399     }
400   }
401   return $clause;
402 }
403
404 sub match_clause {
405   # $offset defined if we have checked an offset.
406   my ($self, $args, $item) = @_;
407   my ($offset, $indent) = @{$args}{qw(checked_at indent)};
408   $indent = ' ' x ($indent || 4);
409   my $body = '';
410   my ($no, $yes, $either, $name, $inner_indent);
411   if (ref $item eq 'ARRAY') {
412     ($yes, $no) = @$item;
413     $either = $yes || $no;
414     confess "$item is $either expecting hashref in [0] || [1]"
415       unless ref $either eq 'HASH';
416     $name = $either->{name};
417   } else {
418     confess "$item->{name} has utf8 flag '$item->{utf8}', should be false"
419       if $item->{utf8};
420     $name = $item->{name};
421     $inner_indent = $indent;
422   }
423
424   $body .= $self->memEQ_clause ({name => $name, checked_at => $offset,
425                                  indent => length $indent});
426   # If we've been presented with an arrayref for $item, then the user string
427   # contains in the range 128-255, and we need to check whether it was utf8
428   # (or not).
429   # In the worst case we have two named constants, where one's name happens
430   # encoded in UTF8 happens to be the same byte sequence as the second's
431   # encoded in (say) ISO-8859-1.
432   # In this case, $yes and $no both have item hashrefs.
433   if ($yes) {
434     $body .= $indent . "  if (" . $self->is_utf8_param . ") {\n";
435   } elsif ($no) {
436     $body .= $indent . "  if (!" . $self->is_utf8_param . ") {\n";
437   }
438   if ($either) {
439     $body .= $self->return_clause ({indent=>4 + length $indent}, $either);
440     if ($yes and $no) {
441       $body .= $indent . "  } else {\n";
442       $body .= $self->return_clause ({indent=>4 + length $indent}, $no);
443     }
444     $body .= $indent . "  }\n";
445   } else {
446     $body .= $self->return_clause ({indent=>2 + length $indent}, $item);
447   }
448   $body .= $indent . "}\n";
449 }
450
451
452 =item switch_clause arg_hashref, NAMELEN, ITEMHASH, ITEM...
453
454 An internal method to generate a suitable C<switch> clause, called by
455 C<C_constant> I<ITEM>s are in the hash ref format as given in the description
456 of C<C_constant>, and must all have the names of the same length, given by
457 I<NAMELEN>.  I<ITEMHASH> is a reference to a hash, keyed by name, values being
458 the hashrefs in the I<ITEM> list.  (No parameters are modified, and there can
459 be keys in the I<ITEMHASH> that are not in the list of I<ITEM>s without
460 causing problems - the hash is passed in to save generating it afresh for
461 each call).
462
463 =cut
464
465 sub switch_clause {
466   my ($self, $args, $namelen, $items, @items) = @_;
467   my ($indent, $comment) = @{$args}{qw(indent comment)};
468   $indent = ' ' x ($indent || 2);
469
470   local $Text::Wrap::huge = 'overflow';
471   local $Text::Wrap::columns = 80;
472
473   my @names = sort map {$_->{name}} @items;
474   my $leader = $indent . '/* ';
475   my $follower = ' ' x length $leader;
476   my $body = $indent . "/* Names all of length $namelen.  */\n";
477   if (defined $comment) {
478     $body = wrap ($leader, $follower, $comment) . "\n";
479     $leader = $follower;
480   }
481   my @safe_names = @names;
482   foreach (@safe_names) {
483     confess sprintf "Name '$_' is length %d, not $namelen", length
484       unless length == $namelen;
485     # Argh. 5.6.1
486     # next unless tr/A-Za-z0-9_//c;
487     next if tr/A-Za-z0-9_// == length;
488     $_ = '"' . perl_stringify ($_) . '"';
489     # Ensure that the enclosing C comment doesn't end
490     # by turning */  into *" . "/
491     s!\*\/!\*"."/!gs;
492     # gcc -Wall doesn't like finding /* inside a comment
493     s!\/\*!/"."\*!gs;
494   }
495   $body .= wrap ($leader, $follower, join (" ", @safe_names) . " */") . "\n";
496   # Figure out what to switch on.
497   # (RMS, Spread of jump table, Position, Hashref)
498   my @best = (1e38, ~0);
499   # Prefer the last character over the others. (As it lets us shorten the
500   # memEQ clause at no cost).
501   foreach my $i ($namelen - 1, 0 .. ($namelen - 2)) {
502     my ($min, $max) = (~0, 0);
503     my %spread;
504     if ($is_perl56) {
505       # Need proper Unicode preserving hash keys for bytes in range 128-255
506       # here too, for some reason. grr 5.6.1 yet again.
507       tie %spread, 'ExtUtils::Constant::Aaargh56Hash';
508     }
509     foreach (@names) {
510       my $char = substr $_, $i, 1;
511       my $ord = ord $char;
512       confess "char $ord is out of range" if $ord > 255;
513       $max = $ord if $ord > $max;
514       $min = $ord if $ord < $min;
515       push @{$spread{$char}}, $_;
516       # warn "$_ $char";
517     }
518     # I'm going to pick the character to split on that minimises the root
519     # mean square of the number of names in each case. Normally this should
520     # be the one with the most keys, but it may pick a 7 where the 8 has
521     # one long linear search. I'm not sure if RMS or just sum of squares is
522     # actually better.
523     # $max and $min are for the tie-breaker if the root mean squares match.
524     # Assuming that the compiler may be building a jump table for the
525     # switch() then try to minimise the size of that jump table.
526     # Finally use < not <= so that if it still ties the earliest part of
527     # the string wins. Because if that passes but the memEQ fails, it may
528     # only need the start of the string to bin the choice.
529     # I think. But I'm micro-optimising. :-)
530     # OK. Trump that. Now favour the last character of the string, before the
531     # rest.
532     my $ss;
533     $ss += @$_ * @$_ foreach values %spread;
534     my $rms = sqrt ($ss / keys %spread);
535     if ($rms < $best[0] || ($rms == $best[0] && ($max - $min) < $best[1])) {
536       @best = ($rms, $max - $min, $i, \%spread);
537     }
538   }
539   confess "Internal error. Failed to pick a switch point for @names"
540     unless defined $best[2];
541   # use Data::Dumper; print Dumper (@best);
542   my ($offset, $best) = @best[2,3];
543   $body .= $indent . "/* Offset $offset gives the best switch position.  */\n";
544
545   my $do_front_chop = $offset == 0 && $namelen > 2;
546   if ($do_front_chop) {
547     $body .= $indent . "switch (*" . $self->name_param() . "++) {\n";
548   } else {
549     $body .= $indent . "switch (" . $self->name_param() . "[$offset]) {\n";
550   }
551   foreach my $char (sort keys %$best) {
552     confess sprintf "'$char' is %d bytes long, not 1", length $char
553       if length ($char) != 1;
554     confess sprintf "char %#X is out of range", ord $char if ord ($char) > 255;
555     $body .= $indent . "case '" . C_stringify ($char) . "':\n";
556     foreach my $thisone (sort {
557         # Deal with the case of an item actually being an array ref to 1 or 2
558         # hashrefs. Don't assign to $a or $b, as they're aliases to the orignal
559         my $l = ref $a eq 'ARRAY' ? ($a->[0] || $->[1]) : $a;
560         my $r = ref $b eq 'ARRAY' ? ($b->[0] || $->[1]) : $b;
561         # Sort by weight first
562         ($r->{weight} || 0) <=> ($l->{weight} || 0)
563             # Sort equal weights by name
564             or $l->{name} cmp $r->{name}}
565                          # If this looks evil, maybe it is.  $items is a
566                          # hashref, and we're doing a hash slice on it
567                          @{$items}{@{$best->{$char}}}) {
568       # warn "You are here";
569       if ($do_front_chop) {
570         $body .= $self->match_clause ({indent => 2 + length $indent,
571                                        checked_at => \$char}, $thisone);
572       } else {
573         $body .= $self->match_clause ({indent => 2 + length $indent,
574                                        checked_at => $offset}, $thisone);
575       }
576     }
577     $body .= $indent . "  break;\n";
578   }
579   $body .= $indent . "}\n";
580   return $body;
581 }
582
583 sub C_constant_return_type {
584   "static int";
585 }
586
587 sub C_constant_prefix_param {
588   '';
589 }
590
591 sub C_constant_prefix_param_defintion {
592   '';
593 }
594
595 sub name_param_definition {
596   "const char *" . $_[0]->name_param;
597 }
598
599 sub namelen_param {
600   'len';
601 }
602
603 sub namelen_param_definition {
604   'size_t ' . $_[0]->namelen_param;
605 }
606
607 sub C_constant_other_params {
608   '';
609 }
610
611 sub C_constant_other_params_defintion {
612   '';
613 }
614
615 =item params WHAT
616
617 An "internal" method, subject to change, currently called to allow an
618 overriding class to cache information that will then be passed into all
619 the C<*param*> calls. (Yes, having to read the source to make sense of this is
620 considered a known bug). I<WHAT> is be a hashref of types the constant
621 function will return. In ExtUtils::Constant::XS this method is used to
622 returns a hashref keyed IV NV PV SV to show which combination of pointers will
623 be needed in the C argument list generated by
624 C_constant_other_params_definition and C_constant_other_params
625
626 =cut
627
628 sub params {
629   '';
630 }
631
632
633 =item dogfood arg_hashref, ITEM...
634
635 An internal function to generate the embedded perl code that will regenerate
636 the constant subroutines.  Parameters are the same as for C_constant.
637
638 Currently the base class does nothing and returns an empty string.
639
640 =cut
641
642 sub dogfood {
643   ''
644 }
645
646 =item C_constant arg_hashref, ITEM...
647
648 A function that returns a B<list> of C subroutine definitions that return
649 the value and type of constants when passed the name by the XS wrapper.
650 I<ITEM...> gives a list of constant names. Each can either be a string,
651 which is taken as a C macro name, or a reference to a hash with the following
652 keys
653
654 =over 8
655
656 =item name
657
658 The name of the constant, as seen by the perl code.
659
660 =item type
661
662 The type of the constant (I<IV>, I<NV> etc)
663
664 =item value
665
666 A C expression for the value of the constant, or a list of C expressions if
667 the type is aggregate. This defaults to the I<name> if not given.
668
669 =item macro
670
671 The C pre-processor macro to use in the C<#ifdef>. This defaults to the
672 I<name>, and is mainly used if I<value> is an C<enum>. If a reference an
673 array is passed then the first element is used in place of the C<#ifdef>
674 line, and the second element in place of the C<#endif>. This allows
675 pre-processor constructions such as
676
677     #if defined (foo)
678     #if !defined (bar)
679     ...
680     #endif
681     #endif
682
683 to be used to determine if a constant is to be defined.
684
685 A "macro" 1 signals that the constant is always defined, so the C<#if>/C<#endif>
686 test is omitted.
687
688 =item default
689
690 Default value to use (instead of C<croak>ing with "your vendor has not
691 defined...") to return if the macro isn't defined. Specify a reference to
692 an array with type followed by value(s).
693
694 =item pre
695
696 C code to use before the assignment of the value of the constant. This allows
697 you to use temporary variables to extract a value from part of a C<struct>
698 and return this as I<value>. This C code is places at the start of a block,
699 so you can declare variables in it.
700
701 =item post
702
703 C code to place between the assignment of value (to a temporary) and the
704 return from the function. This allows you to clear up anything in I<pre>.
705 Rarely needed.
706
707 =item def_pre
708
709 =item def_post
710
711 Equivalents of I<pre> and I<post> for the default value.
712
713 =item utf8
714
715 Generated internally. Is zero or undefined if name is 7 bit ASCII,
716 "no" if the name is 8 bit (and so should only match if SvUTF8() is false),
717 "yes" if the name is utf8 encoded.
718
719 The internals automatically clone any name with characters 128-255 but none
720 256+ (ie one that could be either in bytes or utf8) into a second entry
721 which is utf8 encoded.
722
723 =item weight
724
725 Optional sorting weight for names, to determine the order of
726 linear testing when multiple names fall in the same case of a switch clause.
727 Higher comes earlier, undefined defaults to zero.
728
729 =back
730
731 In the argument hashref, I<package> is the name of the package, and is only
732 used in comments inside the generated C code. I<subname> defaults to
733 C<constant> if undefined.
734
735 I<default_type> is the type returned by C<ITEM>s that don't specify their
736 type. It defaults to the value of C<default_type()>. I<types> should be given
737 either as a comma separated list of types that the C subroutine I<subname>
738 will generate or as a reference to a hash. I<default_type> will be added to
739 the list if not present, as will any types given in the list of I<ITEM>s. The
740 resultant list should be the same list of types that C<XS_constant> is
741 given. [Otherwise C<XS_constant> and C<C_constant> may differ in the number of
742 parameters to the constant function. I<indent> is currently unused and
743 ignored. In future it may be used to pass in information used to change the C
744 indentation style used.]  The best way to maintain consistency is to pass in a
745 hash reference and let this function update it.
746
747 I<breakout> governs when child functions of I<subname> are generated.  If there
748 are I<breakout> or more I<ITEM>s with the same length of name, then the code
749 to switch between them is placed into a function named I<subname>_I<len>, for
750 example C<constant_5> for names 5 characters long.  The default I<breakout> is
751 3.  A single C<ITEM> is always inlined.
752
753 =cut
754
755 # The parameter now BREAKOUT was previously documented as:
756 #
757 # I<NAMELEN> if defined signals that all the I<name>s of the I<ITEM>s are of
758 # this length, and that the constant name passed in by perl is checked and
759 # also of this length. It is used during recursion, and should be C<undef>
760 # unless the caller has checked all the lengths during code generation, and
761 # the generated subroutine is only to be called with a name of this length.
762 #
763 # As you can see it now performs this function during recursion by being a
764 # scalar reference.
765
766 sub C_constant {
767   my ($self, $args, @items) = @_;
768   my ($package, $subname, $default_type, $what, $indent, $breakout) =
769     @{$args}{qw(package subname default_type types indent breakout)};
770   $package ||= 'Foo';
771   $subname ||= 'constant';
772   # I'm not using this. But a hashref could be used for full formatting without
773   # breaking this API
774   # $indent ||= 0;
775
776   my ($namelen, $items);
777   if (ref $breakout) {
778     # We are called recursively. We trust @items to be normalised, $what to
779     # be a hashref, and pinch %$items from our parent to save recalculation.
780     ($namelen, $items) = @$breakout;
781   } else {
782     if ($is_perl56) {
783       # Need proper Unicode preserving hash keys.
784       require ExtUtils::Constant::Aaargh56Hash;
785       $items = {};
786       tie %$items, 'ExtUtils::Constant::Aaargh56Hash';
787     }
788     $breakout ||= 3;
789     $default_type ||= $self->default_type();
790     if (!ref $what) {
791       # Convert line of the form IV,UV,NV to hash
792       $what = {map {$_ => 1} split /,\s*/, ($what || '')};
793       # Figure out what types we're dealing with, and assign all unknowns to the
794       # default type
795     }
796     my @new_items;
797     foreach my $orig (@items) {
798       my ($name, $item);
799       if (ref $orig) {
800         # Make a copy which is a normalised version of the ref passed in.
801         $name = $orig->{name};
802         my ($type, $macro, $value) = @$orig{qw (type macro value)};
803         $type ||= $default_type;
804         $what->{$type} = 1;
805         $item = {name=>$name, type=>$type};
806
807         undef $macro if defined $macro and $macro eq $name;
808         $item->{macro} = $macro if defined $macro;
809         undef $value if defined $value and $value eq $name;
810         $item->{value} = $value if defined $value;
811         foreach my $key (qw(default pre post def_pre def_post weight)) {
812           my $value = $orig->{$key};
813           $item->{$key} = $value if defined $value;
814           # warn "$key $value";
815         }
816       } else {
817         $name = $orig;
818         $item = {name=>$name, type=>$default_type};
819         $what->{$default_type} = 1;
820       }
821       warn +(ref ($self) || $self)
822         . "doesn't know how to handle values of type $_ used in macro $name"
823           unless $self->valid_type ($item->{type});
824       # tr///c is broken on 5.6.1 for utf8, so my original tr/\0-\177//c
825       # doesn't work. Upgrade to 5.8
826       # if ($name !~ tr/\0-\177//c || $] < 5.005_50) {
827       if ($name =~ tr/\0-\177// == length $name || $] < 5.005_50) {
828         # No characters outside 7 bit ASCII.
829         if (exists $items->{$name}) {
830           die "Multiple definitions for macro $name";
831         }
832         $items->{$name} = $item;
833       } else {
834         # No characters outside 8 bit. This is hardest.
835         if (exists $items->{$name} and ref $items->{$name} ne 'ARRAY') {
836           confess "Unexpected ASCII definition for macro $name";
837         }
838         # Again, 5.6.1 tr broken, so s/5\.6.*/5\.8\.0/;
839         # if ($name !~ tr/\0-\377//c) {
840         if ($name =~ tr/\0-\377// == length $name) {
841 #          if ($] < 5.007) {
842 #            $name = pack "C*", unpack "U*", $name;
843 #          }
844           $item->{utf8} = 'no';
845           $items->{$name}[1] = $item;
846           push @new_items, $item;
847           # Copy item, to create the utf8 variant.
848           $item = {%$item};
849         }
850         # Encode the name as utf8 bytes.
851         unless ($is_perl56) {
852           utf8::encode($name);
853         } else {
854 #          warn "Was >$name< " . length ${name};
855           $name = pack 'C*', unpack 'C*', $name . pack 'U*';
856 #          warn "Now '${name}' " . length ${name};
857         }
858         if ($items->{$name}[0]) {
859           die "Multiple definitions for macro $name";
860         }
861         $item->{utf8} = 'yes';
862         $item->{name} = $name;
863         $items->{$name}[0] = $item;
864         # We have need for the utf8 flag.
865         $what->{''} = 1;
866       }
867       push @new_items, $item;
868     }
869     @items = @new_items;
870     # use Data::Dumper; print Dumper @items;
871   }
872   my $params = $self->params ($what);
873
874   # Probably "static int"
875   my ($body, @subs);
876   $body = $self->C_constant_return_type($params) . "\n$subname ("
877     # Eg "pTHX_ "
878     . $self->C_constant_prefix_param_defintion($params)
879       # Probably "const char *name"
880       . $self->name_param_definition($params);
881   # Something like ", STRLEN len"
882   $body .= ", " . $self->namelen_param_definition($params)
883     unless defined $namelen;
884   $body .= $self->C_constant_other_params_defintion($params);
885   $body .= ") {\n";
886
887   if (defined $namelen) {
888     # We are a child subroutine. Print the simple description
889     my $comment = 'When generated this function returned values for the list'
890       . ' of names given here.  However, subsequent manual editing may have'
891         . ' added or removed some.';
892     $body .= $self->switch_clause ({indent=>2, comment=>$comment},
893                                    $namelen, $items, @items);
894   } else {
895     # We are the top level.
896     $body .= "  /* Initially switch on the length of the name.  */\n";
897     $body .= $self->dogfood ({package => $package, subname => $subname,
898                               default_type => $default_type, what => $what,
899                               indent => $indent, breakout => $breakout},
900                              @items);
901     $body .= '  switch ('.$self->namelen_param().") {\n";
902     # Need to group names of the same length
903     my @by_length;
904     foreach (@items) {
905       push @{$by_length[length $_->{name}]}, $_;
906     }
907     foreach my $i (0 .. $#by_length) {
908       next unless $by_length[$i];       # None of this length
909       $body .= "  case $i:\n";
910       if (@{$by_length[$i]} == 1) {
911         my $only_thing = $by_length[$i]->[0];
912         if ($only_thing->{utf8}) {
913           if ($only_thing->{utf8} eq 'yes') {
914             # With utf8 on flag item is passed in element 0
915             $body .= $self->match_clause (undef, [$only_thing]);
916           } else {
917             # With utf8 off flag item is passed in element 1
918             $body .= $self->match_clause (undef, [undef, $only_thing]);
919           }
920         } else {
921           $body .= $self->match_clause (undef, $only_thing);
922         }
923       } elsif (@{$by_length[$i]} < $breakout) {
924         $body .= $self->switch_clause ({indent=>4},
925                                        $i, $items, @{$by_length[$i]});
926       } else {
927         # Only use the minimal set of parameters actually needed by the types
928         # of the names of this length.
929         my $what = {};
930         foreach (@{$by_length[$i]}) {
931           $what->{$_->{type}} = 1;
932           $what->{''} = 1 if $_->{utf8};
933         }
934         $params = $self->params ($what);
935         push @subs, $self->C_constant ({package=>$package,
936                                         subname=>"${subname}_$i",
937                                         default_type => $default_type,
938                                         types => $what, indent => $indent,
939                                         breakout => [$i, $items]},
940                                        @{$by_length[$i]});
941         $body .= "    return ${subname}_$i ("
942           # Eg "aTHX_ "
943           . $self->C_constant_prefix_param($params)
944             # Probably "name"
945             . $self->name_param($params);
946         $body .= $self->C_constant_other_params($params);
947         $body .= ");\n";
948       }
949       $body .= "    break;\n";
950     }
951     $body .= "  }\n";
952   }
953   my $notfound = $self->return_statement_for_notfound();
954   $body .= "  $notfound\n" if $notfound;
955   $body .= "}\n";
956   return (@subs, $body);
957 }
958
959 1;
960 __END__
961
962 =back
963
964 =head1 BUGS
965
966 Not everything is documented yet.
967
968 Probably others.
969
970 =head1 AUTHOR
971
972 Nicholas Clark <nick@ccl4.org> based on the code in C<h2xs> by Larry Wall and
973 others