📄 dbipport.h
字号:
sv_pos_u2b||5.006000|sv_pvbyten_force||5.006000|sv_pvbyten||5.006000|sv_pvbyte||5.006000|sv_pvn_force_flags||5.007002|sv_pvn_force|||psv_pvn_nomg|5.007003||psv_pvn|5.006000||psv_pvutf8n_force||5.006000|sv_pvutf8n||5.006000|sv_pvutf8||5.006000|sv_pv||5.006000|sv_recode_to_utf8||5.007003|sv_reftype|||sv_release_COW|||sv_release_IVX|||sv_replace|||sv_report_used|||sv_reset|||sv_rvweaken||5.006000|sv_setiv_mg|5.006000||psv_setiv|||sv_setnv_mg|5.006000||psv_setnv|||sv_setpv_mg|5.006000||psv_setpvf_mg_nocontext|||pvnsv_setpvf_mg|5.006000|5.004000|pvsv_setpvf_nocontext|||vnsv_setpvf||5.004000|vsv_setpviv_mg||5.008001|sv_setpviv||5.008001|sv_setpvn_mg|5.006000||psv_setpvn|||sv_setpv|||sv_setref_iv|||sv_setref_nv|||sv_setref_pvn|||sv_setref_pv|||sv_setref_uv||5.007001|sv_setsv_cow|||sv_setsv_flags||5.007002|sv_setsv_mg|5.006000||psv_setsv_nomg|5.007002||psv_setsv|||sv_setuv_mg|5.006000||psv_setuv|5.006000||psv_tainted||5.004000|sv_taint||5.004000|sv_true||5.005000|sv_unglob|||sv_uni_display||5.007003|sv_unmagic|||sv_unref_flags||5.007001|sv_unref|||sv_untaint||5.004000|sv_upgrade|||sv_usepvn_mg|5.006000||psv_usepvn|||sv_utf8_decode||5.006000|sv_utf8_downgrade||5.006000|sv_utf8_encode||5.006000|sv_utf8_upgrade_flags||5.007002|sv_utf8_upgrade||5.007001|sv_uv|5.006000||psv_vcatpvf_mg|5.006000|5.004000|psv_vcatpvfn||5.004000|sv_vcatpvf|5.006000|5.004000|psv_vsetpvf_mg|5.006000|5.004000|psv_vsetpvfn||5.004000|sv_vsetpvf|5.006000|5.004000|psvtype|||swallow_bom|||swash_fetch||5.007002|swash_init||5.006000|sys_intern_clear|||sys_intern_dup|||sys_intern_init|||taint_env|||taint_proper|||tmps_grow||5.006000|toLOWER|||toUPPER|||to_byte_substr|||to_uni_fold||5.007003|to_uni_lower_lc||5.006000|to_uni_lower||5.007003|to_uni_title_lc||5.006000|to_uni_title||5.007003|to_uni_upper_lc||5.006000|to_uni_upper||5.007003|to_utf8_case||5.007003|to_utf8_fold||5.007003|to_utf8_lower||5.007003|to_utf8_substr|||to_utf8_title||5.007003|to_utf8_upper||5.007003|tokeq|||tokereport|||too_few_arguments|||too_many_arguments|||unlnk|||unpack_rec|||unpack_str||5.007003|unpackstring||5.008001|unshare_hek_or_pvn|||unshare_hek|||unsharepvn||5.004000|upg_version||5.009000|usage|||utf16_textfilter|||utf16_to_utf8_reversed||5.006001|utf16_to_utf8||5.006001|utf16rev_textfilter|||utf8_distance||5.006000|utf8_hop||5.006000|utf8_length||5.007001|utf8_mg_pos_init|||utf8_mg_pos|||utf8_to_bytes||5.006001|utf8_to_uvchr||5.007001|utf8_to_uvuni||5.007001|utf8n_to_uvchr||5.007001|utf8n_to_uvuni||5.007001|utilize|||uvchr_to_utf8_flags||5.007003|uvchr_to_utf8||5.007001|uvuni_to_utf8_flags||5.007003|uvuni_to_utf8||5.007001|validate_suid|||varname|||vcmp||5.009000|vcroak||5.006000|vdeb||5.007003|vdie|||vform||5.006000|visit|||vivify_defelem|||vivify_ref|||vload_module||5.006000|vmess||5.006000|vnewSVpvf|5.006000|5.004000|pvnormal||5.009002|vnumify||5.009000|vstringify||5.009000|vwarner||5.006000|vwarn||5.006000|wait4pid|||warn_nocontext|||vnwarner_nocontext|||vnwarner||5.006000|vwarn|||vwatch|||whichsig|||write_to_stderr|||yyerror|||yylex|||yyparse|||yywarn|||);if (exists $opt{'list-unsupported'}) { my $f; for $f (sort { lc $a cmp lc $b } keys %API) { next unless $API{$f}{todo}; print "$f ", '.'x(40-length($f)), " ", format_version($API{$f}{todo}), "\n"; } exit 0;}# Scan for possible replacement candidatesmy(%replace, %need, %hints, %depends);my $replace = 0;my $hint = '';while (<DATA>) { if ($hint) { if (m{^\s*\*\s(.*?)\s*$}) { $hints{$hint} ||= ''; # suppress warning with older perls $hints{$hint} .= "$1\n"; } else { $hint = ''; } } $hint = $1 if m{^\s*$rccs\sHint:\s+(\w+)\s*$}; $replace = $1 if m{^\s*$rccs\s+Replace:\s+(\d+)\s+$rcce\s*$}; $replace{$2} = $1 if $replace and m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+)}; $replace{$2} = $1 if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+).*$rccs\s+Replace\s+$rcce}; $replace{$1} = $2 if m{^\s*$rccs\s+Replace (\w+) with (\w+)\s+$rcce\s*$}; if (m{^\s*$rccs\s+(\w+)\s+depends\s+on\s+(\w+(\s*,\s*\w+)*)\s+$rcce\s*$}) { push @{$depends{$1}}, map { s/\s+//g; $_ } split /,/, $2; } $need{$1} = 1 if m{^#if\s+defined\(NEED_(\w+)(?:_GLOBAL)?\)};}if (exists $opt{'api-info'}) { my $f; my $count = 0; my $match = $opt{'api-info'} =~ m!^/(.*)/$! ? $1 : "^\Q$opt{'api-info'}\E\$"; for $f (sort { lc $a cmp lc $b } keys %API) { next unless $f =~ /$match/; print "\n=== $f ===\n\n"; my $info = 0; if ($API{$f}{base} || $API{$f}{todo}) { my $base = format_version($API{$f}{base} || $API{$f}{todo}); print "Supported at least starting from perl-$base.\n"; $info++; } if ($API{$f}{provided}) { my $todo = $API{$f}{todo} ? format_version($API{$f}{todo}) : "5.003"; print "Support by $ppport provided back to perl-$todo.\n"; print "Support needs to be explicitly requested by NEED_$f.\n" if exists $need{$f}; print "Depends on: ", join(', ', @{$depends{$f}}), ".\n" if exists $depends{$f}; print "$hints{$f}" if exists $hints{$f}; $info++; } unless ($info) { print "No portability information available.\n"; } $count++; } if ($count > 0) { print "\n"; } else { print "Found no API matching '$opt{'api-info'}'.\n"; } exit 0;}if (exists $opt{'list-provided'}) { my $f; for $f (sort { lc $a cmp lc $b } keys %API) { next unless $API{$f}{provided}; my @flags; push @flags, 'explicit' if exists $need{$f}; push @flags, 'depend' if exists $depends{$f}; push @flags, 'hint' if exists $hints{$f}; my $flags = @flags ? ' ['.join(', ', @flags).']' : ''; print "$f$flags\n"; } exit 0;}my @files;my @srcext = qw( xs c h cc cpp );my $srcext = join '|', @srcext;if (@ARGV) { my %seen; @files = grep { -f && !exists $seen{$_} } map { glob $_ } @ARGV;}else { eval { require File::Find; File::Find::find(sub { $File::Find::name =~ /\.($srcext)$/i and push @files, $File::Find::name; }, '.'); }; if ($@) { @files = map { glob "*.$_" } @srcext; }}if (!@ARGV || $opt{filter}) { my(@in, @out); my %xsc = map { /(.*)\.xs$/ ? ("$1.c" => 1, "$1.cc" => 1) : () } @files; for (@files) { my $out = exists $xsc{$_} || /\b\Q$ppport\E$/i || !/\.($srcext)$/i; push @{ $out ? \@out : \@in }, $_; } if (@ARGV && @out) { warning("Skipping the following files (use --nofilter to avoid this):\n| ", join "\n| ", @out); } @files = @in;}unless (@files) { die "No input files given!\n";}my(%files, %global, %revreplace);%revreplace = reverse %replace;my $filename;my $patch_opened = 0;for $filename (@files) { unless (open IN, "<$filename") { warn "Unable to read from $filename: $!\n"; next; } info("Scanning $filename ..."); my $c = do { local $/; <IN> }; close IN; my %file = (orig => $c, changes => 0); # temporarily remove C comments from the code my @ccom; $c =~ s{ ( [^"'/]+ | (?:"[^"\\]*(?:\\.[^"\\]*)*" [^"'/]*)+ | (?:'[^'\\]*(?:\\.[^'\\]*)*' [^"'/]*)+ ) | (/ (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]* )) }{ defined $2 and push @ccom, $2; defined $1 ? $1 : "$ccs$#ccom$cce"; }egsx; $file{ccom} = \@ccom; $file{code} = $c; $file{has_inc_ppport} = ($c =~ /#.*include.*\Q$ppport\E/); my $func; for $func (keys %API) { my $match = $func; $match .= "|$revreplace{$func}" if exists $revreplace{$func}; if ($c =~ /\b(?:Perl_)?($match)\b/) { $file{uses_replace}{$1}++ if exists $revreplace{$func} && $1 eq $revreplace{$func}; $file{uses_Perl}{$func}++ if $c =~ /\bPerl_$func\b/; if (exists $API{$func}{provided}) { if (!exists $API{$func}{base} || $API{$func}{base} > $opt{'compat-version'}) { $file{uses}{$func}++; my @deps = rec_depend($func); if (@deps) { $file{uses_deps}{$func} = \@deps; for (@deps) { $file{uses}{$_} = 0 unless exists $file{uses}{$_}; } } for ($func, @deps) { if (exists $need{$_}) { $file{needs}{$_} = 'static'; } } } } if (exists $API{$func}{todo} && $API{$func}{todo} > $opt{'compat-version'}) { if ($c =~ /\b$func\b/) { $file{uses_todo}{$func}++; } } } } while ($c =~ /^$HS*#$HS*define$HS+(NEED_(\w+?)(_GLOBAL)?)\b/mg) { if (exists $need{$2}) { $file{defined $3 ? 'needed_global' : 'needed_static'}{$2}++; } else { warning("Possibly wrong #define $1 in $filename"); } } for (qw(uses needs uses_todo needed_global needed_static)) { for $func (keys %{$file{$_}}) { push @{$global{$_}{$func}}, $filename; } } $files{$filename} = \%file;}# Globally resolve NEED_'smy $need;for $need (keys %{$global{needs}}) { if (@{$global{needs}{$need}} > 1) { my @targets = @{$global{needs}{$need}}; my @t = grep $files{$_}{needed_global}{$need}, @targets; @targets = @t if @t; @t = grep /\.xs$/i, @targets; @targets = @t if @t; my $target = shift @targets; $files{$target}{needs}{$need} = 'global'; for (@{$global{needs}{$need}}) { $files{$_}{needs}{$need} = 'extern' if $_ ne $target; } }}for $filename (@files) { exists $files{$filename} or next; info("=== Analyzing $filename ==="); my %file = %{$files{$filename}}; my $func; my $c = $file{code}; for $func (sort keys %{$file{uses_Perl}}) { if ($API{$func}{varargs}) { my $changes = ($c =~ s{\b(Perl_$func\s*\(\s*)(?!aTHX_?)(\)|[^\s)]*\))} { $1 . ($2 eq ')' ? 'aTHX' : 'aTHX_ ') . $2 }ge); if ($changes) { warning("Doesn't pass interpreter argument aTHX to Perl_$func"); $file{changes} += $changes; } } else { warning("Uses Perl_$func instead of $func"); $file{changes} += ($c =~ s{\bPerl_$func(\s*)\((\s*aTHX_?)?\s*} {$func$1(}g); } } for $func (sort keys %{$file{uses_replace}}) { warning("Uses $func instead of $replace{$func}"); $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g); } for $func (sort keys %{$file{uses}}) { next unless $file{uses}{$func}; # if it's only a dependency if (exists $file{uses_deps}{$func}) { diag("Uses $func, which depends on ", join(', ', @{$file{uses_deps}{$func}})); } elsif (exists $replace{$func}) { warning("Uses $func instead of $replace{$func}"); $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g); } else { diag("Uses $func"); } hint($func); } for $func (sort keys %{$file{uses_todo}}) { warning("Uses $func, which may not be portable below perl ", format_version($API{$func}{todo})); } for $func (sort keys %{$file{needed_static}}) { my $message = ''; if (not exists $file{uses}{$func}) { $message = "No need to define NEED_$func if $func is never used"; } elsif (exists $file{needs}{$func} && $file{needs}{$func} ne 'static') { $message = "No need to define NEED_$func when already needed globally"; } if ($message) { diag($message); $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_$func\b.*$LF//mg); } } for $func (sort keys %{$file{needed_global}}) { my $message = ''; if (not exists $global{uses}{$func}) { $message = "No need to define NEED_${func}_GLOBAL if $func is never used"; } elsif (exists $file{needs}{$func}) { if ($file{needs}{$func} eq 'extern') { $message = "No need to define NEED_${func}_GLOBAL when already needed globally"; } elsif ($file{needs}{$func} eq 'static') { $message = "No need to define NEED_${func}_GLOBAL when only used in this file"; } } if ($message) { diag($message); $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_${func}_GLOBAL\b.*$LF//mg); } } $file{needs_inc_ppport} = keys %{$file{uses}}; if ($file{needs_inc_ppport}) { my $pp = ''; for $func (sort keys %{$file{needs}}) { my $type = $file{needs}{$func}; next if $type eq 'extern'; my $suffix = $type eq 'global' ? '_GLOBAL' : ''; unless (exists $file{"needed_$type"}{$func}) { if ($type eq 'global') { diag("Files [@{$global{needs}{$func}}] need $func, adding global request"); } else { diag("File needs $func, adding static request"); } $pp .= "#define NEED_$func$suffix\n"; } } if ($pp && ($c =~ s/^(?=$HS*#$HS*define$HS+NEED_\w+)/$pp/m)) { $pp = ''; $file{changes}++; } unless ($file{has_inc_ppport}) { diag("Needs to include '$ppport'"); $pp .= qq(#include "$ppport"\n) } if ($pp) { $file{changes} += ($c =~ s/^($HS*#$HS*define$HS+NEED_\w+.*?)^/$1$pp/ms) || ($c =~ s/^(?=$HS*#$HS*include.*\Q$ppport\E)/$pp/m) || ($c =~ s/^($HS*#$HS*include.*XSUB.*\s*?)^/$1$pp/m) || ($c =~ s/^/$pp/); } } else { if ($file{has_inc_ppport}) { diag("No need to include '$ppport'"); $file{changes} += ($c =~ s/^$HS*?#$HS*include.*\Q$ppport\E.*?$LF//m); } } # put back in our C comments my $ix; my $cppc = 0; my @ccom = @{$file{ccom}}; for $ix (0 .. $#ccom) { if (!$opt{cplusplus} && $ccom[$ix] =~ s!^//!!) { $cppc++; $file{changes} += $c =~ s/$rccs$ix$rcce/$ccs$ccom[$ix] $cce/; } else { $c =~ s/$rccs$ix$rcce/$ccom[$ix]/; } } if ($cppc) { my $s = $cppc != 1 ? 's' : ''; warning("Uses $cppc C++ style comment$s, which is not portable"); } if ($file{changes}) { if (exists $opt{copy}) { my $newfile = "$filename$opt{copy}"; if (-e $newfile) { error("'$newfile' already exists, refusing to write copy of '$filename'"); } else { local *F; if (open F, ">$newfile") { info("Writing copy of '$filename' with changes to '$newfile'"); print F $c; close F; } else { error("Cannot open '$newfile' for writing: $!"); } } } elsif (exists $opt{patch} || $opt{changes}) { if (exists $opt{patch}) { unless ($patch_opened) { if (open PATCH, ">$opt{patch}") { $patch_opened = 1; } else { error("Cannot open '$opt{patch}' for writing: $!"); delete $opt{patch}; $opt{changes} = 1; goto fallback; } } mydiff(\*PATCH, $filename, $c); } else {fallback: info("Suggested changes:"); mydiff(\*STDOUT, $filename, $c); } } else { my $s = $file{changes} == 1 ? '' : 's'; info("$file{changes} potentially required change$s detected"); } } else { info("Looks good"); }}close PATCH if $patch_opened;exit 0;sub mydiff{ local *F = shift; my($file, $str) = @_; my $diff; if (exists $opt{diff}) { $diff = run_diff($opt{diff}, $file, $str); } if (!defined $diff and can_use('Text::Diff')) { $diff = Text::Diff::diff($file, \$str, { STYLE => 'Unified' }); $diff = <<HEADER . $diff;--- $file+++ $file.patched
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -