This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
autodoc: Add clarifying info to error messages
[perl5.git] / autodoc.pl
1 #!/usr/bin/perl -w
2
3 use Text::Tabs;
4 #
5 # Unconditionally regenerate:
6 #
7 #    pod/perlintern.pod
8 #    pod/perlapi.pod
9 #
10 # from information stored in
11 #
12 #    embed.fnc
13 #    plus all the core .c, .h, and .pod files listed in MANIFEST
14 #
15 # Has an optional arg, which is the directory to chdir to before reading
16 # MANIFEST and the files
17 #
18 # This script is invoked as part of 'make all'
19 #
20 # The generated pod consists of sections of related elements, functions,
21 # macros, and variables.  The keys of %valid_sections give the current legal
22 # ones.  Just add a new key to add a section.
23 #
24 # Throughout the files read by this script are lines like
25 #
26 # =for apidoc_section Section Name
27 #
28 # "Section Name" (after having been stripped of leading space) must be one of
29 # the legal section names, or an error is thrown.  All API elements defined
30 # between this line and the next 'apidoc_section' line will go into the
31 # section "Section Name", sorted by dictionary order within it.  perlintern
32 # and perlapi are parallel documents, each potentially with a section "Section
33 # Name".  Each element is marked as to which document it goes into.  If there
34 # are none for a particular section in perlapi, that section is
35 # omitted.
36 #
37 # Also, in .[ch] files, there may be
38 #
39 # =head1 Section Name
40 #
41 # lines in comments.  These are also used by this program to switch to section
42 # "Section Name".  The difference is that if there are any lines after the
43 # =head1, inside the same comment, and before any =for apidoc-ish lines, they
44 # are used as a heading for section "Section Name" (in both perlintern and
45 # perlapi).  This includes any =head[2-5].  If more than one '=head1 Section
46 # Name' line has content, they appear in the generated pod in an undefined
47 # order.
48 #
49 # The next =head1, =for apidoc_section, or file end terminates what goes into
50 # the current section
51 #
52 # The %valid_sections hash below also can have header content, which will
53 # appear before any =head1 content.  The hash can also have footer content
54 # content, which will appear at the end of the section, after all the
55 # elements.
56 #
57 # The lines that define the actual functions, etc are documented in embed.fnc,
58 # because they have flags which must be kept in sync with that file.
59
60 use strict;
61 use warnings;
62
63 # 80 column terminal - 1 for pager adding a column; -7 for nroff
64 # indent;
65 my $max_width = 80 - 1 - 7;
66
67 if (@ARGV) {
68     my $workdir = shift;
69     chdir $workdir
70         or die "Couldn't chdir to '$workdir': $!";
71 }
72 require './regen/regen_lib.pl';
73 require './regen/embed_lib.pl';
74
75 my %described_elsewhere;
76
77 #
78 # See database of global and static function prototypes in embed.fnc
79 # This is used to generate prototype headers under various configurations,
80 # export symbols lists for different platforms, and macros to provide an
81 # implicit interpreter context argument.
82 #
83
84 my %docs;
85 my %seen;
86 my %funcflags;
87 my %missing;
88 my %missing_macros;
89
90 my $link_text = "Described in";
91
92 my $description_indent = 4;
93 my $usage_indent = 3;   # + initial blank yields 4 total
94
95 my $av_scn = 'AV Handling';
96 my $callback_scn = 'Callback Functions';
97 my $casting_scn = 'Casting';
98 my $casing_scn = 'Character case changing';
99 my $classification_scn = 'Character classification';
100 my $names_scn = 'Character names';
101 my $scope_scn = 'Compile-time scope hooks';
102 my $compiler_scn = 'Compiler and Preprocessor information';
103 my $directives_scn = 'Compiler directives';
104 my $concurrency_scn = 'Concurrency';
105 my $COP_scn = 'COP Hint Hashes';
106 my $CV_scn = 'CV Handling';
107 my $custom_scn = 'Custom Operators';
108 my $dump_scn = 'Display and Dump functions';
109 my $embedding_scn = 'Embedding and Interpreter Cloning';
110 my $errno_scn = 'Errno';
111 my $exceptions_scn = 'Exception Handling (simple) Macros';
112 my $filesystem_scn = 'Filesystem configuration values';
113 my $floating_scn = 'Floating point configuration values';
114 my $formats_scn = 'Formats';
115 my $genconfig_scn = 'General Configuration';
116 my $globals_scn = 'Global Variables';
117 my $GV_scn = 'GV Handling';
118 my $hook_scn = 'Hook manipulation';
119 my $HV_scn = 'HV Handling';
120 my $io_scn = 'Input/Output';
121 my $integer_scn = 'Integer configuration values';
122 my $lexer_scn = 'Lexer interface';
123 my $locales_scn = 'Locales';
124 my $magic_scn = 'Magic';
125 my $memory_scn = 'Memory Management';
126 my $mro_scn = 'MRO';
127 my $multicall_scn = 'Multicall Functions';
128 my $numeric_scn = 'Numeric Functions';
129 my $optree_construction_scn = 'Optree construction';
130 my $optree_manipulation_scn = 'Optree Manipulation Functions';
131 my $pack_scn = 'Pack and Unpack';
132 my $pad_scn = 'Pad Data Structures';
133 my $password_scn = 'Password and Group access';
134 my $paths_scn = 'Paths to system commands';
135 my $intrpvar_scn = 'Per-Interpreter Variables';
136 my $prototypes_scn = 'Prototype information';
137 my $regexp_scn = 'REGEXP Functions';
138 my $signals_scn = 'Signals';
139 my $site_scn = 'Site configuration';
140 my $sockets_scn = 'Sockets configuration values';
141 my $filters_scn = 'Source Filters';
142 my $stack_scn = 'Stack Manipulation Macros';
143 my $string_scn = 'String Handling';
144 my $SV_flags_scn = 'SV Flags';
145 my $SV_scn = 'SV Handling';
146 my $time_scn = 'Time';
147 my $typedefs_scn = 'Typedef names';
148 my $unicode_scn = 'Unicode Support';
149 my $utility_scn = 'Utility Functions';
150 my $versioning_scn = 'Versioning';
151 my $warning_scn = 'Warning and Dieing';
152 my $xs_scn = 'XS';
153
154 my %valid_sections = (
155     $av_scn => {},
156     $callback_scn => {},
157     $casting_scn => {},
158     $casing_scn => {},
159     $classification_scn => {},
160     $scope_scn => {},
161     $compiler_scn => {},
162     $directives_scn => {},
163     $concurrency_scn => {},
164     $COP_scn => {},
165     $CV_scn => {},
166     $custom_scn => {},
167     $dump_scn => {},
168     $embedding_scn => {},
169     $errno_scn => {},
170     $exceptions_scn => {},
171     $filesystem_scn => {
172         header => <<~'EOT',
173             Also see L</List of capability HAS_foo symbols>.
174             EOT
175         },
176     $floating_scn => {
177         header => <<~'EOT',
178             Also L</List of capability HAS_foo symbols> lists capabilities
179             that arent in this section.  For example C<HAS_ASINH>, for the
180             hyperbolic sine function.
181             EOT
182         },
183     $formats_scn => {
184         header => <<~'EOT',
185             These are used for formatting the corresponding type For example,
186             instead of saying
187
188              Perl_newSVpvf(pTHX_ "Create an SV with a %d in it\n", iv);
189
190             use
191
192              Perl_newSVpvf(pTHX_ "Create an SV with a " IVdf " in it\n", iv);
193
194             This keeps you from having to know if, say an IV, needs to be
195             printed as C<%d>, C<%ld>, or something else.
196             EOT
197       },
198     $genconfig_scn => {
199         header => <<~'EOT',
200             This section contains configuration information not otherwise
201             found in the more specialized sections of this document.  At the
202             end is a list of C<#defines> whose name should be enough to tell
203             you what they do, and a list of #defines which tell you if you
204             need to C<#include> files to get the corresponding functionality.
205             EOT
206
207         footer => <<~'EOT',
208
209             =head2 List of capability C<HAS_I<foo>> symbols
210
211             This is a list of those symbols that dont appear elsewhere in ths
212             document that indicate if the current platform has a certain
213             capability.  Their names all begin with C<HAS_>.  Only those
214             symbols whose capability is directly derived from the name are
215             listed here.  All others have their meaning expanded out elsewhere
216             in this document.  This (relatively) compact list is because we
217             think that the expansion would add little or no value and take up
218             a lot of space (because there are so many).  If you think certain
219             ones should be expanded, send email to
220             L<perl5-porters@perl.org|mailto:perl5-porters@perl.org>.
221
222             Each symbol here will be C<#define>d if and only if the platform
223             has the capability.  If you need more detail, see the
224             corresponding entry in F<config.h>.  For convenience, the list is
225             split so that the ones that indicate there is a reentrant version
226             of a capability are listed separately
227
228             __HAS_LIST__
229
230             And, the reentrant capabilities:
231
232             __HAS_R_LIST__
233
234             Example usage:
235
236             =over
237
238              #ifdef HAS_STRNLEN
239                use strnlen()
240              #else
241                use an alternative implementation
242              #endif
243
244             =back
245
246             =head2 List of C<#include> needed symbols
247
248             This list contains symbols that indicate if certain C<#include>
249             files are present on the platform.  If your code accesses the
250             functionality that one of these is for, you will need to
251             C<#include> it if the symbol on this list is C<#define>d.  For
252             more detail, see the corresponding entry in F<config.h>.
253
254             __INCLUDE_LIST__
255
256             Example usage:
257
258             =over
259
260              #ifdef I_WCHAR
261                #include <wchar.h>
262              #endif
263
264             =back
265             EOT
266       },
267     $globals_scn => {},
268     $GV_scn => {},
269     $hook_scn => {},
270     $HV_scn => {},
271     $io_scn => {},
272     $integer_scn => {},
273     $lexer_scn => {},
274     $locales_scn => {},
275     $magic_scn => {},
276     $memory_scn => {},
277     $mro_scn => {},
278     $multicall_scn => {},
279     $numeric_scn => {},
280     $optree_construction_scn => {},
281     $optree_manipulation_scn => {},
282     $pack_scn => {},
283     $pad_scn => {},
284     $password_scn => {},
285     $paths_scn => {},
286     $intrpvar_scn => {},
287     $prototypes_scn => {},
288     $regexp_scn => {},
289     $signals_scn => {},
290     $site_scn => {
291         header => <<~'EOT',
292             These variables give details as to where various libraries,
293             installation destinations, I<etc.>, go, as well as what various
294             installation options were selected
295             EOT
296       },
297     $sockets_scn => {},
298     $filters_scn => {},
299     $stack_scn => {},
300     $string_scn => {
301         header => <<~'EOT',
302             See also C<L</Unicode Support>>.
303             EOT
304       },
305     $SV_flags_scn => {},
306     $SV_scn => {},
307     $time_scn => {},
308     $typedefs_scn => {},
309     $unicode_scn => {},
310     $utility_scn => {},
311     $versioning_scn => {},
312     $warning_scn => {},
313     $xs_scn => {},
314 );
315
316 # Somewhat loose match for an apidoc line so we can catch minor typos.
317 # Parentheses are used to capture portions so that below we verify
318 # that things are the actual correct syntax.
319 my $apidoc_re = qr/ ^ (\s*)            # $1
320                       (=?)             # $2
321                       (\s*)            # $3
322                       for (\s*)        # $4
323                       apidoc (_item)?  # $5
324                       (\s*)            # $6
325                       (.*?)            # $7
326                       \s* \n /x;
327 # Only certain flags, dealing with display, are acceptable for apidoc_item
328 my $display_flags = "fFnDopsT";
329
330 sub check_api_doc_line ($$) {
331     my ($file, $in) = @_;
332
333     return unless $in =~ $apidoc_re;
334
335     my $is_item = defined $5;
336     my $is_in_proper_form = length $1 == 0
337                          && length $2 > 0
338                          && length $3 == 0
339                          && length $4 > 0
340                          && length $6 > 0
341                          && length $7 > 0;
342     my $proto_in_file = $7;
343     my $proto = $proto_in_file;
344     $proto = "||$proto" if $proto !~ /\|/;
345     my ($flags, $ret_type, $name, @args) = split /\s*\|\s*/, $proto;
346
347     $name && $is_in_proper_form or die <<EOS;
348 Bad apidoc at $file line $.:
349   $in
350 Expected:
351   =for apidoc flags|returntype|name|arg|arg|...
352   =for apidoc flags|returntype|name
353   =for apidoc name
354 (or 'apidoc_item')
355 EOS
356
357     die "Only [$display_flags] allowed in apidoc_item:\n$in"
358                             if $is_item && $flags =~ /[^$display_flags]/;
359
360     return ($name, $flags, $ret_type, $is_item, $proto_in_file, @args);
361 }
362
363 sub embed_override($) {
364     my ($element_name) = shift;
365
366     # If the entry is also in embed.fnc, it should be defined
367     # completely there, but not here
368     my $embed_docref = delete $funcflags{$element_name};
369
370     return unless $embed_docref and %$embed_docref;
371
372     my $flags = $embed_docref->{'flags'};
373     warn "embed.fnc entry '$element_name' missing 'd' flag"
374                                             unless $flags =~ /d/;
375
376     return ($flags, $embed_docref->{'ret_type'}, $embed_docref->{args}->@*);
377 }
378
379 sub autodoc ($$) { # parse a file and extract documentation info
380     my($fh,$file) = @_;
381     my($in, $line_num, $header, $section);
382
383     my $file_is_C = $file =~ / \. [ch] $ /x;
384
385     # Count lines easier
386     my $get_next_line = sub { $line_num++; return <$fh> };
387
388     # Read the file
389     while ($in = $get_next_line->()) {
390         last unless defined $in;
391
392         next unless (    $in =~ / ^ =for [ ]+ apidoc /x
393                                       # =head1 lines only have effect in C files
394                      || ($file_is_C && $in =~ /^=head1/));
395
396         # Here, the line introduces a portion of the input that we care about.
397         # Either it is for an API element, or heading text which we expect
398         # will be used for elements later in the file
399
400         my ($text, $element_name, $flags, $ret_type, $is_item, $proto_in_file);
401         my (@args, @items);
402
403         # If the line starts a new section ...
404         if ($in=~ /^ = (?: for [ ]+ apidoc_section | head1 ) [ ]+ (.*) /x) {
405
406             $section = $1;
407             die "Unknown section name '$section' in $file near line $.\n"
408                                     unless defined $valid_sections{$section};
409
410         }
411         elsif ($in=~ /^ =for [ ]+ apidoc \B /x) {   # Otherwise better be a
412                                                     # plain apidoc line
413             die "Unkown apidoc-type line '$in'" unless $in=~ /^=for apidoc_item/;
414             die "apidoc_item doesn't immediately follow an apidoc entry: '$in'";
415         }
416         else {  # Plain apidoc
417
418             ($element_name, $flags, $ret_type, $is_item, $proto_in_file, @args)
419                                                 = check_api_doc_line($file, $in);
420             # Override this line with any info in embed.fnc
421             my ($embed_flags, $embed_ret_type, @embed_args)
422                                                 = embed_override($element_name);
423             if ($embed_ret_type) {
424                 warn "embed.fnc entry overrides redundant information in"
425                     . " '$proto_in_file' in $file"
426                                                if $flags || $ret_type || @args;
427                 $flags = $embed_flags;
428                 $ret_type = $embed_ret_type;
429                 @args = @embed_args;
430             }
431             elsif ($flags !~ /[my]/)  { # Not in embed.fnc, is missing if not
432                                         # a macro or typedef
433                 $missing{$element_name} = $file;
434             }
435
436             die "flag '$1' is not legal (for function $element_name (from $file))"
437                         if $flags =~ / ( [^AabCDdEeFfhiMmNnTOoPpRrSsUuWXxy] ) /x;
438
439             die "'u' flag must also have 'm' or 'y' flags' for $element_name"
440                                             if $flags =~ /u/ && $flags !~ /[my]/;
441             warn ("'$element_name' not \\w+ in '$proto_in_file' in $file")
442                         if $flags !~ /N/ && $element_name !~ / ^ [_[:alpha:]] \w* $ /x;
443
444             if (exists $seen{$element_name} && $flags !~ /h/) {
445                 die ("'$element_name' in $file was already documented in $seen{$element_name}");
446             }
447             else {
448                 $seen{$element_name} = $file;
449             }
450         }
451
452         # Here we have processed the initial line in the heading text or API
453         # element, and have saved the important information from it into the
454         # corresponding variables.  Now accumulate the text that applies to it
455         # up to a terminating line, which is one of:
456         # 1) =cut
457         # 2) =head (in a C file only =head1)
458         # 3) an end comment line in a C file: m:^\s*\*/:
459         # 4) =for apidoc... (except apidoc_item lines)
460         $text = "";
461         my $head_ender_num = ($file_is_C) ? 1 : "";
462         while (defined($in = $get_next_line->())) {
463
464             last if $in =~ /^=cut/x;
465             last if $in =~ /^=head$head_ender_num/;
466
467             if ($file_is_C && $in =~ m: ^ \s* \* / $ :x) {
468
469                 # End of comment line in C files is a fall-back terminator,
470                 # but warn only if there actually is some accumulated text
471                 warn "=cut missing? $file:$line_num:$in" if $text =~ /\S/;
472                 last;
473             }
474
475             if ($in !~ / ^ =for [ ]+ apidoc /x) {
476                 $text .= $in;
477                 next;
478             }
479
480             # Here, the line is an apidoc line.  All but apidoc_item terminate
481             # the text being accumulated.
482             last if $in =~ / ^ =for [ ]+ apidoc_section /x;
483
484             my ($item_name, $item_flags, $item_ret_type, $is_item,
485                     $item_proto, @item_args) = check_api_doc_line($file, $in);
486             last unless $is_item;
487
488             # Here, is an apidoc_item_line; They can only come within apidoc
489             # paragraphs.
490             die "Unexpected api_doc_item line '$item_proto'"
491                                                         unless $element_name;
492
493             # We accept blank lines between these, but nothing else;
494             die "apidoc_item lines must immediately follow apidoc lines for "
495               . " '$element_name' in $file"
496                                                             if $text =~ /\S/;
497             # Override this line with any info in embed.fnc
498             my ($embed_flags, $embed_ret_type, @embed_args)
499                                                 = embed_override($item_name);
500             if ($embed_ret_type) {
501                 warn "embed.fnc entry overrides redundant information in"
502                     . " '$item_proto' in $file"
503                                 if $item_flags || $item_ret_type || @item_args;
504
505                 $item_flags = $embed_flags;
506                 $item_ret_type = $embed_ret_type;
507                 @item_args = @embed_args;
508             }
509
510             # Use the base entry flags if none for this item; otherwise add in
511             # any non-display base entry flags.
512             if ($item_flags) {
513                 $item_flags .= $flags =~ s/[$display_flags]//rg;
514             }
515             else {
516                 $item_flags = $flags;
517             }
518             $item_ret_type = $ret_type unless $item_ret_type;
519             @item_args = @args unless @item_args;
520             push @items, { name     => $item_name,
521                            ret_type => $item_ret_type,
522                            flags    => $item_flags,
523                            args     => [ @item_args ],
524                          };
525
526             # This line shows that this element is documented.
527             delete $funcflags{$item_name};
528         }
529
530         # Here, are done accumulating the text for this item.  Trim it
531         $text =~ s/ ^ \s* //x;
532         $text =~ s/ \s* $ //x;
533         $text .= "\n" if $text ne "";
534
535         # And treat all-spaces as nothing at all
536         undef $text unless $text =~ /\S/;
537
538         if ($element_name) {
539
540             # Here, we have accumulated into $text, the pod for $element_name
541             my $where = $flags =~ /A/ ? 'api' : 'guts';
542
543             $section = "Functions in file $file" unless defined $section;
544             die "No =for apidoc_section nor =head1 in $file for '$element_name'\n"
545                                                     unless defined $section;
546             if (exists $docs{$where}{$section}{$element_name}) {
547                 warn "$0: duplicate API entry for '$element_name' in"
548                     . " $where/$section\n";
549                 next;
550             }
551
552             # Override the text with just a link if the flags call for that
553             my $is_link_only = ($flags =~ /h/);
554             if ($is_link_only) {
555                 if ($file_is_C) {
556                     die "Can't currently handle link with items to it:\n$in" if @items;
557                     redo;    # Don't put anything if C source
558                 }
559
560                 # Here, is an 'h' flag in pod.  We add a reference to the pod (and
561                 # nothing else) to perlapi/intern.  (It would be better to add a
562                 # reference to the correct =item,=header, but something that makes
563                 # it harder is that it that might be a duplicate, like '=item *';
564                 # so that is a future enhancement XXX.  Another complication is
565                 # there might be more than one deserving candidates.)
566                 my $podname = $file =~ s!.*/!!r;    # Rmv directory name(s)
567                 $podname =~ s/\.pod//;
568                 $text = "Described in L<$podname>.\n";
569
570                 # Don't output a usage example for linked to documentation if
571                 # it is trivial (has no arguments) and we aren't to add a
572                 # semicolon
573                 $flags .= 'U' if $flags =~ /n/ && $flags !~ /[Us]/;
574
575                 # Keep track of all the pod files that we refer to.
576                 push $described_elsewhere{$podname}->@*, $podname;
577             }
578
579             $docs{$where}{$section}{$element_name}{flags} = $flags;
580             $docs{$where}{$section}{$element_name}{pod} = $text;
581             $docs{$where}{$section}{$element_name}{file} = $file;
582             $docs{$where}{$section}{$element_name}{ret_type} = $ret_type;
583             push $docs{$where}{$section}{$element_name}{args}->@*, @args;
584             push $docs{$where}{$section}{$element_name}{items}->@*, @items;
585         }
586         elsif ($text) {
587             $valid_sections{$section}{header} = "" unless
588                                     defined $valid_sections{$section}{header};
589             $valid_sections{$section}{header} .= "\n$text";
590         }
591
592         # We already have the first line of what's to come in $in
593         redo;
594
595     } # End of loop through input
596 }
597
598 my %configs;
599 my @has_defs;
600 my @has_r_defs;     # Reentrant symbols
601 my @include_defs;
602 sub parse_config_h {
603     use re '/aa';   # Everthing is ASCII in this file
604
605     # Process config.h
606     my $config_h = 'config.h';
607     $config_h = 'win32/config.h' unless -e $config_h;
608     die "Can't find $config_h" unless -e $config_h;
609     open my $fh, '<', $config_h or die "Can't open $config_h: $!";
610     while (<$fh>) {
611
612         # Look for lines like /* FOO_BAR:
613         # By convention all config.h descriptions begin like that
614         if (m[ ^ /\* [ ] ( [[:alpha:]] \w+ ) : \s* $ ]ax) {
615             my $name = $1;
616
617             # Here we are starting the description for $name in config.h.  We
618             # accumulate the entire description for it into @description.
619             # Flowing text from one input line to another is appended into the
620             # same array element to make a single flowing line element, but
621             # verbatim lines are kept as separate elements in @description.
622             # This will facilitate later doing pattern matching without regard
623             # to line boundaries on non-verbatim text.
624
625             die "Multiple config.h entries for '$name'"
626                                         if defined $configs{$name}{description};
627
628             # Get first line of description
629             $_ = <$fh>;
630
631             # Each line in the description begins with blanks followed by '/*'
632             # and some spaces.
633             die "Unexpected config.h initial line for $name: '$_'"
634                                             unless s/ ^ ( \s* \* \s* ) //x;
635             my $initial_text = $1;
636
637             # Initialize the description with this first line (after having
638             # stripped the prefix text)
639             my @description = $_;
640
641             # The first line is used as a template for how much indentation
642             # each normal succeeding line has.  Lines indented further
643             # will be considered as intended to be verbatim.  But, empty lines
644             # likely won't have trailing blanks, so just strip the whole thing
645             # for them.
646             my $strip_initial_qr = qr!   \s* \* \s* $
647                                     | \Q$initial_text\E
648                                     !x;
649             $configs{$name}{verbatim} = 0;
650
651             # Read in the remainder of the description
652             while (<$fh>) {
653                 last if s| ^ \s* \* / ||x;  # A '*/' ends it
654
655                 die "Unexpected config.h description line for $name: '$_'"
656                                                 unless s/$strip_initial_qr//;
657
658                 # Fix up the few flawed lines in config.h wherein a new
659                 # sentence begins with a tab (and maybe a space after that).
660                 # Although none of them currently do, let it recognize
661                 # something like
662                 #
663                 #   "... text").  The next sentence ...
664                 #
665                 s/ ( \w "? \)? \. ) \t \s* ( [[:alpha:]] ) /$1  $2/xg;
666
667                 # If this line has extra indentation or looks to have columns,
668                 # it should be treated as verbatim.  Columns are indicated by
669                 # use of interior: tabs, 3 spaces in a row, or even 2 spaces
670                 # not preceded by punctuation.
671                 if ($_ !~ m/  ^ \s
672                               | \S (?:                    \t
673                                     |                     \s{3}
674                                     |  (*nlb:[[:punct:]]) \s{2}
675                                    )
676                            /x)
677                 {
678                     # But here, is not a verbatim line.  Add an empty line if
679                     # this is the first non-verbatim after a run of verbatims
680                     if ($description[-1] =~ /^\s/) {
681                         push @description, "\n", $_;
682                     }
683                     else {  # Otherwise, append this flowing line to the
684                             # current flowing line
685                         $description[-1] .= $_;
686                     }
687                 }
688                 else {
689                     $configs{$name}{verbatim} = 1;
690
691                     # The first verbatim line in a run of them is separated by an
692                     # empty line from the flowing lines above it
693                     push @description, "\n" if $description[-1] =~ /^\S/;
694
695                     $_ = Text::Tabs::expand($_);
696
697                     # Only a single space so less likely to wrap
698                     s/ ^ \s* / /x;
699
700                     push @description, $_;
701                 }
702             }
703
704             push $configs{$name}{description}->@*, @description
705
706         }   # Not a description; see if it is a macro definition.
707         elsif (m! ^
708                   (?: / \* )?                   # Optional commented-out
709                                                 # indication
710                       \# \s* define \s+ ( \w+ ) # $1 is the name
711                   (   \s* )                     # $2 indicates if args or not
712                   (   .*? )                     # $3 is any definition
713                   (?: / \s* \* \* / )?          # Optional trailing /**/ or / **/
714                   $
715                 !x)
716         {
717             my $name = $1;
718
719             # There can be multiple definitions for a name.  We want to know
720             # if any of them has arguments, and if any has a body.
721             $configs{$name}{has_args} //= $2 eq "";
722             $configs{$name}{has_args} ||= $2 eq "";
723             $configs{$name}{has_defn} //= $3 ne "";
724             $configs{$name}{has_defn} ||= $3 ne "";
725         }
726     }
727
728     # We now have stored the description and information about every #define
729     # in the file.  The description is in a form convenient to operate on to
730     # convert to pod.  Do that now.
731     foreach my $name (keys %configs) {
732         next unless defined $configs{$name}{description};
733
734         # All adjacent non-verbatim lines of the description are appended
735         # together in a single element in the array.  This allows the patterns
736         # to work across input line boundaries.
737
738         my $pod = "";
739         while (defined ($_ = shift $configs{$name}{description}->@*)) {
740             chomp;
741
742             if (/ ^ \S /x) {  # Don't edit verbatim lines
743
744                 # Enclose known file/path names not already so enclosed
745                 # with <...>.  (Some entries in config.h are already
746                 # '<path/to/file>')
747                 my $file_name_qr = qr! [ \w / ]+ \.
748                                     (?: c | h | xs | p [lm] | pmc | PL
749                                         | sh | SH | exe ) \b
750                                     !xx;
751                 my $path_name_qr = qr! (?: / \w+ )+ !x;
752                 for my $re ($file_name_qr, $path_name_qr) {
753                     s! (*nlb:[ < \w / ]) ( $re ) !<$1>!gxx;
754                 }
755
756                 # Enclose <... file/path names with F<...> (but no double
757                 # angle brackets)
758                 for my $re ($file_name_qr, $path_name_qr) {
759                     s! < ( $re ) > !F<$1>!gxx;
760                 }
761
762                 # Explain metaconfig units
763                 s/ ( \w+ \. U \b ) /$1 (part of metaconfig)/gx;
764
765                 # Convert "See foo" to "See C<L</foo>>" if foo is described in
766                 # this file.  Also create a link to the known file INSTALL.
767                 # And, to be more general, handle "See also foo and bar", and
768                 # "See also foo, bar, and baz"
769                 while (m/ \b [Ss]ee \s+
770                          (?: also \s+ )?    ( \w+ )
771                          (?: ,  \s+         ( \w+ ) )?
772                          (?: ,? \s+ and \s+ ( \w+ ) )? /xg) {
773                     my @links = $1;
774                     push @links, $2 if defined $2;
775                     push @links, $3 if defined $3;
776                     foreach my $link (@links) {
777                         if ($link eq 'INSTALL') {
778                             s/ \b INSTALL \b /C<L<INSTALL>>/xg;
779                         }
780                         elsif (grep { $link =~ / \b $_ \b /x } keys %configs) {
781                             s| \b $link \b |C<L</$link>>|xg;
782                             $configs{$link}{linked} = 1;
783                             $configs{$name}{linked} = 1;
784                         }
785                     }
786                 }
787
788                 # Enclose what we think are symbols with C<...>.
789                 no warnings 'experimental::vlb';
790                 s/ (*nlb:<)
791                    (
792                         # Any word followed immediately with parens or
793                         # brackets
794                         \b \w+ (?: \( [^)]* \)    # parameter list
795                                  | \[ [^]]* \]    # or array reference
796                                )
797                     | (*plb: ^ | \s ) -D \w+    # Also -Dsymbols.
798                     | \b (?: struct | union ) \s \w+
799
800                         # Words that contain underscores (which are
801                         # definitely not text) or three uppercase letters in
802                         # a row.  Length two ones, like IV, aren't enclosed,
803                         # because they often don't look as nice.
804                     | \b \w* (?: _ | [[:upper:]]{3,} ) \w* \b
805                    )
806                     (*nla:>)
807                  /C<$1>/xg;
808
809                 # These include foo when the name is HAS_foo.  This is a
810                 # heuristic which works in most cases.
811                 if ($name =~ / ^ HAS_ (.*) /x) {
812                     my $symbol = lc $1;
813
814                     # Don't include path components, nor things already in
815                     # <>, or with trailing '(', '['
816                     s! \b (*nlb:[/<]) $symbol (*nla:[[/>(]) \b !C<$symbol>!xg;
817                 }
818             }
819
820             $pod .=  "$_\n";
821         }
822         delete $configs{$name}{description};
823
824         $configs{$name}{pod} = $pod;
825     }
826
827     # Now have converted the description to pod.  We also now have enough
828     # information that we can do cross checking to find definitions without
829     # corresponding pod, and see if they are mentioned in some description;
830     # otherwise they aren't documented.
831   NAME:
832     foreach my $name (keys %configs) {
833
834         # A definition without pod
835         if (! defined $configs{$name}{pod}) {
836
837             # Leading/trailing underscore means internal to config.h, e.g.,
838             # _GNU_SOURCE
839             next if $name =~ / ^ _ /x;
840             next if $name =~ / _ $ /x;
841
842             # MiXeD case names are internal to config.h; the first 4
843             # characters are sufficient to determine this
844             next if $name =~ / ^ [[:upper:]] [[:lower:]]
845                                  [[:upper:]] [[:lower:]]
846                             /x;
847
848             # Here, not internal to config.h.  Look to see if this symbol is
849             # mentioned in the pod of some other.  If so, assume it is
850             # documented.
851             foreach my $check_name (keys %configs) {
852                 my $this_element = $configs{$check_name};
853                 my $this_pod = $this_element->{pod};
854                 if (defined $this_pod) {
855                     next NAME if $this_pod =~ / \b $name \b /x;
856                 }
857             }
858
859             warn "$name has no documentation\n";
860             $missing_macros{$name} = 'config.h';
861
862             next;
863         }
864
865         my $has_defn = $configs{$name}{has_defn};
866         my $has_args = $configs{$name}{has_args};
867
868         # Check if any section already has an entry for this element.
869         # If so, it better be a placeholder, in which case we replace it
870         # with this entry.
871         foreach my $section (keys $docs{'api'}->%*) {
872             if (exists $docs{'api'}{$section}{$name}) {
873                 my $was = $docs{'api'}{$section}{$name}->{pod};
874                 $was = "" unless $was;
875                 chomp $was;
876                 if ($was ne "" && $was !~ m/$link_text/) {
877                     die "Multiple descriptions for $name\n"
878                         . "$section contained '$was'";
879                 }
880                 $docs{'api'}{$section}{$name}->{pod} = $configs{$name}{pod};
881                 $configs{$name}{section} = $section;
882                 last;
883             }
884         }
885
886         my $handled = 0;    # Haven't handled this yet
887
888         if (defined $configs{$name}{'section'}) {
889             # This has been taken care of elsewhere.
890             $handled = 1;
891         }
892         else {
893             my $flags = "";
894             if ($has_defn && ! $has_args) {
895                 $configs{$name}{args} = 1;
896             }
897
898             # Symbols of the form I_FOO are for #include files.  They have
899             # special usage information
900             if ($name =~ / ^ I_ ( .* ) /x) {
901                 my $file = lc $1 . '.h';
902                 $configs{$name}{usage} = <<~"EOT";
903                     #ifdef $name
904                         #include <$file>
905                     #endif
906                     EOT
907             }
908
909             # Compute what section this variable should go into.  This
910             # heuristic was determined by manually inspecting the current
911             # things in config.h, and should be adjusted as necessary as
912             # deficiencies are found.
913             #
914             # This is the default section for macros with a definiton but
915             # no arguments, meaning it is replaced unconditionally
916             #
917             my $sb = qr/ _ | \b /x; # segment boundary
918             my $dash_or_spaces = qr/ - | \s+ /x;
919             my $pod = $configs{$name}{pod};
920             if ($name =~ / ^ USE_ /x) {
921                 $configs{$name}{'section'} = $site_scn;
922             }
923             elsif ($name =~ / SLEEP | (*nlb:SYS_) TIME | TZ | $sb TM $sb /x)
924             {
925                 $configs{$name}{'section'} = $time_scn;
926             }
927             elsif ($name =~ /  DOUBLE | FLOAT | LONGDBL | LDBL | ^ NV
928                             | $sb CASTFLAGS $sb
929                             | QUADMATH
930                             | $sb (?: IS )? NAN
931                             | $sb (?: IS )? FINITE
932                             /x)
933             {
934                 $configs{$name}{'section'} =
935                                     $floating_scn;
936             }
937             elsif ($name =~ / (?: POS | OFF | DIR ) 64 /x) {
938                 $configs{$name}{'section'} = $filesystem_scn;
939             }
940             elsif (   $name =~ / $sb (?: BUILTIN | CPP ) $sb | ^ CPP /x
941                    || $configs{$name}{pod} =~ m/ \b align /x)
942             {
943                 $configs{$name}{'section'} = $compiler_scn;
944             }
945             elsif ($name =~ / ^ [IU] [ \d V ]
946                             | ^ INT | SHORT | LONG | QUAD | 64 | 32 /xx)
947             {
948                 $configs{$name}{'section'} = $integer_scn;
949             }
950             elsif ($name =~ / $sb t $sb /x) {
951                 $configs{$name}{'section'} = $typedefs_scn;
952                 $flags .= 'y';
953             }
954             elsif (   $name =~ / ^ PERL_ ( PRI | SCN ) | $sb FORMAT $sb /x
955                     && $configs{$name}{pod} =~ m/ \b format \b /ix)
956             {
957                 $configs{$name}{'section'} = $formats_scn;
958             }
959             elsif ($name =~ / BACKTRACE /x) {
960                 $configs{$name}{'section'} = $dump_scn;
961             }
962             elsif ($name =~ / ALLOC $sb /x) {
963                 $configs{$name}{'section'} = $memory_scn;
964             }
965             elsif (   $name =~ /   STDIO | FCNTL | EOF | FFLUSH
966                                 | $sb FILE $sb
967                                 | $sb DIR $sb
968                                 | $sb LSEEK
969                                 | $sb INO $sb
970                                 | $sb OPEN
971                                 | $sb CLOSE
972                                 | ^ DIR
973                                 | ^ INO $sb
974                                 | DIR $
975                                 | FILENAMES
976                                 /x
977                     || $configs{$name}{pod} =~ m!  I/O | stdio
978                                                 | file \s+ descriptor
979                                                 | file \s* system
980                                                 | statfs
981                                                 !x)
982             {
983                 $configs{$name}{'section'} = $filesystem_scn;
984             }
985             elsif ($name =~ / ^ SIG | SIGINFO | signal /ix) {
986                 $configs{$name}{'section'} = $signals_scn;
987             }
988             elsif ($name =~ / $sb ( PROTO (?: TYPE)? S? ) $sb /x) {
989                 $configs{$name}{'section'} = $prototypes_scn;
990             }
991             elsif (   $name =~ / ^ LOC_ /x
992                     || $configs{$name}{pod} =~ /full path/i)
993             {
994                 $configs{$name}{'section'} = $paths_scn;
995             }
996             elsif ($name =~ / $sb LC_ | LOCALE | langinfo /xi) {
997                 $configs{$name}{'section'} = $locales_scn;
998             }
999             elsif ($configs{$name}{pod} =~ /  GCC | C99 | C\+\+ /xi) {
1000                 $configs{$name}{'section'} = $compiler_scn;
1001             }
1002             elsif ($name =~ / PASSW (OR)? D | ^ PW | ( PW | GR ) ENT /x)
1003             {
1004                 $configs{$name}{'section'} = $password_scn;
1005             }
1006             elsif ($name =~ /  SOCKET | $sb SOCK /x) {
1007                 $configs{$name}{'section'} = $sockets_scn;
1008             }
1009             elsif (   $name =~ / THREAD | MULTIPLICITY /x
1010                     || $configs{$name}{pod} =~ m/ \b pthread /ix)
1011             {
1012                 $configs{$name}{'section'} = $concurrency_scn;
1013             }
1014             elsif ($name =~ /  PERL | ^ PRIV | SITE | ARCH | BIN
1015                                 | VENDOR | ^ USE
1016                             /x)
1017             {
1018                 $configs{$name}{'section'} = $site_scn;
1019             }
1020             elsif (   $pod =~ / \b floating $dash_or_spaces point \b /ix
1021                     || $pod =~ / \b (double | single) $dash_or_spaces precision \b /ix
1022                     || $pod =~ / \b doubles \b /ix
1023                     || $pod =~ / \b (?: a | the | long ) \s+ (?: double | NV ) \b /ix)
1024             {
1025                 $configs{$name}{'section'} =
1026                                     $floating_scn;
1027             }
1028             else {
1029                 # Above are the specific sections.  The rest go into a
1030                 # grab-bag of general configuration values.  However, we put
1031                 # two classes of them into lists of their names, without their
1032                 # descriptions, when we think that the description doesn't add
1033                 # any real value.  One list contains the #include variables:
1034                 # the description is basically boiler plate for each of these.
1035                 # The other list contains the very many things that are of the
1036                 # form HAS_foo, and \bfoo\b is contained in its description,
1037                 # and there is no verbatim text in the pod or links to/from it
1038                 # (which would add value).  That means that it is likely the
1039                 # intent of the variable can be gleaned from just its name,
1040                 # and unlikely the description adds signficant value, so just
1041                 # listing them suffices.  Giving their descriptions would
1042                 # expand this pod significantly with little added value.
1043                 if (   ! $has_defn
1044                     && ! $configs{$name}{verbatim}
1045                     && ! $configs{$name}{linked})
1046                 {
1047                     if ($name =~ / ^ I_ ( .* ) /x) {
1048                         push @include_defs, $name;
1049                         next;
1050                     }
1051                     elsif ($name =~ / ^ HAS_ ( .* ) /x) {
1052                         my $canonical_name = $1;
1053                         $canonical_name =~ s/_//g;
1054
1055                         my $canonical_pod = $configs{$name}{pod};
1056                         $canonical_pod =~ s/_//g;
1057
1058                         if ($canonical_pod =~ / \b $canonical_name \b /xi) {
1059                             if ($name =~ / $sb R $sb /x) {
1060                                 push @has_r_defs, $name;
1061                             }
1062                             else {
1063                                 push @has_defs, $name;
1064                             }
1065                             next;
1066                         }
1067                     }
1068                 }
1069
1070                 $configs{$name}{'section'} = $genconfig_scn;
1071             }
1072
1073             my $section = $configs{$name}{'section'};
1074             die "Internal error: '$section' not in \%valid_sections"
1075                             unless grep { $_ eq $section } keys %valid_sections;
1076             $flags .= 'AdmnT';
1077             $flags .= 'U' unless defined $configs{$name}{usage};
1078
1079             $docs{'api'}{$section}{$name}{flags} = $flags;
1080             $docs{'api'}{$section}{$name}{pod} = $configs{$name}{pod};
1081             $docs{'api'}{$section}{$name}{ret_type} = "";
1082             $docs{'api'}{$section}{$name}{file} = 'config.h';
1083             $docs{'api'}{$section}{$name}{usage}
1084                 = $configs{$name}{usage} if defined $configs{$name}{usage};
1085             push $docs{'api'}{$section}{$name}{args}->@*, ();
1086             push $docs{'api'}{$section}{$name}{items}->@*, ();
1087         }
1088     }
1089 }
1090
1091 sub docout ($$$) { # output the docs for one function
1092     my($fh, $element_name, $docref) = @_;
1093
1094     # Trim trailing space
1095     $element_name =~ s/\s*$//;
1096
1097     my $flags = $docref->{flags};
1098     my $pod = $docref->{pod} // "";
1099     my $file = $docref->{file};
1100
1101     my @items = $docref->{items}->@*;
1102
1103     # Make the main element the first of the items.  This allows uniform
1104     # treatment below
1105     unshift @items, {   name => $element_name,
1106                         flags => $flags,
1107                         ret_type => $docref->{ret_type},
1108                         args => [ $docref->{args}->@* ],
1109                     };
1110
1111     warn("Empty pod for $element_name (from $file)") unless $pod =~ /\S/;
1112
1113     print $fh "\n=over $description_indent\n";
1114     print $fh "\n=item C<$_->{name}>\n" for @items;
1115
1116     # If we're printing only a link to an element, this isn't the major entry,
1117     # so no X<> here.
1118     if ($flags !~ /h/) {
1119         print $fh "X<$_->{name}>" for @items;
1120         print $fh "\n";
1121     }
1122
1123     for my $item (@items) {
1124         if ($item->{flags} =~ /D/) {
1125             print $fh <<~"EOT";
1126
1127                 C<B<DEPRECATED!>>  It is planned to remove C<$item->{name}> from a
1128                 future release of Perl.  Do not use it for new code; remove it from
1129                 existing code.
1130                 EOT
1131         }
1132         elsif ($item->{flags} =~ /x/) {
1133             print $fh <<~"EOT";
1134
1135                 NOTE: C<$item->{name}> is B<experimental> and may change or be
1136                 removed without notice.
1137                 EOT
1138         }
1139     }
1140
1141     chomp $pod;     # Make sure prints pod with a single trailing \n
1142     print $fh "\n", $pod, "\n";
1143
1144     for my $item (@items) {
1145         my $item_flags = $item->{flags};
1146         my $item_name = $item->{name};
1147
1148         print $fh "\nNOTE: the C<perl_$item_name()> form is B<deprecated>.\n"
1149                                                     if $item_flags =~ /O/;
1150         # Is Perl_, but no #define foo # Perl_foo
1151         if (($item_flags =~ /p/ && $item_flags =~ /o/ && $item_flags !~ /M/)
1152
1153              # Can't handle threaded varargs
1154          || ($item_flags =~ /f/ && $item_flags !~ /T/))
1155         {
1156             $item->{name} = "Perl_$item_name";
1157             print $fh <<~"EOT";
1158
1159                 NOTE: C<$item_name> must be explicitly called as
1160                 C<$item->{name}>
1161                 EOT
1162             print $fh "with an C<aTHX_> parameter" if $item_flags !~ /T/;
1163             print $fh ".\n";
1164         }
1165     }
1166
1167     if ($flags =~ /[Uy]/) { # no usage; typedefs are considered simple enough
1168                             # to never warrant a usage line
1169         warn("U and s flags are incompatible")
1170                                             if $flags =~ /U/ && $flags =~ /s/;
1171         # nothing
1172     } else {
1173
1174         print $fh "\n=over $usage_indent\n";
1175
1176         if (defined $docref->{usage}) {     # An override of the usage section
1177             print $fh "\n", ($docref->{usage} =~ s/^/ /mrg), "\n";
1178         }
1179         else {
1180
1181             # Add the thread context formal parameter on expanded-out names
1182             for my $item (@items) {
1183                 unshift $item->{args}->@*, (($item->{args}->@*)
1184                                             ? "pTHX_"
1185                                             : "pTHX")
1186                                                    if $item->{flags} !~ /T/
1187                                                    && $item->{name} =~ /^Perl_/;
1188             }
1189
1190             # Look through all the items in this entry.  If all have the same
1191             # return type and arguments, only the main entry is displayed.
1192             # Also, find the longest return type and longest name so that if
1193             # multiple ones are shown, they can be vertically aligned nicely
1194             my $need_individual_usage = 0;
1195             my $longest_name_length = length $items[0]->{name};
1196             my $base_ret_type = $items[0]->{ret_type};
1197             my $longest_ret = length $base_ret_type;
1198             my @base_args = $items[0]->{args}->@*;
1199             for (my $i = 1; $i < @items; $i++) {
1200                 no warnings 'experimental::smartmatch';
1201                 my $item = $items[$i];
1202                 $need_individual_usage = 1
1203                                     if    $item->{ret_type} ne $base_ret_type
1204                                     || ! ($item->{args}->@* ~~ @base_args);
1205                 my $ret_length = length $item->{ret_type};
1206                 $longest_ret = $ret_length if $ret_length > $longest_ret;
1207                 my $name_length = length $item->{name};
1208                 $longest_name_length = $name_length
1209                                         if $name_length > $longest_name_length;
1210             }
1211
1212             # If we're only showing one entry, only its length matters.
1213             $longest_name_length = length($items[0]->{name})
1214                                                 unless $need_individual_usage;
1215             print $fh "\n";
1216
1217             my $indent = 1;     # 1 is sufficient for verbatim; =over is used
1218                                 # for more
1219             my $ret_name_sep_length = 2; # spaces between return type and name
1220             my $name_indent = $indent + $longest_ret;
1221             $name_indent += $ret_name_sep_length if $longest_ret;
1222
1223             # 80 column terminal - 1 for pager adding a column; -7 for nroff
1224             # indent;
1225             my $max_length = 80 - 1 - 7 - $description_indent - $usage_indent;
1226
1227             for my $item (@items) {
1228                 my $ret_type = $item->{ret_type};
1229                 my @args = $item->{args}->@*;
1230                 my $name = $item->{name};
1231                 my $item_flags = $item->{flags};
1232
1233                 # The return type
1234                 print $fh (" " x $indent), $ret_type;
1235
1236                 print $fh " " x (  $ret_name_sep_length
1237                                  + $longest_ret - length $ret_type);
1238                 print $fh $name;
1239
1240                 if ($item_flags =~ /n/) { # no args
1241                     warn("$file: $element_name: n flag without m")
1242                                                     unless $item_flags =~ /m/;
1243                     warn("$file: $name: n flag but apparently has args")
1244                                                                     if @args;
1245                 }
1246                 else {
1247                     # +1 for the '('
1248                     my $arg_indent = $name_indent + $longest_name_length + 1;
1249
1250                     # Align the argument lists of the items
1251                     print $fh " " x ($longest_name_length - length($name));
1252                     print $fh "(";
1253
1254                     # Display as many of the arguments on the same line as
1255                     # will fit.
1256                     my $total_length = $arg_indent;
1257                     my $first_line = 1;
1258                     for (my $i = 0; $i < @args; $i++) {
1259                         my $arg = $args[$i];
1260                         my $arg_length = length($arg);
1261
1262                         # All but the first arg are preceded by a blank
1263                         my $use_blank = $i > 0;
1264
1265                         # +1 here and below because either the argument has a
1266                         # trailing comma or trailing ')'
1267                         $total_length += $arg_length + $use_blank + 1;
1268
1269                         # We want none of the arguments to be positioned so
1270                         # they extend too far to the right.  Ideally, they
1271                         # should all start in the same column as the arguments
1272                         # on the first line of the function display do.  But, if
1273                         # necessary, outdent them so that they all start in
1274                         # another column, with the longest ending at the right
1275                         # margin, like so:
1276                         #                   void  function_name(pTHX_ short1,
1277                         #                                    short2,
1278                         #                                    very_long_argument,
1279                         #                                    short3)
1280                         if ($total_length > $max_length) {
1281
1282                             # If this is the first continuation line,
1283                             # calculate the longest argument; this will be the
1284                             # one we may have to outdent for.
1285                             if ($first_line) {
1286                                 $first_line = 0;
1287
1288                                 # We will need at least as much as the current
1289                                 # argument
1290                                 my $longest_arg_length = $arg_length
1291                                                        + $use_blank + 1;
1292
1293                                 # Look through the rest of the args to see if
1294                                 # any are longer than this one.
1295                                 for (my $j = $i + 1; $j < @args; $j++) {
1296
1297                                     # Include the trailing ',' or ')' in the
1298                                     # length.  No need to concern ourselves
1299                                     # with a leading blank, as the argument
1300                                     # would be positioned first on the next
1301                                     # line
1302                                     my $peek_arg_length = length ($args[$j])
1303                                                         + 1;
1304                                     $longest_arg_length = $peek_arg_length
1305                                       if $peek_arg_length > $longest_arg_length;
1306                                 }
1307
1308                                 # Calculate the new indent if necessary.
1309                                 $arg_indent = $max_length - $longest_arg_length
1310                                         if $arg_indent + $longest_arg_length
1311                                                                 > $max_length;
1312                             }
1313
1314                             print $fh "\n", (" " x $arg_indent);
1315                             $total_length = $arg_indent + $arg_length + 1;
1316                             $use_blank = 0;
1317                         }
1318
1319                         # Display this argument
1320                         print $fh " " if $use_blank;
1321                         print $fh $arg;
1322                         print $fh "," if $i < @args - 1 && $args[$i] ne 'pTHX_';
1323
1324                     } # End of loop through args
1325
1326                     print $fh ")";
1327                 }
1328
1329                 print $fh ";" if $item_flags =~ /s/; # semicolon: "dTHR;"
1330                 print $fh "\n";
1331
1332                 # Only the first entry is normally displayed
1333                 last unless $need_individual_usage;
1334             }
1335         }
1336
1337         print $fh "\n=back\n";
1338     }
1339
1340     print $fh "\n=back\n";
1341     print $fh "\n=for hackers\nFound in file $file\n";
1342 }
1343
1344 sub construct_missings_section {
1345     my ($pod_name, $missings_ref) = @_;
1346     my $text = "";
1347
1348     return $text unless $missings_ref->@*;
1349
1350     $text .= <<~EOT;
1351
1352         =head1 Undocumented functions
1353
1354         EOT
1355     if ($pod_name eq 'perlapi') {
1356         $text .= <<~'EOT';
1357             The following functions have been flagged as part of the public
1358             API, but are currently undocumented.  Use them at your own risk,
1359             as the interfaces are subject to change.  Functions that are not
1360             listed in this document are not intended for public use, and
1361             should NOT be used under any circumstances.
1362
1363             If you feel you need to use one of these functions, first send
1364             email to L<perl5-porters@perl.org|mailto:perl5-porters@perl.org>.
1365             It may be that there is a good reason for the function not being
1366             documented, and it should be removed from this list; or it may
1367             just be that no one has gotten around to documenting it.  In the
1368             latter case, you will be asked to submit a patch to document the
1369             function.  Once your patch is accepted, it will indicate that the
1370             interface is stable (unless it is explicitly marked otherwise) and
1371             usable by you.
1372             EOT
1373     }
1374     else {
1375         $text .= <<~'EOT';
1376             The following functions are currently undocumented.  If you use
1377             one of them, you may wish to consider creating and submitting
1378             documentation for it.
1379             EOT
1380     }
1381
1382     $text .= "\n";
1383
1384     # Sort the elements.
1385     my @missings = sort dictionary_order $missings_ref->@*;
1386
1387     # Output the X<> references to the names, packed since they don't get
1388     # displayed, but not too many per line so that when someone is editing the
1389     # file, it doesn't run on
1390     my $line_length = 0;
1391     for my $missing (sort dictionary_order @missings) {
1392         my $entry = "X<$missing>";
1393         my $entry_length = length $entry;
1394
1395         # Don't loop forever if we have a verrry long name, and don't go too
1396         # far to the right.
1397         if ($line_length > 0 && $line_length + $entry_length > $max_width) {
1398             $text .= "\n";
1399             $line_length = 0;
1400         }
1401
1402         $text .= $entry;
1403         $line_length += $entry_length;
1404     }
1405
1406     use integer;
1407
1408     # Look through all the elements in the list and see how many columns we
1409     # could place them in the output what will fit in the available width.
1410     my $min_spacer = 2;     # Need this much space between columns
1411     my $columns;
1412     my $rows;
1413     my @col_widths;
1414
1415   COLUMN:
1416     # We start with more columns, and work down until we find a number that
1417     # can accommodate all the data.  This algorithm doesn't require the
1418     # resulting columns to all have the same width.  This can allow for
1419     # as tight of packing as the data will possibly allow.
1420     for ($columns = 7; $columns > 1; $columns--) {
1421
1422         # For this many columns, we will need this many rows (final row might
1423         # not be completely filled)
1424         $rows = (@missings + $columns - 1) / $columns;
1425
1426         my $row_width = 0;
1427         my $i = 0;  # Which missing element
1428
1429         # For each column ...
1430         for my $col (0 .. $columns - 1) {
1431
1432             # Calculate how wide the column needs to be, which is based on the
1433             # widest element in it
1434             $col_widths[$col] = 0;
1435
1436             # Look through all the rows to find the widest element
1437             for my $row (0 .. $rows - 1) {
1438
1439                 # Skip if this row doesn't have an entry for this column
1440                 last if $i >= @missings;
1441
1442                 # This entry occupies this many bytes.
1443                 my $this_width = length $missings[$i];
1444
1445                 # All but the final column need a spacer between it and the
1446                 # next column over.
1447                 $this_width += $min_spacer if $col < $columns - 1;
1448
1449
1450                 # This column will need to have enough width to accommodate
1451                 # this element
1452                 if ($this_width > $col_widths[$col]) {
1453
1454                     # We can't have this many columns if the total width
1455                     # exceeds the available; bail now and try fewer columns
1456                     next COLUMN if $row_width + $this_width > $max_width;
1457
1458                     $col_widths[$col] = $this_width;
1459                 }
1460
1461                 $i++;   # The next row will contain the next item
1462             }
1463
1464             $row_width += $col_widths[$col];
1465             next COLUMN if $row_width > $max_width;
1466         }
1467
1468         # If we get this far, this many columns works
1469         last;
1470     }
1471
1472     # Here, have calculated the number of rows ($rows) and columns ($columns)
1473     # required to list the elements.  @col_widths contains the width of each
1474     # column.
1475
1476     $text .= "\n\n=over $description_indent\n\n";
1477
1478     # Assemble the output
1479     for my $row (0 .. $rows - 1) {
1480         for my $col (0 .. $columns - 1) {
1481             $text .= " " if $col == 0;  # Indent one to mark as verbatim
1482
1483             my $index = $row + $rows * $col;  # Convert 2 dimensions to 1
1484
1485             # Skip if this row doesn't have an entry for this column
1486             next if $index >= @missings;
1487
1488             my $element = $missings[$index];
1489             $text .= $element;
1490
1491             # Add alignment spaces for all but final column
1492             $text .= " " x ($col_widths[$col] - length $element)
1493                                                         if $col < $columns - 1;
1494         }
1495
1496         $text .= "\n";  # End of row
1497     }
1498
1499     $text .= "\n=back\n";
1500
1501     return $text;
1502 }
1503
1504 sub dictionary_order {
1505     # Do a case-insensitive dictionary sort, with only alphabetics
1506     # significant, falling back to using everything for determinancy
1507     return (uc($a =~ s/[[:^alpha:]]//r) cmp uc($b =~ s/[[:^alpha:]]//r))
1508            || uc($a) cmp uc($b)
1509            || $a cmp $b;
1510 }
1511
1512 sub output {
1513     my ($podname, $header, $dochash, $missings_ref, $footer) = @_;
1514     #
1515     # strip leading '|' from each line which had been used to hide
1516     # pod from pod checkers.
1517     s/^\|//gm for $header, $footer;
1518
1519     my $fh = open_new("pod/$podname.pod", undef,
1520                       {by => "$0 extracting documentation",
1521                        from => 'the C source files'}, 1);
1522
1523     print $fh $header, "\n";
1524
1525     for my $section_name (sort dictionary_order keys %valid_sections) {
1526         my $section_info = $dochash->{$section_name};
1527
1528         # We allow empty sections in perlintern.
1529         if (! $section_info && $podname eq 'perlapi') {
1530             warn "Empty section '$section_name'; skipped";
1531             next;
1532         }
1533
1534         print $fh "\n=head1 $section_name\n";
1535
1536         if ($podname eq 'perlapi') {
1537             print $fh "\n", $valid_sections{$section_name}{header}, "\n"
1538                                 if defined $valid_sections{$section_name}{header};
1539
1540             # Output any heading-level documentation and delete so won't get in
1541             # the way later
1542             if (exists $section_info->{""}) {
1543                 print $fh "\n", $section_info->{""}, "\n";
1544                 delete $section_info->{""};
1545             }
1546         }
1547
1548
1549         if ($section_info) {
1550             for my $function_name (sort dictionary_order keys %$section_info) {
1551                 docout($fh, $function_name, $section_info->{$function_name});
1552             }
1553         }
1554         else {
1555             print $fh "\nThere are only public API items currently in $section_name\n";
1556         }
1557
1558         print $fh "\n", $valid_sections{$section_name}{footer}, "\n"
1559                             if $podname eq 'perlapi'
1560                             && defined $valid_sections{$section_name}{footer};
1561     }
1562
1563     print $fh construct_missings_section($podname, $missings_ref);
1564
1565     print $fh "\n$footer\n=cut\n";
1566
1567     read_only_bottom_close_and_rename($fh);
1568 }
1569
1570 foreach (@{(setup_embed())[0]}) {
1571     next if @$_ < 2;
1572     my ($flags, $ret_type, $func, @args) = @$_;
1573     s/\b(?:NN|NULLOK)\b\s+//g for @args;
1574
1575     $funcflags{$func} = {
1576                          flags => $flags,
1577                          ret_type => $ret_type,
1578                          args => \@args,
1579                         };
1580 }
1581
1582 # glob() picks up docs from extra .c or .h files that may be in unclean
1583 # development trees.
1584 open my $fh, '<', 'MANIFEST'
1585     or die "Can't open MANIFEST: $!";
1586 while (my $line = <$fh>) {
1587     next unless my ($file) = $line =~ /^(\S+\.(?:[ch]|pod))\t/;
1588
1589     # Don't pick up pods from these.  (We may pick up generated stuff from
1590     # /lib though)
1591     next if $file =~ m! ^ ( cpan | dist | ext ) / !x;
1592
1593     open F, '<', $file or die "Cannot open $file for docs: $!\n";
1594     autodoc(\*F,$file);
1595     close F or die "Error closing $file: $!\n";
1596 }
1597 close $fh or die "Error whilst reading MANIFEST: $!";
1598
1599 parse_config_h();
1600
1601 for (sort keys %funcflags) {
1602     next unless $funcflags{$_}{flags} =~ /d/;
1603     next if $funcflags{$_}{flags} =~ /h/;
1604     warn "no docs for $_\n";
1605 }
1606
1607 foreach (sort keys %missing) {
1608     warn "Function '$_', documented in $missing{$_}, not listed in embed.fnc";
1609 }
1610
1611 # List of funcs in the public API that aren't also marked as core-only,
1612 # experimental nor deprecated.
1613 my @missing_api = grep $funcflags{$_}{flags} =~ /A/
1614                     && $funcflags{$_}{flags} !~ /[xD]/
1615                     && !$docs{api}{$_}, keys %funcflags;
1616 push @missing_api, keys %missing_macros;
1617
1618 my $other_places = join ", ", map { "L<$_>" } sort dictionary_order qw( perlclib perlxs),
1619                                                                keys %described_elsewhere;
1620
1621 # The S< > makes things less densely packed, hence more readable
1622 my $has_defs_text .= join ",S< > ", map { "C<$_>" } sort dictionary_order @has_defs;
1623 my $has_r_defs_text .= join ",S< > ", map { "C<$_>" } sort dictionary_order @has_r_defs;
1624 $valid_sections{$genconfig_scn}{footer} =~ s/__HAS_LIST__/$has_defs_text/;
1625 $valid_sections{$genconfig_scn}{footer} =~ s/__HAS_R_LIST__/$has_r_defs_text/;
1626
1627 my $include_defs_text .= join ",S< > ", map { "C<$_>" } sort dictionary_order @include_defs;
1628 $valid_sections{$genconfig_scn}{footer} =~ s/__INCLUDE_LIST__/$include_defs_text/;
1629
1630 my $section_list = join "\n\n", map { "=item L</$_>" } sort dictionary_order keys %valid_sections;
1631
1632 output('perlapi', <<"_EOB_", $docs{api}, \@missing_api, <<"_EOE_");
1633 |=encoding UTF-8
1634 |
1635 |=head1 NAME
1636 |
1637 |perlapi - autogenerated documentation for the perl public API
1638 |
1639 |=head1 DESCRIPTION
1640 |X<Perl API> X<API> X<api>
1641 |
1642 |This file contains most of the documentation of the perl public API, as
1643 |generated by F<embed.pl>.  Specifically, it is a listing of functions,
1644 |macros, flags, and variables that may be used by extension writers.  Besides
1645 |L<perlintern> and F<config.h>, some items are listed here as being actually
1646 |documented in another pod.
1647 |
1648 |L<At the end|/Undocumented functions> is a list of functions which have yet
1649 |to be documented.  Patches welcome!  The interfaces of these are subject to
1650 |change without notice.
1651 |
1652 |Some of the functions documented here are consolidated so that a single entry
1653 |serves for multiple functions which all do basically the same thing, but have
1654 |some slight differences.  For example, one form might process magic, while
1655 |another doesn't.  The name of each variation is listed at the top of the
1656 |single entry.  But if all have the same signature (arguments and return type)
1657 |except for their names, only the usage for the base form is shown.  If any
1658 |one of the forms has a different signature (such as returning C<const> or
1659 |not) every function's signature is explicitly displayed.
1660 |
1661 |Anything not listed here or in the other mentioned pods is not part of the
1662 |public API, and should not be used by extension writers at all.  For these
1663 |reasons, blindly using functions listed in F<proto.h> is to be avoided when
1664 |writing extensions.
1665 |
1666 |In Perl, unlike C, a string of characters may generally contain embedded
1667 |C<NUL> characters.  Sometimes in the documentation a Perl string is referred
1668 |to as a "buffer" to distinguish it from a C string, but sometimes they are
1669 |both just referred to as strings.
1670 |
1671 |Note that all Perl API global variables must be referenced with the C<PL_>
1672 |prefix.  Again, those not listed here are not to be used by extension writers,
1673 |and can be changed or removed without notice; same with macros.
1674 |Some macros are provided for compatibility with the older,
1675 |unadorned names, but this support may be disabled in a future release.
1676 |
1677 |Perl was originally written to handle US-ASCII only (that is characters
1678 |whose ordinal numbers are in the range 0 - 127).
1679 |And documentation and comments may still use the term ASCII, when
1680 |sometimes in fact the entire range from 0 - 255 is meant.
1681 |
1682 |The non-ASCII characters below 256 can have various meanings, depending on
1683 |various things.  (See, most notably, L<perllocale>.)  But usually the whole
1684 |range can be referred to as ISO-8859-1.  Often, the term "Latin-1" (or
1685 |"Latin1") is used as an equivalent for ISO-8859-1.  But some people treat
1686 |"Latin1" as referring just to the characters in the range 128 through 255, or
1687 |sometimes from 160 through 255.
1688 |This documentation uses "Latin1" and "Latin-1" to refer to all 256 characters.
1689 |
1690 |Note that Perl can be compiled and run under either ASCII or EBCDIC (See
1691 |L<perlebcdic>).  Most of the documentation (and even comments in the code)
1692 |ignore the EBCDIC possibility.
1693 |For almost all purposes the differences are transparent.
1694 |As an example, under EBCDIC,
1695 |instead of UTF-8, UTF-EBCDIC is used to encode Unicode strings, and so
1696 |whenever this documentation refers to C<utf8>
1697 |(and variants of that name, including in function names),
1698 |it also (essentially transparently) means C<UTF-EBCDIC>.
1699 |But the ordinals of characters differ between ASCII, EBCDIC, and
1700 |the UTF- encodings, and a string encoded in UTF-EBCDIC may occupy a different
1701 |number of bytes than in UTF-8.
1702 |
1703 |The organization of this document is tentative and subject to change.
1704 |Suggestions and patches welcome
1705 |L<perl5-porters\@perl.org|mailto:perl5-porters\@perl.org>.
1706 |
1707 |The sections in this document currently are
1708 |
1709 |=over
1710
1711 |$section_list
1712 |
1713 |=back
1714 |
1715 |The listing below is alphabetical, case insensitive.
1716 _EOB_
1717 |=head1 AUTHORS
1718 |
1719 |Until May 1997, this document was maintained by Jeff Okamoto
1720 |<okamoto\@corp.hp.com>.  It is now maintained as part of Perl itself.
1721 |
1722 |With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
1723 |Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
1724 |Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer,
1725 |Stephen McCamant, and Gurusamy Sarathy.
1726 |
1727 |API Listing originally by Dean Roehrich <roehrich\@cray.com>.
1728 |
1729 |Updated to be autogenerated from comments in the source by Benjamin Stuhl.
1730 |
1731 |=head1 SEE ALSO
1732 |
1733 |F<config.h>, L<perlintern>, $other_places
1734 _EOE_
1735
1736 # List of non-static internal functions
1737 my @missing_guts =
1738  grep $funcflags{$_}{flags} !~ /[AS]/ && !$docs{guts}{$_}, keys %funcflags;
1739
1740 output('perlintern', <<'_EOB_', $docs{guts}, \@missing_guts, <<"_EOE_");
1741 |=head1 NAME
1742 |
1743 |perlintern - autogenerated documentation of purely B<internal>
1744 |Perl functions
1745 |
1746 |=head1 DESCRIPTION
1747 |X<internal Perl functions> X<interpreter functions>
1748 |
1749 |This file is the autogenerated documentation of functions in the
1750 |Perl interpreter that are documented using Perl's internal documentation
1751 |format but are not marked as part of the Perl API.  In other words,
1752 |B<they are not for use in extensions>!
1753
1754 |It has the same sections as L<perlapi>, though some may be empty.
1755 |
1756 _EOB_
1757 |
1758 |=head1 AUTHORS
1759 |
1760 |The autodocumentation system was originally added to the Perl core by
1761 |Benjamin Stuhl.  Documentation is by whoever was kind enough to
1762 |document their functions.
1763 |
1764 |=head1 SEE ALSO
1765 |
1766 |F<config.h>, L<perlapi>, $other_places
1767 _EOE_