#!/usr/bin/env patchperl # This chunk of stuff was generated by App::FatPacker. To find the original # file's code, look for the end of this BEGIN block or the string 'FATPACK' BEGIN { my %fatpacked; $fatpacked{"Devel/PatchPerl.pm"} = <<'DEVEL_PATCHPERL'; package Devel::PatchPerl; BEGIN { $Devel::PatchPerl::VERSION = '0.32'; } # ABSTRACT: Patch perl source a la Devel::PPort's buildperl.pl use strict; use warnings; use File::pushd qw[pushd]; use File::Spec; use IO::File; use IPC::Cmd qw[can_run run]; use Devel::PatchPerl::Hints qw[hint_file]; use vars qw[@ISA @EXPORT_OK]; @ISA = qw(Exporter); @EXPORT_OK = qw(patch_source); my $patch_exe = can_run('patch'); my @patch = ( { perl => [ qr/^5\.00[01234]/, qw/ 5.005 5.005_01 5.005_02 5.005_03 /, ], subs => [ [ \&_patch_db, 1 ], ], }, { perl => [ qw/ 5.6.0 5.6.1 5.7.0 5.7.1 5.7.2 5.7.3 5.8.0 /, ], subs => [ [ \&_patch_db, 3 ], ], }, { perl => [ qr/^5\.004_0[1234]$/, ], subs => [ [ \&_patch_doio ], ], }, { perl => [ qw/ 5.005 5.005_01 5.005_02 /, ], subs => [ [ \&_patch_sysv, old_format => 1 ], ], }, { perl => [ qw/ 5.005_03 5.005_04 /, qr/^5\.6\.[0-2]$/, qr/^5\.7\.[0-3]$/, qr/^5\.8\.[0-8]$/, qr/^5\.9\.[0-5]$/ ], subs => [ [ \&_patch_sysv, old_format => 0 ], ], }, { perl => [ qr/^5\.004_05$/, qr/^5\.005(?:_0[1-4])?$/, qr/^5\.6\.[01]$/, ], subs => [ [ \&_patch_configure ], [ \&_patch_makedepend_lc ], ], }, { perl => [ '5.8.0', ], subs => [ [ \&_patch_makedepend_lc ], ], }, { perl => [ qr/.*/, ], subs => [ [ \&_patch_hints ], ], }, { perl => [ qr/^5\.6\.[0-2]$/, qr/^5\.7\.[0-3]$/, qr/^5\.8\.[0-8]$/, ], subs => [ [ \&_patch_makedepend_SH ], ], }, { perl => [ qr/^5\.1[0-2]/, ], subs => [ [ \&_patch_archive_tar_tests ], ], }, ); sub patch_source { my $vers = shift; $vers = shift if eval { $vers->isa(__PACKAGE__) }; my $source = shift || '.'; if ( !$vers ) { $vers = _determine_version($source); if ( $vers ) { warn "Auto-guessed '$vers'\n"; } else { die "You didn't provide a perl version and I don't appear to be in a perl source tree\n"; } } $source = File::Spec->rel2abs($source); warn "No patch utility found\n" unless $patch_exe; { my $dir = pushd( $source ); for my $p ( grep { _is( $_->{perl}, $vers ) } @patch ) { for my $s (@{$p->{subs}}) { my($sub, @args) = @$s; push @args, $vers unless scalar @args; $sub->(@args); } } } } sub _is { my($s1, $s2) = @_; defined $s1 != defined $s2 and return 0; ref $s2 and ($s1, $s2) = ($s2, $s1); if (ref $s1) { if (ref $s1 eq 'ARRAY') { _is($_, $s2) and return 1 for @$s1; return 0; } return $s2 =~ $s1; } return $s1 eq $s2; } sub _patch { my($patch) = @_; print "patching $_\n" for $patch =~ /^\+{3}\s+(\S+)/gm; my $diff = 'tmp.diff'; _write_or_die($diff, $patch); _run_or_die("$patch_exe -f -s -p0 <$diff"); unlink $diff or die "unlink $diff: $!\n"; } sub _write_or_die { my($file, $data) = @_; my $fh = IO::File->new(">$file") or die "$file: $!\n"; $fh->print($data); } sub _run_or_die { # print "[running @_]\n"; die unless scalar run( command => [ @_ ], verbose => 1 ); } sub _determine_version { my ($source) = @_; my $patchlevel_h = File::Spec->catfile($source, 'patchlevel.h'); return unless -e $patchlevel_h; my $version; { open my $fh, '<', $patchlevel_h; my @vers; while (<$fh>) { chomp; next unless /^#define PERL_[RVS]/; push @vers, (split /\s+/)[2]; } $version = join '.', @vers; } return $version; } sub _patch_hints { return unless my ($file,$data) = hint_file(); my $path = File::Spec->catfile( 'hints', $file ); chmod 0755, $path or die "$!\n"; open my $fh, '>', $path or die "$!\n"; print $fh $data; close $fh; return 1; } sub _patch_db { my $ver = shift; print "patching ext/DB_File/DB_File.xs\n"; _run_or_die($^X, '-pi.bak', '-e', "s///", 'ext/DB_File/DB_File.xs'); unlink 'ext/DB_File/DB_File.xs.bak' if -e 'ext/DB_File/DB_File.xs.bak'; } sub _patch_doio { _patch(<<'END'); --- doio.c.org 2004-06-07 23:14:45.000000000 +0200 +++ doio.c 2003-11-04 08:03:03.000000000 +0100 @@ -75,6 +75,16 @@ # endif #endif +#if _SEM_SEMUN_UNDEFINED +union semun +{ + int val; + struct semid_ds *buf; + unsigned short int *array; + struct seminfo *__buf; +}; +#endif + bool do_open(gv,name,len,as_raw,rawmode,rawperm,supplied_fp) GV *gv; END } sub _patch_sysv { my %opt = @_; # check if patching is required return if $^O ne 'linux' or -f '/usr/include/asm/page.h'; if ($opt{old_format}) { _patch(<<'END'); --- ext/IPC/SysV/SysV.xs.org 1998-07-20 10:20:07.000000000 +0200 +++ ext/IPC/SysV/SysV.xs 2007-08-12 10:51:06.000000000 +0200 @@ -3,9 +3,6 @@ #include "XSUB.h" #include -#ifdef __linux__ -#include -#endif #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM) #include #ifdef HAS_MSG END } else { _patch(<<'END'); --- ext/IPC/SysV/SysV.xs.org 2007-08-11 00:12:46.000000000 +0200 +++ ext/IPC/SysV/SysV.xs 2007-08-11 00:10:51.000000000 +0200 @@ -3,9 +3,6 @@ #include "XSUB.h" #include -#ifdef __linux__ -# include -#endif #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM) #ifndef HAS_SEM # include END } } sub _patch_configure { _patch(<<'END'); --- Configure +++ Configure @@ -3380,6 +3380,18 @@ test "X$gfpthkeep" != Xy && gfpth="" EOSC +# gcc 3.1 complains about adding -Idirectories that it already knows about, +# so we will take those off from locincpth. +case "$gccversion" in +3*) + echo "main(){}">try.c + for incdir in `$cc -v -c try.c 2>&1 | \ + sed '1,/^#include <\.\.\.>/d;/^End of search list/,$d;s/^ //'` ; do + locincpth=`echo $locincpth | sed s!$incdir!!` + done + $rm -f try try.* +esac + : What should the include directory be ? echo " " $echo $n "Hmm... $c" END } sub _patch_makedepend_lc { _patch(<<'END'); --- makedepend.SH +++ makedepend.SH @@ -58,6 +58,10 @@ case $PERL_CONFIG_SH in ;; esac +# Avoid localized gcc/cc messages +LC_ALL=C +export LC_ALL + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not END } sub _patch_makedepend_SH { my $perl = shift; SWITCH: { # If 5.6.0 if ( $perl eq '5.6.0' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2000-03-02 18:12:26.000000000 +0000 +++ makedepend.SH 2010-09-01 10:13:37.000000000 +0100 @@ -1,5 +1,5 @@ #! /bin/sh -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -29,6 +29,13 @@ !GROK!THIS! $spitshell >>makedepend <<'!NO!SUBS!' +if test -d .depending; then + echo "$0: Already running, exiting." + exit 0 +fi + +mkdir .depending + # This script should be called with # sh ./makedepend MAKE=$(MAKE) case "$1" in @@ -37,7 +44,7 @@ export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$) -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -51,6 +58,11 @@ ;; esac +# Avoid localized gcc messages +case "$ccname" in + gcc) LC_ALL=C ; export LC_ALL ;; +esac + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not @@ -58,6 +70,10 @@ PATH=".$path_sep..$path_sep$PATH" export PATH +case "$osname" in +amigaos) cat=/bin/cat ;; # must be absolute +esac + $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then @@ -67,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -99,25 +114,20 @@ $echo *.c | $tr ' ' $trnl | $egrep -v '\*' >.clist) for file in `$cat .clist`; do # for file in `cat /dev/null`; do - if [ "$osname" = uwin ]; then - uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" - else - if [ "$osname" = os2 ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$archname" = cygwin ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - uwinfix= - fi - fi - fi + case "$osname" in + uwin) uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" ;; + os2) uwinfix="-e s,\\\\\\\\,/,g" ;; + cygwin) uwinfix="-e s,\\\\\\\\,/,g" ;; + posix-bc) uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" ;; + vos) uwinfix="-e s/\#/\\\#/" ;; + *) uwinfix="" ;; + esac case "$file" in *.c) filebase=`basename $file .c` ;; *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -130,22 +140,45 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + if [ "$osname" = os390 -a "$file" = perly.c ]; then $echo '#endif' >>UU/$file.c fi - $cppstdin $finc -I. $cppflags $cppminus /d' \ - -e '/^#.*"-"/d' \ - -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ - -e 's/^[ ]*#[ ]*line/#/' \ - -e '/^# *[0-9][0-9]* *[".\/]/!d' \ - -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ - -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ - -e 's|: \./|: |' \ - -e 's|\.c\.c|.c|' $uwinfix | \ - $uniq | $sort | $uniq >> .deptmp + + if [ "$osname" = os390 ]; then + $cppstdin $finc -I. $cppflags $cppminus /d' \ + -e '/^#.*"-"/d' \ + -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ + -e 's/^[ ]*#[ ]*line/#/' \ + -e '/^# *[0-9][0-9]* *[".\/]/!d' \ + -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ + -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ + -e 's|: \./|: |' \ + -e 's|\.c\.c|.c|' $uwinfix | \ + $uniq | $sort | $uniq >> .deptmp + else + $cppstdin $finc -I. $cppflags $cppminus .cout 2>.cerr + $sed \ + -e '1d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ + -e '/: file path prefix .* never used$/d' \ + -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ + -e 's/^[ ]*#[ ]*line/#/' \ + -e '/^# *[0-9][0-9]* *[".\/]/!d' \ + -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ + -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ + -e 's|: \./|: |' \ + -e 's|\.c\.c|.c|' $uwinfix .cout .cerr| \ + $uniq | $sort | $uniq >> .deptmp + fi done $sed <$mf >$mf.new -e '1,/^# AUTOMATICALLY/!d' @@ -177,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else @@ -208,7 +245,8 @@ $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf -$rm -rf .deptmp UU .shlist .clist .hlist .hsed +$rm -rf .deptmp UU .shlist .clist .hlist .hsed .cout .cerr +rmdir .depending !NO!SUBS! $eunicefix makedepend BADGER last SWITCH; } # If 5.6.1 if ( $perl eq '5.6.1' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2001-03-19 07:33:17.000000000 +0000 +++ makedepend.SH 2010-09-01 10:14:47.000000000 +0100 @@ -1,5 +1,5 @@ #! /bin/sh -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -29,6 +29,13 @@ !GROK!THIS! $spitshell >>makedepend <<'!NO!SUBS!' +if test -d .depending; then + echo "$0: Already running, exiting." + exit 0 +fi + +mkdir .depending + # This script should be called with # sh ./makedepend MAKE=$(MAKE) case "$1" in @@ -37,7 +44,7 @@ export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$) -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -51,6 +58,11 @@ ;; esac +# Avoid localized gcc messages +case "$ccname" in + gcc) LC_ALL=C ; export LC_ALL ;; +esac + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not @@ -58,6 +70,10 @@ PATH=".$path_sep..$path_sep$PATH" export PATH +case "$osname" in +amigaos) cat=/bin/cat ;; # must be absolute +esac + $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then @@ -67,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -99,29 +114,20 @@ $echo *.c | $tr ' ' $trnl | $egrep -v '\*' >.clist) for file in `$cat .clist`; do # for file in `cat /dev/null`; do - if [ "$osname" = uwin ]; then - uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" - else - if [ "$osname" = os2 ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$archname" = cygwin ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$osname" = posix-bc ]; then - uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" - else - uwinfix= - fi - fi - fi - fi + case "$osname" in + uwin) uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" ;; + os2) uwinfix="-e s,\\\\\\\\,/,g" ;; + cygwin) uwinfix="-e s,\\\\\\\\,/,g" ;; + posix-bc) uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" ;; + vos) uwinfix="-e s/\#/\\\#/" ;; + *) uwinfix="" ;; + esac case "$file" in *.c) filebase=`basename $file .c` ;; *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -134,10 +140,12 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + + if [ "$osname" = os390 -a "$file" = perly.c ]; then + $echo '#endif' >>UU/$file.c + fi + if [ "$osname" = os390 ]; then - if [ "$file" = perly.c ]; then - $echo '#endif' >>UU/$file.c - fi $cppstdin $finc -I. $cppflags $cppminus /d' \ @@ -151,18 +159,24 @@ -e 's|\.c\.c|.c|' $uwinfix | \ $uniq | $sort | $uniq >> .deptmp else - $cppstdin $finc -I. $cppflags $cppminus .cout 2>.cerr $sed \ -e '1d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ + -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ -e '/^# *[0-9][0-9]* *[".\/]/!d' \ -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's|: \./|: |' \ - -e 's|\.c\.c|.c|' $uwinfix | \ + -e 's|\.c\.c|.c|' $uwinfix .cout .cerr| \ $uniq | $sort | $uniq >> .deptmp fi done @@ -196,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else @@ -227,7 +245,8 @@ $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf -$rm -rf .deptmp UU .shlist .clist .hlist .hsed +$rm -rf .deptmp UU .shlist .clist .hlist .hsed .cout .cerr +rmdir .depending !NO!SUBS! $eunicefix makedepend BADGER last SWITCH; } # If 5.6.2 if ( $perl eq '5.6.2' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2003-07-30 23:46:59.000000000 +0100 +++ makedepend.SH 2010-09-01 10:15:47.000000000 +0100 @@ -1,5 +1,5 @@ #! /bin/sh -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -29,6 +29,13 @@ !GROK!THIS! $spitshell >>makedepend <<'!NO!SUBS!' +if test -d .depending; then + echo "$0: Already running, exiting." + exit 0 +fi + +mkdir .depending + # This script should be called with # sh ./makedepend MAKE=$(MAKE) case "$1" in @@ -37,7 +44,7 @@ export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$) -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -63,6 +70,10 @@ PATH=".$path_sep..$path_sep$PATH" export PATH +case "$osname" in +amigaos) cat=/bin/cat ;; # must be absolute +esac + $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then @@ -72,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -104,29 +114,20 @@ $echo *.c | $tr ' ' $trnl | $egrep -v '\*' >.clist) for file in `$cat .clist`; do # for file in `cat /dev/null`; do - if [ "$osname" = uwin ]; then - uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" - else - if [ "$osname" = os2 ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$archname" = cygwin ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$osname" = posix-bc ]; then - uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" - else - uwinfix= - fi - fi - fi - fi + case "$osname" in + uwin) uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" ;; + os2) uwinfix="-e s,\\\\\\\\,/,g" ;; + cygwin) uwinfix="-e s,\\\\\\\\,/,g" ;; + posix-bc) uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" ;; + vos) uwinfix="-e s/\#/\\\#/" ;; + *) uwinfix="" ;; + esac case "$file" in *.c) filebase=`basename $file .c` ;; *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -139,10 +140,12 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + + if [ "$osname" = os390 -a "$file" = perly.c ]; then + $echo '#endif' >>UU/$file.c + fi + if [ "$osname" = os390 ]; then - if [ "$file" = perly.c ]; then - $echo '#endif' >>UU/$file.c - fi $cppstdin $finc -I. $cppflags $cppminus /d' \ @@ -156,21 +159,24 @@ -e 's|\.c\.c|.c|' $uwinfix | \ $uniq | $sort | $uniq >> .deptmp else - $cppstdin $finc -I. $cppflags $cppminus .cout 2>.cerr $sed \ -e '1d' \ -e '/^#.*/d' \ - -e '/^#.*/d' \ - -e '/^#.*/d' \ - -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ + -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ -e '/^# *[0-9][0-9]* *[".\/]/!d' \ -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's|: \./|: |' \ - -e 's|\.c\.c|.c|' $uwinfix | \ + -e 's|\.c\.c|.c|' $uwinfix .cout .cerr| \ $uniq | $sort | $uniq >> .deptmp fi done @@ -204,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else @@ -235,7 +245,8 @@ $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf -$rm -rf .deptmp UU .shlist .clist .hlist .hsed +$rm -rf .deptmp UU .shlist .clist .hlist .hsed .cout .cerr +rmdir .depending !NO!SUBS! $eunicefix makedepend BADGER last SWITCH; } # If 5.7.0 if ( $perl eq '5.7.0' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2000-08-13 19:35:04.000000000 +0100 +++ makedepend.SH 2010-09-01 10:47:14.000000000 +0100 @@ -1,5 +1,5 @@ #! /bin/sh -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -29,6 +29,13 @@ !GROK!THIS! $spitshell >>makedepend <<'!NO!SUBS!' +if test -d .depending; then + echo "$0: Already running, exiting." + exit 0 +fi + +mkdir .depending + # This script should be called with # sh ./makedepend MAKE=$(MAKE) case "$1" in @@ -37,7 +44,7 @@ export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$) -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -51,6 +58,11 @@ ;; esac +# Avoid localized gcc messages +case "$ccname" in + gcc) LC_ALL=C ; export LC_ALL ;; +esac + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not @@ -58,6 +70,10 @@ PATH=".$path_sep..$path_sep$PATH" export PATH +case "$osname" in +amigaos) cat=/bin/cat ;; # must be absolute +esac + $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then @@ -67,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -99,25 +114,20 @@ $echo *.c | $tr ' ' $trnl | $egrep -v '\*' >.clist) for file in `$cat .clist`; do # for file in `cat /dev/null`; do - if [ "$osname" = uwin ]; then - uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" - else - if [ "$osname" = os2 ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$archname" = cygwin ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - uwinfix= - fi - fi - fi + case "$osname" in + uwin) uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" ;; + os2) uwinfix="-e s,\\\\\\\\,/,g" ;; + cygwin) uwinfix="-e s,\\\\\\\\,/,g" ;; + posix-bc) uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" ;; + vos) uwinfix="-e s/\#/\\\#/" ;; + *) uwinfix="" ;; + esac case "$file" in *.c) filebase=`basename $file .c` ;; *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -130,10 +140,12 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + + if [ "$osname" = os390 -a "$file" = perly.c ]; then + $echo '#endif' >>UU/$file.c + fi + if [ "$osname" = os390 ]; then - if [ "$file" = perly.c ]; then - $echo '#endif' >>UU/$file.c - fi $cppstdin $finc -I. $cppflags $cppminus /d' \ @@ -147,18 +159,24 @@ -e 's|\.c\.c|.c|' $uwinfix | \ $uniq | $sort | $uniq >> .deptmp else - $cppstdin $finc -I. $cppflags $cppminus .cout 2>.cerr $sed \ -e '1d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ + -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ -e '/^# *[0-9][0-9]* *[".\/]/!d' \ -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's|: \./|: |' \ - -e 's|\.c\.c|.c|' $uwinfix | \ + -e 's|\.c\.c|.c|' $uwinfix .cout .cerr| \ $uniq | $sort | $uniq >> .deptmp fi done @@ -192,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else @@ -223,7 +245,8 @@ $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf -$rm -rf .deptmp UU .shlist .clist .hlist .hsed +$rm -rf .deptmp UU .shlist .clist .hlist .hsed .cout .cerr +rmdir .depending !NO!SUBS! $eunicefix makedepend BADGER last SWITCH; } # If 5.7.1 if ( $perl eq '5.7.1' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2001-03-11 16:30:08.000000000 +0000 +++ makedepend.SH 2010-09-01 10:44:54.000000000 +0100 @@ -1,5 +1,5 @@ #! /bin/sh -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -29,6 +29,13 @@ !GROK!THIS! $spitshell >>makedepend <<'!NO!SUBS!' +if test -d .depending; then + echo "$0: Already running, exiting." + exit 0 +fi + +mkdir .depending + # This script should be called with # sh ./makedepend MAKE=$(MAKE) case "$1" in @@ -37,7 +44,7 @@ export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$) -case $CONFIGDOTSH in +case $PERL_CONFIG_SH in '') if test -f config.sh; then TOP=.; elif test -f ../config.sh; then TOP=..; @@ -51,6 +58,11 @@ ;; esac +# Avoid localized gcc messages +case "$ccname" in + gcc) LC_ALL=C ; export LC_ALL ;; +esac + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not @@ -58,6 +70,10 @@ PATH=".$path_sep..$path_sep$PATH" export PATH +case "$osname" in +amigaos) cat=/bin/cat ;; # must be absolute +esac + $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then @@ -67,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -99,29 +114,20 @@ $echo *.c | $tr ' ' $trnl | $egrep -v '\*' >.clist) for file in `$cat .clist`; do # for file in `cat /dev/null`; do - if [ "$osname" = uwin ]; then - uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" - else - if [ "$osname" = os2 ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$archname" = cygwin ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$osname" = posix-bc ]; then - uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" - else - uwinfix= - fi - fi - fi - fi + case "$osname" in + uwin) uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" ;; + os2) uwinfix="-e s,\\\\\\\\,/,g" ;; + cygwin) uwinfix="-e s,\\\\\\\\,/,g" ;; + posix-bc) uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" ;; + vos) uwinfix="-e s/\#/\\\#/" ;; + *) uwinfix="" ;; + esac case "$file" in *.c) filebase=`basename $file .c` ;; *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -134,10 +140,12 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + + if [ "$osname" = os390 -a "$file" = perly.c ]; then + $echo '#endif' >>UU/$file.c + fi + if [ "$osname" = os390 ]; then - if [ "$file" = perly.c ]; then - $echo '#endif' >>UU/$file.c - fi $cppstdin $finc -I. $cppflags $cppminus /d' \ @@ -151,18 +159,24 @@ -e 's|\.c\.c|.c|' $uwinfix | \ $uniq | $sort | $uniq >> .deptmp else - $cppstdin $finc -I. $cppflags $cppminus .cout 2>.cerr $sed \ -e '1d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ + -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ -e '/^# *[0-9][0-9]* *[".\/]/!d' \ -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's|: \./|: |' \ - -e 's|\.c\.c|.c|' $uwinfix | \ + -e 's|\.c\.c|.c|' $uwinfix .cout .cerr| \ $uniq | $sort | $uniq >> .deptmp fi done @@ -196,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else @@ -227,7 +245,8 @@ $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf -$rm -rf .deptmp UU .shlist .clist .hlist .hsed +$rm -rf .deptmp UU .shlist .clist .hlist .hsed .cout .cerr +rmdir .depending !NO!SUBS! $eunicefix makedepend BADGER last SWITCH; } # If 5.7.2 if ( $perl eq '5.7.2' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2001-07-09 15:11:05.000000000 +0100 +++ makedepend.SH 2010-09-01 10:45:32.000000000 +0100 @@ -18,10 +18,6 @@ */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac -case "$osname" in -amigaos) cat=/bin/cat ;; # must be absolute -esac - echo "Extracting makedepend (with variable substitutions)" rm -f makedepend $spitshell >makedepend <>makedepend <<'!NO!SUBS!' +if test -d .depending; then + echo "$0: Already running, exiting." + exit 0 +fi + +mkdir .depending + # This script should be called with # sh ./makedepend MAKE=$(MAKE) case "$1" in @@ -55,6 +58,11 @@ ;; esac +# Avoid localized gcc messages +case "$ccname" in + gcc) LC_ALL=C ; export LC_ALL ;; +esac + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not @@ -62,6 +70,10 @@ PATH=".$path_sep..$path_sep$PATH" export PATH +case "$osname" in +amigaos) cat=/bin/cat ;; # must be absolute +esac + $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then @@ -71,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -103,29 +114,20 @@ $echo *.c | $tr ' ' $trnl | $egrep -v '\*' >.clist) for file in `$cat .clist`; do # for file in `cat /dev/null`; do - if [ "$osname" = uwin ]; then - uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" - else - if [ "$osname" = os2 ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$archname" = cygwin ]; then - uwinfix="-e s,\\\\\\\\,/,g" - else - if [ "$osname" = posix-bc ]; then - uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" - else - uwinfix= - fi - fi - fi - fi + case "$osname" in + uwin) uwinfix="-e s,\\\\\\\\,/,g -e s,\\([a-zA-Z]\\):/,/\\1/,g" ;; + os2) uwinfix="-e s,\\\\\\\\,/,g" ;; + cygwin) uwinfix="-e s,\\\\\\\\,/,g" ;; + posix-bc) uwinfix="-e s/\\*POSIX(\\(.*\\))/\\1/" ;; + vos) uwinfix="-e s/\#/\\\#/" ;; + *) uwinfix="" ;; + esac case "$file" in *.c) filebase=`basename $file .c` ;; *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -138,10 +140,12 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + + if [ "$osname" = os390 -a "$file" = perly.c ]; then + $echo '#endif' >>UU/$file.c + fi + if [ "$osname" = os390 ]; then - if [ "$file" = perly.c ]; then - $echo '#endif' >>UU/$file.c - fi $cppstdin $finc -I. $cppflags $cppminus /d' \ @@ -155,18 +159,24 @@ -e 's|\.c\.c|.c|' $uwinfix | \ $uniq | $sort | $uniq >> .deptmp else - $cppstdin $finc -I. $cppflags $cppminus .cout 2>.cerr $sed \ -e '1d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ + -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ -e '/^# *[0-9][0-9]* *[".\/]/!d' \ -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's|: \./|: |' \ - -e 's|\.c\.c|.c|' $uwinfix | \ + -e 's|\.c\.c|.c|' $uwinfix .cout .cerr| \ $uniq | $sort | $uniq >> .deptmp fi done @@ -200,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else @@ -231,7 +245,8 @@ $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf -$rm -rf .deptmp UU .shlist .clist .hlist .hsed +$rm -rf .deptmp UU .shlist .clist .hlist .hsed .cout .cerr +rmdir .depending !NO!SUBS! $eunicefix makedepend BADGER last SWITCH; } # If 5.7.3 if ( $perl eq '5.7.3' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2002-03-05 01:10:22.000000000 +0000 +++ makedepend.SH 2010-09-01 10:46:13.000000000 +0100 @@ -18,10 +18,6 @@ */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac -case "$osname" in -amigaos) cat=/bin/cat ;; # must be absolute -esac - echo "Extracting makedepend (with variable substitutions)" rm -f makedepend $spitshell >makedepend <>makedepend <<'!NO!SUBS!' +if test -d .depending; then + echo "$0: Already running, exiting." + exit 0 +fi + +mkdir .depending + # This script should be called with # sh ./makedepend MAKE=$(MAKE) case "$1" in @@ -55,6 +58,11 @@ ;; esac +# Avoid localized gcc messages +case "$ccname" in + gcc) LC_ALL=C ; export LC_ALL ;; +esac + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not @@ -62,6 +70,10 @@ PATH=".$path_sep..$path_sep$PATH" export PATH +case "$osname" in +amigaos) cat=/bin/cat ;; # must be absolute +esac + $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then @@ -71,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -116,7 +127,7 @@ *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -129,6 +140,11 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + + if [ "$osname" = os390 -a "$file" = perly.c ]; then + $echo '#endif' >>UU/$file.c + fi + if [ "$osname" = os390 ]; then $cppstdin $finc -I. $cppflags $cppminus > .deptmp else - $cppstdin $finc -I. $cppflags $cppminus &1 | + $cppstdin $finc -I. $cppflags $cppminus .cout 2>.cerr $sed \ -e '1d' \ -e '/^#.*/d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ @@ -157,7 +176,7 @@ -e 's/^.*"\(.*\)".*$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's/^# *[0-9][0-9]* \(.*\)$/'$filebase'\$(OBJ_EXT): \1/' \ -e 's|: \./|: |' \ - -e 's|\.c\.c|.c|' $uwinfix | \ + -e 's|\.c\.c|.c|' $uwinfix .cout .cerr| \ $uniq | $sort | $uniq >> .deptmp fi done @@ -191,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else @@ -222,7 +245,8 @@ $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf -$rm -rf .deptmp UU .shlist .clist .hlist .hsed +$rm -rf .deptmp UU .shlist .clist .hlist .hsed .cout .cerr +rmdir .depending !NO!SUBS! $eunicefix makedepend BADGER last SWITCH; } # If 5.8.0 if ( $perl eq '5.8.0' ) { _patch(<<'BADGER'); --- makedepend.SH.org 2002-07-09 15:06:42.000000000 +0100 +++ makedepend.SH 2010-09-01 10:16:37.000000000 +0100 @@ -58,6 +58,11 @@ ;; esac +# Avoid localized gcc messages +case "$ccname" in + gcc) LC_ALL=C ; export LC_ALL ;; +esac + # We need .. when we are in the x2p directory if we are using the # cppstdin wrapper script. # Put .. and . first so that we pick up the present cppstdin, not @@ -78,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -123,7 +127,7 @@ *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -136,6 +140,11 @@ -e 's|\\$||' \ -e p \ -e '}' ) >UU/$file.c + + if [ "$osname" = os390 -a "$file" = perly.c ]; then + $echo '#endif' >>UU/$file.c + fi + if [ "$osname" = os390 ]; then $cppstdin $finc -I. $cppflags $cppminus /d' \ -e '/^#.*/d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ @@ -199,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else BADGER last SWITCH; } # If 5.8.[12345678] _patch(<<'BADGER'); --- makedepend.SH.org 2003-06-05 19:11:10.000000000 +0100 +++ makedepend.SH 2010-09-01 10:24:39.000000000 +0100 @@ -83,7 +83,6 @@ # to be out of date. I don't know if OS/2 has touch, so do this: case "$osname" in os2) ;; - netbsd) ;; *) $touch $firstmakefile ;; esac fi @@ -128,7 +127,7 @@ *.y) filebase=`basename $file .y` ;; esac case "$file" in - */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;; + */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;; *) finc= ;; esac $echo "Finding dependencies for $filebase$_o." @@ -167,7 +166,9 @@ -e '/^#.*/d' \ -e '/^#.*/d' \ -e '/^#.*/d' \ + -e '/^#.*/d' \ -e '/^#.*"-"/d' \ + -e '/^#.*"\/.*\/"/d' \ -e '/: file path prefix .* never used$/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ @@ -209,6 +210,10 @@ $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new + if [ "$osname" = vos ]; then + $sed 's|.incl.c|.h|' .deptmp >.deptmp.vos + mv -f .deptmp.vos .deptmp + fi $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else BADGER } } sub _patch_archive_tar_tests { my $perl = shift; if ($perl =~ /^5\.10/) { _patch(<<'END'); --- lib/Archive/Tar/t/02_methods.t +++ lib/Archive/Tar/t/02_methods.t @@ -70,6 +70,20 @@ my $LONG_FILE = qq[directory/really-really-really-really-really-really-really-re my $TOO_LONG = ($^O eq 'MSWin32' or $^O eq 'cygwin' or $^O eq 'VMS') && length( cwd(). $LONG_FILE ) > 247; +if(!$TOO_LONG) { + my $alt = File::Spec->catfile( cwd(), $LONG_FILE); + eval 'mkpath([$alt]);'; + if($@) + { + $TOO_LONG = 1; + } + else + { + $@ = ''; + my $base = File::Spec->catfile( cwd(), 'directory'); + rmtree $base; + } +} ### warn if we are going to skip long file names if ($TOO_LONG) { diag("No long filename support - long filename extraction disabled") if ! $ENV{PERL_CORE}; END } else { _patch(<<'END'); --- cpan/Archive-Tar/t/02_methods.t +++ cpan/Archive-Tar/t/02_methods.t @@ -70,6 +70,20 @@ my $LONG_FILE = qq[directory/really-really-really-really-really-really-really-re my $TOO_LONG = ($^O eq 'MSWin32' or $^O eq 'cygwin' or $^O eq 'VMS') && length( cwd(). $LONG_FILE ) > 247; +if(!$TOO_LONG) { + my $alt = File::Spec->catfile( cwd(), $LONG_FILE); + eval 'mkpath([$alt]);'; + if($@) + { + $TOO_LONG = 1; + } + else + { + $@ = ''; + my $base = File::Spec->catfile( cwd(), 'directory'); + rmtree $base; + } +} ### warn if we are going to skip long file names if ($TOO_LONG) { diag("No long filename support - long filename extraction disabled") if ! $ENV{PERL_CORE}; END } } qq[patchin']; __END__ =pod =head1 NAME Devel::PatchPerl - Patch perl source a la Devel::PPort's buildperl.pl =head1 VERSION version 0.32 =head1 SYNOPSIS use strict; use warnings; use Devel::PatchPerl; Devel::PatchPerl->patch_source( '5.6.1', '/path/to/untarred/perl/source/perl-5.6.1' ); =head1 DESCRIPTION Devel::PatchPerl is a modularisation of the patching code contained in L's C. It does not build perls, it merely provides an interface to the source patching functionality. =head1 FUNCTION =over =item C Takes two parameters, a C version and the path to unwrapped perl source for that version. It dies on any errors. If you don't supply a C version, it will attempt to auto-determine the C version from the specified path. If you don't supply the path to unwrapped perl source, it will assume the current working directory. =back =head1 SEE ALSO L =head1 AUTHOR Chris Williams =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Chris Williams and Marcus Holland-Moritz. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut DEVEL_PATCHPERL $fatpacked{"Devel/PatchPerl/Hints.pm"} = <<'DEVEL_PATCHPERL_HINTS'; package Devel::PatchPerl::Hints; BEGIN { $Devel::PatchPerl::Hints::VERSION = '0.32'; } #ABSTRACT: replacement 'hints' files use strict; use warnings; use MIME::Base64 qw[decode_base64]; use File::Spec; our @ISA = qw[Exporter]; our @EXPORT_OK = qw[hint_file]; my %hints = ( 'netbsd' => 'IyBoaW50cy9uZXRic2Quc2gKIwojIFBsZWFzZSBjaGVjayB3aXRoIHBhY2thZ2VzQG5ldGJzZC5v cmcgYmVmb3JlIG1ha2luZyBtb2RpZmljYXRpb25zCiMgdG8gdGhpcyBmaWxlLgoKY2FzZSAiJGFy Y2huYW1lIiBpbgonJykKICAgIGFyY2huYW1lPWB1bmFtZSAtbWAtJHtvc25hbWV9CiAgICA7Owpl c2FjCgojIE5ldEJTRCBrZWVwcyBkeW5hbWljIGxvYWRpbmcgZGwqKCkgZnVuY3Rpb25zIGluIC91 c3IvbGliL2NydDAubywKIyBzbyBDb25maWd1cmUgZG9lc24ndCBmaW5kIHRoZW0gKHVubGVzcyB5 b3UgYWJhbmRvbiB0aGUgbm0gc2NhbikuCiMgQWxzbywgTmV0QlNEIDAuOWEgd2FzIHRoZSBmaXJz dCByZWxlYXNlIHRvIGludHJvZHVjZSBzaGFyZWQKIyBsaWJyYXJpZXMuCiMKY2FzZSAiJG9zdmVy cyIgaW4KMC45fDAuOCopCgl1c2VkbD0iJHVuZGVmIgoJOzsKKikKCWNhc2UgYHVuYW1lIC1tYCBp bgoJcG1heCkKCQkjIE5ldEJTRCAxLjMgYW5kIDEuMy4xIG9uIHBtYXggc2hpcHBlZCBhbiBgb2xk JyBsZC5zbywKCQkjIHdoaWNoIHdpbGwgbm90IHdvcmsuCgkJY2FzZSAiJG9zdmVycyIgaW4KCQkx LjN8MS4zLjEpCgkJCWRfZGxvcGVuPSR1bmRlZgoJCQk7OwoJCWVzYWMKCQk7OwoJZXNhYwoJaWYg dGVzdCAtZiAvdXNyL2xpYmV4ZWMvbGQuZWxmX3NvOyB0aGVuCgkJIyBFTEYKCQlkX2Rsb3Blbj0k ZGVmaW5lCgkJZF9kbGVycm9yPSRkZWZpbmUKCQljY2NkbGZsYWdzPSItRFBJQyAtZlBJQyAkY2Nj ZGxmbGFncyIKCQlsZGRsZmxhZ3M9Ii0td2hvbGUtYXJjaGl2ZSAtc2hhcmVkICRsZGRsZmxhZ3Mi CgkJcnBhdGhmbGFnPSItV2wsLXJwYXRoLCIKCQljYXNlICIkb3N2ZXJzIiBpbgoJCTEuWzAtNV0q KQoJCQkjCgkJCSMgSW5jbHVkZSB0aGUgd2hvbGUgbGliZ2NjLmEgaW50byB0aGUgcGVybCBleGVj dXRhYmxlCgkJCSMgc28gdGhhdCBjZXJ0YWluIHN5bWJvbHMgbmVlZGVkIGJ5IGxvYWRhYmxlIG1v ZHVsZXMKCQkJIyBidWlsdCBhcyBDKysgb2JqZWN0cyAoX19laF9hbGxvYywgX19wdXJlX3ZpcnR1 YWwsCgkJCSMgZXRjLikgd2lsbCBhbHdheXMgYmUgZGVmaW5lZC4KCQkJIwoJCQljY2RsZmxhZ3M9 Ii1XbCwtd2hvbGUtYXJjaGl2ZSAtbGdjYyBcCgkJCQktV2wsLW5vLXdob2xlLWFyY2hpdmUgLVds LC1FICRjY2RsZmxhZ3MiCgkJCTs7CgkJKikKCQkJY2NkbGZsYWdzPSItV2wsLUUgJGNjZGxmbGFn cyIKCQkJOzsKCQllc2FjCgllbGlmIHRlc3QgLWYgL3Vzci9saWJleGVjL2xkLnNvOyB0aGVuCgkJ IyBhLm91dAoJCWRfZGxvcGVuPSRkZWZpbmUKCQlkX2RsZXJyb3I9JGRlZmluZQoJCWNjY2RsZmxh Z3M9Ii1EUElDIC1mUElDICRjY2NkbGZsYWdzIgoJCWxkZGxmbGFncz0iLUJzaGFyZWFibGUgJGxk ZGxmbGFncyIKCQlycGF0aGZsYWc9Ii1SIgoJZWxzZQoJCWRfZGxvcGVuPSR1bmRlZgoJCXJwYXRo ZmxhZz0KCWZpCgk7Owplc2FjCgojIG5ldGJzZCBoYWQgdGhlc2UgYnV0IHRoZXkgZG9uJ3QgcmVh bGx5IHdvcmsgYXMgYWR2ZXJ0aXNlZCwgaW4gdGhlCiMgdmVyc2lvbnMgbGlzdGVkIGJlbG93LiAg aWYgdGhleSBhcmUgZGVmaW5lZCwgdGhlbiB0aGVyZSBpc24ndCBhCiMgd2F5IHRvIG1ha2UgcGVy bCBjYWxsIHNldHVpZCgpIG9yIHNldGdpZCgpLiAgaWYgdGhleSBhcmVuJ3QsIHRoZW4KIyAoJDws ICQ+KSA9ICgkdSwgJHUpOyB3aWxsIHdvcmsgKHNhbWUgZm9yICQoLyQpKS4gIHRoaXMgaXMgYmVj YXVzZQojIHlvdSBjYW4gbm90IGNoYW5nZSB0aGUgcmVhbCB1c2VyaWQgb2YgYSBwcm9jZXNzIHVu ZGVyIDQuNEJTRC4KIyBuZXRic2QgZml4ZWQgdGhpcyBpbiAxLjMuMi4KY2FzZSAiJG9zdmVycyIg aW4KMC45KnwxLlswMTJdKnwxLjN8MS4zLjEpCglkX3NldHJlZ2lkPSIkdW5kZWYiCglkX3NldHJl dWlkPSIkdW5kZWYiCgk7Owplc2FjCmNhc2UgIiRvc3ZlcnMiIGluCjAuOSp8MS4qfDIuKnwzLip8 NC4qfDUuKikKCWRfZ2V0cHJvdG9lbnRfcj0iJHVuZGVmIgoJZF9nZXRwcm90b2J5bmFtZV9yPSIk dW5kZWYiCglkX2dldHByb3RvYnludW1iZXJfcj0iJHVuZGVmIgoJZF9zZXRwcm90b2VudF9yPSIk dW5kZWYiCglkX2VuZHByb3RvZW50X3I9IiR1bmRlZiIKCWRfZ2V0c2VydmVudF9yPSIkdW5kZWYi CglkX2dldHNlcnZieW5hbWVfcj0iJHVuZGVmIgoJZF9nZXRzZXJ2Ynlwb3J0X3I9IiR1bmRlZiIK CWRfc2V0c2VydmVudF9yPSIkdW5kZWYiCglkX2VuZHNlcnZlbnRfcj0iJHVuZGVmIgoJZF9nZXRw cm90b2VudF9yX3Byb3RvPSIwIgoJZF9nZXRwcm90b2J5bmFtZV9yX3Byb3RvPSIwIgoJZF9nZXRw cm90b2J5bnVtYmVyX3JfcHJvdG89IjAiCglkX3NldHByb3RvZW50X3JfcHJvdG89IjAiCglkX2Vu ZHByb3RvZW50X3JfcHJvdG89IjAiCglkX2dldHNlcnZlbnRfcl9wcm90bz0iMCIKCWRfZ2V0c2Vy dmJ5bmFtZV9yX3Byb3RvPSIwIgoJZF9nZXRzZXJ2Ynlwb3J0X3JfcHJvdG89IjAiCglkX3NldHNl cnZlbnRfcl9wcm90bz0iMCIKCWRfZW5kc2VydmVudF9yX3Byb3RvPSIwIgoJOzsKZXNhYwoKIyBU aGVzZSBhcmUgb2Jzb2xldGUgaW4gYW55IG5ldGJzZC4KZF9zZXRyZ2lkPSIkdW5kZWYiCmRfc2V0 cnVpZD0iJHVuZGVmIgoKIyB0aGVyZSdzIG5vIHByb2JsZW0gd2l0aCB2Zm9yay4KdXNldmZvcms9 dHJ1ZQoKIyBUaGlzIGlzIHRoZXJlIGJ1dCBpbiBtYWNoaW5lL2llZWVmcF9oLgppZWVlZnBfaD0i ZGVmaW5lIgoKIyBUaGlzIHNjcmlwdCBVVS91c2V0aHJlYWRzLmNidSB3aWxsIGdldCAnY2FsbGVk LWJhY2snIGJ5IENvbmZpZ3VyZQojIGFmdGVyIGl0IGhhcyBwcm9tcHRlZCB0aGUgdXNlciBmb3Ig d2hldGhlciB0byB1c2UgdGhyZWFkcy4KY2F0ID4gVVUvdXNldGhyZWFkcy5jYnUgPDwnRU9DQlUn CmNhc2UgIiR1c2V0aHJlYWRzIiBpbgokZGVmaW5lfHRydWV8W3lZXSopCglscHRocmVhZD0KCWZv ciB4eHggaW4gcHRocmVhZDsgZG8KCQlmb3IgeXl5IGluICRsb2NsaWJwdGggJHBsaWJwdGggJGds aWJwdGggZHVtbXk7IGRvCgkJCXp6ej0keXl5L2xpYiR4eHguYQoJCQlpZiB0ZXN0IC1mICIkenp6 IjsgdGhlbgoJCQkJbHB0aHJlYWQ9JHh4eAoJCQkJYnJlYWs7CgkJCWZpCgkJCXp6ej0keXl5L2xp YiR4eHguc28KCQkJaWYgdGVzdCAtZiAiJHp6eiI7IHRoZW4KCQkJCWxwdGhyZWFkPSR4eHgKCQkJ CWJyZWFrOwoJCQlmaQoJCQl6eno9YGxzICR5eXkvbGliJHh4eC5zby4qIDI+L2Rldi9udWxsYAoJ CQlpZiB0ZXN0ICJYJHp6eiIgIT0gWDsgdGhlbgoJCQkJbHB0aHJlYWQ9JHh4eAoJCQkJYnJlYWs7 CgkJCWZpCgkJZG9uZQoJCWlmIHRlc3QgIlgkbHB0aHJlYWQiICE9IFg7IHRoZW4KCQkJYnJlYWs7 CgkJZmkKCWRvbmUKCWlmIHRlc3QgIlgkbHB0aHJlYWQiICE9IFg7IHRoZW4KCQkjIEFkZCAtbHB0 aHJlYWQuCgkJbGlic3dhbnRlZD0iJGxpYnN3YW50ZWQgJGxwdGhyZWFkIgoJCSMgVGhlcmUgaXMg bm8gbGliY19yIGFzIG9mIE5ldEJTRCAxLjUuMiwgc28gbm8gYyAtPiBjX3IuCgkJIyBUaGlzIHdp bGwgYmUgcmV2aXNpdGVkIHdoZW4gTmV0QlNEIGdhaW5zIGEgbmF0aXZlIHB0aHJlYWRzCgkJIyBp bXBsZW1lbnRhdGlvbi4KCWVsc2UKCQllY2hvICIkMDogTm8gUE9TSVggdGhyZWFkcyBsaWJyYXJ5 ICgtbHB0aHJlYWQpIGZvdW5kLiAgIiBcCgkJICAgICAiWW91IG1heSB3YW50IHRvIGluc3RhbGwg R05VIHB0aC4gIEFib3J0aW5nLiIgPiY0CgkJZXhpdCAxCglmaQoJdW5zZXQgbHB0aHJlYWQKCgkj IHNldmVyYWwgcmVlbnRyYW50IGZ1bmN0aW9ucyBhcmUgZW1iZWRkZWQgaW4gbGliYywgYnV0IGhh dmVuJ3QKCSMgYmVlbiBhZGRlZCB0byB0aGUgaGVhZGVyIGZpbGVzIHlldC4gIExldCdzIGhvbGQg b2ZmIG9uIHVzaW5nCgkjIHRoZW0gdW50aWwgdGhleSBhcmUgYSB2YWxpZCBwYXJ0IG9mIHRoZSBB UEkKCWNhc2UgIiRvc3ZlcnMiIGluCglbMDEyXS4qfDMuWzAtMV0pCgkJZF9nZXRwcm90b2J5bmFt ZV9yPSR1bmRlZgoJCWRfZ2V0cHJvdG9ieW51bWJlcl9yPSR1bmRlZgoJCWRfZ2V0cHJvdG9lbnRf cj0kdW5kZWYKCQlkX2dldHNlcnZieW5hbWVfcj0kdW5kZWYKCQlkX2dldHNlcnZieXBvcnRfcj0k dW5kZWYKCQlkX2dldHNlcnZlbnRfcj0kdW5kZWYKCQlkX3NldHByb3RvZW50X3I9JHVuZGVmCgkJ ZF9zZXRzZXJ2ZW50X3I9JHVuZGVmCgkJZF9lbmRwcm90b2VudF9yPSR1bmRlZgoJCWRfZW5kc2Vy dmVudF9yPSR1bmRlZiA7OwoJZXNhYwoJOzsKCmVzYWMKRU9DQlUKCiMgU2V0IHNlbnNpYmxlIGRl ZmF1bHRzIGZvciBOZXRCU0Q6IGxvb2sgZm9yIGxvY2FsIHNvZnR3YXJlIGluCiMgL3Vzci9wa2cg KE5ldEJTRCBQYWNrYWdlcyBDb2xsZWN0aW9uKSBhbmQgaW4gL3Vzci9sb2NhbC4KIwpsb2NsaWJw dGg9Ii91c3IvcGtnL2xpYiAvdXNyL2xvY2FsL2xpYiIKbG9jaW5jcHRoPSIvdXNyL3BrZy9pbmNs dWRlIC91c3IvbG9jYWwvaW5jbHVkZSIKY2FzZSAiJHJwYXRoZmxhZyIgaW4KJycpCglsZGZsYWdz PQoJOzsKKikKCWxkZmxhZ3M9Cglmb3IgeXl5IGluICRsb2NsaWJwdGg7IGRvCgkJbGRmbGFncz0i JGxkZmxhZ3MgJHJwYXRoZmxhZyR5eXkiCglkb25lCgk7Owplc2FjCgpjYXNlIGB1bmFtZSAtbWAg aW4KYWxwaGEpCiAgICBlY2hvICdpbnQgbWFpbigpIHt9JyA+IHRyeS5jCiAgICBnY2M9YCR7Y2M6 LWNjfSAtdiAtYyB0cnkuYyAyPiYxfGdyZXAgJ2djYyB2ZXJzaW9uIGVnY3MtMidgCiAgICBjYXNl ICIkZ2NjIiBpbgogICAgJycgfCAiZ2NjIHZlcnNpb24gZWdjcy0yLjk1LiJbMy05XSopIDs7ICMg Mi45NS4zIG9yIGJldHRlciBva2F5CiAgICAqKQljYXQgPiY0IDw8RU9GCioqKgoqKiogWW91ciBn Y2MgKCRnY2MpIGlzIGtub3duIHRvIGJlCioqKiB0b28gYnVnZ3kgb24gbmV0YnNkL2FscGhhIHRv IGNvbXBpbGUgUGVybCB3aXRoIG9wdGltaXphdGlvbi4KKioqIEl0IGlzIHN1Z2dlc3RlZCB5b3Ug aW5zdGFsbCB0aGUgbGFuZy9nY2MgcGFja2FnZSB3aGljaCBzaG91bGQKKioqIGhhdmUgYXQgbGVh c3QgZ2NjIDIuOTUuMyB3aGljaCBzaG91bGQgd29yayBva2F5OiB1c2UgZm9yIGV4YW1wbGUKKioq IENvbmZpZ3VyZSAtRGNjPS91c3IvcGtnL2djYy0yLjk1LjMvYmluL2NjLiAgWW91IGNvdWxkIGFs c28KKioqIENvbmZpZ3VyZSAtRG9wdGltaXplPS1PMCB0byBjb21waWxlIFBlcmwgd2l0aG91dCBh bnkgb3B0aW1pemF0aW9uCioqKiBidXQgdGhhdCBpcyBub3QgcmVjb21tZW5kZWQuCioqKgpFT0YK CWV4aXQgMQoJOzsKICAgIGVzYWMKICAgIHJtIC1mIHRyeS4qCiAgICA7Owplc2FjCgojIE5ldEJT RC9zcGFyYyAxLjUuMy8xLjYuMSBkdW1wcyBjb3JlIGluIHRoZSBzZW1pZF9kcyB0ZXN0IG9mIENv bmZpZ3VyZS4KY2FzZSBgdW5hbWUgLW1gIGluCnNwYXJjKSBkX3NlbWN0bF9zZW1pZF9kcz11bmRl ZiA7Owplc2FjCgojIG1hbGxvYyB3cmFwIHdvcmtzCmNhc2UgIiR1c2VtYWxsb2N3cmFwIiBpbgon JykgdXNlbWFsbG9jd3JhcD0nZGVmaW5lJyA7Owplc2FjCgojIGRvbid0IHVzZSBwZXJsIG1hbGxv YyBieSBkZWZhdWx0CmNhc2UgIiR1c2VteW1hbGxvYyIgaW4KJycpIHVzZW15bWFsbG9jPW4gOzsK ZXNhYwo=', 'freebsd' => 'IyBPcmlnaW5hbCBiYXNlZCBvbiBpbmZvIGZyb20KIyBDYXJsIE0uIEZvbmdoZWlzZXIgPGNtZkBp bnMuaW5mb25ldC5uZXQ+CiMgRGF0ZTogVGh1LCAyOCBKdWwgMTk5NCAxOToxNzowNSAtMDUwMCAo Q0RUKQojCiMgQWRkaXRpb25hbCAxLjEuNSBkZWZpbmVzIGZyb20gCiMgT2xsaXZpZXIgUm9iZXJ0 IDxPbGxpdmllci5Sb2JlcnRAa2VsdGlhLmZybXVnLmZyLm5ldD4KIyBEYXRlOiBXZWQsIDI4IFNl cCAxOTk0IDAwOjM3OjQ2ICswMTAwIChNRVQpCiMKIyBBZGRpdGlvbmFsIDIuKiBkZWZpbmVzIGZy b20KIyBPbGxpdmllciBSb2JlcnQgPE9sbGl2aWVyLlJvYmVydEBrZWx0aWEuZnJtdWcuZnIubmV0 PgojIERhdGU6IFNhdCwgOCBBcHIgMTk5NSAyMDo1Mzo0MSArMDIwMCAoTUVUIERTVCkKIwojIEFk ZGl0aW9uYWwgMi4wLjUgYW5kIDIuMSBkZWZpbmVkIGZyb20KIyBPbGxpdmllciBSb2JlcnQgPE9s bGl2aWVyLlJvYmVydEBrZWx0aWEuZnJtdWcuZnIubmV0PgojIERhdGU6IEZyaSwgMTIgTWF5IDE5 OTUgMTQ6MzA6MzggKzAyMDAgKE1FVCBEU1QpCiMKIyBBZGRpdGlvbmFsIDIuMiBkZWZpbmVzIGZy b20KIyBNYXJrIE11cnJheSA8bWFya0Bncm9uZGFyLnphPgojIERhdGU6IFdlZCwgNiBOb3YgMTk5 NiAwOTo0NDo1OCArMDIwMCAoTUVUKQojCiMgTW9kaWZpZWQgdG8gZW5zdXJlIHdlIHJlcGxhY2Ug LWxjIHdpdGggLWxjX3IsIGFuZAojIHRvIHB1dCBpbiBwbGFjZS1ob2xkZXJzIGZvciB2YXJpb3Vz IHNwZWNpZmljIGhpbnRzLgojIEFuZHkgRG91Z2hlcnR5IDxkb3VnaGVyYUBsYWZheWV0dGUuZWR1 PgojIERhdGU6IFR1ZSBNYXIgMTAgMTY6MDc6MDAgRVNUIDE5OTgKIwojIFN1cHBvcnQgZm9yIEZy ZWVCU0QvRUxGCiMgT2xsaXZpZXIgUm9iZXJ0IDxyb2JlcnRvQGtlbHRpYS5mcmVlbml4LmZyPgoj IERhdGU6IFdlZCBTZXAgIDIgMTY6MjI6MTIgQ0VTVCAxOTk4CiMKIyBUaGUgdHdvIGZsYWdzICIt ZnBpYyAtRFBJQyIgYXJlIHVzZWQgdG8gaW5kaWNhdGUgYQojIHdpbGwtYmUtc2hhcmVkIG9iamVj dC4gIENvbmZpZ3VyZSB3aWxsIGd1ZXNzIHRoZSAtZnBpYywgKGFuZCB0aGUKIyAtRFBJQyBpcyBu b3QgdXNlZCBieSBwZXJsIHByb3BlcikgYnV0IHRoZSBmdWxsIGRlZmluZSBpcyBpbmNsdWRlZCB0 byAKIyBiZSBjb25zaXN0ZW50IHdpdGggdGhlIEZyZWVCU0QgZ2VuZXJhbCBzaGFyZWQgbGlicyBi dWlsZGluZyBwcm9jZXNzLgojCiMgc2V0cmV1aWQgYW5kIGZyaWVuZHMgYXJlIGluaGVyZW50bHkg YnJva2VuIGluIGFsbCB2ZXJzaW9ucyBvZiBGcmVlQlNECiMgYmVmb3JlIDIuMS1jdXJyZW50IChi ZWZvcmUgYXBwcm94IGRhdGUgNC8xNS85NSkuIEl0IGlzIGZpeGVkIGluIDIuMC41CiMgYW5kIHdo YXQtd2lsbC1iZS0yLjEKIwoKY2FzZSAiJG9zdmVycyIgaW4KMC4qfDEuMCopCgl1c2VkbD0iJHVu ZGVmIgoJOzsKMS4xKikKCW1hbGxvY3R5cGU9J3ZvaWQgKicKCWdyb3Vwc3R5cGU9J2ludCcKCWRf c2V0cmVnaWQ9J3VuZGVmJwoJZF9zZXRyZXVpZD0ndW5kZWYnCglkX3NldHJnaWQ9J3VuZGVmJwoJ ZF9zZXRydWlkPSd1bmRlZicKCTs7CjIuMC1yZWxlYXNlKikKCWRfc2V0cmVnaWQ9J3VuZGVmJwoJ ZF9zZXRyZXVpZD0ndW5kZWYnCglkX3NldHJnaWQ9J3VuZGVmJwoJZF9zZXRydWlkPSd1bmRlZicK CTs7CiMKIyBUcnlpbmcgdG8gY292ZXIgMi4wLjUsIDIuMS1jdXJyZW50IGFuZCBmdXR1cmUgMi4x LzIuMgojIEl0IGRvZXMgbm90IGNvdmVydCBhbGwgMi4xLWN1cnJlbnQgdmVyc2lvbnMgYXMgdGhl IG91dHB1dCBvZiB1bmFtZQojIGNoYW5nZWQgYSBmZXcgdGltZXMuCiMKIyBFdmVuIHRob3VnaCBz ZXRldWlkL3NldGVnaWQgYXJlIGF2YWlsYWJsZSwgdGhleSd2ZSBiZWVuIHR1cm5lZCBvZmYKIyBi ZWNhdXNlIHBlcmwgaXNuJ3QgY29kZWQgd2l0aCBzYXZlZCBzZXRbdWddaWQgdmFyaWFibGVzIGlu IG1pbmQuCiMgSW4gYWRkaXRpb24sIGEgc21hbGwgcGF0Y2ggaXMgcmVxdWlyZWQgdG8gc3VpZHBl cmwgdG8gYXZvaWQgYSBzZWN1cml0eQojIHByb2JsZW0gd2l0aCBGcmVlQlNELgojCjIuMC41Knwy LjAtYnVpbHQqfDIuMSopCiAJdXNldmZvcms9J3RydWUnCgljYXNlICIkdXNlbXltYWxsb2MiIGlu CgkgICAgIiIpIHVzZW15bWFsbG9jPSduJwoJICAgICAgICA7OwoJZXNhYwoJZF9zZXRyZWdpZD0n ZGVmaW5lJwoJZF9zZXRyZXVpZD0nZGVmaW5lJwoJZF9zZXRlZ2lkPSd1bmRlZicKCWRfc2V0ZXVp ZD0ndW5kZWYnCgl0ZXN0IC1yIC4vYnJva2VuLWRiLm1zZyAmJiAuIC4vYnJva2VuLWRiLm1zZwoJ OzsKIwojIDIuMiBhbmQgYWJvdmUgaGF2ZSBwaGttYWxsb2MoMykuCiMgZG9uJ3QgdXNlIC1sbWFs bG9jIChtYXliZSB0aGVyZSdzIGFuIG9sZCBvbmUgZnJvbSAxLjEuNS4xIGZsb2F0aW5nIGFyb3Vu ZCkKMi4yKikKIAl1c2V2Zm9yaz0ndHJ1ZScKCWNhc2UgIiR1c2VteW1hbGxvYyIgaW4KCSAgICAi IikgdXNlbXltYWxsb2M9J24nCgkgICAgICAgIDs7Cgllc2FjCglsaWJzd2FudGVkPWBlY2hvICRs aWJzd2FudGVkIHwgc2VkICdzLyBtYWxsb2MgLyAvJ2AKCWxpYnN3YW50ZWQ9YGVjaG8gJGxpYnN3 YW50ZWQgfCBzZWQgJ3MvIGJpbmQgLyAvJ2AKCSMgaWNvbnYgZ29uZSBpbiBQZXJsIDUuOC4xLCBi dXQgaWYgc29tZW9uZSBjb21waWxlcyA1LjguMCBvciBlYXJsaWVyLgoJbGlic3dhbnRlZD1gZWNo byAkbGlic3dhbnRlZCB8IHNlZCAncy8gaWNvbnYgLyAvJ2AKCWRfc2V0cmVnaWQ9J2RlZmluZScK CWRfc2V0cmV1aWQ9J2RlZmluZScKCWRfc2V0ZWdpZD0nZGVmaW5lJwoJZF9zZXRldWlkPSdkZWZp bmUnCgkjIGRfZG9zdWlkPSdkZWZpbmUnICMgT2Jzb2xldGUuCgk7OwoqKQl1c2V2Zm9yaz0ndHJ1 ZScKCWNhc2UgIiR1c2VteW1hbGxvYyIgaW4KCSAgICAiIikgdXNlbXltYWxsb2M9J24nCgkgICAg ICAgIDs7Cgllc2FjCglsaWJzd2FudGVkPWBlY2hvICRsaWJzd2FudGVkIHwgc2VkICdzLyBtYWxs b2MgLyAvJ2AKCTs7CmVzYWMKCiMgRHluYW1pYyBMb2FkaW5nIGZsYWdzIGhhdmUgbm90IGNoYW5n ZWQgbXVjaCwgc28gdGhleSBhcmUgc2VwYXJhdGVkCiMgb3V0IGhlcmUgdG8gYXZvaWQgZHVwbGlj YXRpbmcgdGhlbSBldmVyeXdoZXJlLgpjYXNlICIkb3N2ZXJzIiBpbgowLip8MS4wKikgOzsKCjEq fDIqKQljY2NkbGZsYWdzPSctRFBJQyAtZnBpYycKCWxkZGxmbGFncz0iLUJzaGFyZWFibGUgJGxk ZGxmbGFncyIKCTs7CgozKnw0Knw1Knw2KikKICAgICAgICBvYmpmb3JtYXQ9YC91c3IvYmluL29i amZvcm1hdGAKICAgICAgICBpZiBbIHgkb2JqZm9ybWF0ID0geGFvdXQgXTsgdGhlbgogICAgICAg ICAgICBpZiBbIC1lIC91c3IvbGliL2FvdXQgXTsgdGhlbgogICAgICAgICAgICAgICAgbGlicHRo PSIvdXNyL2xpYi9hb3V0IC91c3IvbG9jYWwvbGliIC91c3IvbGliIgogICAgICAgICAgICAgICAg Z2xpYnB0aD0iL3Vzci9saWIvYW91dCAvdXNyL2xvY2FsL2xpYiAvdXNyL2xpYiIKICAgICAgICAg ICAgZmkKICAgICAgICAgICAgbGRkbGZsYWdzPSctQnNoYXJlYWJsZScKICAgICAgICBlbHNlCiAg ICAgICAgICAgIGxpYnB0aD0iL3Vzci9saWIgL3Vzci9sb2NhbC9saWIiCiAgICAgICAgICAgIGds aWJwdGg9Ii91c3IvbGliIC91c3IvbG9jYWwvbGliIgogICAgICAgICAgICBsZGZsYWdzPSItV2ws LUUgIgogICAgICAgICAgICBsZGRsZmxhZ3M9Ii1zaGFyZWQgIgogICAgICAgIGZpCiAgICAgICAg Y2NjZGxmbGFncz0nLURQSUMgLWZQSUMnCiAgICAgICAgOzsKKikKICAgICAgIGxpYnB0aD0iL3Vz ci9saWIgL3Vzci9sb2NhbC9saWIiCiAgICAgICBnbGlicHRoPSIvdXNyL2xpYiAvdXNyL2xvY2Fs L2xpYiIKICAgICAgIGxkZmxhZ3M9Ii1XbCwtRSAiCiAgICAgICAgbGRkbGZsYWdzPSItc2hhcmVk ICIKICAgICAgICBjY2NkbGZsYWdzPSctRFBJQyAtZlBJQycKICAgICAgIDs7CmVzYWMKCmNhc2Ug IiRvc3ZlcnMiIGluCjAqfDEqfDIqfDMqKSA7OwoKKikKCWNjZmxhZ3M9IiR7Y2NmbGFnc30gLURI QVNfRlBTRVRNQVNLIC1ESEFTX0ZMT0FUSU5HUE9JTlRfSCIKCWlmIC91c3IvYmluL2ZpbGUgLUwg L3Vzci9saWIvbGliYy5zbyB8IC91c3IvYmluL2dyZXAgLXZxICJub3Qgc3RyaXBwZWQiIDsgdGhl bgoJICAgIHVzZW5tPWZhbHNlCglmaQogICAgICAgIDs7CmVzYWMKCmNhdCA8PCdFT00nID4mNAoK U29tZSB1c2VycyBoYXZlIHJlcG9ydGVkIHRoYXQgQ29uZmlndXJlIGhhbHRzIHdoZW4gdGVzdGlu ZyBmb3IKdGhlIE9fTk9OQkxPQ0sgc3ltYm9sIHdpdGggYSBzeW50YXggZXJyb3IuICBUaGlzIGlz IGFwcGFyZW50bHkgYQpzaCBlcnJvci4gIFJlcnVubmluZyBDb25maWd1cmUgd2l0aCBrc2ggYXBw YXJlbnRseSBmaXhlcyB0aGUKcHJvYmxlbS4gIFRyeQoJa3NoIENvbmZpZ3VyZSBbeW91ciBvcHRp b25zXQoKRU9NCgojIEZyb206IEFudG9uIEJlcmV6aW4gPHRvYmV6QHBsYWIua3UuZGs+CiMgVG86 IHBlcmw1LXBvcnRlcnNAcGVybC5vcmcKIyBTdWJqZWN0OiBbUEFUQ0ggNS4wMDVfNTRdIENvbmZp Z3VyZSAtIGhpbnRzL2ZyZWVic2Quc2ggc2lnbmFsIGhhbmRsZXIgdHlwZQojIERhdGU6IDMwIE5v diAxOTk4IDE5OjQ2OjI0ICswMTAwCiMgTWVzc2FnZS1JRDogPDg2NHNyaGh2Y3YuZnNmQGxpb24u cGxhYi5rdS5kaz4KCnNpZ25hbF90PSd2b2lkJwpkX3ZvaWRzaWc9J2RlZmluZScKCiMgc2V0IGxp YnBlcmwuc28uWC5YIGZvciAyLjIuWApjYXNlICIkb3N2ZXJzIiBpbgoyLjIqKQogICAgIyB1bmZv cnR1bmF0ZWx5IHRoaXMgY29kZSBnZXRzIGV4ZWN1dGVkIGJlZm9yZQogICAgIyB0aGUgZXF1aXZh bGVudCBpbiB0aGUgbWFpbiBDb25maWd1cmUgc28gd2UgY29weSBhIGxpdHRsZQogICAgIyBmcm9t IENvbmZpZ3VyZSBYWFggQ29uZmlndXJlIHNob3VsZCBiZSBmaXhlZC4KICAgIGlmICR0ZXN0IC1y ICRzcmMvcGF0Y2hsZXZlbC5oO3RoZW4KICAgICAgIHBhdGNobGV2ZWw9YGF3ayAnL2RlZmluZVsg CV0rUEVSTF9WRVJTSU9OLyB7cHJpbnQgJDN9JyAkc3JjL3BhdGNobGV2ZWwuaGAKICAgICAgIHN1 YnZlcnNpb249YGF3ayAnL2RlZmluZVsgCV0rUEVSTF9TVUJWRVJTSU9OLyB7cHJpbnQgJDN9JyAk c3JjL3BhdGNobGV2ZWwuaGAKICAgIGVsc2UKICAgICAgIHBhdGNobGV2ZWw9MAogICAgICAgc3Vi dmVyc2lvbj0wCiAgICBmaQogICAgbGlicGVybD0ibGlicGVybC5zby4kcGF0Y2hsZXZlbC4kc3Vi dmVyc2lvbiIKICAgIHVuc2V0IHBhdGNobGV2ZWwKICAgIHVuc2V0IHN1YnZlcnNpb24KICAgIDs7 CmVzYWMKCiMgVGhpcyBzY3JpcHQgVVUvdXNldGhyZWFkcy5jYnUgd2lsbCBnZXQgJ2NhbGxlZC1i YWNrJyBieSBDb25maWd1cmUgCiMgYWZ0ZXIgaXQgaGFzIHByb21wdGVkIHRoZSB1c2VyIGZvciB3 aGV0aGVyIHRvIHVzZSB0aHJlYWRzLgpjYXQgPiBVVS91c2V0aHJlYWRzLmNidSA8PCdFT0NCVScK Y2FzZSAiJHVzZXRocmVhZHMiIGluCiRkZWZpbmV8dHJ1ZXxbeVldKikKICAgICAgICBsY19yPWAv c2Jpbi9sZGNvbmZpZyAtcnxncmVwICc6LWxjX3InfGF3ayAne3ByaW50ICRORn0nfHNlZCAtbiAn JHAnYAogICAgICAgIGNhc2UgIiRvc3ZlcnMiIGluICAKCTAqfDEqfDIuMCp8Mi4xKikgICBjYXQg PDxFT00gPiY0CkkgZGlkIG5vdCBrbm93IHRoYXQgRnJlZUJTRCAkb3N2ZXJzIHN1cHBvcnRzIFBP U0lYIHRocmVhZHMuCgpGZWVsIGZyZWUgdG8gdGVsbCBwZXJsYnVnQHBlcmwub3JnIG90aGVyd2lz ZS4KRU9NCgkgICAgICBleGl0IDEKCSAgICAgIDs7CgogICAgICAgIDIuMi5bMC03XSopCiAgICAg ICAgICAgICAgY2F0IDw8RU9NID4mNApQT1NJWCB0aHJlYWRzIGFyZSBub3Qgc3VwcG9ydGVkIHdl bGwgYnkgRnJlZUJTRCAkb3N2ZXJzLgoKUGxlYXNlIGNvbnNpZGVyIHVwZ3JhZGluZyB0byBhdCBs ZWFzdCBGcmVlQlNEIDIuMi44LApvciBwcmVmZXJhYmx5IHRvIHRoZSBtb3N0IHJlY2VudCAtUkVM RUFTRSBvciAtU1RBQkxFCnZlcnNpb24gKHNlZSBodHRwOi8vd3d3LmZyZWVic2Qub3JnL3JlbGVh c2VzLykuCgooV2hpbGUgMi4yLjcgZG9lcyBoYXZlIHB0aHJlYWRzLCBpdCBoYXMgc29tZSBwcm9i bGVtcwogd2l0aCB0aGUgY29tYmluYXRpb24gb2YgdGhyZWFkcyBhbmQgcGlwZXMgYW5kIHRoZXJl Zm9yZQogbWFueSBQZXJsIHRlc3RzIHdpbGwgZWl0aGVyIGhhbmcgb3IgZmFpbC4pCkVPTQoJICAg ICAgZXhpdCAxCgkgICAgICA7OwoKCVszLTVdLiopCgkgICAgICBpZiBbICEgLXIgIiRsY19yIiBd OyB0aGVuCgkgICAgICBjYXQgPDxFT00gPiY0ClBPU0lYIHRocmVhZHMgc2hvdWxkIGJlIHN1cHBv cnRlZCBieSBGcmVlQlNEICRvc3ZlcnMgLS0KYnV0IHlvdXIgc3lzdGVtIGlzIG1pc3NpbmcgdGhl IHNoYXJlZCBsaWJjX3IuCigvc2Jpbi9sZGNvbmZpZyAtciBkb2Vzbid0IGZpbmQgYW55KS4KCkNv bnNpZGVyIHVzaW5nIHRoZSBsYXRlc3QgU1RBQkxFIHJlbGVhc2UuCkVPTQoJCSBleGl0IDEKCSAg ICAgIGZpCgkgICAgICAjIDUwMDAxNiBpcyB0aGUgZmlyc3Qgb3NyZWxkYXRlIGluIHdoaWNoIG9u ZSBjb3VsZAoJICAgICAgIyBqdXN0IGxpbmsgYWdhaW5zdCBsaWJjX3Igd2l0aG91dCBkaXNwb3Np bmcgb2YgbGliYwoJICAgICAgIyBhdCB0aGUgc2FtZSB0aW1lLiAgNTAwMDE2IC4uLiB1cCB0byB3 aGF0ZXZlciBpdCB3YXMKCSAgICAgICMgb24gdGhlIDMxc3Qgb2YgQXVndXN0IDIwMDMgY2FuIHN0 aWxsIGJlIHVzZWQgd2l0aCAtcHRocmVhZCwKCSAgICAgICMgYnV0IGl0IGlzIG5vdCBuZWNlc3Nh cnkuCgoJICAgICAgIyBBbnRvbiBCZXJlemluIHNheXMgdGhhdCBwb3N0IDUwMHNvbWV0aGluZyB3 ZSdyZSB3cm9uZyB0byBiZQoJICAgICAgIyB0byBiZSB1c2luZyAtbGNfciwgYW5kIHNob3VsZCBq dXN0IGJlIHVzaW5nIC1wdGhyZWFkIG9uIHRoZQoJICAgICAgIyBsaW5rZXIgbGluZS4KCSAgICAg ICMgU28gcHJlc3VtYWJseSByZWFsbHkgd2Ugc2hvdWxkIGJlIGNoZWNraW5nIHRoYXQgJG9zdmVy IGlzIDUuKikKCSAgICAgICMgYW5kIHRoYXQgYC9zYmluL3N5c2N0bCAtbiBrZXJuLm9zcmVsZGF0 ZWAgLWdlIDUwMDAxNgoJICAgICAgIyBvciAtbHQgNTAwc29tZXRoaW5nIGFuZCBvbmx5IGluIHRo YXQgcmFuZ2Ugbm90IGRvaW5nIHRoaXM6CgkgICAgICBsZGZsYWdzPSItcHRocmVhZCAkbGRmbGFn cyIKCgkgICAgICAjIEJvdGggaW4gNC54IGFuZCA1LnggZ2V0aG9zdGJ5YWRkcl9yIGV4aXN0cyBi dXQKCSAgICAgICMgaXQgaXMgIlRlbXBvcmFyeSBmdW5jdGlvbiwgbm90IHRocmVhZHNhZmUiLi4u CgkgICAgICAjIFByZXN1bWFibHkgZWFybGllciBpdCBkaWRuJ3QgZXZlbiBleGlzdC4KCSAgICAg IGRfZ2V0aG9zdGJ5YWRkcl9yPSJ1bmRlZiIKCSAgICAgIGRfZ2V0aG9zdGJ5YWRkcl9yX3Byb3Rv PSIwIgoJICAgICAgOzsKCgkqKQoJICAgICAgIyA3LnggZG9lc24ndCBpbnN0YWxsIGxpYmNfciBi eSBkZWZhdWx0LCBhbmQgQ29uZmlndXJlCgkgICAgICAjIHdvdWxkIGZhaWwgaW4gdGhlIGNvZGUg Zm9sbG93aW5nCgkgICAgICAjCgkgICAgICAjIGdldGhvc3RieWFkZHJfcigpIGFwcGVhcnMgdG8g aGF2ZSBiZWVuIGltcGxlbWVudGVkIGluIDYueCsKCSAgICAgIGxkZmxhZ3M9Ii1wdGhyZWFkICRs ZGZsYWdzIgoJICAgICAgOzsKCgllc2FjCgogICAgICAgIGNhc2UgIiRvc3ZlcnMiIGluCiAgICAg ICAgWzEtNF0qKQoJICAgIHNldCBgZWNobyBYICIkbGlic3dhbnRlZCAifCBzZWQgLWUgJ3MvIGMg LyBjX3IgLydgCgkgICAgc2hpZnQKCSAgICBsaWJzd2FudGVkPSIkKiIKCSAgICA7OwogICAgICAg ICopCgkgICAgc2V0IGBlY2hvIFggIiRsaWJzd2FudGVkICJ8IHNlZCAtZSAncy8gYyAvLydgCgkg ICAgc2hpZnQKCSAgICBsaWJzd2FudGVkPSIkKiIKCSAgICA7OwoJZXNhYwoJICAgIAoJIyBDb25m aWd1cmUgd2lsbCBwcm9iYWJseSBwaWNrIHRoZSB3cm9uZyBsaWJjIHRvIHVzZSBmb3Igbm0gc2Nh bi4KCSMgVGhlIHNhZmVzdCBxdWljay1maXggaXMganVzdCB0byBub3QgdXNlIG5tIGF0IGFsbC4u LgoJdXNlbm09ZmFsc2UKCiAgICAgICAgY2FzZSAiJG9zdmVycyIgaW4KICAgICAgICAyLjIuOCop CiAgICAgICAgICAgICMgLi4uIGJ1dCB0aGlzIGRvZXMgbm90IGFwcGx5IGZvciAyLjIuOCAtIHdl IGtub3cgaXQncyBzYWZlCiAgICAgICAgICAgIGxpYmM9IiRsY19yIgogICAgICAgICAgICB1c2Vu bT10cnVlCiAgICAgICAgICAgOzsKICAgICAgICBlc2FjCgogICAgICAgIHVuc2V0IGxjX3IKCgkj IEV2ZW4gd2l0aCB0aGUgbWFsbG9jIG11dGV4ZXMgdGhlIFBlcmwgbWFsbG9jIGRvZXMgbm90Cgkj IHNlZW0gdG8gYmUgdGhyZWFkc2FmZSBpbiBGcmVlQlNEPwoJY2FzZSAiJHVzZW15bWFsbG9jIiBp bgoJJycpIHVzZW15bWFsbG9jPW4gOzsKCWVzYWMKZXNhYwpFT0NCVQoKIyBtYWxsb2Mgd3JhcCB3 b3JrcwpjYXNlICIkdXNlbWFsbG9jd3JhcCIgaW4KJycpIHVzZW1hbGxvY3dyYXA9J2RlZmluZScg OzsKZXNhYwoKIyBYWFggVW5kZXIgRnJlZUJTRCA2LjAgKGFuZCBwcm9iYWJseSBtb3N0IG90aGVy IHNpbWlsYXIgdmVyc2lvbnMpCiMgUGVybF9kaWUoTlVMTCkgZ2VuZXJhdGVzIGEgd2FybmluZzoK IyAgICBwcF9zeXMuYzo0OTE6IHdhcm5pbmc6IG51bGwgZm9ybWF0IHN0cmluZwojIENvbmZpZ3Vy ZSBzdXBwb3NlZGVseSB0ZXN0cyBmb3IgdGhpcywgYnV0IGFwcGFyZW50bHkgdGhlIHRlc3QgZG9l c24ndAojIHdvcmsuICBWb2x1bnRlZXJzIHdpdGggRnJlZUJTRCBhcmUgbmVlZGVkIHRvIGltcHJv dmluZyB0aGUgQ29uZmlndXJlIHRlc3QuCiMgTWVhbndoaWxlLCB0aGUgZm9sbG93aW5nIHdvcmth cm91bmQgc2hvdWxkIGJlIHNhZmUgb24gYWxsIHZlcnNpb25zCiMgb2YgRnJlZUJTRC4KZF9wcmlu dGZfZm9ybWF0X251bGw9J3VuZGVmJwo=', 'openbsd' => 'IyBoaW50cy9vcGVuYnNkLnNoCiMKIyBoaW50cyBmaWxlIGZvciBPcGVuQlNEOyBUb2RkIE1pbGxl ciA8bWlsbGVydEBvcGVuYnNkLm9yZz4KIyBFZGl0ZWQgdG8gYWxsb3cgQ29uZmlndXJlIGNvbW1h bmQtbGluZSBvdmVycmlkZXMgYnkKIyAgQW5keSBEb3VnaGVydHkgPGRvdWdoZXJhQGxhZmF5ZXR0 ZS5lZHU+CiMKIyBUbyBidWlsZCB3aXRoIGRpc3RyaWJ1dGlvbiBwYXRocywgdXNlOgojCS4vQ29u ZmlndXJlIC1kZXMgLURvcGVuYnNkX2Rpc3RyaWJ1dGlvbj1kZWZpbmVkCiMKCiMgSW4gT3BlbkJT RCA+IDMuNywgdXNlIHBlcmwncyBtYWxsb2MgW3BlcmwgIzc1NzQyXQpjYXNlICIkb3N2ZXJzIiBp bgozLls4OV0qfFs0LTldKikKICAgIHRlc3QgIiR1c2VteW1hbGxvYyIgfHwgdXNlbXltYWxsb2M9 eQogICAgOzsKZXNhYwoKIyBtYWxsb2Mgd3JhcCB3b3JrcwpjYXNlICIkdXNlbWFsbG9jd3JhcCIg aW4KJycpIHVzZW1hbGxvY3dyYXA9J2RlZmluZScgOzsKZXNhYwoKIyBDdXJyZW50bHksIHZmb3Jr KDIpIGlzIG5vdCBhIHJlYWwgd2luIG92ZXIgZm9yaygyKS4KdXNldmZvcms9IiR1bmRlZiIKCiMg SW4gT3BlbkJTRCA8IDMuMywgdGhlIHNldHJlP1t1Z11pZCgpIGFyZSBlbXVsYXRlZCB1c2luZyB0 aGUKIyBfUE9TSVhfU0FWRURfSURTIGZ1bmN0aW9uYWxpdHkgd2hpY2ggZG9lcyBub3QgaGF2ZSB0 aGUgc2FtZQojIHNlbWFudGljcyBhcyA0LjNCU0QuICBTdGFydGluZyB3aXRoIE9wZW5CU0QgMy4z LCB0aGUgb3JpZ2luYWwKIyBzZW1hbnRpY3MgaGF2ZSBiZWVuIHJlc3RvcmVkLgpjYXNlICIkb3N2 ZXJzIiBpbgpbMC0yXS4qfDMuWzAtMl0pCglkX3NldHJlZ2lkPSR1bmRlZgoJZF9zZXRyZXVpZD0k dW5kZWYKCWRfc2V0cmdpZD0kdW5kZWYKCWRfc2V0cnVpZD0kdW5kZWYKZXNhYwoKIwojIE5vdCBh bGwgcGxhdGZvcm1zIHN1cHBvcnQgZHluYW1pYyBsb2FkaW5nLi4uCiMgRm9yIHRoZSBjYXNlIG9m ICIkb3BlbmJzZF9kaXN0cmlidXRpb24iLCB0aGUgaGludHMgZmlsZQojIG5lZWRzIHRvIGtub3cg d2hldGhlciB3ZSBhcmUgdXNpbmcgZHluYW1pYyBsb2FkaW5nIHNvIHRoYXQKIyBpdCBjYW4gc2V0 IHRoZSBsaWJwZXJsIG5hbWUgYXBwcm9wcmlhdGVseS4KIyBBbGxvdyBjb21tYW5kIGxpbmUgb3Zl cnJpZGVzLgojCkFSQ0g9YGFyY2ggfCBzZWQgJ3MvXk9wZW5CU0QuLy8nYApjYXNlICIke0FSQ0h9 LSR7b3N2ZXJzfSIgaW4KYWxwaGEtMi5bMC04XXxtaXBzLTIuWzAtOF18cG93ZXJwYy0yLlswLTdd fG04OGstKnxocHBhLSp8dmF4LSopCgl0ZXN0IC16ICIkdXNlZGwiICYmIHVzZWRsPSR1bmRlZgoJ OzsKKikKCXRlc3QgLXogIiR1c2VkbCIgJiYgdXNlZGw9JGRlZmluZQoJIyBXZSB1c2UgLWZQSUMg aGVyZSBiZWNhdXNlIC1mcGljIGlzICpOT1QqIGVub3VnaCBmb3Igc29tZSBvZiB0aGUKCSMgZXh0 ZW5zaW9ucyBsaWtlIFRrIG9uIHNvbWUgT3BlbkJTRCBwbGF0Zm9ybXMgKGllOiBzcGFyYykKCWNj Y2RsZmxhZ3M9Ii1EUElDIC1mUElDICRjY2NkbGZsYWdzIgoJY2FzZSAiJG9zdmVycyIgaW4KCVsw MV0uKnwyLlswLTddfDIuWzAtN10uKikKCQlsZGRsZmxhZ3M9Ii1Cc2hhcmVhYmxlICRsZGRsZmxh Z3MiCgkJOzsKCTIuWzgtOV18My4wKQoJCWxkPSR7Y2M6LWNjfQoJCWxkZGxmbGFncz0iLXNoYXJl ZCAtZlBJQyAkbGRkbGZsYWdzIgoJCTs7CgkqKSAjIGZyb20gMy4xIG9ud2FyZHMKCQlsZD0ke2Nj Oi1jY30KCQlsZGRsZmxhZ3M9Ii1zaGFyZWQgLWZQSUMgJGxkZGxmbGFncyIKCQlsaWJzd2FudGVk PWBlY2hvICRsaWJzd2FudGVkIHwgc2VkICdzLyBkbCAvIC8nYAoJCTs7Cgllc2FjCgoJIyBXZSBu ZWVkIHRvIGZvcmNlIGxkIHRvIGV4cG9ydCBzeW1ib2xzIG9uIEVMRiBwbGF0Zm9ybXMuCgkjIFdp dGhvdXQgdGhpcywgZGxvcGVuKCkgaXMgY3JpcHBsZWQuCglFTEY9YCR7Y2M6LWNjfSAtZE0gLUUg LSA8L2Rldi9udWxsIHwgZ3JlcCBfX0VMRl9fYAoJdGVzdCAtbiAiJEVMRiIgJiYgbGRmbGFncz0i LVdsLC1FICRsZGZsYWdzIgoJOzsKZXNhYwoKIwojIFR3ZWFrcyBmb3IgdmFyaW91cyB2ZXJzaW9u cyBvZiBPcGVuQlNECiMKY2FzZSAiJG9zdmVycyIgaW4KMi41KQoJIyBPcGVuQlNEIDIuNSBoYXMg YnJva2VuIG9kYm0gc3VwcG9ydAoJaV9kYm09JHVuZGVmCgk7Owplc2FjCgojIE9wZW5CU0QgZG9l c24ndCBuZWVkIGxpYmNyeXB0IGJ1dCBtYW55IGZvbGtzIGtlZXAgYSBzdHViIGxpYgojIGFyb3Vu ZCBmb3Igb2xkIE5ldEJTRCBiaW5hcmllcy4KbGlic3dhbnRlZD1gZWNobyAkbGlic3dhbnRlZCB8 IHNlZCAncy8gY3J5cHQgLyAvJ2AKCiMgQ29uZmlndXJlIGNhbid0IGZpZ3VyZSB0aGlzIG91dCBu b24taW50ZXJhY3RpdmVseQpkX3N1aWRzYWZlPSRkZWZpbmUKCiMgY2MgaXMgZ2NjIHNvIHdlIGNh biBkbyBiZXR0ZXIgdGhhbiAtTwojIEFsbG93IGEgY29tbWFuZC1saW5lIG92ZXJyaWRlLCBzdWNo IGFzIC1Eb3B0aW1pemU9LWcKY2FzZSAke0FSQ0h9IGluCm04OGspCiAgIG9wdGltaXplPSctTzAn CiAgIDs7CmhwcGEpCiAgIG9wdGltaXplPSctTzAnCiAgIDs7CiopCiAgIHRlc3QgIiRvcHRpbWl6 ZSIgfHwgb3B0aW1pemU9Jy1PMicKICAgOzsKZXNhYwoKIyBUaGlzIHNjcmlwdCBVVS91c2V0aHJl YWRzLmNidSB3aWxsIGdldCAnY2FsbGVkLWJhY2snIGJ5IENvbmZpZ3VyZSAKIyBhZnRlciBpdCBo YXMgcHJvbXB0ZWQgdGhlIHVzZXIgZm9yIHdoZXRoZXIgdG8gdXNlIHRocmVhZHMuCmNhdCA+IFVV L3VzZXRocmVhZHMuY2J1IDw8J0VPQ0JVJwpjYXNlICIkdXNldGhyZWFkcyIgaW4KJGRlZmluZXx0 cnVlfFt5WV0qKQoJIyBhbnkgb3BlbmJzZCB2ZXJzaW9uIGRlcGVuZGVuY2llcyB3aXRoIHB0aHJl YWRzPwoJY2NmbGFncz0iLXB0aHJlYWQgJGNjZmxhZ3MiCglsZGZsYWdzPSItcHRocmVhZCAkbGRm bGFncyIKCWNhc2UgIiRvc3ZlcnMiIGluCglbMC0yXS4qfDMuWzAtMl0pCgkJIyBDaGFuZ2UgZnJv bSAtbGMgdG8gLWxjX3IKCQlzZXQgYGVjaG8gIlggJGxpYnN3YW50ZWQgIiB8IHNlZCAncy8gYyAv IGNfciAvJ2AKCQlzaGlmdAoJCWxpYnN3YW50ZWQ9IiQqIgoJOzsKCWVzYWMKCWNhc2UgIiRvc3Zl cnMiIGluCglbMDEyXS4qfDMuWzAtNl0pCiAgICAgICAgCSMgQnJva2VuIGF0IGxlYXN0IHVwIHRv IE9wZW5CU0QgMy42LCB3ZSdsbCBzZWUgYWJvdXQgMy43CgkJZF9nZXRzZXJ2YnluYW1lX3I9JHVu ZGVmIDs7Cgllc2FjCmVzYWMKRU9DQlUKCiMgVGhpcyBzY3JpcHQgVVUvdXNlNjRiaXRpbnQuY2J1 IHdpbGwgZ2V0ICdjYWxsZWQtYmFjaycgYnkgQ29uZmlndXJlIAojIGFmdGVyIGl0IGhhcyBwcm9t cHRlZCB0aGUgdXNlciBmb3Igd2hldGhlciB0byB1c2UgNjQtYml0bmVzcy4KY2F0ID4gVVUvdXNl NjRiaXRpbnQuY2J1IDw8J0VPQ0JVJwpjYXNlICIkdXNlNjRiaXRpbnQiIGluCiRkZWZpbmV8dHJ1 ZXxbeVldKikKCWVjaG8gIiAiCgllY2hvICJDaGVja2luZyBpZiB5b3VyIEMgbGlicmFyeSBoYXMg YnJva2VuIDY0LWJpdCBmdW5jdGlvbnMuLi4iID4mNAoJJGNhdCA+Y2hlY2suYyA8PEVPQ1AKI2lu Y2x1ZGUgPHN0ZGlvLmg+CnR5cGVkZWYgJHVxdWFkdHlwZSBteVVMTDsKaW50IG1haW4gKHZvaWQp CnsKICAgIHN0cnVjdCB7Cglkb3VibGUgZDsKCW15VUxMICB1OwogICAgfSAqcCwgdGVzdFtdID0g ewoJezQyOTQ5NjczMDMuMTUsIDQyOTQ5NjczMDNVTEx9LAoJezQyOTQ5NjcyOTQuMiwgIDQyOTQ5 NjcyOTRVTEx9LAoJezQyOTQ5NjcyOTUuNywgIDQyOTQ5NjcyOTVVTEx9LAoJezAuMCwgMFVMTH0K ICAgIH07CiAgICBmb3IgKHAgPSB0ZXN0OyBwLT51OyBwKyspIHsKCW15VUxMIHggPSAobXlVTEwp cC0+ZDsKCWlmICh4ICE9IHAtPnUpIHsKCSAgICBwcmludGYoImJ1Z2d5XG4iKTsKCSAgICByZXR1 cm4gMDsKCX0KICAgIH0KICAgIHByaW50Zigib2tcbiIpOwogICAgcmV0dXJuIDA7Cn0KRU9DUAoJ c2V0IGNoZWNrCglpZiBldmFsICRjb21waWxlX29rOyB0aGVuCgkgICAgbGliY3F1YWQ9YC4vY2hl Y2tgCgkgICAgZWNobyAiWW91ciBDIGxpYnJhcnkncyA2NC1iaXQgZnVuY3Rpb25zIGFyZSAkbGli Y3F1YWQuIgoJZWxzZQoJICAgIGVjaG8gIihJIGNhbid0IHNlZW0gdG8gY29tcGlsZSB0aGUgdGVz dCBwcm9ncmFtLikiCgkgICAgZWNobyAiQXNzdW1pbmcgdGhhdCB5b3VyIEMgbGlicmFyeSdzIDY0 LWJpdCBmdW5jdGlvbnMgYXJlIG9rLiIKCSAgICBsaWJjcXVhZD0ib2siCglmaQoJJHJtIC1mIGNo ZWNrLmMgY2hlY2sKCgljYXNlICIkbGliY3F1YWQiIGluCgkgICAgYnVnZ3kqKQoJCWNhdCA+JjQg PDxFT00KCioqKiBZb3UgaGF2ZSBhIEMgbGlicmFyeSB3aXRoIGJyb2tlbiA2NC1iaXQgZnVuY3Rp b25zLgoqKiogNjQtYml0IHN1cHBvcnQgZG9lcyBub3Qgd29yayByZWxpYWJseSBpbiB0aGlzIGNv bmZpZ3VyYXRpb24uCioqKiBQbGVhc2UgcmVydW4gQ29uZmlndXJlIHdpdGhvdXQgLUR1c2U2NGJp dGludCBhbmQvb3IgLUR1c2Vtb3JlYml0cy4KKioqIENhbm5vdCBjb250aW51ZSwgYWJvcnRpbmcu CgpFT00KCQlleGl0IDEKCQk7OwoJZXNhYwplc2FjCkVPQ0JVCgojIFdoZW4gYnVpbGRpbmcgaW4g dGhlIE9wZW5CU0QgdHJlZSB3ZSB1c2UgZGlmZmVyZW50IHBhdGhzCiMgVGhpcyBpcyBvbmx5IHBh cnQgb2YgdGhlIHN0b3J5LCB0aGUgcmVzdCBjb21lcyBmcm9tIGNvbmZpZy5vdmVyCmNhc2UgIiRv cGVuYnNkX2Rpc3RyaWJ1dGlvbiIgaW4KJyd8JHVuZGVmfGZhbHNlKSA7OwoqKQoJIyBXZSBwdXQg dGhpbmdzIGluIC91c3IsIG5vdCAvdXNyL2xvY2FsCglwcmVmaXg9Jy91c3InCglwcmVmaXhleHA9 Jy91c3InCglzeXNtYW49Jy91c3Ivc2hhcmUvbWFuL21hbjEnCglsaWJwdGg9Jy91c3IvbGliJwoJ Z2xpYnB0aD0nL3Vzci9saWInCgkjIExvY2FsIHRoaW5ncywgaG93ZXZlciwgZG8gZ28gaW4gL3Vz ci9sb2NhbAoJc2l0ZXByZWZpeD0nL3Vzci9sb2NhbCcKCXNpdGVwcmVmaXhleHA9Jy91c3IvbG9j YWwnCgkjIFBvcnRzIGluc3RhbGxzIG5vbi1zdGQgbGlicyBpbiAvdXNyL2xvY2FsL2xpYiBzbyBs b29rIHRoZXJlIHRvbwoJbG9jaW5jcHRoPScvdXNyL2xvY2FsL2luY2x1ZGUnCglsb2NsaWJwdGg9 Jy91c3IvbG9jYWwvbGliJwoJIyBMaW5rIHBlcmwgd2l0aCBzaGFyZWQgbGlicGVybAoJaWYgWyAi JHVzZWRsIiA9ICIkZGVmaW5lIiAtYSAtciBzaGxpYl92ZXJzaW9uIF07IHRoZW4KCQl1c2VzaHJw bGliPXRydWUKCQlsaWJwZXJsPWAuIC4vc2hsaWJfdmVyc2lvbjsgZWNobyBsaWJwZXJsLnNvLiR7 bWFqb3J9LiR7bWlub3J9YAoJZmkKCTs7CmVzYWMKCiMgZW5kCg==', 'linux' => 'IyBoaW50cy9saW51eC5zaAojIE9yaWdpbmFsIHZlcnNpb24gYnkgcnNhbmRlcnMKIyBBZGRpdGlv bmFsIHN1cHBvcnQgYnkgS2VubmV0aCBBbGJhbm93c2tpIDxramFoZHNAa2phaGRzLmNvbT4KIwoj IEVMRiBzdXBwb3J0IGJ5IEguSi4gTHUgPGhqbEBueW5leHN0LmNvbT4KIyBBZGRpdGlvbmFsIGlu Zm8gZnJvbSBOaWdlbCBIZWFkIDxuaGVhZEBFU09DLmJpdG5ldD4KIyBhbmQgS2VubmV0aCBBbGJh bm93c2tpIDxramFoZHNAa2phaGRzLmNvbT4KIwojIENvbnNvbGlkYXRlZCBieSBBbmR5IERvdWdo ZXJ0eSA8ZG91Z2hlcmFAbGFmYXlldHRlLmVkdT4KIwojIFVwZGF0ZWQgVGh1IEZlYiAgOCAxMTo1 NjoxMCBFU1QgMTk5NgoKIyBVcGRhdGVkIFRodSBNYXkgMzAgMTA6NTA6MjIgRURUIDE5OTYgYnkg PGRvdWdoZXJhQGxhZmF5ZXR0ZS5lZHU+CgojIFVwZGF0ZWQgRnJpIEp1biAyMSAxMTowNzo1NCBF RFQgMTk5NgojIE5EQk0gc3VwcG9ydCBmb3IgRUxGIHJlLWVuYWJsZWQgYnkgPGtqYWhkc0BramFo ZHMuY29tPgoKIyBObyB2ZXJzaW9uIG9mIExpbnV4IHN1cHBvcnRzIHNldHVpZCBzY3JpcHRzLgpk X3N1aWRzYWZlPSd1bmRlZicKCiMgRGViaWFuIGFuZCBSZWQgSGF0LCBhbmQgcGVyaGFwcyBvdGhl ciB2ZW5kb3JzLCBwcm92aWRlIGJvdGggcnVudGltZSBhbmQKIyBkZXZlbG9wbWVudCBwYWNrYWdl cyBmb3Igc29tZSBsaWJyYXJpZXMuICBUaGUgcnVudGltZSBwYWNrYWdlcyBjb250YWluIHNoYXJl ZAojIGxpYnJhcmllcyB3aXRoIHZlcnNpb24gaW5mb3JtYXRpb24gaW4gdGhlaXIgbmFtZXMgKGUu Zy4sIGxpYmdkYm0uc28uMS43LjMpOwojIHRoZSBkZXZlbG9wbWVudCBwYWNrYWdlcyBzdXBwbGVt ZW50IHRoaXMgd2l0aCB2ZXJzaW9ubGVzcyBzaGFyZWQgbGlicmFyaWVzCiMgKGUuZy4sIGxpYmdk Ym0uc28pLgojCiMgSWYgeW91IHdhbnQgdG8gbGluayBhZ2FpbnN0IHN1Y2ggYSBsaWJyYXJ5LCB5 b3UgbXVzdCBpbnN0YWxsIHRoZSBkZXZlbG9wbWVudAojIHZlcnNpb24gb2YgdGhlIHBhY2thZ2Uu CiMKIyBUaGVzZSBwYWNrYWdlcyB1c2UgYSAtZGV2IG5hbWluZyBjb252ZW50aW9uIGluIGJvdGgg RGViaWFuIGFuZCBSZWQgSGF0OgojICAgbGliZ2RibWcxICAobm9uLWRldmVsb3BtZW50IHZlcnNp b24gb2YgR05VIGxpYmMgMi1saW5rZWQgR0RCTSBsaWJyYXJ5KQojICAgbGliZ2RibWcxLWRldiAo ZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiBHTlUgbGliYyAyLWxpbmtlZCBHREJNIGxpYnJhcnkpCiMg U28gbWFrZSBzdXJlIHRoYXQgZm9yIGFueSBsaWJyYXJpZXMgeW91IHdpc2ggdG8gbGluayBQZXJs IHdpdGggdW5kZXIKIyBEZWJpYW4gb3IgUmVkIEhhdCB5b3UgaGF2ZSB0aGUgLWRldiBwYWNrYWdl cyBpbnN0YWxsZWQuCgojIFN1U0UgTGludXggY2FuIGJlIHVzZWQgYXMgY3Jvc3MtY29tcGlsYXRp b24gaG9zdCBmb3IgQ3JheSBYVDQgQ2F0YW1vdW50L1FrLgppZiB0ZXN0IC1kIC9vcHQveHQtcGUK dGhlbgogIGNhc2UgImBjYyAtViAyPiYxYCIgaW4KICAqY2F0YW1vdW50KikgLiBoaW50cy9jYXRh bW91bnQuc2g7IHJldHVybiA7OwogIGVzYWMKZmkKCiMgU29tZSBvcGVyYXRpbmcgc3lzdGVtcyAo ZS5nLiwgU29sYXJpcyAyLjYpIHdpbGwgbGluayB0byBhIHZlcnNpb25lZCBzaGFyZWQKIyBsaWJy YXJ5IGltcGxpY2l0bHkuICBGb3IgZXhhbXBsZSwgb24gU29sYXJpcywgYGxkIGZvby5vIC1sZ2Ri bScgd2lsbCBmaW5kIGFuCiMgYXBwcm9wcmlhdGUgdmVyc2lvbiBvZiBsaWJnZGJtLCBpZiBvbmUg aXMgYXZhaWxhYmxlOyBMaW51eCwgaG93ZXZlciwgZG9lc24ndAojIGRvIHRoZSBpbXBsaWNpdCBt YXBwaW5nLgppZ25vcmVfdmVyc2lvbmVkX3NvbGlicz0neScKCiMgQlNEIGNvbXBhdGliaWxpdHkg bGlicmFyeSBubyBsb25nZXIgbmVlZGVkCiMgJ2thZmZlJyBoYXMgYSAvdXNyL2xpYi9saWJuZXQu c28gd2hpY2ggaXMgbm90IGF0IGFsbCByZWxldmFudCBmb3IgcGVybC4KIyBiaW5kIGNhdXNlcyBp c3N1ZXMgd2l0aCBzZXZlcmFsIHJlZW50cmFudCBmdW5jdGlvbnMKc2V0IGBlY2hvIFggIiRsaWJz d2FudGVkICJ8IHNlZCAtZSAncy8gYnNkIC8gLycgLWUgJ3MvIG5ldCAvIC8nIC1lICdzLyBiaW5k IC8gLydgCnNoaWZ0CmxpYnN3YW50ZWQ9IiQqIgoKIyBEZWJpYW4gNC4wIHB1dHMgbmRibSBpbiB0 aGUgLWxnZGJtX2NvbXBhdCBsaWJyYXJ5LgpsaWJzd2FudGVkPSIkbGlic3dhbnRlZCBnZGJtX2Nv bXBhdCIKCiMgSWYgeW91IGhhdmUgZ2xpYmMsIHRoZW4gcmVwb3J0IHRoZSB2ZXJzaW9uIGZvciAu L215Y29uZmlnIGJ1ZyByZXBvcnRpbmcuCiMgKENvbmZpZ3VyZSBkb2Vzbid0IG5lZWQgdG8ga25v dyB0aGUgc3BlY2lmaWMgdmVyc2lvbiBzaW5jZSBpdCBqdXN0IHVzZXMKIyBnY2MgdG8gbG9hZCB0 aGUgbGlicmFyeSBmb3IgYWxsIHRlc3RzLikKIyBXZSBkb24ndCB1c2UgX19HTElCQ19fIGFuZCAg X19HTElCQ19NSU5PUl9fIGJlY2F1c2UgdGhleQojIGFyZSBpbnN1ZmZpY2llbnRseSBwcmVjaXNl IHRvIGRpc3Rpbmd1aXNoIHRoaW5ncyBsaWtlCiMgbGliYy0yLjAuNiBhbmQgbGliYy0yLjAuNy4K aWYgdGVzdCAtTCAvbGliL2xpYmMuc28uNjsgdGhlbgogICAgbGliYz1gbHMgLWwgL2xpYi9saWJj LnNvLjYgfCBhd2sgJ3twcmludCAkTkZ9J2AKICAgIGxpYmM9L2xpYi8kbGliYwpmaQoKIyBDb25m aWd1cmUgbWF5IGZhaWwgdG8gZmluZCBsc3RhdCgpIHNpbmNlIGl0J3MgYSBzdGF0aWMvaW5saW5l CiMgZnVuY3Rpb24gaW4gPHN5cy9zdGF0Lmg+LgpkX2xzdGF0PWRlZmluZQoKIyBtYWxsb2Mgd3Jh cCB3b3JrcwpjYXNlICIkdXNlbWFsbG9jd3JhcCIgaW4KJycpIHVzZW1hbGxvY3dyYXA9J2RlZmlu ZScgOzsKZXNhYwoKIyBUaGUgc3lzdGVtIG1hbGxvYygpIGlzIGFib3V0IGFzIGZhc3QgYW5kIGFz IGZydWdhbCBhcyBwZXJsJ3MuCiMgU2luY2UgdGhlIHN5c3RlbSBtYWxsb2MoKSBoYXMgYmVlbiB0 aGUgZGVmYXVsdCBzaW5jZSBhdCBsZWFzdAojIDUuMDAxLCB3ZSBtaWdodCBhcyB3ZWxsIGxlYXZl IGl0IHRoYXQgd2F5LiAgLS1BRCAgMTAgSmFuIDIwMDIKY2FzZSAiJHVzZW15bWFsbG9jIiBpbgon JykgdXNlbXltYWxsb2M9J24nIDs7CmVzYWMKCiMgQ2hlY2sgaWYgd2UncmUgYWJvdXQgdG8gdXNl IEludGVsJ3MgSUNDIGNvbXBpbGVyCmNhc2UgImAke2NjOi1jY30gLVYgMj4mMWAiIGluCioiSW50 ZWwoUikgQysrIENvbXBpbGVyIip8KiJJbnRlbChSKSBDIENvbXBpbGVyIiopCiAgICAjIHJlY29y ZCB0aGUgdmVyc2lvbiwgZm9ybWF0czoKICAgICMgaWNjIChJQ0MpIDEwLjEgMjAwODA4MDEKICAg ICMgaWNwYyAoSUNDKSAxMC4xIDIwMDgwODAxCiAgICAjIGZvbGxvd2VkIGJ5IGEgY29weXJpZ2h0 IG9uIHRoZSBzZWNvbmQgbGluZQogICAgY2N2ZXJzaW9uPWAke2NjOi1jY30gLS12ZXJzaW9uIHwg c2VkIC1uIC1lICdzL15pY3BcP2MgXCgoSUNDKSBcKVw/Ly9wJ2AKICAgICMgVGhpcyBpcyBuZWVk ZWQgZm9yIENvbmZpZ3VyZSdzIHByb3RvdHlwZSBjaGVja3MgdG8gd29yayBjb3JyZWN0bHkKICAg ICMgVGhlIC1tcCBmbGFnIGlzIG5lZWRlZCB0byBwYXNzIHZhcmlvdXMgZmxvYXRpbmcgcG9pbnQg cmVsYXRlZCB0ZXN0cwogICAgIyBUaGUgLW5vLWdjYyBmbGFnIGlzIG5lZWRlZCBvdGhlcndpc2Us IGljYyBwcmV0ZW5kcyAocG9vcmx5KSB0byBiZSBnY2MKICAgIGNjZmxhZ3M9Ii13ZTE0NyAtbXAg LW5vLWdjYyAkY2NmbGFncyIKICAgICMgUHJldmVudCByZWxvY2F0aW9uIGVycm9ycyBvbiA2NGJp dHMgYXJjaAogICAgY2FzZSAiYHVuYW1lIC1tYCIgaW4KCSppYTY0KnwqeDg2XzY0KikKCSAgICBj Y2NkbGZsYWdzPSctZlBJQycKCTs7CiAgICBlc2FjCiAgICAjIElmIHdlJ3JlIHVzaW5nIElDQywg d2UgdXN1YWxseSB3YW50IHRoZSBiZXN0IHBlcmZvcm1hbmNlCiAgICBjYXNlICIkb3B0aW1pemUi IGluCiAgICAnJykgb3B0aW1pemU9Jy1PMycgOzsKICAgIGVzYWMKICAgIDs7CioiIFN1biAiKiJD IiopCiAgICAjIFN1bidzIEMgY29tcGlsZXIsIHdoaWNoIG1pZ2h0IGhhdmUgYSAndGFnJyBuYW1l IGJldHdlZW4KICAgICMgJ1N1bicgYW5kIHRoZSAnQyc6ICBFeGFtcGxlczoKICAgICMgY2M6IFN1 biBDIDUuOSBMaW51eF9pMzg2IFBhdGNoIDEyNDg3MS0wMSAyMDA3LzA3LzMxCiAgICAjIGNjOiBT dW4gQ2VyZXMgQyA1LjEwIExpbnV4X2kzODYgMjAwOC8wNy8xMAogICAgdGVzdCAiJG9wdGltaXpl IiB8fCBvcHRpbWl6ZT0nLXhPMicKICAgIGNjY2RsZmxhZ3M9Jy1LUElDJwogICAgbGRkbGZsYWdz PSctRyAtQmR5bmFtaWMnCiAgICAjIFN1biBDIGRvZXNuJ3Qgc3VwcG9ydCBnY2MgYXR0cmlidXRl cywgYnV0LCBpbiBtYW55IGNhc2VzLCBkb2Vzbid0CiAgICAjIGNvbXBsYWluIGVpdGhlci4gIE5v dCBhbGwgY2FzZXMsIHRob3VnaC4KICAgIGRfYXR0cmlidXRlX2Zvcm1hdD0ndW5kZWYnCiAgICBk X2F0dHJpYnV0ZV9tYWxsb2M9J3VuZGVmJwogICAgZF9hdHRyaWJ1dGVfbm9ubnVsbD0ndW5kZWYn CiAgICBkX2F0dHJpYnV0ZV9ub3JldHVybj0ndW5kZWYnCiAgICBkX2F0dHJpYnV0ZV9wdXJlPSd1 bmRlZicKICAgIGRfYXR0cmlidXRlX3VudXNlZD0ndW5kZWYnCiAgICBkX2F0dHJpYnV0ZV93YXJu X3VudXNlZF9yZXN1bHQ9J3VuZGVmJwogICAgOzsKZXNhYwoKY2FzZSAiJG9wdGltaXplIiBpbgoj IHVzZSAtTzIgYnkgZGVmYXVsdCA7IC1PMyBkb2Vzbid0IHNlZW0gdG8gYnJpbmcgc2lnbmlmaWNh bnQgYmVuZWZpdHMgd2l0aCBnY2MKJycpCiAgICBvcHRpbWl6ZT0nLU8yJwogICAgY2FzZSAiYHVu YW1lIC1tYCIgaW4KICAgICAgICBwcGMqKQogICAgICAgICAgICAjIG9uIHBwYywgaXQgc2VlbXMg dGhhdCBnY2MgKGF0IGxlYXN0IGdjYyAzLjMuMikgaXNuJ3QgaGFwcHkKICAgICAgICAgICAgIyB3 aXRoIC1PMiA7IHNvIGRvd25ncmFkZSB0byAtTzEuCiAgICAgICAgICAgIG9wdGltaXplPSctTzEn CiAgICAgICAgOzsKICAgICAgICBpYTY0KikKICAgICAgICAgICAgIyBUaGlzIGFyY2hpdGVjdHVy ZSBoYXMgaGFkIHZhcmlvdXMgcHJvYmxlbXMgd2l0aCBnY2MncwogICAgICAgICAgICAjIGluIHRo ZSAzLjIsIDMuMywgYW5kIDMuNCByZWxlYXNlcyB3aGVuIG9wdGltaXplZCB0byAtTzIuICBTZWUK ICAgICAgICAgICAgIyBSVCAjMzcxNTYgZm9yIGEgZGlzY3Vzc2lvbiBvZiB0aGUgcHJvYmxlbS4K ICAgICAgICAgICAgY2FzZSAiYCR7Y2M6LWdjY30gLXYgMj4mMWAiIGluCiAgICAgICAgICAgICoi dmVyc2lvbiAzLjIiKnwqInZlcnNpb24gMy4zIip8KiJ2ZXJzaW9uIDMuNCIqKQogICAgICAgICAg ICAgICAgY2NmbGFncz0iLWZuby1kZWxldGUtbnVsbC1wb2ludGVyLWNoZWNrcyAkY2NmbGFncyIK ICAgICAgICAgICAgOzsKICAgICAgICAgICAgZXNhYwogICAgICAgIDs7CiAgICBlc2FjCiAgICA7 Owplc2FjCgojIFVidW50dSAxMS4wNCAoYW5kIGxhdGVyLCBwcmVzdW1hYmx5KSBkb2Vzbid0IGtl ZXAgbW9zdCBsaWJyYXJpZXMKIyAoc3VjaCBhcyAtbG0pIGluIC9saWIgb3IgL3Vzci9saWIuICBT byB3ZSBoYXZlIHRvIGFzayBnY2MgdG8gdGVsbCB1cwojIHdoZXJlIHRvIGxvb2suICBXZSBkb24n dCB3YW50IGdjYydzIG93biBsaWJyYXJpZXMsIGhvd2V2ZXIsIHNvIHdlCiMgZmlsdGVyIHRob3Nl IG91dC4KIyBUaGlzIGNvdWxkIGJlIGNvbmRpdGlvbmFsIG9uIFVuYnVudHUsIGJ1dCBvdGhlciBk aXN0cmlidXRpb25zIG1heQojIGZvbGxvdyBzdWl0LCBhbmQgdGhpcyBzY2hlbWUgc2VlbXMgdG8g d29yayBldmVuIG9uIHJhdGhlciBvbGQgZ2NjJ3MuCiMgVGhpcyB1bmNvbmRpdGlvbmFsbHkgdXNl cyBnY2MgYmVjYXVzZSBldmVuIGlmIHRoZSB1c2VyIGlzIHVzaW5nIGFub3RoZXIKIyBjb21waWxl ciwgd2Ugc3RpbGwgbmVlZCB0byBmaW5kIHRoZSBtYXRoIGxpYnJhcnkgYW5kIGZyaWVuZHMsIGFu ZCBJIGRvbid0CiMga25vdyBob3cgb3RoZXIgY29tcGlsZXJzIHdpbGwgY29wZSB3aXRoIHRoYXQg c2l0dWF0aW9uLgojIFN0aWxsLCBhcyBhbiBlc2NhcGUgaGF0Y2gsIGFsbG93IENvbmZpZ3VyZSBj b21tYW5kIGxpbmUgb3ZlcnJpZGVzIHRvCiMgcGxpYnB0aCB0byBieXBhc3MgdGhpcyBjaGVjay4K Y2FzZSAiJHBsaWJwdGgiIGluCicnKSBwbGlicHRoPWBnY2MgLXByaW50LXNlYXJjaC1kaXJzIHwg Z3JlcCBsaWJyYXJpZXMgfAoJY3V0IC1mMi0gLWQ9IHwgdHIgJzonICR0cm5sIHwgZ3JlcCAtdiAn Z2NjJyB8IHNlZCAtZSAnczovJDo6J2AKICAgIHNldCBYICRwbGlicHRoICMgQ29sbGFwc2UgYWxs IGVudHJpZXMgb24gb25lIGxpbmUKICAgIHNoaWZ0CiAgICBwbGlicHRoPSIkKiIKICAgIDs7CmVz YWMKCiMgQXJlIHdlIHVzaW5nIEVMRj8gIFRoYW5rcyB0byBLZW5uZXRoIEFsYmFub3dza2kgPGtq YWhkc0BramFoZHMuY29tPgojIGZvciB0aGlzIHRlc3QuCmNhdCA+dHJ5LmMgPDwnRU9NJwovKiBU ZXN0IGZvciB3aGV0aGVyIEVMRiBiaW5hcmllcyBhcmUgcHJvZHVjZWQgKi8KI2luY2x1ZGUgPGZj bnRsLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgptYWluKCkgewoJ Y2hhciBidWZmZXJbNF07CglpbnQgaT1vcGVuKCJhLm91dCIsT19SRE9OTFkpOwoJaWYoaT09LTEp CgkJZXhpdCgxKTsgLyogZmFpbCAqLwoJaWYocmVhZChpLCZidWZmZXJbMF0sNCk8NCkKCQlleGl0 KDEpOyAvKiBmYWlsICovCglpZihidWZmZXJbMF0gIT0gMTI3IHx8IGJ1ZmZlclsxXSAhPSAnRScg fHwKICAgICAgICAgICBidWZmZXJbMl0gIT0gJ0wnIHx8IGJ1ZmZlclszXSAhPSAnRicpCgkJZXhp dCgxKTsgLyogZmFpbCAqLwoJZXhpdCgwKTsgLyogc3VjY2VlZCAoeWVzLCBpdCdzIEVMRikgKi8K fQpFT00KaWYgJHtjYzotZ2NjfSB0cnkuYyA+L2Rldi9udWxsIDI+JjEgJiYgJHJ1biAuL2Eub3V0 OyB0aGVuCiAgICBjYXQgPDwnRU9NJyA+JjQKCllvdSBhcHBlYXIgdG8gaGF2ZSBFTEYgc3VwcG9y dC4gIEknbGwgdHJ5IHRvIHVzZSBpdCBmb3IgZHluYW1pYyBsb2FkaW5nLgpJZiBkeW5hbWljIGxv YWRpbmcgZG9lc24ndCB3b3JrLCByZWFkIGhpbnRzL2xpbnV4LnNoIGZvciBmdXJ0aGVyIGluZm9y bWF0aW9uLgpFT00KCmVsc2UKICAgIGNhdCA8PCdFT00nID4mNAoKWW91IGRvbid0IGhhdmUgYW4g RUxGIGdjYy4gIEkgd2lsbCB1c2UgZGxkIGlmIHBvc3NpYmxlLiAgSWYgeW91IGFyZQp1c2luZyBh IHZlcnNpb24gb2YgRExEIGVhcmxpZXIgdGhhbiAzLjIuNiwgb3IgZG9uJ3QgaGF2ZSBpdCBhdCBh bGwsIHlvdQpzaG91bGQgcHJvYmFibHkgdXBncmFkZS4gSWYgeW91IGFyZSBmb3JjZWQgdG8gdXNl IDMuMi40LCB5b3Ugc2hvdWxkCnVuY29tbWVudCBhIGNvdXBsZSBvZiBsaW5lcyBpbiBoaW50cy9s aW51eC5zaCBhbmQgcmVzdGFydCBDb25maWd1cmUgc28KdGhhdCBzaGFyZWQgbGlicmFyaWVzIHdp bGwgYmUgZGlzYWxsb3dlZC4KCkVPTQogICAgbGRkbGZsYWdzPSItciAkbGRkbGZsYWdzIgogICAg IyBUaGVzZSBlbXB0eSB2YWx1ZXMgYXJlIHNvIHRoYXQgQ29uZmlndXJlIGRvZXNuJ3QgcHV0IGlu IHRoZQogICAgIyBMaW51eCBFTEYgdmFsdWVzLgogICAgY2NkbGZsYWdzPScgJwogICAgY2NjZGxm bGFncz0nICcKICAgIGNjZmxhZ3M9Ii1ET1ZSX0RCTF9ESUc9MTQgJGNjZmxhZ3MiCiAgICBzbz0n c2EnCiAgICBkbGV4dD0nbycKICAgIG5tX3NvX29wdD0nICcKICAgICMjIElmIHlvdSBhcmUgdXNp bmcgRExEIDMuMi40IHdoaWNoIGRvZXMgbm90IHN1cHBvcnQgc2hhcmVkIGxpYnMsCiAgICAjIyB1 bmNvbW1lbnQgdGhlIG5leHQgdHdvIGxpbmVzOgogICAgI2xkZmxhZ3M9Ii1zdGF0aWMiCiAgICAj c289J25vbmUnCgoJIyBJbiBhZGRpdGlvbiwgb24gc29tZSBzeXN0ZW1zIHRoZXJlIGlzIGEgcHJv YmxlbSB3aXRoIHBlcmwgYW5kIE5EQk0KCSMgd2hpY2ggY2F1c2VzIEFueURCTSBhbmQgTkRCTV9G aWxlIHRvIGxvY2sgdXAuIFRoaXMgaXMgZXZpZGVuY2VkCgkjIGluIHRoZSB0ZXN0cyBhcyBBbnlE Qk0ganVzdCBmcmVlemluZy4gIEFwcGFyZW50bHksIHRoaXMgb25seQoJIyBoYXBwZW5zIG9uIGEu b3V0IHN5c3RlbXMsIHNvIHdlIGRpc2FibGUgTkRCTSBmb3IgYWxsIGEub3V0IGxpbnV4CgkjIHN5 c3RlbXMuICBJZiBzb21lb25lIGNhbiBzdWdnZXN0IGEgbW9yZSByb2J1c3QgdGVzdAoJIyAgdGhh dCB3b3VsZCBiZSBhcHByZWNpYXRlZC4KCSMKCSMgTW9yZSBpbmZvOgoJIyBEYXRlOiBXZWQsIDcg RmViIDE5OTYgMDM6MjE6MDQgKzA5MDAKCSMgRnJvbTogSmVmZnJleSBGcmllZGwgPGpmcmllZGxA bmZmLm5jbC5vbXJvbi5jby5qcD4KCSMKCSMgSSB0cmllZCBjb21waWxpbmcgd2l0aCBEQk0gc3Vw cG9ydCBhbmQgc3VyZSBlbm91Z2ggdGhpbmdzIGxvY2tlZCB1cAoJIyBqdXN0IGFzIGFkdmVydGlz ZWQuIENoZWNraW5nIGludG8gaXQsIEkgZm91bmQgdGhhdCB0aGUgbG9ja3VwIHdhcwoJIyBkdXJp bmcgdGhlIGNhbGwgdG8gZGJtX29wZW4uIE5vdCAqaW4qIGRibV9vcGVuIC0tIGJ1dCBiZXR3ZWVu IHRoZSBjYWxsCgkjIHRvIGFuZCB0aGUganVtcCBpbnRvLgoJIwoJIyBUbyBtYWtlIGEgbG9uZyBz dG9yeSBzaG9ydCwgbWFraW5nIHN1cmUgdGhhdCB0aGUgKi5hIGFuZCAqLnNhIHBhaXJzIG9mCgkj ICAgL3Vzci9saWIvbGlie20sZGIsZ2RibX0ue2Esc2F9CgkjIHdlcmUgcGVyZmVjdGx5IGluIHN5 bmMgdG9vayBjYXJlIG9mIGl0LgoJIwoJIyBUaGlzIHdpbGwgZ2VuZXJhdGUgYSBoYXJtbGVzcyBX aG9hIFRoZXJlISBtZXNzYWdlCgljYXNlICIkZF9kYm1fb3BlbiIgaW4KCScnKQljYXQgPDwnRU9N JyA+JjQKCkRpc2FibGluZyBuZGJtLiAgVGhpcyB3aWxsIGdlbmVyYXRlIGEgV2hvYSBUaGVyZSBt ZXNzYWdlIGluIENvbmZpZ3VyZS4KUmVhZCBoaW50cy9saW51eC5zaCBmb3IgZnVydGhlciBpbmZv cm1hdGlvbi4KRU9NCgkJIyBZb3UgY2FuIG92ZXJyaWRlIHRoaXMgd2l0aCBDb25maWd1cmUgLURk X2RibV9vcGVuCgkJZF9kYm1fb3Blbj11bmRlZgoJCTs7Cgllc2FjCmZpCgpybSAtZiB0cnkuYyBh Lm91dAoKaWYgL2Jpbi9zaCAtYyBleGl0OyB0aGVuCiAgZWNobyAnJwogIGVjaG8gJ1lvdSBhcHBl YXIgdG8gaGF2ZSBhIHdvcmtpbmcgYmFzaC4gIEdvb2QuJwplbHNlCiAgY2F0IDw8ICdFT00nID4m NAoKKioqKioqKioqKioqKioqKioqKioqKiogV2FybmluZyEgKioqKioqKioqKioqKioqKioqKioq Ckl0IHdvdWxkIGFwcGVhciB5b3UgaGF2ZSBhIGRlZmVjdGl2ZSBiYXNoIHNoZWxsIGluc3RhbGxl ZC4gVGhpcyBpcyBsaWtlbHkgdG8KZ2l2ZSB5b3UgYSBmYWlsdXJlIG9mIG9wL2V4ZWMgdGVzdCAj NSBkdXJpbmcgdGhlIHRlc3QgcGhhc2Ugb2YgdGhlIGJ1aWxkLApVcGdyYWRpbmcgdG8gYSByZWNl bnQgdmVyc2lvbiAoMS4xNC40IG9yIGxhdGVyKSBzaG91bGQgZml4IHRoZSBwcm9ibGVtLgoqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKRU9NCgpm aQoKIyBPbiBTUEFSQ2xpbnV4LAojIFRoZSBmb2xsb3dpbmcgY3NoIGNvbnNpc3RlbnRseSBjb3Jl ZHVtcGVkIGluIHRoZSB0ZXN0IGRpcmVjdG9yeQojICIvaG9tZS9taWtlZGxyL3Blcmw1LjAwM185 NC90IiwgdGhvdWdoIG5vdCBtb3N0IG90aGVyIGRpcmVjdG9yaWVzLgoKI05hbWUgICAgICAgIDog Y3NoICAgICAgICAgICAgICAgICAgICBEaXN0cmlidXRpb246IFJlZCBIYXQgTGludXggKFJlbWJy YW5kdCkKI1ZlcnNpb24gICAgIDogNS4yLjYgICAgICAgICAgICAgICAgICAgICAgICBWZW5kb3I6 IFJlZCBIYXQgU29mdHdhcmUKI1JlbGVhc2UgICAgIDogMyAgICAgICAgICAgICAgICAgICAgICAg IEJ1aWxkIERhdGU6IEZyaSBNYXkgMjQgMTk6NDI6MTQgMTk5NgojSW5zdGFsbCBkYXRlOiBUaHUg SnVsIDExIDE2OjIwOjE0IDE5OTYgQnVpbGQgSG9zdDogaXRjaHkucmVkaGF0LmNvbQojR3JvdXAg ICAgICAgOiBTaGVsbHMgICAgICAgICAgICAgICAgICAgU291cmNlIFJQTTogY3NoLTUuMi42LTMu c3JjLnJwbQojU2l6ZSAgICAgICAgOiAxODQ0MTcKI0Rlc2NyaXB0aW9uIDogQlNEIGMtc2hlbGwK CiMgRm9yIHRoaXMgcmVhc29uIEkgc3VnZ2VzdCB1c2luZyB0aGUgbXVjaCBidWctZml4ZWQgdGNz aCBmb3IgZ2xvYmJpbmcKIyB3aGVyZSBhdmFpbGFibGUuCgojIE5vdmVtYmVyIDIwMDE6ICBUaGF0 IHdhcm5pbmcncyBwcmV0dHkgb2xkIG5vdyBhbmQgcHJvYmFibHkgbm90IHNvCiMgcmVsZXZhbnQs IGVzcGVjaWFsbHkgc2luY2UgcGVybCBub3cgdXNlcyBGaWxlOjpHbG9iIGZvciBnbG9iYmluZy4K IyBXZSdsbCBzdGlsbCBsb29rIGZvciB0Y3NoLCBidXQgdG9uZSBkb3duIHRoZSB3YXJuaW5ncy4K IyBBbmR5IERvdWdoZXJ0eSwgTm92LiA2LCAyMDAxCmlmICRjc2ggLWMgJ2VjaG8gJHZlcnNpb24n ID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgZWNobyAnWW91ciBjc2ggaXMgcmVhbGx5IHRjc2gu ICBHb29kLicKZWxzZQogICAgaWYgeHh4PWAuL1VVL2xvYyB0Y3NoIGJsdXJmbCAkcHRoYDsgJHRl c3QgLWYgIiR4eHgiOyB0aGVuCgllY2hvICJGb3VuZCB0Y3NoLiAgSSdsbCB1c2UgaXQgZm9yIGds b2JiaW5nLiIKCSMgV2UgY2FuJ3QgY2hhbmdlIENvbmZpZ3VyZSdzIHNldHRpbmcgb2YgJGNzaCwg ZHVlIHRvIHRoZSB3YXkKCSMgQ29uZmlndXJlIGhhbmRsZXMgJGRfcG9ydGFibGUgYW5kIGNvbW1h bmRzIGZvdW5kIGluICRsb2NsaXN0LgoJIyBXZSBjYW4gc2V0IHRoZSB2YWx1ZSBmb3IgQ1NIIGlu IGNvbmZpZy5oIGJ5IHNldHRpbmcgZnVsbF9jc2guCglmdWxsX2NzaD0keHh4CiAgICBlbGlmIFsg LWYgIiRjc2giIF07IHRoZW4KCWVjaG8gIkNvdWxkbid0IGZpbmQgdGNzaC4gIENzaC1iYXNlZCBn bG9iYmluZyBtaWdodCBiZSBicm9rZW4uIgogICAgZmkKZmkKCiMgU2hpbXBlaSBZYW1hc2hpdGEg PHNoaW1wZWlAc29jcmF0ZXMucGF0bmV0LmNhbHRlY2guZWR1PgojIE1lc3NhZ2UtSWQ6IDwzM0VG MTYzNC5CMzZCNjUwMEBwb2JveC5jb20+CiMKIyBUaGUgRFIyIG9mIE1rTGludXggKG9zbmFtZT1s aW51eCxhcmNobmFtZT1wcGMtbGludXgpIG1heSBuZWVkCiMgc3BlY2lhbCBmbGFncyBwYXNzZWQg aW4gb3JkZXIgZm9yIGR5bmFtaWMgbG9hZGluZyB0byB3b3JrLgojIGluc3RlYWQgb2YgdGhlIHJl Y29tbWVuZGVkOgojCiMgY2NkbGZsYWdzPSctcmR5bmFtaWMnCiMKIyBpdCBzaG91bGQgYmU6CiMg Y2NkbGZsYWdzPSctV2wsLUUnCiMKIyBTbyBpZiB5b3VyIERSMiAoRFIzIGNhbWUgb3V0IHN1bW1l ciAxOTk4LCBjb25zaWRlciB1cGdyYWRpbmcpCiMgaGFzIHByb2JsZW1zIHdpdGggZHluYW1pYyBs b2FkaW5nLCB1bmNvbW1lbnQgdGhlCiMgZm9sbG93aW5nIHRocmVlIGxpbmVzLCBtYWtlIGRpc3Rj bGVhbiwgYW5kIHJlLUNvbmZpZ3VyZToKI2Nhc2UgImB1bmFtZSAtciB8IHNlZCAncy9eWzAtOS4t XSovLydgYGFyY2hgIiBpbgojJ29zZm1hY2gzcHBjJykgY2NkbGZsYWdzPSctV2wsLUUnIDs7CiNl c2FjCgpjYXNlICJgdW5hbWUgLW1gIiBpbgpzcGFyYyopCgljYXNlICIkY2NjZGxmbGFncyIgaW4K CSotZnBpYyopIGNjY2RsZmxhZ3M9ImBlY2hvICRjY2NkbGZsYWdzfHNlZCAncy8tZnBpYy8tZlBJ Qy8nYCIgOzsKCSotZlBJQyopIDs7CgkqKQkgY2NjZGxmbGFncz0iJGNjY2RsZmxhZ3MgLWZQSUMi IDs7Cgllc2FjCgk7Owplc2FjCgojIFN1U0U4LjIgaGFzIC91c3IvbGliL2xpYm5kYm0qIHdoaWNo IGFyZSBsZCBzY3JpcHRzIHJhdGhlciB0aGFuCiMgdHJ1ZSBsaWJyYXJpZXMuIFRoZSBzY3JpcHRz IGNhdXNlIGJpbmRpbmcgYWdhaW5zdCBzdGF0aWMKIyB2ZXJzaW9uIG9mIC1sZ2RibSB3aGljaCBp cyBhIGJhZCBpZGVhLiBTbyBpZiB3ZSBoYXZlICdubScKIyBtYWtlIHN1cmUgaXQgY2FuIHJlYWQg dGhlIGZpbGUKIyBOSS1TIDIwMDMvMDgvMDcKaWYgWyAtciAvdXNyL2xpYi9saWJuZGJtLnNvICAt YSAgLXggL3Vzci9iaW4vbm0gXSA7IHRoZW4KICAgaWYgL3Vzci9iaW4vbm0gL3Vzci9saWIvbGli bmRibS5zbyA+L2Rldi9udWxsIDI+JjEgOyB0aGVuCiAgICBlY2hvICdZb3VyIHNoYXJlZCAtbG5k Ym0gc2VlbXMgdG8gYmUgYSByZWFsIGxpYnJhcnkuJwogICBlbHNlCiAgICBlY2hvICdZb3VyIHNo YXJlZCAtbG5kYm0gaXMgbm90IGEgcmVhbCBsaWJyYXJ5LicKICAgIHNldCBgZWNobyBYICIkbGli c3dhbnRlZCAifCBzZWQgLWUgJ3MvIG5kYm0gLyAvJ2AKICAgIHNoaWZ0CiAgICBsaWJzd2FudGVk PSIkKiIKICAgZmkKZmkKCgojIFRoaXMgc2NyaXB0IFVVL3VzZXRocmVhZHMuY2J1IHdpbGwgZ2V0 ICdjYWxsZWQtYmFjaycgYnkgQ29uZmlndXJlCiMgYWZ0ZXIgaXQgaGFzIHByb21wdGVkIHRoZSB1 c2VyIGZvciB3aGV0aGVyIHRvIHVzZSB0aHJlYWRzLgpjYXQgPiBVVS91c2V0aHJlYWRzLmNidSA8 PCdFT0NCVScKaWYgZ2V0Y29uZiBHTlVfTElCUFRIUkVBRF9WRVJTSU9OIHwgZ3JlcCBOUFRMID4v ZGV2L251bGwgMj4vZGV2L251bGwKdGhlbgogICAgdGhyZWFkc2hhdmVwaWRzPSIiCmVsc2UKICAg IHRocmVhZHNoYXZlcGlkcz0iLURUSFJFQURTX0hBVkVfUElEUyIKZmkKY2FzZSAiJHVzZXRocmVh ZHMiIGluCiRkZWZpbmV8dHJ1ZXxbeVldKikKICAgICAgICBjY2ZsYWdzPSItRF9SRUVOVFJBTlQg LURfR05VX1NPVVJDRSAkdGhyZWFkc2hhdmVwaWRzICRjY2ZsYWdzIgogICAgICAgIGlmIGVjaG8g JGxpYnN3YW50ZWQgfCBncmVwIC12IHB0aHJlYWQgPi9kZXYvbnVsbAogICAgICAgIHRoZW4KICAg ICAgICAgICAgc2V0IGBlY2hvIFggIiRsaWJzd2FudGVkICJ8IHNlZCAtZSAncy8gYyAvIHB0aHJl YWQgYyAvJ2AKICAgICAgICAgICAgc2hpZnQKICAgICAgICAgICAgbGlic3dhbnRlZD0iJCoiCiAg ICAgICAgZmkKCgkjIFNvbWVob3cgYXQgbGVhc3QgaW4gRGViaWFuIDIuMiB0aGVzZSBtYW5hZ2Ug dG8gZXNjYXBlCgkjIHRoZSAjZGVmaW5lIGZvcmVzdCBvZiA8ZmVhdHVyZXMuaD4gYW5kIDx0aW1l Lmg+IHNvIHRoYXQKCSMgdGhlIGhhc3Byb3RvIG1hY3JvIG9mIENvbmZpZ3VyZSBkb2Vzbid0IHNl ZSB0aGVzZSBwcm90b3MsCgkjIGV2ZW4gd2l0aCB0aGUgLURfR05VX1NPVVJDRS4KCglkX2FzY3Rp bWVfcl9wcm90bz0iJGRlZmluZSIKCWRfY3J5cHRfcl9wcm90bz0iJGRlZmluZSIKCWRfY3RpbWVf cl9wcm90bz0iJGRlZmluZSIKCWRfZ210aW1lX3JfcHJvdG89IiRkZWZpbmUiCglkX2xvY2FsdGlt ZV9yX3Byb3RvPSIkZGVmaW5lIgoJZF9yYW5kb21fcl9wcm90bz0iJGRlZmluZSIKCgk7Owplc2Fj CkVPQ0JVCgpjYXQgPiBVVS91c2VsYXJnZWZpbGVzLmNidSA8PCdFT0NCVScKIyBUaGlzIHNjcmlw dCBVVS91c2VsYXJnZWZpbGVzLmNidSB3aWxsIGdldCAnY2FsbGVkLWJhY2snIGJ5IENvbmZpZ3Vy ZQojIGFmdGVyIGl0IGhhcyBwcm9tcHRlZCB0aGUgdXNlciBmb3Igd2hldGhlciB0byB1c2UgbGFy Z2UgZmlsZXMuCmNhc2UgIiR1c2VsYXJnZWZpbGVzIiBpbgonJ3wkZGVmaW5lfHRydWV8W3lZXSop CiMgS2VlcCB0aGlzIGluIHRoZSBsZWZ0IG1hcmdpbi4KY2NmbGFnc191c2VsYXJnZWZpbGVzPSIt RF9MQVJHRUZJTEVfU09VUkNFIC1EX0ZJTEVfT0ZGU0VUX0JJVFM9NjQiCgoJY2NmbGFncz0iJGNj ZmxhZ3MgJGNjZmxhZ3NfdXNlbGFyZ2VmaWxlcyIKCTs7CmVzYWMKRU9DQlUKCiMgUHVyaWZ5IGZh aWxzIHRvIGxpbmsgUGVybCBpZiBhICItbGMiIGlzIHBhc3NlZCBpbnRvIGl0cyBsaW5rZXIKIyBk dWUgdG8gZHVwbGljYXRlIHN5bWJvbHMuCmNhc2UgIiRQVVJJRlkiIGluCiRkZWZpbmV8dHJ1ZXxb eVldKikKICAgIHNldCBgZWNobyBYICIkbGlic3dhbnRlZCAifCBzZWQgLWUgJ3MvIGMgLyAvJ2AK ICAgIHNoaWZ0CiAgICBsaWJzd2FudGVkPSIkKiIKICAgIDs7CmVzYWMKCiMgSWYgd2UgYXJlIHVz aW5nIGcrKyB3ZSBtdXN0IHVzZSBubSBhbmQgZm9yY2Ugb3Vyc2VsdmVzIHRvIHVzZQojIHRoZSAv dXNyL2xpYi9saWJjLmEgKHJlc2V0dGluZyB0aGUgbGliYyBiZWxvdyB0byBhbiBlbXB0eSBzdHJp bmcKIyBtYWtlcyBDb25maWd1cmUgdG8gbG9vayBmb3IgdGhlIHJpZ2h0IG9uZSkgYmVjYXVzZSB0 aGUgc3ltYm9sCiMgc2Nhbm5pbmcgdHJpY2tzIG9mIENvbmZpZ3VyZSB3aWxsIGNyYXNoIGFuZCBi dXJuIGhvcnJpYmx5LgpjYXNlICIkY2MiIGluCipnKysqKSB1c2VubT10cnVlCiAgICAgICBsaWJj PScnCiAgICAgICA7Owplc2FjCgojIElmIHVzaW5nIGcrKywgdGhlIENvbmZpZ3VyZSBzY2FuIGZv ciBkbG9wZW4oKSBhbmQgKGVzcGVjaWFsbHkpCiMgZGxlcnJvcigpIG1pZ2h0IGZhaWwsIGVhc2ll ciBqdXN0IHRvIGZvcmNpYmx5IGhpbnQgdGhlbSBpbi4KY2FzZSAiJGNjIiBpbgoqZysrKikKICBk X2Rsb3Blbj0nZGVmaW5lJwogIGRfZGxlcnJvcj0nZGVmaW5lJwogIDs7CmVzYWMKCiMgVW5kZXIg c29tZSBjaXJjdW1zdGFuY2VzIGxpYmRiIGNhbiBnZXQgYnVpbHQgaW4gc3VjaCBhIHdheSBhcyB0 bwojIG5lZWQgcHRocmVhZCBleHBsaWNpdGx5IGxpbmtlZC4KCmxpYmRiX25lZWRzX3B0aHJlYWQ9 Ik4iCgppZiBlY2hvICIgJGxpYnN3YW50ZWQgIiB8IGdyZXAgLXYgIiBwdGhyZWFkICIgPi9kZXYv bnVsbAp0aGVuCiAgIGlmIGVjaG8gIiAkbGlic3dhbnRlZCAiIHwgZ3JlcCAiIGRiICIgPi9kZXYv bnVsbAogICB0aGVuCiAgICAgZm9yIERCRElSIGluICRnbGlicHRoCiAgICAgZG8KICAgICAgIERC TElCPSIkREJESVIvbGliZGIuc28iCiAgICAgICBpZiBbIC1mICREQkxJQiBdCiAgICAgICB0aGVu CiAgICAgICAgIGlmIG5tIC11ICREQkxJQiB8IGdyZXAgcHRocmVhZCA+L2Rldi9udWxsCiAgICAg ICAgIHRoZW4KICAgICAgICAgICBpZiBsZGQgJERCTElCIHwgZ3JlcCBwdGhyZWFkID4vZGV2L251 bGwKICAgICAgICAgICB0aGVuCiAgICAgICAgICAgICBsaWJkYl9uZWVkc19wdGhyZWFkPSJOIgog ICAgICAgICAgIGVsc2UKICAgICAgICAgICAgIGxpYmRiX25lZWRzX3B0aHJlYWQ9IlkiCiAgICAg ICAgICAgZmkKICAgICAgICAgZmkKICAgICAgIGZpCiAgICAgZG9uZQogICBmaQpmaQoKY2FzZSAi JGxpYmRiX25lZWRzX3B0aHJlYWQiIGluCiAgIlkiKQogICAgbGlic3dhbnRlZD0iJGxpYnN3YW50 ZWQgcHRocmVhZCIKICAgIDs7CmVzYWMK==', ); my %files = ( 'freebsd' => 'freebsd.sh', 'netbsd' => 'netbsd.sh', 'openbsd' => 'openbsd.sh', 'linux' => 'linux.sh', ); sub hint_file { my $os = shift; $os = shift if eval { $os->isa(__PACKAGE__) }; $os = $^O unless $os; return unless defined $hints{ $os }; my $content = decode_base64( $hints{ $os } ); return $content unless wantarray; return ( $files{ $os }, $content ); } qq'nudge nudge wink wink'; __END__ =pod =head1 NAME Devel::PatchPerl::Hints - replacement 'hints' files =head1 VERSION version 0.32 =head1 SYNOPSIS use Devel::PatchPerl::Hints; if ( my $content = Devel::PatchPerl::Hints->hint_file() ) { chmod 0755, 'hints/netbsd.sh' or die "$!"; open my $hints, '>', 'hints/netbsd.sh' or die "$!"; print $hints $content; close $hints; } =head1 DESCRIPTION Sometimes there is a problem with Perls C file for a particular perl port. This module provides fixed C files encoded using C. =head1 FUNCTION The function is exported, but has to implicitly imported into the requesting package. use Devel::PatchPerl::Hints qw[hint_file]; It may also be called as a class method: use Devel::PatchPerl::Hints; my $content = Devel::PatchPerl::Hints->hint_file(); =over =item C Takes an optional argument which is the OS name ( as would be returned by C<$^O> ). By default it will use C<$^O>. In a scalar context, Will return the decoded content of the C file suitable for writing straight to a file handle or undef list if there isn't an applicable C file for the given or derived OS. If called in a list context, will return a list, the first item will be the name of the C file that will need to be amended, the second item will be a string with the decoded content of the C file suitable for writing straight to a file handle. Otherwise an empty list will be returned. =back =head1 AUTHOR Chris Williams =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Chris Williams and Marcus Holland-Moritz. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut DEVEL_PATCHPERL_HINTS $fatpacked{"File/pushd.pm"} = <<'FILE_PUSHD'; package File::pushd; $VERSION = '1.00'; @EXPORT = qw( pushd tempd ); @ISA = qw( Exporter ); use 5.004; use strict; #use warnings; use Exporter; use Carp; use Cwd qw( cwd abs_path ); use File::Path qw( rmtree ); use File::Temp qw(); use File::Spec; use overload q{""} => sub { File::Spec->canonpath( $_[0]->{_pushd} ) }, fallback => 1; #--------------------------------------------------------------------------# # pushd() #--------------------------------------------------------------------------# sub pushd { my ($target_dir) = @_; my $orig = cwd; my $dest; eval { $dest = $target_dir ? abs_path( $target_dir ) : $orig }; croak "Can't locate directory $target_dir: $@" if $@; if ($dest ne $orig) { chdir $dest or croak "Can't chdir to $dest\: $!"; } my $self = bless { _pushd => $dest, _original => $orig }, __PACKAGE__; return $self; } #--------------------------------------------------------------------------# # tempd() #--------------------------------------------------------------------------# sub tempd { my $dir = pushd( File::Temp::tempdir( CLEANUP => 0 ) ); $dir->{_tempd} = 1; return $dir; } #--------------------------------------------------------------------------# # preserve() #--------------------------------------------------------------------------# sub preserve { my $self = shift; return 1 if ! $self->{"_tempd"}; if ( @_ == 0 ) { return $self->{_preserve} = 1; } else { return $self->{_preserve} = $_[0] ? 1 : 0; } } #--------------------------------------------------------------------------# # DESTROY() # Revert to original directory as object is destroyed and cleanup # if necessary #--------------------------------------------------------------------------# sub DESTROY { my ($self) = @_; my $orig = $self->{_original}; chdir $orig if $orig; # should always be so, but just in case... if ( $self->{_tempd} && !$self->{_preserve} ) { eval { rmtree( $self->{_pushd} ) }; carp $@ if $@; } } 1; #this line is important and will help the module return a true value __END__ =begin wikidoc = NAME File::pushd - change directory temporarily for a limited scope = VERSION This documentation describes version %%VERSION%%. = SYNOPSIS use File::pushd; chdir $ENV{HOME}; # change directory again for a limited scope { my $dir = pushd( '/tmp' ); # working directory changed to /tmp } # working directory has reverted to $ENV{HOME} # tempd() is equivalent to pushd( File::Temp::tempdir ) { my $dir = tempd(); } # object stringifies naturally as an absolute path { my $dir = pushd( '/tmp' ); my $filename = File::Spec->catfile( $dir, "somefile.txt" ); # gives /tmp/somefile.txt } = DESCRIPTION File::pushd does a temporary {chdir} that is easily and automatically reverted, similar to {pushd} in some Unix command shells. It works by creating an object that caches the original working directory. When the object is destroyed, the destructor calls {chdir} to revert to the original working directory. By storing the object in a lexical variable with a limited scope, this happens automatically at the end of the scope. This is very handy when working with temporary directories for tasks like testing; a function is provided to streamline getting a temporary directory from [File::Temp]. For convenience, the object stringifies as the canonical form of the absolute pathname of the directory entered. = USAGE use File::pushd; Using File::pushd automatically imports the {pushd} and {tempd} functions. == pushd { my $dir = pushd( $target_directory ); } Caches the current working directory, calls {chdir} to change to the target directory, and returns a File::pushd object. When the object is destroyed, the working directory reverts to the original directory. The provided target directory can be a relative or absolute path. If called with no arguments, it uses the current directory as its target and returns to the current directory when the object is destroyed. == tempd { my $dir = tempd(); } This function is like {pushd} but automatically creates and calls {chdir} to a temporary directory created by [File::Temp]. Unlike normal [File::Temp] cleanup which happens at the end of the program, this temporary directory is removed when the object is destroyed. (But also see {preserve}.) A warning will be issued if the directory cannot be removed. == preserve { my $dir = tempd(); $dir->preserve; # mark to preserve at end of scope $dir->preserve(0); # mark to delete at end of scope } Controls whether a temporary directory will be cleaned up when the object is destroyed. With no arguments, {preserve} sets the directory to be preserved. With an argument, the directory will be preserved if the argument is true, or marked for cleanup if the argument is false. Only {tempd} objects may be marked for cleanup. (Target directories to {pushd} are always preserved.) {preserve} returns true if the directory will be preserved, and false otherwise. = SEE ALSO * [File::chdir] = BUGS Please report any bugs or feature using the CPAN Request Tracker. Bugs can be submitted through the web interface at [http://rt.cpan.org/Dist/Display.html?Queue=File-pushd] When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. = AUTHOR David A. Golden (DAGOLDEN) = COPYRIGHT AND LICENSE Copyright (c) 2005, 2006, 2007 by David A. Golden Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0] Files produced as output though the use of this software, including generated copies of boilerplate templates provided with this software, shall not be considered Derivative Works, but shall be considered the original work of the Licensor. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =end wikidoc FILE_PUSHD $fatpacked{"Locale/Maketext/Extract.pm"} = <<'LOCALE_MAKETEXT_EXTRACT'; package Locale::Maketext::Extract; $Locale::Maketext::Extract::VERSION = '0.38'; use strict; use Locale::Maketext::Lexicon(); =head1 NAME Locale::Maketext::Extract - Extract translatable strings from source =head1 SYNOPSIS my $Ext = Locale::Maketext::Extract->new; $Ext->read_po('messages.po'); $Ext->extract_file($_) for <*.pl>; # Set $entries_are_in_gettext_format if the .pl files above use # loc('%1') instead of loc('[_1]') $Ext->compile($entries_are_in_gettext_format); $Ext->write_po('messages.po'); ----------------------------------- ### Specifying parser plugins ### my $Ext = Locale::Maketext::Extract->new( # Specify which parser plugins to use plugins => { # Use Perl parser, process files with extension .pl .pm .cgi perl => [], # Use YAML parser, process all files yaml => ['*'], # Use TT2 parser, process files with extension .tt2 .tt .html # or which match the regex tt2 => [ 'tt2', 'tt', 'html', qr/\.tt2?\./ ], # Use My::Module as a parser for all files 'My::Module' => ['*'], }, # Warn if a parser can't process a file warnings => 1, # List processed files verbose => 1, ); =head1 DESCRIPTION This module can extract translatable strings from files, and write them back to PO files. It can also parse existing PO files and merge their contents with newly extracted strings. A command-line utility, L, is installed with this module as well. The format parsers are loaded as plugins, so it is possible to define your own parsers. Following formats of input files are supported: =over 4 =item Perl source files (plugin: perl) Valid localization function names are: C, C, C, C, C, C<_> and C<__>. For a slightly more accurate, but much slower Perl parser, you can use the PPI plugin. This does not have a short name (like C), but must be specified in full. =item HTML::Mason (plugin: mason) Strings inside C&|/lEI<...>E/&E> and C&|/locEI<...>E/&E> are extracted. =item Template Toolkit (plugin: tt2) Valid forms are: [% | l(arg1,argn) %]string[% END %] [% 'string' | l(arg1,argn) %] [% l('string',arg1,argn) %] FILTER and | are interchangeable l and loc are interchangeable args are optional =item Text::Template (plugin: text) Sentences between C and C are extracted individually. =item YAML (plugin: yaml) Valid forms are _"string" or _'string', eg: title: _"My title" desc: _'My "quoted" string' Quotes do not have to be escaped, so you could also do: desc: _"My "quoted" string" =item HTML::FormFu (plugin: formfu) HTML::FormFu uses a config-file to generate forms, with built in support for localizing errors, labels etc. We extract the text after C<_loc: >: content_loc: this is the string message_loc: ['Max string length: [_1]', 10] =item Generic Template (plugin: generic) Strings inside {{...}} are extracted. =back =head1 METHODS =head2 Constructor new() new( plugins => {...}, warnings => 1 | 0, verbose => 0 | 1 | 2 | 3, ) See L, L and L for details =head2 Plugins $ext->plugins({...}); Locale::Maketext::Extract uses plugins (see below for the list) to parse different formats. Each plugin can also specify which file types it can parse. # use only the YAML plugin # only parse files with the default extension list defined in the plugin # ie .yaml .yml .conf $ext->plugins({ yaml => [], }) # use only the Perl plugin # parse all file types $ext->plugins({ perl => '*' }) $ext->plugins({ tt2 => [ 'tt', # matches base filename against /\.tt$/ qr/\.tt2?\./, # matches base filename against regex \&my_filter, # codref called ] }) sub my_filter { my ($base_filename,$path_to_file) = @_; return 1 | 0; } # Specify your own parser # only parse files with the default extension list defined in the plugin $ext->plugins({ 'My::Extract::Parser' => [] }) By default, if no plugins are specified, then it uses all of the builtin plugins, and overrides the file types specified in each plugin - instead, each plugin is tried for every file. =head3 Available plugins =over 4 =item C : L For a slightly more accurate but much slower Perl parser, you can use the PPI plugin. This does not have a short name, but must be specified in full, ie: L =item C : L =item C : L =item C : L =item C : L =item C : L =item C : L =back Also, see L for details of how to write your own plugin. =head2 Warnings Because the YAML and TT2 plugins use proper parsers, rather than just regexes, if a source file is not valid and it is unable to parse the file, then the parser will throw an error and abort parsing. The next enabled plugin will be tried. By default, you will not see these errors. If you would like to see them, then enable warnings via new(). All parse errors will be printed to STDERR. =head2 Verbose If you would like to see which files have been processed, which plugins were used, and which strings were extracted, then enable C. If no acceptable plugin was found, or no strings were extracted, then the file is not listed: $ext = Locale::Extract->new( verbose => 1 | 2 | 3); OR xgettext.pl ... -v # files reported xgettext.pl ... -v -v # files and plugins reported xgettext.pl ... -v -v -v # files, plugins and strings reported =cut our %Known_Plugins = ( perl => 'Locale::Maketext::Extract::Plugin::Perl', yaml => 'Locale::Maketext::Extract::Plugin::YAML', tt2 => 'Locale::Maketext::Extract::Plugin::TT2', text => 'Locale::Maketext::Extract::Plugin::TextTemplate', mason => 'Locale::Maketext::Extract::Plugin::Mason', generic => 'Locale::Maketext::Extract::Plugin::Generic', formfu => 'Locale::Maketext::Extract::Plugin::FormFu', ); sub new { my $class = shift; my %params = @_; my $plugins = delete $params{plugins} || { map { $_ => '*' } keys %Known_Plugins }; Locale::Maketext::Lexicon::set_option( 'keep_fuzzy' => 1 ); my $self = bless( { header => '', entries => {}, compiled_entries => {}, lexicon => {}, warnings => 0, verbose => 0, wrap => 0, %params, }, $class ); $self->{verbose} ||= 0; die "No plugins defined in new()" unless $plugins; $self->plugins($plugins); return $self; } =head2 Accessors header, set_header lexicon, set_lexicon, msgstr, set_msgstr entries, set_entries, entry, add_entry, del_entry compiled_entries, set_compiled_entries, compiled_entry, add_compiled_entry, del_compiled_entry clear =cut sub header { $_[0]{header} || _default_header() } sub set_header { $_[0]{header} = $_[1] } sub lexicon { $_[0]{lexicon} } sub set_lexicon { $_[0]{lexicon} = $_[1] || {}; delete $_[0]{lexicon}{''}; } sub msgstr { $_[0]{lexicon}{ $_[1] } } sub set_msgstr { $_[0]{lexicon}{ $_[1] } = $_[2] } sub entries { $_[0]{entries} } sub set_entries { $_[0]{entries} = $_[1] || {} } sub compiled_entries { $_[0]{compiled_entries} } sub set_compiled_entries { $_[0]{compiled_entries} = $_[1] || {} } sub entry { @{ $_[0]->entries->{ $_[1] } || [] } } sub add_entry { push @{ $_[0]->entries->{ $_[1] } }, $_[2] } sub del_entry { delete $_[0]->entries->{ $_[1] } } sub compiled_entry { @{ $_[0]->compiled_entries->{ $_[1] } || [] } } sub add_compiled_entry { push @{ $_[0]->compiled_entries->{ $_[1] } }, $_[2] } sub del_compiled_entry { delete $_[0]->compiled_entries->{ $_[1] } } sub plugins { my $self = shift; if (@_) { my @plugins; my %params = %{ shift @_ }; foreach my $name ( keys %params ) { my $plugin_class = $Known_Plugins{$name} || $name; my $filename = $plugin_class . '.pm'; $filename =~ s/::/\//g; local $@; eval { require $filename && 1; 1; } or next; push @plugins, $plugin_class->new( $params{$name} ); } $self->{plugins} = \@plugins; } return $self->{plugins} || []; } sub clear { $_[0]->set_header; $_[0]->set_lexicon; $_[0]->set_comments; $_[0]->set_fuzzy; $_[0]->set_entries; $_[0]->set_compiled_entries; } =head2 PO File manipulation =head3 method read_po ($file) =cut sub read_po { my ( $self, $file ) = @_; print STDERR "READING PO FILE : $file\n" if $self->{verbose}; my $header = ''; local ( *LEXICON, $_ ); open LEXICON, $file or die $!; while () { ( 1 .. /^$/ ) or last; $header .= $_; } 1 while chomp $header; $self->set_header("$header\n"); require Locale::Maketext::Lexicon::Gettext; my $lexicon = {}; my $comments = {}; my $fuzzy = {}; $self->set_compiled_entries( {} ); if ( defined($_) ) { ( $lexicon, $comments, $fuzzy ) = Locale::Maketext::Lexicon::Gettext->parse( $_, ); } # Internally the lexicon is in gettext format already. $self->set_lexicon( { map _maketext_to_gettext($_), %$lexicon } ); $self->set_comments($comments); $self->set_fuzzy($fuzzy); close LEXICON; } sub msg_comment { my $self = shift; my $msgid = shift; my $comment = $self->{comments}->{$msgid}; return $comment; } sub msg_fuzzy { return $_[0]->{fuzzy}{$_[1]} ? ', fuzzy' : ''; } sub set_comments { $_[0]->{comments} = $_[1]; } sub set_fuzzy { $_[0]->{fuzzy} = $_[1]; } =head3 method write_po ($file, $add_format_marker?) =cut sub write_po { my ( $self, $file, $add_format_marker ) = @_; print STDERR "WRITING PO FILE : $file\n" if $self->{verbose}; local *LEXICON; open LEXICON, ">$file" or die "Can't write to $file$!\n"; print LEXICON $self->header; foreach my $msgid ( $self->msgids ) { $self->normalize_space($msgid); print LEXICON "\n"; if ( my $comment = $self->msg_comment($msgid) ) { my @lines = split "\n", $comment; print LEXICON map {"# $_\n"} @lines; } print LEXICON $self->msg_variables($msgid); print LEXICON $self->msg_positions($msgid); my $flags = $self->msg_fuzzy($msgid); $flags.= $self->msg_format($msgid) if $add_format_marker; print LEXICON "#$flags\n" if $flags; print LEXICON $self->msg_out($msgid); } print STDERR "DONE\n\n" if $self->{verbose}; } =head2 Extraction extract extract_file =cut sub extract { my $self = shift; my $file = shift; my $content = shift; local $@; my ( @messages, $total, $error_found ); $total = 0; my $verbose = $self->{verbose}; foreach my $plugin ( @{ $self->plugins } ) { if ( $plugin->known_file_type($file) ) { pos($content) = 0; my $success = eval { $plugin->extract($content); 1; }; if ($success) { my $entries = $plugin->entries; if ( $verbose > 1 && @$entries ) { push @messages, " - " . ref($plugin) . ' - Strings extracted : ' . ( scalar @$entries ); } for my $entry (@$entries) { my ( $string, $line, $vars ) = @$entry; $self->add_entry( $string => [ $file, $line, $vars ] ); if ( $verbose > 2 ) { $vars = '' if !defined $vars; # pad string $string =~ s/\n/\n /g; push @messages, sprintf( qq[ - %-8s "%s" (%s)], $line . ':', $string, $vars ), ; } } $total += @$entries; } else { $error_found++; if ( $self->{warnings} ) { push @messages, "Error parsing '$file' with plugin " . ( ref $plugin ) . ": \n $@\n"; } } $plugin->clear; } } print STDERR " * $file\n - Total strings extracted : $total" . ( $error_found ? ' [ERROR ] ' : '' ) . "\n" if $verbose && ( $total || $error_found ); print STDERR join( "\n", @messages ) . "\n" if @messages; } sub extract_file { my ( $self, $file ) = @_; local ( $/, *FH ); open FH, $file or die "Error reading from file '$file' : $!"; my $content = scalar ; $self->extract( $file => $content ); close FH; } =head2 Compilation =head3 compile($entries_are_in_gettext_style?) Merges the C into C. If C<$entries_are_in_gettext_style> is true, the previously extracted entries are assumed to be in the B style (e.g. C<%1>). Otherwise they are assumed to be in B style (e.g. C<[_1]>) and are converted into B style before merging into C. The C are I cleared after each compilation; use C<->set_entries()> to clear them if you need to extract from sources with varying styles. =cut sub compile { my ( $self, $entries_are_in_gettext_style ) = @_; my $entries = $self->entries; my $lexicon = $self->lexicon; my $comp = $self->compiled_entries; while ( my ( $k, $v ) = each %$entries ) { my $compiled_key = ( ($entries_are_in_gettext_style) ? $k : _maketext_to_gettext($k) ); $comp->{$compiled_key} = $v; $lexicon->{$compiled_key} = '' unless exists $lexicon->{$compiled_key}; } return %$lexicon; } =head3 normalize_space =cut my %Escapes = map { ( "\\$_" => eval("qq(\\$_)") ) } qw(t r f b a e); sub normalize_space { my ( $self, $msgid ) = @_; my $nospace = $msgid; $nospace =~ s/ +$//; return unless ( !$self->has_msgid($msgid) and $self->has_msgid($nospace) ); $self->set_msgstr( $msgid => $self->msgstr($nospace) . ( ' ' x ( length($msgid) - length($nospace) ) ) ); } =head2 Lexicon accessors msgids, has_msgid, msgstr, set_msgstr msg_positions, msg_variables, msg_format, msg_out =cut sub msgids { sort keys %{ $_[0]{lexicon} } } sub has_msgid { my $msg_str = $_[0]->msgstr( $_[1] ); return defined $msg_str ? length $msg_str : 0; } sub msg_positions { my ( $self, $msgid ) = @_; my %files = ( map { ( " $_->[0]:$_->[1]" => 1 ) } $self->compiled_entry($msgid) ); return $self->{wrap} ? join( "\n", ( map { '#:' . $_ } sort( keys %files ) ), '' ) : join( '', '#:', sort( keys %files ), "\n" ); } sub msg_variables { my ( $self, $msgid ) = @_; my $out = ''; my %seen; foreach my $entry ( grep { $_->[2] } $self->compiled_entry($msgid) ) { my ( $file, $line, $var ) = @$entry; $var =~ s/^\s*,\s*//; $var =~ s/\s*$//; $out .= "#. ($var)\n" unless !length($var) or $seen{$var}++; } return $out; } sub msg_format { my ( $self, $msgid ) = @_; return ", perl-maketext-format" if $msgid =~ /%(?:[1-9]\d*|\w+\([^\)]*\))/; return ''; } sub msg_out { my ( $self, $msgid ) = @_; my $msgstr = $self->msgstr($msgid); return "msgid " . _format($msgid) . "msgstr " . _format($msgstr); } =head2 Internal utilities _default_header _maketext_to_gettext _escape _format =cut sub _default_header { return << '.'; # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" . } sub _maketext_to_gettext { my $text = shift; return '' unless defined $text; $text =~ s{((?, L, L =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE =head1 COPYRIGHT Copyright 2003-2008 by Audrey Tang Ecpan@audreyt.orgE. This software is released under the MIT license cited below. =head2 The "MIT" License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut LOCALE_MAKETEXT_EXTRACT $fatpacked{"Locale/Maketext/Extract/Plugin/Base.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_BASE'; package Locale::Maketext::Extract::Plugin::Base; use strict; use File::Basename qw(fileparse); =head1 NAME Locale::Maketext::Extract::Plugin::Base - Base module for format parser plugins =head1 SYNOPSIS package My::Parser::Plugin; use base qw(Locale::Maketext::Extract::Plugin::Base); sub file_types { return [qw( ext ext2 )] } sub extract { my $self = shift; my $filename = shift; local $_ = shift; my $line = 1; while (my $found = $self->routine_to_extract_strings) { $self->add_entry($str,[$filename,$line,$vars]) } return; } =head1 DESCRIPTION All format parser plugins in Locale::Maketext::Extract inherit from Locale::Maketext::Extract::Plugin::Base. If you want to write your own custom parser plugin, you will need to inherit from this module, and provide C and C methods, as shown above. =head1 METHODS =over 4 =item new() $plugin = My::Parser->new( @file_types # Optionally specify a list of recognised file types ) =cut sub new { my $class = shift; my $self = bless { entries => [], }, $class; $self->_compile_file_types(@_); return $self; } =item add_entry() $plugin->add_entry($str,$line,$vars) =cut sub add_entry { my $self = shift; push @{$self->{entries}},[@_]; } =item C $entries = $plugin->entries; =cut #=================================== sub entries { #=================================== my $self = shift; return $self->{entries}; } =item C $plugin->clear Clears all stored entries. =cut #=================================== sub clear { #=================================== my $self = shift; $self->{entries}=[]; } =item file_types() @default_file_types = $plugin->file_types Returns a list of recognised file types that your module knows how to parse. Each file type can be one of: =over 4 =item * A plain string 'pl' => base filename is matched against qr/\.pl$/ '*' => all files are accepted =item * A regex qr/\.tt2?\./ => base filename is matched against this regex =item * A codref sub {} => this codref is called as $coderef->($base_filename,$path_to_file) It should return true or false =back =cut sub file_types { die "Please override sub file_types() to return " . "a list of recognised file extensions, or regexes"; } =item extract() $plugin->extract($filecontents); extract() is the method that will be called to process the contents of the current file. When it finds a string that should be extracted, it should call $self->add_entry($string,$line,$vars]) where C<$vars> refers to any arguments that are being passed to the localise function. For instance: l("You found [quant,_1,file,files]",files_found) string: "You found [quant,_1,file,files]" vars : (files_found) IMPORTANT: a single plugin instance is used for all files, so if you plan on storing state information in the C<$plugin> object, this should be cleared out at the beginning of C =cut sub extract { die "Please override sub extract()"; } sub _compile_file_types { my $self = shift; my @file_types = ref $_[0] eq 'ARRAY' ? @{ shift @_ } : @_; @file_types = $self->file_types unless @file_types; my @checks; if ( grep { $_ eq '*' } @file_types ) { $self->{file_checks} = [ sub {1} ]; return; } foreach my $type (@file_types) { if ( ref $type eq 'CODE' ) { push @checks, $type; next; } else { my $regex = ref $type ? $type : qr/^.*\.\Q$type\E$/; push @checks, sub { $_[0] =~ m/$regex/ }; } } $self->{file_checks} = \@checks; } =item known_file_type() if ($plugin->known_file_type($filename_with_path)) { .... } Determines whether the current file should be handled by this parser, based either on the list of file_types specified when this object was created, or the default file_types specified in the module. =cut sub known_file_type { my $self = shift; my ( $name, $path ) = fileparse( shift @_ ); foreach my $check ( @{ $self->{file_checks} } ) { return 1 if $check->( $name, $path ); } return 0; } =back =head1 SEE ALSO =over 4 =item L for extracting translatable strings from common template systems and perl source files. =item L =item L =item L =item L =item L =item L =item L =item L =item L =back =head1 AUTHORS Clinton Gormley [DRTECH] Eclinton@traveljury.comE =head1 COPYRIGHT Copyright 2002-2008 by Audrey Tang Ecpan@audreyt.orgE. This software is released under the MIT license cited below. =head2 The "MIT" License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut 1; LOCALE_MAKETEXT_EXTRACT_PLUGIN_BASE $fatpacked{"Locale/Maketext/Extract/Plugin/FormFu.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_FORMFU'; package Locale::Maketext::Extract::Plugin::FormFu; use strict; use base qw(Locale::Maketext::Extract::Plugin::Base); =head1 NAME Locale::Maketext::Extract::Plugin::FormFu - FormFu format parser =head1 SYNOPSIS $plugin = Locale::Maketext::Extract::Plugin::FormFu->new( $lexicon # A Locale::Maketext::Extract object @file_types # Optionally specify a list of recognised file types ) $plugin->extract($filename,$filecontents); =head1 DESCRIPTION HTML::FormFu uses a config-file to generate forms, with built in support for localizing errors, labels etc. =head1 SHORT PLUGIN NAME formfu =head1 VALID FORMATS We extract the text after any key which ends in C<_loc>: content_loc: this is the string message_loc: ['Max length [_1]', 10] =head1 KNOWN FILE TYPES =over 4 =item .yaml =item .yml =item .conf =back =head1 REQUIRES L =head1 NOTES The docs for the YAML module describes it as alpha code. It is not as tolerant of errors as L. However, because it is pure Perl, it is easy to hook into. I have seen it enter endless loops, so if xgettext.pl hangs, try running it again with C<--verbose --verbose> (twice) enabled, so that you can see if the fault lies with YAML. If it does, either correct the YAML source file, or use the file_types to exclude that file. =cut sub file_types { return qw( yaml yml conf ); } sub extract { my $self = shift; my $data = shift; my $y = Locale::Maketext::Extract::Plugin::FormFu::Extractor->new(); $y->load($data); foreach my $entry ( @{ $y->found } ) { $self->add_entry(@$entry); } } package Locale::Maketext::Extract::Plugin::FormFu::Extractor; use base qw(YAML::Loader); #=================================== sub new { #=================================== my $class = shift; my $self = $class->SUPER::new(@_); $self->{found} = []; return $self; } #=================================== sub _check_key { #=================================== my $self = shift; my ( $key, $value, $line ) = @_; my ( $str, $vars ); if ( ref $value ) { return if ref $value ne 'ARRAY'; $str = shift @$value; $vars = join( ', ', @$value ); } else { $str = $value; } return unless $key && $key =~ /_loc$/ && defined $str; push @{ $self->{found} }, [ $str, $line, $vars ]; } #=================================== sub _parse_mapping { #=================================== my $self = shift; my ($anchor) = @_; my $mapping = {}; $self->anchor2node->{$anchor} = $mapping; my $key; while ( not $self->done and $self->indent == $self->offset->[ $self->level ] ) { # If structured key: if ( $self->{content} =~ s/^\?\s*// ) { $self->preface( $self->content ); $self->_parse_next_line(YAML::Loader::COLLECTION); $key = $self->_parse_node(); $key = "$key"; } # If "default" key (equals sign) elsif ( $self->{content} =~ s/^\=\s*// ) { $key = YAML::Loader::VALUE; } # If "comment" key (slash slash) elsif ( $self->{content} =~ s/^\=\s*// ) { $key = YAML::Loader::COMMENT; } # Regular scalar key: else { $self->inline( $self->content ); $key = $self->_parse_inline(); $key = "$key"; $self->content( $self->inline ); $self->inline(''); } unless ( $self->{content} =~ s/^:\s*// ) { $self->die('YAML_LOAD_ERR_BAD_MAP_ELEMENT'); } $self->preface( $self->content ); my $line = $self->line; $self->_parse_next_line(YAML::Loader::COLLECTION); my $value = $self->_parse_node(); if ( exists $mapping->{$key} ) { $self->warn('YAML_LOAD_WARN_DUPLICATE_KEY'); } else { $mapping->{$key} = $value; $self->_check_key( $key, $value, $line ); } } return $mapping; } #=================================== sub _parse_inline_mapping { #=================================== my $self = shift; my ($anchor) = @_; my $node = {}; my $start_line = $self->{_start_line}; $self->anchor2node->{$anchor} = $node; $self->die('YAML_PARSE_ERR_INLINE_MAP') unless $self->{inline} =~ s/^\{\s*//; while ( not $self->{inline} =~ s/^\s*\}// ) { my $key = $self->_parse_inline(); $self->die('YAML_PARSE_ERR_INLINE_MAP') unless $self->{inline} =~ s/^\: \s*//; my $value = $self->_parse_inline(); if ( exists $node->{$key} ) { $self->warn('YAML_LOAD_WARN_DUPLICATE_KEY'); } else { $node->{$key} = $value; $self->_check_key( $key, $value, $start_line ); } next if $self->inline =~ /^\s*\}/; $self->die('YAML_PARSE_ERR_INLINE_MAP') unless $self->{inline} =~ s/^\,\s*//; } return $node; } #=================================== sub _parse_next_line { #=================================== my $self = shift; $self->{_start_line} = $self->line; $self->SUPER::_parse_next_line(@_); } #=================================== sub found { #=================================== my $self = shift; return $self->{found}; } =head1 SEE ALSO =over 4 =item L for extracting translatable strings from common template systems and perl source files. =item L =item L =item L =item L =item L =item L =item L =item L =item L =item L =back =head1 AUTHORS Clinton Gormley Eclint@traveljury.comE =head1 COPYRIGHT Copyright 2002-2008 by Audrey Tang Ecpan@audreyt.orgE. This software is released under the MIT license cited below. =head2 The "MIT" License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut 1; LOCALE_MAKETEXT_EXTRACT_PLUGIN_FORMFU $fatpacked{"Locale/Maketext/Extract/Plugin/Generic.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_GENERIC'; package Locale::Maketext::Extract::Plugin::Generic; use strict; use base qw(Locale::Maketext::Extract::Plugin::Base); =head1 NAME Locale::Maketext::Extract::Plugin::Generic - Generic template parser =head1 SYNOPSIS $plugin = Locale::Maketext::Extract::Plugin::Generic->new( $lexicon # A Locale::Maketext::Extract object @file_types # Optionally specify a list of recognised file types ) $plugin->extract($filename,$filecontents); =head1 DESCRIPTION Extracts strings to localise from generic templates. =head1 SHORT PLUGIN NAME generic =head1 VALID FORMATS Strings inside {{...}} are extracted. =head1 KNOWN FILE TYPES =over 4 =item All file types =back =cut sub file_types { return qw( * ); } sub extract { my $self = shift; local $_ = shift; my $line = 1; # Generic Template: $line = 1; pos($_) = 0; while (m/\G(.*?(?add_entry($str, $line, $vars ); } my $quoted = '(\')([^\\\']*(?:\\.[^\\\']*)*)(\')|(\")([^\\\"]*(?:\\.[^\\\"]*)*)(\")'; # Comment-based mark: "..." # loc $line = 1; pos($_) = 0; while (m/\G(.*?($quoted)[\}\)\],;]*\s*\#\s*loc\s*$)/smog) { my $str = substr($2, 1, -1); $line += ( () = ( $1 =~ /\n/g ) ); # cryptocontext! $str =~ s/\\(["'])/$1/g; $self->add_entry($str, $line, '' ); } # Comment-based pair mark: "..." => "..." # loc_pair $line = 1; pos($_) = 0; while (m/\G(.*?(\w+)\s*=>\s*($quoted)[\}\)\],;]*\s*\#\s*loc_pair\s*$)/smg) { my $key = $2; my $val = substr($3, 1, -1); $line += ( () = ( $1 =~ /\n/g ) ); # cryptocontext! $key =~ s/\\(["'])/$1/g; $val =~ s/\\(["'])/$1/g; $self->add_entry($val, $line, '' ); } } =head1 SEE ALSO =over 4 =item L for extracting translatable strings from common template systems and perl source files. =item L =item L =item L =item L =item L =item L =item L =item L =back =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE =head1 COPYRIGHT Copyright 2002-2008 by Audrey Tang Ecpan@audreyt.orgE. This software is released under the MIT license cited below. =head2 The "MIT" License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut 1; LOCALE_MAKETEXT_EXTRACT_PLUGIN_GENERIC $fatpacked{"Locale/Maketext/Extract/Plugin/Mason.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_MASON'; package Locale::Maketext::Extract::Plugin::Mason; use strict; use base qw(Locale::Maketext::Extract::Plugin::Base); =head1 NAME Locale::Maketext::Extract::Plugin::Mason - Mason format parser =head1 SYNOPSIS $plugin = Locale::Maketext::Extract::Plugin::Mason->new( $lexicon # A Locale::Maketext::Extract object @file_types # Optionally specify a list of recognised file types ) $plugin->extract($filename,$filecontents); =head1 DESCRIPTION Extracts strings to localise from Mason files. =head1 SHORT PLUGIN NAME mason =head1 VALID FORMATS Strings inside <&|/l>... and <&|/loc>... are extracted. =head1 KNOWN FILE TYPES =over 4 =item All file types =back =cut sub file_types { return qw( * ); } sub extract { my $self = shift; local $_ = shift; my $line = 1; # HTML::Mason while (m!\G(.*?<&\|/l(?:oc)?(.*?)&>(.*?))!sg) { my ($vars, $str) = ($2, $3); $line += ( () = ($1 =~ /\n/g) ); # cryptocontext! $self->add_entry($str, $line, $vars ); } } =head1 SEE ALSO =over 4 =item L for extracting translatable strings from common template systems and perl source files. =item L =item L =item L =item L =item L =item L =item L =item L =back =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE =head1 COPYRIGHT Copyright 2002-2008 by Audrey Tang Ecpan@audreyt.orgE. This software is released under the MIT license cited below. =head2 The "MIT" License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut 1; LOCALE_MAKETEXT_EXTRACT_PLUGIN_MASON $fatpacked{"Locale/Maketext/Extract/Plugin/PPI.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_PPI'; package Locale::Maketext::Extract::Plugin::PPI; use strict; use base qw(Locale::Maketext::Extract::Plugin::Base); use PPI(); =head1 NAME Locale::Maketext::Extract::Plugin::PPI - Perl format parser =head1 SYNOPSIS $plugin = Locale::Maketext::Extract::Plugin::PPI->new( $lexicon # A Locale::Maketext::Extract object @file_types # Optionally specify a list of recognised file types ) $plugin->extract($filename,$filecontents); =head1 DESCRIPTION Does exactly the same thing as the L parser, but more accurately, and more slowly. Considerably more slowly! For this reason it isn't a built-in plugin. =head1 SHORT PLUGIN NAME none - the module must be specified in full =head1 VALID FORMATS Valid localization function names are: =over 4 =item translate =item maketext =item gettext =item loc =item x =item _ =item __ =back =head1 KNOWN FILE TYPES =over 4 =item .pm =item .pl =item .cgi =back =cut sub file_types { return qw( pm pl cgi ); } my %subnames = map { $_ => 1 } qw (translate maketext gettext loc x __); #=================================== sub extract { #=================================== my $self = shift; my $text = shift; my $doc = PPI::Document->new( \$text, index_locations => 1 ); foreach my $statement ( @{ $doc->find('PPI::Statement') } ) { my @children = $statement->schildren; while ( my $child = shift @children ) { next unless @children && ( $child->isa('PPI::Token::Word') && $subnames{ $child->content } || $child->isa('PPI::Token::Magic') && $child->content eq '_' ); my $list = shift @children; next unless $list->isa('PPI::Structure::List') && $list->schildren; $self->_check_arg_list($list); } } } #=================================== sub _check_arg_list { #=================================== my $self = shift; my $list = shift; my @args = ( $list->schildren )[0]->schildren; my $final_string = ''; my ( $line, $mode ); while ( my $string_el = shift @args ) { return unless $string_el->isa('PPI::Token::Quote') || $string_el->isa('PPI::Token::HereDoc'); $line ||= $string_el->location->[0]; my $string; if ( $string_el->isa('PPI::Token::HereDoc') ) { $string = join( '', $string_el->heredoc ); $mode = $string_el->{_mode} eq 'interpolate' ? 'double' : 'literal'; } else { $string = $string_el->string; $mode = $string_el->isa('PPI::Token::Quote::Literal') ? 'literal' : ( $string_el->isa('PPI::Token::Quote::Double') || $string_el->isa('PPI::Token::Quote::Interpolate') ) ? 'double' : 'single'; } if ( $mode eq 'double' ) { return if !!( $string =~ /(?isa('PPI::Token::Operator') && $next_op->content eq '.'; } return unless $final_string; my $vars = join( '', map { $_->content } @args ); $self->add_entry( $final_string, $line, $vars ); } =head1 SEE ALSO =over 4 =item L for extracting translatable strings from common template systems and perl source files. =item L =item L =item L =item L =item L =item L =item L =item L =item L =back =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE =head1 COPYRIGHT Copyright 2002-2008 by Audrey Tang Ecpan@audreyt.orgE. This software is released under the MIT license cited below. =head2 The "MIT" License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut 1; LOCALE_MAKETEXT_EXTRACT_PLUGIN_PPI $fatpacked{"Locale/Maketext/Extract/Plugin/Perl.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_PERL'; package Locale::Maketext::Extract::Plugin::Perl; use strict; use base qw(Locale::Maketext::Extract::Plugin::Base); =head1 NAME Locale::Maketext::Extract::Plugin::Perl - Perl format parser =head1 SYNOPSIS $plugin = Locale::Maketext::Extract::Plugin::Perl->new( $lexicon # A Locale::Maketext::Extract object @file_types # Optionally specify a list of recognised file types ) $plugin->extract($filename,$filecontents); =head1 DESCRIPTION Extracts strings to localise (including HEREDOCS and concatenated strings) from Perl code. This Perl parser is very fast and very good, but not perfect - it does make mistakes. The PPI parser (L) is more accurate, but a lot slower, and so is not enabled by default. =head1 SHORT PLUGIN NAME perl =head1 VALID FORMATS Valid localization function names are: =over 4 =item translate =item maketext =item gettext =item loc =item x =item _ =item __ =back =head1 KNOWN FILE TYPES =over 4 =item .pm =item .pl =item .cgi =back =cut use constant NUL => 0; use constant BEG => 1; use constant PAR => 2; use constant HERE => 10; use constant QUO1 => 3; use constant QUO2 => 4; use constant QUO3 => 5; use constant QUO4 => 6; use constant QUO5 => 7; use constant QUO6 => 8; use constant QUO7 => 9; sub file_types { return qw( pm pl cgi ); } sub extract { my $self = shift; local $_ = shift; local $SIG{__WARN__} = sub { die @_ }; # Perl code: my ( $state, $line_offset, $str, $str_part, $vars, $quo, $heredoc ) = ( 0, 0 ); my $orig = 1 + ( () = ( ( my $__ = $_ ) =~ /\n/g ) ); PARSER: { $_ = substr( $_, pos($_) ) if ( pos($_) ); my $line = $orig - ( () = ( ( my $__ = $_ ) =~ /\n/g ) ); # various ways to spell the localization function $state == NUL && m/\b(translate|maketext|gettext|__?|loc(?:ali[sz]e)?|x)/gc && do { $state = BEG; redo }; $state == BEG && m/^([\s\t\n]*)/gc && redo; # begin () $state == BEG && m/^([\S\(])\s*/gc && do { $state = ( ( $1 eq '(' ) ? PAR : NUL ); redo }; # concat $state == PAR && defined($str) && m/^(\s*\.\s*)/gc && do { $line_offset += ( () = ( ( my $__ = $1 ) =~ /\n/g ) ); redo }; # str_part $state == PAR && defined($str_part) && do { if ( ( $quo == QUO1 ) || ( $quo == QUO5 ) ) { $str_part =~ s/\\([\\'])/$1/g if ($str_part); # normalize q strings } elsif ( $quo != QUO6 ) { $str_part =~ s/(\\(?:[0x]..|c?.))/"qq($1)"/eeg if ($str_part); # normalize qq / qx strings } $str .= $str_part; undef $str_part; undef $quo; redo; }; # begin or end of string $state == PAR && m/^(\')/gc && do { $state = $quo = QUO1; redo }; $state == QUO1 && m/^([^'\\]+)/gc && do { $str_part .= $1; redo }; $state == QUO1 && m/^((?:\\.)+)/gcs && do { $str_part .= $1; redo }; $state == QUO1 && m/^\'/gc && do { $state = PAR; redo }; $state == PAR && m/^\"/gc && do { $state = $quo = QUO2; redo }; $state == QUO2 && m/^([^"\\]+)/gc && do { $str_part .= $1; redo }; $state == QUO2 && m/^((?:\\.)+)/gcs && do { $str_part .= $1; redo }; $state == QUO2 && m/^\"/gc && do { $state = PAR; redo }; $state == PAR && m/^\`/gc && do { $state = $quo = QUO3; redo }; $state == QUO3 && m/^([^\`]*)/gc && do { $str_part .= $1; redo }; $state == QUO3 && m/^\`/gc && do { $state = PAR; redo }; $state == PAR && m/^qq\{/gc && do { $state = $quo = QUO4; redo }; $state == QUO4 && m/^([^\}]*)/gc && do { $str_part .= $1; redo }; $state == QUO4 && m/^\}/gc && do { $state = PAR; redo }; $state == PAR && m/^q\{/gc && do { $state = $quo = QUO5; redo }; $state == QUO5 && m/^([^\}]*)/gc && do { $str_part .= $1; redo }; $state == QUO5 && m/^\}/gc && do { $state = PAR; redo }; # find heredoc terminator, then get the #heredoc and go back to current position $state == PAR && m/^<<\s*\'/gc && do { $state = $quo = QUO6; $heredoc = ''; redo }; $state == QUO6 && m/^([^'\\\n]+)/gc && do { $heredoc .= $1; redo }; $state == QUO6 && m/^((?:\\.)+)/gc && do { $heredoc .= $1; redo }; $state == QUO6 && m/^\'/gc && do { $state = HERE; $heredoc =~ s/\\\'/\'/g; redo }; $state == PAR && m/^<<\s*\"/gc && do { $state = $quo = QUO7; $heredoc = ''; redo }; $state == QUO7 && m/^([^"\\\n]+)/gc && do { $heredoc .= $1; redo }; $state == QUO7 && m/^((?:\\.)+)/gc && do { $heredoc .= $1; redo }; $state == QUO7 && m/^\"/gc && do { $state = HERE; $heredoc =~ s/\\\"/\"/g; redo }; $state == PAR && m/^<<(\w*)/gc && do { $state = HERE; $quo = QUO7; $heredoc = $1; redo }; # jump ahaid and get the heredoc, then s/// also # resets the pos and we are back at the current pos $state == HERE && m/^.*\r?\n/gc && s/\G(.*?\r?\n)$heredoc(\r?\n)//s && do { $state = PAR; $str_part .= $1; $line_offset++; redo }; # end () # $state == PAR && m/^\s*[\)]/gc && do { $state = NUL; $vars =~ s/[\n\r]//g if ($vars); $self->add_entry( $str, $line - ( () = $str =~ /\n/g ) - $line_offset, $vars ) if $str; undef $str; undef $vars; undef $heredoc; $line_offset = 0; redo; }; # a line of vars $state == PAR && m/^([^\)]*)/gc && do { $vars .= "$1\n"; redo }; } } =head1 SEE ALSO =over 4 =item L for extracting translatable strings from common template systems and perl source files. =item L =item L =item L =item L =item L =item L =item L =item L =item L =back =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE =head1 COPYRIGHT Copyright 2002-2008 by Audrey Tang Ecpan@audreyt.orgE. This software is released under the MIT license cited below. =head2 The "MIT" License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =cut 1; LOCALE_MAKETEXT_EXTRACT_PLUGIN_PERL $fatpacked{"Locale/Maketext/Extract/Plugin/TT2.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_TT2'; package Locale::Maketext::Extract::Plugin::TT2; use strict; use base qw(Locale::Maketext::Extract::Plugin::Base); use Template::Constants qw( :debug ); use Template::Parser; =head1 NAME Locale::Maketext::Extract::Plugin::TT2 - Template Toolkit format parser =head1 SYNOPSIS $plugin = Locale::Maketext::Extract::Plugin::TT2->new( $lexicon # A Locale::Maketext::Extract object @file_types # Optionally specify a list of recognised file types ) $plugin->extract($filename,$filecontents); =head1 DESCRIPTION Extracts strings to localise from Template Toolkit templates. =head1 SHORT PLUGIN NAME tt2 =head1 VALID FORMATS Valid formats are: =over 4 =item [% |l(args) %]string[% END %] =item [% 'string' | l(args) %] =item [% l('string',args) %] =back l and loc are interchangeable. | and FILTER are interchangeable. =head1 KNOWN FILE TYPES =over 4 =item .tt =item .tt2 =item .html =item .tt.* =item .tt2.* =back =head1 REQUIRES L