wikiheaders: Bridge macros to the wiki!

main
Ryan C. Gordon 2024-04-06 02:10:42 -04:00
parent c8a066019b
commit a26ec343c3
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
1 changed files with 224 additions and 158 deletions

View File

@ -523,11 +523,53 @@ my %only_wiki_sections = ( # The ones don't mean anything, I just need to check
my %headers = (); # $headers{"SDL_audio.h"} -> reference to an array of all lines of text in SDL_audio.h. my %headers = (); # $headers{"SDL_audio.h"} -> reference to an array of all lines of text in SDL_audio.h.
my %headerfuncs = (); # $headerfuncs{"SDL_OpenAudio"} -> string of header documentation for SDL_OpenAudio, with comment '*' bits stripped from the start. Newlines embedded! my %headersyms = (); # $headersyms{"SDL_OpenAudio"} -> string of header documentation for SDL_OpenAudio, with comment '*' bits stripped from the start. Newlines embedded!
my %headerdecls = (); my %headerdecls = ();
my %headerfuncslocation = (); # $headerfuncslocation{"SDL_OpenAudio"} -> name of header holding SDL_OpenAudio define ("SDL_audio.h" in this case). my %headersymslocation = (); # $headersymslocation{"SDL_OpenAudio"} -> name of header holding SDL_OpenAudio define ("SDL_audio.h" in this case).
my %headerfuncschunk = (); # $headerfuncschunk{"SDL_OpenAudio"} -> offset in array in %headers that should be replaced for this function. my %headersymschunk = (); # $headersymschunk{"SDL_OpenAudio"} -> offset in array in %headers that should be replaced for this symbol.
my %headerfuncshasdoxygen = (); # $headerfuncschunk{"SDL_OpenAudio"} -> 1 if there was no existing doxygen for this function. 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)
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'
sub print_undocumented_section {
my $fh = shift;
my $typestr = shift;
my $typeval = shift;
print $fh "## $typestr defined in the headers, but not in the wiki\n\n";
my $header_only_sym = 0;
foreach (sort keys %headersyms) {
my $sym = $_;
if ((not defined $wikisyms{$sym}) && ($headersymstype{$sym} == $typeval)) {
print $fh "- [$sym]($sym)\n";
$header_only_sym = 1;
}
}
if (!$header_only_sym) {
print $fh "(none)\n";
}
print $fh "\n";
if (0) { # !!! FIXME: this lists things that _shouldn't_ be in the headers, like MigrationGuide, etc, but also we don't know if they're functions, macros, etc at this point (can we parse that from the wiki page, though?)
print $fh "## $typestr defined in the wiki, but not in the headers\n\n";
my $wiki_only_sym = 0;
foreach (sort keys %wikisyms) {
my $sym = $_;
if ((not defined $headersyms{$sym}) && ($headersymstype{$sym} == $typeval)) {
print $fh "- [$sym]($sym)\n";
$wiki_only_sym = 1;
}
}
if (!$wiki_only_sym) {
print $fh "(none)\n";
}
print $fh "\n";
}
}
my $incpath = "$srcpath"; my $incpath = "$srcpath";
$incpath .= "/$incsubdir" if $incsubdir ne ''; $incpath .= "/$incsubdir" if $incsubdir ne '';
@ -548,11 +590,17 @@ while (my $d = readdir(DH)) {
while (<FH>) { while (<FH>) {
chomp; chomp;
my $symtype = 0; # nothing, yet.
my $decl; my $decl;
my @templines; my @templines;
my $str; my $str;
my $has_doxygen = 1; my $has_doxygen = 1;
# Since a lot of macros are just preprocessor logic spam and not all macros are worth documenting anyhow, we only pay attention to them when they have a Doxygen comment attached.
# Functions and other things are a different story, though!
if (/\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/) { # a function declaration without a doxygen comment? if (/\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/) { # a function declaration without a doxygen comment?
$symtype = 1; # function declaration
@templines = (); @templines = ();
$decl = $_; $decl = $_;
$str = ''; $str = '';
@ -588,7 +636,11 @@ while (my $d = readdir(DH)) {
$decl = <FH>; $decl = <FH>;
$decl = '' if not defined $decl; $decl = '' if not defined $decl;
chomp($decl); chomp($decl);
if (not $decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/) { if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/) {
$symtype = 1; # function declaration
} elsif ($decl =~ /\A\s*\#\s*define\s+/) {
$symtype = 2; # macro
} else {
#print "Found doxygen but no function sig:\n$str\n\n"; #print "Found doxygen but no function sig:\n$str\n\n";
foreach (@templines) { foreach (@templines) {
push @contents, $_; push @contents, $_;
@ -599,76 +651,106 @@ while (my $d = readdir(DH)) {
} }
my @decllines = ( $decl ); my @decllines = ( $decl );
my $sym = '';
if (not $decl =~ /\)\s*;/) { if ($symtype == 1) { # a function
while (<FH>) { if (not $decl =~ /\)\s*;/) {
chomp; while (<FH>) {
push @decllines, $_; chomp;
s/\A\s+//; push @decllines, $_;
s/\s+\Z//; s/\A\s+//;
$decl .= " $_"; s/\s+\Z//;
last if /\)\s*;/; $decl .= " $_";
last if /\)\s*;/;
}
} }
$decl =~ s/\s+\);\Z/);/;
$decl =~ s/\s+\Z//;
if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(const\s+|)(unsigned\s+|)(.*?)\s*(\*?)\s*SDLCALL\s+(.*?)\s*\((.*?)\);/) {
$sym = $6;
#$decl =~ s/\A\s*extern\s+DECLSPEC\s+(.*?)\s+SDLCALL/$1/;
} else {
#print "Found doxygen but no function sig:\n$str\n\n";
foreach (@templines) {
push @contents, $_;
}
foreach (@decllines) {
push @contents, $_;
}
next;
}
$decl = ''; # build this with the line breaks, since it looks better for syntax highlighting.
foreach (@decllines) {
if ($decl eq '') {
$decl = $_;
$decl =~ s/\Aextern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(.*?)\s+(\*?)SDLCALL\s+/$2$3 /;
} else {
my $trimmed = $_;
# !!! FIXME: trim space for SDL_DEPRECATED if it was used, too.
$trimmed =~ s/\A\s{24}//; # 24 for shrinking to match the removed "extern DECLSPEC SDLCALL "
$decl .= $trimmed;
}
$decl .= "\n";
}
} elsif ($symtype == 2) { # a macro
if ($decl =~ /\A\s*\#\s*define\s+(.*?)(\(.*?\)|)\s+/) {
$sym = $1;
#$decl =~ s/\A\s*extern\s+DECLSPEC\s+(.*?)\s+SDLCALL/$1/;
} else {
#print "Found doxygen but no macro:\n$str\n\n";
foreach (@templines) {
push @contents, $_;
}
foreach (@decllines) {
push @contents, $_;
}
next;
}
while ($decl =~ /\\\Z/) {
my $l = <FH>;
last if not $l;
chomp($l);
push @decllines, $l;
#$l =~ s/\A\s+//;
$l =~ s/\s+\Z//;
$decl .= "\n$l";
}
} else {
die("Unexpected symtype $symtype\n");
} }
$decl =~ s/\s+\);\Z/);/;
$decl =~ s/\s+\Z//;
#print("DECL: [$decl]\n"); #print("DECL: [$decl]\n");
my $fn = ''; #print("$sym:\n$str\n\n");
if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(const\s+|)(unsigned\s+|)(.*?)\s*(\*?)\s*SDLCALL\s+(.*?)\s*\((.*?)\);/) {
$fn = $6;
#$decl =~ s/\A\s*extern\s+DECLSPEC\s+(.*?)\s+SDLCALL/$1/;
} else {
#print "Found doxygen but no function sig:\n$str\n\n";
foreach (@templines) {
push @contents, $_;
}
foreach (@decllines) {
push @contents, $_;
}
next;
}
$decl = ''; # build this with the line breaks, since it looks better for syntax highlighting.
foreach (@decllines) {
if ($decl eq '') {
$decl = $_;
$decl =~ s/\Aextern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(.*?)\s+(\*?)SDLCALL\s+/$2$3 /;
} else {
my $trimmed = $_;
# !!! FIXME: trim space for SDL_DEPRECATED if it was used, too.
$trimmed =~ s/\A\s{24}//; # 24 for shrinking to match the removed "extern DECLSPEC SDLCALL "
$decl .= $trimmed;
}
$decl .= "\n";
}
#print("$fn:\n$str\n\n");
# There might be multiple declarations of a function due to #ifdefs, # There might be multiple declarations of a function due to #ifdefs,
# and only one of them will have documentation. If we hit an # and only one of them will have documentation. If we hit an
# undocumented one before, delete the placeholder line we left for # undocumented one before, delete the placeholder line we left for
# it so it doesn't accumulate a new blank line on each run. # it so it doesn't accumulate a new blank line on each run.
my $skipfn = 0; my $skipsym = 0;
if (defined $headerfuncshasdoxygen{$fn}) { if (defined $headersymshasdoxygen{$sym}) {
if ($headerfuncshasdoxygen{$fn} == 0) { # An undocumented declaration already exists, nuke its placeholder line. if ($headersymshasdoxygen{$sym} == 0) { # An undocumented declaration already exists, nuke its placeholder line.
delete $contents[$headerfuncschunk{$fn}]; # delete DOES NOT RENUMBER existing elements! delete $contents[$headersymschunk{$sym}]; # delete DOES NOT RENUMBER existing elements!
} else { # documented function already existed? } else { # documented function already existed?
$skipfn = 1; # don't add this copy to the list of functions. $skipsym = 1; # don't add this copy to the list of functions.
if ($has_doxygen) { if ($has_doxygen) {
print STDERR "WARNING: Function '$fn' appears to be documented in multiple locations. Only keeping the first one we saw!\n"; 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); # just put the existing declation in as-is.
} }
} }
if (!$skipfn) { if (!$skipsym) {
$headerfuncs{$fn} = $str; $headersyms{$sym} = $str;
$headerdecls{$fn} = $decl; $headerdecls{$sym} = $decl;
$headerfuncslocation{$fn} = $dent; $headersymslocation{$sym} = $dent;
$headerfuncschunk{$fn} = scalar(@contents); $headersymschunk{$sym} = scalar(@contents);
$headerfuncshasdoxygen{$fn} = $has_doxygen; $headersymshasdoxygen{$sym} = $has_doxygen;
$headersymstype{$sym} = $symtype;
push @contents, join("\n", @templines); push @contents, join("\n", @templines);
push @contents, join("\n", @decllines); push @contents, join("\n", @decllines);
} }
@ -684,9 +766,6 @@ closedir(DH);
# !!! FIXME: we need to parse enums and typedefs and structs and defines and and and and and... # !!! FIXME: we need to parse enums and typedefs and structs and defines and and and and and...
# !!! FIXME: (but functions are good enough for now.) # !!! FIXME: (but functions are good enough for now.)
my %wikitypes = (); # contains string of wiki page extension, like $wikitypes{"SDL_OpenAudio"} == 'mediawiki'
my %wikifuncs = (); # contains references to hash of strings, each string being the full contents of a section of a wiki page, like $wikifuncs{"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'
opendir(DH, $wikipath) or die("Can't opendir '$wikipath': $!\n"); opendir(DH, $wikipath) or die("Can't opendir '$wikipath': $!\n");
while (my $d = readdir(DH)) { while (my $d = readdir(DH)) {
my $dent = $d; my $dent = $d;
@ -697,14 +776,14 @@ while (my $d = readdir(DH)) {
next; # only dealing with wiki pages. next; # only dealing with wiki pages.
} }
my $fn = $dent; my $sym = $dent;
$fn =~ s/\..*\Z//; $sym =~ s/\..*\Z//;
# Ignore FrontPage. # Ignore FrontPage.
next if $fn eq 'FrontPage'; next if $sym eq 'FrontPage';
# Ignore "Category*" pages. # Ignore "Category*" pages.
next if ($fn =~ /\ACategory/); next if ($sym =~ /\ACategory/);
open(FH, '<', "$wikipath/$dent") or die("Can't open '$wikipath/$dent': $!\n"); open(FH, '<', "$wikipath/$dent") or die("Can't open '$wikipath/$dent': $!\n");
@ -727,13 +806,13 @@ while (my $d = readdir(DH)) {
next; next;
} elsif (/\A\= (.*?) \=\Z/) { } elsif (/\A\= (.*?) \=\Z/) {
$firstline = 0; $firstline = 0;
$current_section = ($1 eq $fn) ? '[Brief]' : $1; $current_section = ($1 eq $sym) ? '[Brief]' : $1;
die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section};
push @section_order, $current_section; push @section_order, $current_section;
$sections{$current_section} = ''; $sections{$current_section} = '';
} elsif (/\A\=\= (.*?) \=\=\Z/) { } elsif (/\A\=\= (.*?) \=\=\Z/) {
$firstline = 0; $firstline = 0;
$current_section = ($1 eq $fn) ? '[Brief]' : $1; $current_section = ($1 eq $sym) ? '[Brief]' : $1;
die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section};
push @section_order, $current_section; push @section_order, $current_section;
$sections{$current_section} = ''; $sections{$current_section} = '';
@ -752,7 +831,7 @@ while (my $d = readdir(DH)) {
next; next;
} elsif (/\A\#+ (.*?)\Z/) { } elsif (/\A\#+ (.*?)\Z/) {
$firstline = 0; $firstline = 0;
$current_section = ($1 eq $fn) ? '[Brief]' : $1; $current_section = ($1 eq $sym) ? '[Brief]' : $1;
die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section};
push @section_order, $current_section; push @section_order, $current_section;
$sections{$current_section} = ''; $sections{$current_section} = '';
@ -786,70 +865,43 @@ while (my $d = readdir(DH)) {
if (0) { if (0) {
foreach (@section_order) { foreach (@section_order) {
print("$fn SECTION '$_':\n"); print("$sym SECTION '$_':\n");
print($sections{$_}); print($sections{$_});
print("\n\n"); print("\n\n");
} }
} }
$wikitypes{$fn} = $type; $wikitypes{$sym} = $type;
$wikifuncs{$fn} = \%sections; $wikisyms{$sym} = \%sections;
$wikisectionorder{$fn} = \@section_order; $wikisectionorder{$sym} = \@section_order;
} }
closedir(DH); closedir(DH);
delete $wikifuncs{"Undocumented"}; delete $wikisyms{"Undocumented"};
{ {
my $path = "$wikipath/Undocumented.md"; my $path = "$wikipath/Undocumented.md";
open(FH, '>', $path) or die("Can't open '$path': $!\n"); open(my $fh, '>', $path) or die("Can't open '$path': $!\n");
print FH "# Undocumented\n\n"; print $fh "# Undocumented\n\n";
print_undocumented_section($fh, 'Functions', 1);
print_undocumented_section($fh, 'Macros', 2);
print FH "## Functions defined in the headers, but not in the wiki\n\n"; close($fh);
my $header_only_func = 0;
foreach (sort keys %headerfuncs) {
my $fn = $_;
if (not defined $wikifuncs{$fn}) {
print FH "- [$fn]($fn)\n";
$header_only_func = 1;
}
}
if (!$header_only_func) {
print FH "(none)\n";
}
print FH "\n";
print FH "## Functions defined in the wiki, but not in the headers\n\n";
my $wiki_only_func = 0;
foreach (sort keys %wikifuncs) {
my $fn = $_;
if (not defined $headerfuncs{$fn}) {
print FH "- [$fn]($fn)\n";
$wiki_only_func = 1;
}
}
if (!$wiki_only_func) {
print FH "(none)\n";
}
print FH "\n";
close(FH);
} }
if ($warn_about_missing) { if ($warn_about_missing) {
foreach (keys %wikifuncs) { foreach (keys %wikisyms) {
my $fn = $_; my $sym = $_;
if (not defined $headerfuncs{$fn}) { if (not defined $headersyms{$sym}) {
print("WARNING: $fn defined in the wiki but not the headers!\n"); print("WARNING: $sym defined in the wiki but not the headers!\n");
} }
} }
foreach (keys %headerfuncs) { foreach (keys %headersyms) {
my $fn = $_; my $sym = $_;
if (not defined $wikifuncs{$fn}) { if (not defined $wikisyms{$sym}) {
print("WARNING: $fn defined in the headers but not the wiki!\n"); print("WARNING: $sym defined in the headers but not the wiki!\n");
} }
} }
} }
@ -860,11 +912,11 @@ if ($copy_direction == 1) { # --copy-to-headers
$dewikify_mode = 'md'; $dewikify_mode = 'md';
$wordwrap_mode = 'md'; # the headers use Markdown format. $wordwrap_mode = 'md'; # the headers use Markdown format.
foreach (keys %headerfuncs) { foreach (keys %headersyms) {
my $fn = $_; my $sym = $_;
next if not defined $wikifuncs{$fn}; # don't have a page for that function, skip it. next if not defined $wikisyms{$sym}; # don't have a page for that function, skip it.
my $wikitype = $wikitypes{$fn}; my $wikitype = $wikitypes{$sym};
my $sectionsref = $wikifuncs{$fn}; my $sectionsref = $wikisyms{$sym};
my $remarks = $sectionsref->{'Remarks'}; my $remarks = $sectionsref->{'Remarks'};
my $params = $sectionsref->{'Function Parameters'}; my $params = $sectionsref->{'Function Parameters'};
my $returns = $sectionsref->{'Return Value'}; my $returns = $sectionsref->{'Return Value'};
@ -876,7 +928,7 @@ if ($copy_direction == 1) { # --copy-to-headers
my $addblank = 0; my $addblank = 0;
my $str = ''; my $str = '';
$headerfuncshasdoxygen{$fn} = 1; # Added/changed doxygen for this header. $headersymshasdoxygen{$sym} = 1; # Added/changed doxygen for this header.
$brief = dewikify($wikitype, $brief); $brief = dewikify($wikitype, $brief);
$brief =~ s/\A(.*?\.) /$1\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. $brief =~ s/\A(.*?\.) /$1\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary.
@ -926,7 +978,7 @@ if ($copy_direction == 1) { # --copy-to-headers
$name =~ s/\A\*\*(.*?)\*\*/$1/; $name =~ s/\A\*\*(.*?)\*\*/$1/;
$name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/;
$desc =~ s/\A\|\s*//; $desc =~ s/\A\|\s*//;
#print STDERR "FN: $fn NAME: $name DESC: $desc TERM: $terminator\n"; #print STDERR "SYM: $sym NAME: $name DESC: $desc TERM: $terminator\n";
my $whitespacelen = length($name) + 8; my $whitespacelen = length($name) + 8;
my $whitespace = ' ' x $whitespacelen; my $whitespace = ' ' x $whitespacelen;
$desc = wordwrap($desc, -$whitespacelen); $desc = wordwrap($desc, -$whitespacelen);
@ -950,7 +1002,7 @@ if ($copy_direction == 1) { # --copy-to-headers
my $desc = $2; my $desc = $2;
$name =~ s/\A\*\*(.*?)\*\*/$1/; $name =~ s/\A\*\*(.*?)\*\*/$1/;
$name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/;
#print STDERR "FN: $fn NAME: $name DESC: $desc\n"; #print STDERR "SYM: $sym NAME: $name DESC: $desc\n";
my $whitespacelen = length($name) + 8; my $whitespacelen = length($name) + 8;
my $whitespace = ' ' x $whitespacelen; my $whitespace = ' ' x $whitespacelen;
$desc = wordwrap($desc, -$whitespacelen); $desc = wordwrap($desc, -$whitespacelen);
@ -1033,9 +1085,9 @@ if ($copy_direction == 1) { # --copy-to-headers
} }
} }
my $header = $headerfuncslocation{$fn}; my $header = $headersymslocation{$sym};
my $contentsref = $headers{$header}; my $contentsref = $headers{$header};
my $chunk = $headerfuncschunk{$fn}; my $chunk = $headersymschunk{$sym};
my @lines = split /\n/, $str; my @lines = split /\n/, $str;
@ -1053,10 +1105,10 @@ if ($copy_direction == 1) { # --copy-to-headers
} }
$output .= " */"; $output .= " */";
#print("$fn:\n$output\n\n"); #print("$sym:\n$output\n\n");
$$contentsref[$chunk] = $output; $$contentsref[$chunk] = $output;
#$$contentsref[$chunk+1] = $headerdecls{$fn}; #$$contentsref[$chunk+1] = $headerdecls{$sym};
$changed_headers{$header} = 1; $changed_headers{$header} = 1;
} }
@ -1066,12 +1118,12 @@ if ($copy_direction == 1) { # --copy-to-headers
# this is kinda inefficient, but oh well. # this is kinda inefficient, but oh well.
my @removelines = (); my @removelines = ();
foreach (keys %headerfuncslocation) { foreach (keys %headersymslocation) {
my $fn = $_; my $sym = $_;
next if $headerfuncshasdoxygen{$fn}; next if $headersymshasdoxygen{$sym};
next if $headerfuncslocation{$fn} ne $header; next if $headersymslocation{$sym} ne $header;
# the index of the blank line we put before the function declaration in case we needed to replace it with new content from the wiki. # the index of the blank line we put before the function declaration in case we needed to replace it with new content from the wiki.
push @removelines, $headerfuncschunk{$fn}; push @removelines, $headersymschunk{$sym};
} }
my $contentsref = $headers{$header}; my $contentsref = $headers{$header};
@ -1109,18 +1161,19 @@ if ($copy_direction == 1) { # --copy-to-headers
$wordwrap_mode = $changeformat; $wordwrap_mode = $changeformat;
} }
foreach (keys %headerfuncs) { foreach (keys %headersyms) {
my $fn = $_; my $sym = $_;
next if not $headerfuncshasdoxygen{$fn}; next if not $headersymshasdoxygen{$sym};
my $origwikitype = defined $wikitypes{$fn} ? $wikitypes{$fn} : 'md'; # default to MarkDown for new stuff. my $symtype = $headersymstype{$sym};
my $origwikitype = defined $wikitypes{$sym} ? $wikitypes{$sym} : 'md'; # default to MarkDown for new stuff.
my $wikitype = (defined $changeformat) ? $changeformat : $origwikitype; my $wikitype = (defined $changeformat) ? $changeformat : $origwikitype;
die("Unexpected wikitype '$wikitype'\n") if (($wikitype ne 'mediawiki') and ($wikitype ne 'md') and ($wikitype ne 'manpage')); die("Unexpected wikitype '$wikitype'\n") if (($wikitype ne 'mediawiki') and ($wikitype ne 'md') and ($wikitype ne 'manpage'));
#print("$fn\n"); next; #print("$sym\n"); next;
$wordwrap_mode = $wikitype; $wordwrap_mode = $wikitype;
my $raw = $headerfuncs{$fn}; # raw doxygen text with comment characters stripped from start/end and start of each line. my $raw = $headersyms{$sym}; # raw doxygen text with comment characters stripped from start/end and start of each line.
next if not defined $raw; next if not defined $raw;
$raw =~ s/\A\s*\\brief\s+//; # Technically we don't need \brief (please turn on JAVADOC_AUTOBRIEF if you use Doxygen), so just in case one is present, strip it. $raw =~ s/\A\s*\\brief\s+//; # Technically we don't need \brief (please turn on JAVADOC_AUTOBRIEF if you use Doxygen), so just in case one is present, strip it.
@ -1138,6 +1191,9 @@ if ($copy_direction == 1) { # --copy-to-headers
$brief =~ s/\A(.*?\.) /$1\n\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. $brief =~ s/\A(.*?\.) /$1\n\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary.
my @briefsplit = split /\n/, $brief; my @briefsplit = split /\n/, $brief;
next if not defined $briefsplit[0]; # No brief text? Probably a bogus Doxygen comment, skip it.
$brief = wikify($wikitype, shift @briefsplit) . "\n"; $brief = wikify($wikitype, shift @briefsplit) . "\n";
@doxygenlines = (@briefsplit, @doxygenlines); @doxygenlines = (@briefsplit, @doxygenlines);
@ -1165,7 +1221,7 @@ if ($copy_direction == 1) { # --copy-to-headers
$remarks =~ s/\A\s*//; $remarks =~ s/\A\s*//;
$remarks =~ s/\s*\Z//; $remarks =~ s/\s*\Z//;
my $decl = $headerdecls{$fn}; my $decl = $headerdecls{$sym};
#$decl =~ s/\*\s+SDLCALL/ *SDLCALL/; # Try to make "void * Function" become "void *Function" #$decl =~ s/\*\s+SDLCALL/ *SDLCALL/; # Try to make "void * Function" become "void *Function"
#$decl =~ s/\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(.*?)\s+(\*?)SDLCALL/$2$3/; #$decl =~ s/\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(.*?)\s+(\*?)SDLCALL/$2$3/;
@ -1279,7 +1335,7 @@ if ($copy_direction == 1) { # --copy-to-headers
} }
my $hfiletext = $wikiheaderfiletext; my $hfiletext = $wikiheaderfiletext;
$hfiletext =~ s/\%fname\%/$headerfuncslocation{$fn}/g; $hfiletext =~ s/\%fname\%/$headersymslocation{$sym}/g;
$sections{'Header File'} = "$hfiletext\n"; $sections{'Header File'} = "$hfiletext\n";
# Make sure this ends with a double-newline. # Make sure this ends with a double-newline.
@ -1331,7 +1387,7 @@ if ($copy_direction == 1) { # --copy-to-headers
my $path = "$wikipath/$_.${wikitype}.tmp"; my $path = "$wikipath/$_.${wikitype}.tmp";
open(FH, '>', $path) or die("Can't open '$path': $!\n"); open(FH, '>', $path) or die("Can't open '$path': $!\n");
my $sectionsref = $wikifuncs{$fn}; my $sectionsref = $wikisyms{$sym};
foreach (@standard_wiki_sections) { foreach (@standard_wiki_sections) {
# drop sections we either replaced or removed from the original wiki's contents. # drop sections we either replaced or removed from the original wiki's contents.
@ -1340,7 +1396,7 @@ if ($copy_direction == 1) { # --copy-to-headers
} }
} }
my $wikisectionorderref = $wikisectionorder{$fn}; my $wikisectionorderref = $wikisectionorder{$sym};
# Make sure there's a footer in the wiki that puts this function in CategoryAPI... # Make sure there's a footer in the wiki that puts this function in CategoryAPI...
if (not $$sectionsref{'[footer]'}) { if (not $$sectionsref{'[footer]'}) {
@ -1364,15 +1420,25 @@ if ($copy_direction == 1) { # --copy-to-headers
} }
} }
# !!! FIXME: This won't be CategoryAPI if we eventually handle things other than functions.
my $footer = $$sectionsref{'[footer]'}; my $footer = $$sectionsref{'[footer]'};
my $symtypename;
if ($symtype == 1) {
$symtypename = 'Function';
} elsif ($symtype == 2) {
$symtypename = 'Macro';
} else {
die("Unexpected symbol type $symtype!\n");
}
if ($wikitype eq 'mediawiki') { if ($wikitype eq 'mediawiki') {
$footer =~ s/\[\[CategoryAPI\]\],?\s*//g; $footer =~ s/\[\[CategoryAPI\]\],?\s*//g;
$footer = '[[CategoryAPI]]' . (($footer eq '') ? "\n" : ", $footer"); $footer =~ s/\[\[CategoryAPI${symtypename}\]\],?\s*//g;
$footer = "[[CategoryAPI]], [[CategoryAPI$symtypename]]" . (($footer eq '') ? "\n" : ", $footer");
} elsif ($wikitype eq 'md') { } elsif ($wikitype eq 'md') {
$footer =~ s/\[CategoryAPI\]\(CategoryAPI\),?\s*//g; $footer =~ s/\[CategoryAPI\]\(CategoryAPI\),?\s*//g;
$footer = '[CategoryAPI](CategoryAPI)' . (($footer eq '') ? '' : ', ') . $footer; $footer =~ s/\[CategoryAPI${symtypename}\]\(CategoryAPI${symtypename}\),?\s*//g;
$footer = "[CategoryAPI](CategoryAPI), [CategoryAPI$symtypename](CategoryAPI$symtypename)" . (($footer eq '') ? '' : ', ') . $footer;
} else { die("Unexpected wikitype '$wikitype'\n"); } } else { die("Unexpected wikitype '$wikitype'\n"); }
$$sectionsref{'[footer]'} = $footer; $$sectionsref{'[footer]'} = $footer;
@ -1402,9 +1468,9 @@ if ($copy_direction == 1) { # --copy-to-headers
print FH "----\n"; # It's the same in Markdown and MediaWiki. print FH "----\n"; # It's the same in Markdown and MediaWiki.
} elsif ($sect eq '[Brief]') { } elsif ($sect eq '[Brief]') {
if ($wikitype eq 'mediawiki') { if ($wikitype eq 'mediawiki') {
print FH "= $fn =\n\n"; print FH "= $sym =\n\n";
} elsif ($wikitype eq 'md') { } elsif ($wikitype eq 'md') {
print FH "# $fn\n\n"; print FH "# $sym\n\n";
} else { die("Unexpected wikitype '$wikitype'\n"); } } else { die("Unexpected wikitype '$wikitype'\n"); }
} else { } else {
if ($wikitype eq 'mediawiki') { if ($wikitype eq 'mediawiki') {
@ -1513,11 +1579,11 @@ if ($copy_direction == 1) { # --copy-to-headers
close(FH); close(FH);
my $fullversion = "$majorver.$minorver.$patchver"; my $fullversion = "$majorver.$minorver.$patchver";
foreach (keys %headerfuncs) { foreach (keys %headersyms) {
my $fn = $_; my $sym = $_;
next if not defined $wikifuncs{$fn}; # don't have a page for that function, skip it. next if not defined $wikisyms{$sym}; # don't have a page for that function, skip it.
my $wikitype = $wikitypes{$fn}; my $wikitype = $wikitypes{$sym};
my $sectionsref = $wikifuncs{$fn}; my $sectionsref = $wikisyms{$sym};
my $remarks = $sectionsref->{'Remarks'}; my $remarks = $sectionsref->{'Remarks'};
my $params = $sectionsref->{'Function Parameters'}; my $params = $sectionsref->{'Function Parameters'};
my $returns = $sectionsref->{'Return Value'}; my $returns = $sectionsref->{'Return Value'};
@ -1527,11 +1593,11 @@ if ($copy_direction == 1) { # --copy-to-headers
my $examples = $sectionsref->{'Code Examples'}; my $examples = $sectionsref->{'Code Examples'};
my $deprecated = $sectionsref->{'Deprecated'}; my $deprecated = $sectionsref->{'Deprecated'};
my $headerfile = $manpageheaderfiletext; my $headerfile = $manpageheaderfiletext;
$headerfile =~ s/\%fname\%/$headerfuncslocation{$fn}/g; $headerfile =~ s/\%fname\%/$headersymslocation{$sym}/g;
$headerfile .= "\n"; $headerfile .= "\n";
my $brief = $sectionsref->{'[Brief]'}; my $brief = $sectionsref->{'[Brief]'};
my $decl = $headerdecls{$fn}; my $decl = $headerdecls{$sym};
my $str = ''; my $str = '';
$brief = "$brief"; $brief = "$brief";
@ -1551,14 +1617,14 @@ if ($copy_direction == 1) { # --copy-to-headers
$str .= ".\\\" This manpage content is licensed under Creative Commons\n"; $str .= ".\\\" This manpage content is licensed under Creative Commons\n";
$str .= ".\\\" Attribution 4.0 International (CC BY 4.0)\n"; $str .= ".\\\" Attribution 4.0 International (CC BY 4.0)\n";
$str .= ".\\\" https://creativecommons.org/licenses/by/4.0/\n"; $str .= ".\\\" https://creativecommons.org/licenses/by/4.0/\n";
$str .= ".\\\" This manpage was generated from ${projectshortname}'s wiki page for $fn:\n"; $str .= ".\\\" This manpage was generated from ${projectshortname}'s wiki page for $sym:\n";
$str .= ".\\\" $wikiurl/$fn\n"; $str .= ".\\\" $wikiurl/$sym\n";
$str .= ".\\\" Generated with SDL/build-scripts/wikiheaders.pl\n"; $str .= ".\\\" Generated with SDL/build-scripts/wikiheaders.pl\n";
$str .= ".\\\" revision $gitrev\n" if $gitrev ne ''; $str .= ".\\\" revision $gitrev\n" if $gitrev ne '';
$str .= ".\\\" Please report issues in this manpage's content at:\n"; $str .= ".\\\" Please report issues in this manpage's content at:\n";
$str .= ".\\\" $bugreporturl\n"; $str .= ".\\\" $bugreporturl\n";
$str .= ".\\\" Please report issues in the generation of this manpage from the wiki at:\n"; $str .= ".\\\" Please report issues in the generation of this manpage from the wiki at:\n";
$str .= ".\\\" https://github.com/libsdl-org/SDL/issues/new?title=Misgenerated%20manpage%20for%20$fn\n"; $str .= ".\\\" https://github.com/libsdl-org/SDL/issues/new?title=Misgenerated%20manpage%20for%20$sym\n";
$str .= ".\\\" $projectshortname can be found at $projecturl\n"; $str .= ".\\\" $projectshortname can be found at $projecturl\n";
# Define a .URL macro. The "www.tmac" thing decides if we're using GNU roff (which has a .URL macro already), and if so, overrides the macro we just created. # Define a .URL macro. The "www.tmac" thing decides if we're using GNU roff (which has a .URL macro already), and if so, overrides the macro we just created.
@ -1568,10 +1634,10 @@ if ($copy_direction == 1) { # --copy-to-headers
$str .= "..\n"; $str .= "..\n";
$str .= '.if \n[.g] .mso www.tmac' . "\n"; $str .= '.if \n[.g] .mso www.tmac' . "\n";
$str .= ".TH $fn 3 \"$projectshortname $fullversion\" \"$projectfullname\" \"$projectshortname$majorver FUNCTIONS\"\n"; $str .= ".TH $sym 3 \"$projectshortname $fullversion\" \"$projectfullname\" \"$projectshortname$majorver FUNCTIONS\"\n";
$str .= ".SH NAME\n"; $str .= ".SH NAME\n";
$str .= "$fn"; $str .= "$sym";
$str .= " \\- $brief" if (defined $brief); $str .= " \\- $brief" if (defined $brief);
$str .= "\n"; $str .= "\n";
@ -1616,7 +1682,7 @@ if ($copy_direction == 1) { # --copy-to-headers
$name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/;
$desc =~ s/\A\|\s*//; $desc =~ s/\A\|\s*//;
$desc = dewikify($wikitype, $desc); $desc = dewikify($wikitype, $desc);
#print STDERR "FN: $fn NAME: $name DESC: $desc TERM: $terminator\n"; #print STDERR "FN: $sym NAME: $name DESC: $desc TERM: $terminator\n";
$str .= ".TP\n"; $str .= ".TP\n";
$str .= ".I $name\n"; $str .= ".I $name\n";
@ -1703,7 +1769,7 @@ if ($copy_direction == 1) { # --copy-to-headers
$str .= ".UE\n"; $str .= ".UE\n";
$str .= ".PP\n"; $str .= ".PP\n";
$str .= "This manpage was generated from\n"; $str .= "This manpage was generated from\n";
$str .= ".UR $wikiurl/$fn\n"; $str .= ".UR $wikiurl/$sym\n";
$str .= "${projectshortname}'s wiki\n"; $str .= "${projectshortname}'s wiki\n";
$str .= ".UE\n"; $str .= ".UE\n";
$str .= "using SDL/build-scripts/wikiheaders.pl"; $str .= "using SDL/build-scripts/wikiheaders.pl";