wikiheaders: Updated to latest from SDL3.

main
Ryan C. Gordon 2024-05-16 11:46:29 -04:00
parent 1b962b884f
commit b4337693be
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
1 changed files with 216 additions and 72 deletions

View File

@ -622,7 +622,7 @@ my %headersymschunk = (); # $headersymschunk{"SDL_OpenAudio"} -> offset in arr
my %headersymshasdoxygen = (); # $headersymshasdoxygen{"SDL_OpenAudio"} -> 1 if there was no existing doxygen for this function.
my %headersymstype = (); # $headersymstype{"SDL_OpenAudio"} -> 1 (function), 2 (macro), 3 (struct), 4 (enum), 5 (other typedef)
my %headersymscategory = (); # $headersymscategory{"SDL_OpenAudio"} -> 'Audio' ... this is set with a `/* WIKI CATEGEORY: Audio */` comment in the headers that sets it on all symbols until a new comment changes it. So usually, once at the top of the header file.
my %headercategorydocs = (); # $headercategorydocs{"Audio"} -> (fake) symbol for this category's documentation. Undefined if not documented.
my %wikitypes = (); # contains string of wiki page extension, like $wikitypes{"SDL_OpenAudio"} == 'mediawiki'
my %wikisyms = (); # contains references to hash of strings, each string being the full contents of a section of a wiki page, like $wikisyms{"SDL_OpenAudio"}{"Remarks"}.
my %wikisectionorder = (); # contains references to array, each array item being a key to a wikipage section in the correct order, like $wikisectionorder{"SDL_OpenAudio"}[2] == 'Remarks'
@ -710,6 +710,7 @@ while (my $d = readdir(DH)) {
my @contents = ();
my $ignoring_lines = 0;
my $header_comment = -1;
my $saw_category_doxygen = -1;
my $lineno = 0;
while (<FH>) {
chomp;
@ -762,6 +763,8 @@ while (my $d = readdir(DH)) {
add_coverage_gap($_, $dent, $lineno) if ($header_comment == 0);
next;
} else { # Start of a doxygen comment, parse it out.
my $is_category_doxygen = 0;
@templines = ( $_ );
while (<FH>) {
chomp;
@ -783,43 +786,76 @@ while (my $d = readdir(DH)) {
}
}
} else {
s/\A\s*\*\s*//;
s/\A\s*\*\s*//; # Strip off the " * " at the start of the comment line.
# To add documentation to Category Pages, the rule is it has to
# be the first Doxygen comment in the header, and it must start with `# CategoryX`
# (otherwise we'll treat it as documentation for whatever's below it). `X` is
# the category name, which doesn't _necessarily_ have to match
# $current_wiki_category, but it probably should.
#
# For compatibility with Doxygen, if there's a `\file` here instead of
# `# CategoryName`, we'll accept it and use the $current_wiki_category if set.
if ($saw_category_doxygen == -1) {
$saw_category_doxygen = defined($current_wiki_category) && /\A\\file\s+/;
if ($saw_category_doxygen) {
$_ = "# Category$current_wiki_category";
} else {
$saw_category_doxygen = /\A\# Category/;
}
$is_category_doxygen = $saw_category_doxygen;
}
$str .= "$_\n";
}
}
$decl = <FH>;
$lineno++ if defined $decl;
$decl = '' if not defined $decl;
chomp($decl);
if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_)?DECLSPEC/) {
$symtype = 1; # function declaration
} elsif ($decl =~ /\A\s*SDL_FORCE_INLINE/) {
$symtype = 1; # (forced-inline) function declaration
} elsif ($decl =~ /\A\s*\#\s*define\s+/) {
$symtype = 2; # macro
} elsif ($decl =~ /\A\s*(typedef\s+|)(struct|union)/) {
$symtype = 3; # struct or union
} elsif ($decl =~ /\A\s*(typedef\s+|)enum/) {
$symtype = 4; # enum
} elsif ($decl =~ /\A\s*typedef\s+.*\Z/) {
$symtype = 5; # other typedef
if ($is_category_doxygen) {
$str =~ s/\s*\Z//;
$decl = '';
$symtype = -1; # not a symbol at all.
} else {
#print "Found doxygen but no function sig:\n$str\n\n";
foreach (@templines) {
push @contents, $_;
add_coverage_gap($_, $dent, $lineno);
$decl = <FH>;
$lineno++ if defined $decl;
$decl = '' if not defined $decl;
chomp($decl);
if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_)?DECLSPEC/) {
$symtype = 1; # function declaration
} elsif ($decl =~ /\A\s*SDL_FORCE_INLINE/) {
$symtype = 1; # (forced-inline) function declaration
} elsif ($decl =~ /\A\s*\#\s*define\s+/) {
$symtype = 2; # macro
} elsif ($decl =~ /\A\s*(typedef\s+|)(struct|union)/) {
$symtype = 3; # struct or union
} elsif ($decl =~ /\A\s*(typedef\s+|)enum/) {
$symtype = 4; # enum
} elsif ($decl =~ /\A\s*typedef\s+.*\Z/) {
$symtype = 5; # other typedef
} else {
#print "Found doxygen but no function sig:\n$str\n\n";
foreach (@templines) {
push @contents, $_;
add_coverage_gap($_, $dent, $lineno);
}
push @contents, $decl;
add_coverage_gap($decl, $dent, $lineno);
next;
}
push @contents, $decl;
add_coverage_gap($decl, $dent, $lineno);
next;
}
}
my @decllines = ( $decl );
my $sym = '';
if ($symtype == 1) { # a function
if ($symtype == -1) { # category documentation with no symbol attached.
@decllines = ();
if ($str =~ /^#\s*Category(.*?)\s*$/m) {
$sym = "[category documentation] $1"; # make a fake, unique symbol that's not valid C.
} else {
die("Unexpected category documentation line '$str' in '$incpath/$dent' ...?");
}
$headercategorydocs{$current_wiki_category} = $sym;
} elsif ($symtype == 1) { # a function
my $is_forced_inline = ($decl =~ /\A\s*SDL_FORCE_INLINE/);
if ($is_forced_inline) {
@ -1128,7 +1164,7 @@ while (my $d = readdir(DH)) {
if ($has_doxygen) {
print STDERR "WARNING: Symbol '$sym' appears to be documented in multiple locations. Only keeping the first one we saw!\n";
}
push @contents, join("\n", @decllines); # just put the existing declation in as-is.
push @contents, join("\n", @decllines) if (scalar(@decllines) > 0); # just put the existing declation in as-is.
}
}
@ -1141,7 +1177,7 @@ while (my $d = readdir(DH)) {
$headersymshasdoxygen{$sym} = $has_doxygen;
$headersymstype{$sym} = $symtype;
push @contents, join("\n", @templines);
push @contents, join("\n", @decllines);
push @contents, join("\n", @decllines) if (scalar(@decllines) > 0);
}
}
@ -1168,11 +1204,41 @@ while (my $d = readdir(DH)) {
# Ignore FrontPage.
next if $sym eq 'FrontPage';
# Ignore "Category*" pages.
next if ($sym =~ /\ACategory/);
open(FH, '<', "$wikipath/$dent") or die("Can't open '$wikipath/$dent': $!\n");
if ($sym =~ /\ACategory(.*?)\Z/) { # Special case for Category pages.
# Find the end of the category documentation in the existing file and append everything else to the new file.
my $cat = $1;
my $docstr = '';
my $notdocstr = '';
my $docs = 1;
while (<FH>) {
chomp;
if ($docs) {
$docs = 0 if /\A\-\-\-\-\Z/; # Hit a footer? We're done.
$docs = 0 if /\A<!\-\-/; # Hit an HTML comment? We're done.
}
if ($docs) {
$docstr .= "$_\n";
} else {
$notdocstr .= "$_\n";
}
}
close(FH);
$docstr =~ s/\s*\Z//;
$sym = "[category documentation] $cat"; # make a fake, unique symbol that's not valid C.
$wikitypes{$sym} = $type;
my %sections = ();
$sections{'Remarks'} = $docstr;
$sections{'[footer]'} = $notdocstr;
$wikisyms{$sym} = \%sections;
my @section_order = ( 'Remarks', '[footer]' );
$wikisectionorder{$sym} = \@section_order;
next;
}
my $current_section = '[start]';
my @section_order = ( $current_section );
my %sections = ();
@ -1325,7 +1391,9 @@ if ($copy_direction == 1) { # --copy-to-headers
my $params = undef;
my $paramstr = undef;
if (($symtype == 1) || (($symtype == 5))) { # we'll assume a typedef (5) with a \param is a function pointer typedef.
if ($symtype == -1) { # category documentation block.
# nothing to be done here.
} elsif (($symtype == 1) || (($symtype == 5))) { # we'll assume a typedef (5) with a \param is a function pointer typedef.
$params = $sectionsref->{'Function Parameters'};
$paramstr = '\param';
} elsif ($symtype == 2) {
@ -1520,7 +1588,7 @@ if ($copy_direction == 1) { # --copy-to-headers
}
$output .= " */";
#print("$sym:\n$output\n\n");
#print("$sym:\n[$output]\n\n");
$$contentsref[$chunk] = $output;
#$$contentsref[$chunk+1] = $headerdecls{$sym};
@ -1569,6 +1637,7 @@ if ($copy_direction == 1) { # --copy-to-headers
closedir(DH);
}
}
} elsif ($copy_direction == -1) { # --copy-to-wiki
if (defined $changeformat) {
@ -1579,6 +1648,7 @@ if ($copy_direction == 1) { # --copy-to-headers
foreach (keys %headersyms) {
my $sym = $_;
next if not $headersymshasdoxygen{$sym};
next if $sym =~ /\A\[category documentation\]/; # not real symbols, we handle this elsewhere.
my $symtype = $headersymstype{$sym};
my $origwikitype = defined $wikitypes{$sym} ? $wikitypes{$sym} : 'md'; # default to MarkDown for new stuff.
my $wikitype = (defined $changeformat) ? $changeformat : $origwikitype;
@ -1812,7 +1882,7 @@ if ($copy_direction == 1) { # --copy-to-headers
$sections{'Function Parameters'} = $str;
}
my $path = "$wikipath/$_.${wikitype}.tmp";
my $path = "$wikipath/$sym.${wikitype}.tmp";
open(FH, '>', $path) or die("Can't open '$path': $!\n");
my $sectionsref = $wikisyms{$sym};
@ -1848,44 +1918,46 @@ if ($copy_direction == 1) { # --copy-to-headers
}
}
my $footer = $$sectionsref{'[footer]'};
if ($symtype != -1) { # Don't do these in category documentation block
my $footer = $$sectionsref{'[footer]'};
my $symtypename;
if ($symtype == 1) {
$symtypename = 'Function';
} elsif ($symtype == 2) {
$symtypename = 'Macro';
} elsif ($symtype == 3) {
$symtypename = 'Struct';
} elsif ($symtype == 4) {
$symtypename = 'Enum';
} elsif ($symtype == 5) {
$symtypename = 'Datatype';
} else {
die("Unexpected symbol type $symtype!");
}
my $symtypename;
if ($symtype == 1) {
$symtypename = 'Function';
} elsif ($symtype == 2) {
$symtypename = 'Macro';
} elsif ($symtype == 3) {
$symtypename = 'Struct';
} elsif ($symtype == 4) {
$symtypename = 'Enum';
} elsif ($symtype == 5) {
$symtypename = 'Datatype';
} else {
die("Unexpected symbol type $symtype!");
}
my $symcategory = $headersymscategory{$sym};
if ($wikitype eq 'mediawiki') {
$footer =~ s/\[\[CategoryAPI\]\],?\s*//g;
$footer =~ s/\[\[CategoryAPI${symtypename}\]\],?\s*//g;
$footer =~ s/\[\[Category${symcategory}\]\],?\s*//g if defined $symcategory;
$footer = "[[CategoryAPI]], [[CategoryAPI$symtypename]]" . (defined $symcategory ? ", [[Category$symcategory]]" : '') . (($footer eq '') ? "\n" : ", $footer");
} elsif ($wikitype eq 'md') {
$footer =~ s/\[CategoryAPI\]\(CategoryAPI\),?\s*//g;
$footer =~ s/\[CategoryAPI${symtypename}\]\(CategoryAPI${symtypename}\),?\s*//g;
$footer =~ s/\[Category${symcategory}\]\(Category${symcategory}\),?\s*//g if defined $symcategory;
$footer = "[CategoryAPI](CategoryAPI), [CategoryAPI$symtypename](CategoryAPI$symtypename)" . (defined $symcategory ? ", [Category$symcategory](Category$symcategory)" : '') . (($footer eq '') ? '' : ', ') . $footer;
} else { die("Unexpected wikitype '$wikitype'"); }
$$sectionsref{'[footer]'} = $footer;
if (defined $wikipreamble) {
my $wikified_preamble = wikify($wikitype, $wikipreamble);
my $symcategory = $headersymscategory{$sym};
if ($wikitype eq 'mediawiki') {
print FH "====== $wikified_preamble ======\n";
$footer =~ s/\[\[CategoryAPI\]\],?\s*//g;
$footer =~ s/\[\[CategoryAPI${symtypename}\]\],?\s*//g;
$footer =~ s/\[\[Category${symcategory}\]\],?\s*//g if defined $symcategory;
$footer = "[[CategoryAPI]], [[CategoryAPI$symtypename]]" . (defined $symcategory ? ", [[Category$symcategory]]" : '') . (($footer eq '') ? "\n" : ", $footer");
} elsif ($wikitype eq 'md') {
print FH "###### $wikified_preamble\n";
$footer =~ s/\[CategoryAPI\]\(CategoryAPI\),?\s*//g;
$footer =~ s/\[CategoryAPI${symtypename}\]\(CategoryAPI${symtypename}\),?\s*//g;
$footer =~ s/\[Category${symcategory}\]\(Category${symcategory}\),?\s*//g if defined $symcategory;
$footer = "[CategoryAPI](CategoryAPI), [CategoryAPI$symtypename](CategoryAPI$symtypename)" . (defined $symcategory ? ", [Category$symcategory](Category$symcategory)" : '') . (($footer eq '') ? '' : ', ') . $footer;
} else { die("Unexpected wikitype '$wikitype'"); }
$$sectionsref{'[footer]'} = $footer;
if (defined $wikipreamble) {
my $wikified_preamble = wikify($wikitype, $wikipreamble);
if ($wikitype eq 'mediawiki') {
print FH "====== $wikified_preamble ======\n";
} elsif ($wikitype eq 'md') {
print FH "###### $wikified_preamble\n";
} else { die("Unexpected wikitype '$wikitype'"); }
}
}
my $prevsectstr = '';
@ -1925,11 +1997,13 @@ if ($copy_direction == 1) { # --copy-to-headers
}
}
if ($wikitype eq 'mediawiki') {
print FH "\n== $sectname ==\n\n";
} elsif ($wikitype eq 'md') {
print FH "\n## $sectname\n\n";
} else { die("Unexpected wikitype '$wikitype'"); }
if ($symtype != -1) { # Not for category documentation block
if ($wikitype eq 'mediawiki') {
print FH "\n== $sectname ==\n\n";
} elsif ($wikitype eq 'md') {
print FH "\n## $sectname\n\n";
} else { die("Unexpected wikitype '$wikitype'"); }
}
}
my $sectstr = defined $sections{$sect} ? $sections{$sect} : $$sectionsref{$sect};
@ -1973,6 +2047,74 @@ if ($copy_direction == 1) { # --copy-to-headers
close(FH);
}
# Write out Category pages...
foreach (keys %headercategorydocs) {
my $cat = $_;
my $sym = $headercategorydocs{$cat}; # fake symbol
my $raw = $headersyms{$sym}; # raw doxygen text with comment characters stripped from start/end and start of each line.
my $wikitype = defined($wikitypes{$sym}) ? $wikitypes{$sym} : 'md';
my $path = "$wikipath/Category$cat.$wikitype";
$raw = wordwrap(wikify($wikitype, $raw));
my $tmppath = "$path.tmp";
open(FH, '>', $tmppath) or die("Can't open '$tmppath': $!\n");
print FH "$raw\n\n";
if (! -f $path) { # Doesn't exist at all? Write out a template file.
# If writing from scratch, it's always a Markdown file.
die("Unexpected wikitype '$wikitype'!") if $wikitype ne 'md';
print FH <<__EOF__
<!-- END CATEGORY DOCUMENTATION -->
## Functions
<!-- DO NOT HAND-EDIT CATEGORY LISTS, THEY ARE AUTOGENERATED AND WILL BE OVERWRITTEN, BASED ON TAGS IN INDIVIDUAL PAGE FOOTERS. EDIT THOSE INSTEAD. -->
<!-- BEGIN CATEGORY LIST: Category$cat, CategoryAPIFunction -->
<!-- END CATEGORY LIST -->
## Datatypes
<!-- DO NOT HAND-EDIT CATEGORY LISTS, THEY ARE AUTOGENERATED AND WILL BE OVERWRITTEN, BASED ON TAGS IN INDIVIDUAL PAGE FOOTERS. EDIT THOSE INSTEAD. -->
<!-- BEGIN CATEGORY LIST: Category$cat, CategoryAPIDatatype -->
<!-- END CATEGORY LIST -->
## Structs
<!-- DO NOT HAND-EDIT CATEGORY LISTS, THEY ARE AUTOGENERATED AND WILL BE OVERWRITTEN, BASED ON TAGS IN INDIVIDUAL PAGE FOOTERS. EDIT THOSE INSTEAD. -->
<!-- BEGIN CATEGORY LIST: Category$cat, CategoryAPIStruct -->
<!-- END CATEGORY LIST -->
## Enums
<!-- DO NOT HAND-EDIT CATEGORY LISTS, THEY ARE AUTOGENERATED AND WILL BE OVERWRITTEN, BASED ON TAGS IN INDIVIDUAL PAGE FOOTERS. EDIT THOSE INSTEAD. -->
<!-- BEGIN CATEGORY LIST: Category$cat, CategoryAPIEnum -->
<!-- END CATEGORY LIST -->
## Macros
<!-- DO NOT HAND-EDIT CATEGORY LISTS, THEY ARE AUTOGENERATED AND WILL BE OVERWRITTEN, BASED ON TAGS IN INDIVIDUAL PAGE FOOTERS. EDIT THOSE INSTEAD. -->
<!-- BEGIN CATEGORY LIST: Category$cat, CategoryAPIMacro -->
<!-- END CATEGORY LIST -->
----
[CategoryAPICategory](CategoryAPICategory)
__EOF__
;
} else {
my $endstr = $wikisyms{$sym}->{'[footer]'};
if (defined($endstr)) {
print FH $endstr;
}
}
close(FH);
rename($tmppath, $path) or die("Can't rename '$tmppath' to '$path': $!\n");
}
# Write out READMEs...
if (defined $readmepath) {
if ( -d $readmepath ) {
mkdir($wikireadmepath); # just in case
@ -2053,6 +2195,7 @@ if ($copy_direction == 1) { # --copy-to-headers
foreach (keys %headersyms) {
my $sym = $_;
next if not defined $wikisyms{$sym}; # don't have a page for that function, skip it.
next if $sym =~ /\A\[category documentation\]/; # not real symbols
my $symtype = $headersymstype{$sym};
my $wikitype = $wikitypes{$sym};
my $sectionsref = $wikisyms{$sym};
@ -2399,6 +2542,7 @@ __EOF__
foreach (@headersymskeys) {
my $sym = $_;
next if not defined $wikisyms{$sym}; # don't have a page for that function, skip it.
next if $sym =~ /\A\[category documentation\]/; # not real symbols.
my $symtype = $headersymstype{$sym};
my $wikitype = $wikitypes{$sym};
my $sectionsref = $wikisyms{$sym};