From 8b4e389ad07ba2431a3ce56b736a63e034c5663b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 2 May 2024 13:00:03 -0400 Subject: [PATCH] wikiheaders: updated from SDL3, plus fixes to headers to deal with that. --- build-scripts/wikiheaders.pl | 151 ++++++++++++++++++++++++++++++++++- include/SDL_audio.h | 3 + include/SDL_joystick.h | 1 + include/SDL_rwops.h | 1 + include/SDL_stdinc.h | 3 + include/SDL_surface.h | 5 +- include/SDL_system.h | 8 +- 7 files changed, 166 insertions(+), 6 deletions(-) diff --git a/build-scripts/wikiheaders.pl b/build-scripts/wikiheaders.pl index e03a306ce..8f922622b 100755 --- a/build-scripts/wikiheaders.pl +++ b/build-scripts/wikiheaders.pl @@ -41,6 +41,7 @@ foreach (@ARGV) { $copy_direction = 1, next if $_ eq '--copy-to-header'; $copy_direction = -1, next if $_ eq '--copy-to-wiki'; $copy_direction = -2, next if $_ eq '--copy-to-manpages'; + $copy_direction = -3, next if $_ eq '--report-coverage-gaps'; if (/\A--options=(.*)\Z/) { $optionsfname = $1; next; @@ -541,6 +542,21 @@ my %wikitypes = (); # contains string of wiki page extension, like $wikitypes{" 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' +my %referenceonly = (); # $referenceonly{"Y"} -> symbol name that this symbol is bound to. This makes wiki pages that say "See X" where "X" is a typedef and "Y" is a define attached to it. These pages are generated in the wiki only and do not bridge to the headers or manpages. + +my @coverage_gap = (); # array of strings that weren't part of documentation, or blank, or basic preprocessor logic. Lets you see what this script is missing! + +sub add_coverage_gap { + if ($copy_direction == -3) { # --report-coverage-gaps + my $text = shift; + my $dent = shift; + my $lineno = shift; + return if $text =~ /\A\s*\Z/; # skip blank lines + return if $text =~ /\A\s*\#\s*(if|el|endif|include)/; # skip preprocessor floof. + push @coverage_gap, "$dent:$lineno: $text"; + } +} + sub print_undocumented_section { my $fh = shift; my $typestr = shift; @@ -595,9 +611,11 @@ while (my $d = readdir(DH)) { my @contents = (); my $ignoring_lines = 0; - + my $header_comment = -1; + my $lineno = 0; while () { chomp; + $lineno++; my $symtype = 0; # nothing, yet. my $decl; my @templines; @@ -607,6 +625,12 @@ while (my $d = readdir(DH)) { # 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 ($header_comment == -1) { + $header_comment = /\A\/\*\s*\Z/ ? 1 : 0; + } elsif (($header_comment == 1) && (/\A\*\/\s*\Z/)) { + $header_comment = 0; + } + if ($ignoring_lines && /\A\s*\#\s*endif\s*\Z/) { $ignoring_lines = 0; push @contents, $_; @@ -632,17 +656,20 @@ while (my $d = readdir(DH)) { $has_doxygen = 0; } elsif (not /\A\/\*\*\s*\Z/) { # not doxygen comment start? push @contents, $_; + add_coverage_gap($_, $dent, $lineno) if ($header_comment == 0); next; } else { # Start of a doxygen comment, parse it out. @templines = ( $_ ); while () { chomp; + $lineno++; push @templines, $_; last if /\A\s*\*\/\Z/; if (s/\A\s*\*\s*\`\`\`/```/) { # this is a hack, but a lot of other code relies on the whitespace being trimmed, but we can't trim it in code blocks... $str .= "$_\n"; while () { chomp; + $lineno++; push @templines, $_; s/\A\s*\*\s?//; if (s/\A\s*\`\`\`/```/) { @@ -659,6 +686,7 @@ while (my $d = readdir(DH)) { } $decl = ; + $lineno++ if defined $decl; $decl = '' if not defined $decl; chomp($decl); if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/) { @@ -677,8 +705,10 @@ while (my $d = readdir(DH)) { #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; } } @@ -693,6 +723,7 @@ while (my $d = readdir(DH)) { if (not $decl =~ /\)\s*(\{.*|)\s*\Z/) { while () { chomp; + $lineno++; push @decllines, $_; s/\A\s+//; s/\s+\Z//; @@ -705,6 +736,7 @@ while (my $d = readdir(DH)) { if (not $decl =~ /\)\s*;/) { while () { chomp; + $lineno++; push @decllines, $_; s/\A\s+//; s/\s+\Z//; @@ -748,6 +780,53 @@ while (my $d = readdir(DH)) { $decl .= "\n"; } } + + # !!! FIXME: code duplication with typedef processing, below. + # We assume any `#define`s directly after the function are related to it: probably bitflags for an integer typedef. + # We'll also allow some other basic preprocessor lines. + # Blank lines are allowed, anything else, even comments, are not. + my $blank_lines = 0; + my $lastpos = tell(FH); + my $lastlineno = $lineno; + my $additional_decl = ''; + my $saw_define = 0; + while () { + chomp; + + $lineno++; + + if (/\A\s*\Z/) { + $blank_lines++; + } elsif (/\A\s*\#\s*(define|if|else|elif|endif)(\s+|\Z)/) { + if (/\A\s*\#\s*define\s+([a-zA-Z0-9_]*)/) { + $referenceonly{$1} = $sym; + $saw_define = 1; + } elsif (!$saw_define) { + # if the first non-blank thing isn't a #define, assume we're done. + seek(FH, $lastpos, 0); # re-read eaten lines again next time. + $lineno = $lastlineno; + last; + } + + # update strings now that we know everything pending is to be applied to this declaration. Add pending blank lines and the new text. + if ($blank_lines > 0) { + while ($blank_lines > 0) { + $additional_decl .= "\n"; + push @decllines, ''; + $blank_lines--; + } + } + $additional_decl .= "\n$_"; + push @decllines, $_; + $lastpos = tell(FH); + } else { + seek(FH, $lastpos, 0); # re-read eaten lines again next time. + $lineno = $lastlineno; + last; + } + } + $decl .= $additional_decl; + } elsif ($symtype == 2) { # a macro if ($decl =~ /\A\s*\#\s*define\s+(.*?)(\(.*?\)|)\s+/) { $sym = $1; @@ -766,6 +845,7 @@ while (my $d = readdir(DH)) { while ($decl =~ /\\\Z/) { my $l = ; last if not $l; + $lineno++; chomp($l); push @decllines, $l; #$l =~ s/\A\s+//; @@ -823,6 +903,7 @@ while (my $d = readdir(DH)) { if (!$started || ($brackets != 0)) { $pending = ; die("EOF/error reading $incpath/$dent while parsing $sym\n") if not $pending; + $lineno++; chomp($pending); push @decllines, $pending; $decl .= "\n"; @@ -858,6 +939,50 @@ while (my $d = readdir(DH)) { } next; } + + # We assume any `#define`s directly after the typedef are related to it: probably bitflags for an integer typedef. + # We'll also allow some other basic preprocessor lines. + # Blank lines are allowed, anything else, even comments, are not. + my $blank_lines = 0; + my $lastpos = tell(FH); + my $lastlineno = $lineno; + my $additional_decl = ''; + my $saw_define = 0; + while () { + chomp; + + $lineno++; + + if (/\A\s*\Z/) { + $blank_lines++; + } elsif (/\A\s*\#\s*(define|if|else|elif|endif)(\s+|\Z)/) { + if (/\A\s*\#\s*define\s+([a-zA-Z0-9_]*)/) { + $referenceonly{$1} = $sym; + $saw_define = 1; + } elsif (!$saw_define) { + # if the first non-blank thing isn't a #define, assume we're done. + seek(FH, $lastpos, 0); # re-read eaten lines again next time. + $lineno = $lastlineno; + last; + } + # update strings now that we know everything pending is to be applied to this declaration. Add pending blank lines and the new text. + if ($blank_lines > 0) { + while ($blank_lines > 0) { + $additional_decl .= "\n"; + push @decllines, ''; + $blank_lines--; + } + } + $additional_decl .= "\n$_"; + push @decllines, $_; + $lastpos = tell(FH); + } else { + seek(FH, $lastpos, 0); # re-read eaten lines again next time. + $lineno = $lastlineno; + last; + } + } + $decl .= $additional_decl; } else { die("Unexpected symtype $symtype"); } @@ -1697,6 +1822,26 @@ if ($copy_direction == 1) { # --copy-to-headers rename($path, "$wikipath/$_.${wikitype}") or die("Can't rename '$path' to '$wikipath/$_.${wikitype}': $!\n"); } + # Write out simple redirector pages if they don't already exist. + foreach (keys %referenceonly) { + my $sym = $_; + my $refersto = $referenceonly{$sym}; + my $path = "$wikipath/$sym.md"; # we only do Markdown for these. + next if (-f $path); # don't overwrite if it already exists. Delete the file if you need a rebuild! + open(FH, '>', $path) or die("Can't open '$path': $!\n"); + + if (defined $wikipreamble) { + my $wikified_preamble = wikify('md', $wikipreamble); + print FH "###### $wikified_preamble\n"; + } + + print FH "# $sym\n\nPlease refer to [$refersto]($refersto) for details.\n\n"; + #print FH "----\n"; + #print FH "[CategoryAPI](CategoryAPI)\n\n"; + + close(FH); + } + if (defined $readmepath) { if ( -d $readmepath ) { mkdir($wikireadmepath); # just in case @@ -2012,6 +2157,10 @@ if ($copy_direction == 1) { # --copy-to-headers close(FH); rename($tmppath, $path) or die("Can't rename '$tmppath' to '$path': $!\n"); } +} elsif ($copy_direction == -3) { # --report-coverage_gaps + foreach (@coverage_gap) { + print("$_\n"); + } } # end of wikiheaders.pl ... diff --git a/include/SDL_audio.h b/include/SDL_audio.h index cd4013836..e28dcbd55 100644 --- a/include/SDL_audio.h +++ b/include/SDL_audio.h @@ -1122,6 +1122,9 @@ extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); */ extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); +/** + * Maximum volume allowed in calls to SDL_MixAudio and SDL_MixAudioFormat. + */ #define SDL_MIX_MAXVOLUME 128 /** diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index 9d6ee92e7..10be5dcbb 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -807,6 +807,7 @@ extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); */ extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); +/* Limits for joystick axes... */ #define SDL_JOYSTICK_AXIS_MAX 32767 #define SDL_JOYSTICK_AXIS_MIN -32768 diff --git a/include/SDL_rwops.h b/include/SDL_rwops.h index 9d7665a70..b481a4b3c 100644 --- a/include/SDL_rwops.h +++ b/include/SDL_rwops.h @@ -366,6 +366,7 @@ extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); */ extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); +/* Possible `whence` values for SDL_RWops seeking... */ #define RW_SEEK_SET 0 /**< Seek from the beginning of data */ #define RW_SEEK_CUR 1 /**< Seek relative to current read point */ #define RW_SEEK_END 2 /**< Seek relative to the end of data */ diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 3ebfed81b..63f01591c 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -528,6 +528,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_crc32(Uint32 crc, const void *data, size_t le extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len); +/* Some safe(r) macros for zero'ing structures... */ #define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) #define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) #define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x))) @@ -713,6 +714,8 @@ extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); + +/* Some helper macros for common cases... */ #define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) diff --git a/include/SDL_surface.h b/include/SDL_surface.h index 2815844a1..62fb8e28a 100644 --- a/include/SDL_surface.h +++ b/include/SDL_surface.h @@ -927,8 +927,6 @@ extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src, const SDL_Rect * dstrect); -#define SDL_BlitScaled SDL_UpperBlitScaled - /** * Perform a scaled surface copy to a destination surface. * @@ -943,6 +941,9 @@ extern DECLSPEC int SDLCALL SDL_UpperBlitScaled (SDL_Surface * src, const SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect); +#define SDL_BlitScaled SDL_UpperBlitScaled + + /** * Perform low-level surface scaled blitting only. * diff --git a/include/SDL_system.h b/include/SDL_system.h index 12c56fefa..e0216a7df 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -188,8 +188,6 @@ extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, /* Platform specific functions for iOS */ #ifdef __IPHONEOS__ -#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) - /** * Use this function to set the animation callback on Apple iOS. * @@ -224,7 +222,8 @@ extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, */ extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (SDLCALL *callback)(void*), void *callbackParam); -#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) +#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) + /** * Use this function to enable or disable the SDL event pump on Apple iOS. @@ -242,6 +241,9 @@ extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, */ extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); +#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) + +/* end of iOS-specific functions. */ #endif /* __IPHONEOS__ */