-
-
Save rwstauner/962861 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# 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/<db.h>/<db$ver\\/db.h>/", '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 <sys/types.h> | |
-#ifdef __linux__ | |
-#include <asm/page.h> | |
-#endif | |
#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM) | |
#include <sys/ipc.h> | |
#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 <sys/types.h> | |
-#ifdef __linux__ | |
-# include <asm/page.h> | |
-#endif | |
#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM) | |
#ifndef HAS_SEM | |
# include <sys/ipc.h> | |
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 <UU/$file.c | | |
- $sed \ | |
- -e '1d' \ | |
- -e '/^#.*<stdin>/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 <UU/$file.c | | |
+ $sed \ | |
+ -e '/^#.*<stdin>/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 <UU/$file.c >.cout 2>.cerr | |
+ $sed \ | |
+ -e '1d' \ | |
+ -e '/^#.*<stdin>/d' \ | |
+ -e '/^#.*<builtin>/d' \ | |
+ -e '/^#.*<built-in>/d' \ | |
+ -e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 <UU/$file.c | | |
$sed \ | |
-e '/^#.*<stdin>/d' \ | |
@@ -151,18 +159,24 @@ | |
-e 's|\.c\.c|.c|' $uwinfix | \ | |
$uniq | $sort | $uniq >> .deptmp | |
else | |
- $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c | | |
+ $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c >.cout 2>.cerr | |
$sed \ | |
-e '1d' \ | |
-e '/^#.*<stdin>/d' \ | |
+ -e '/^#.*<builtin>/d' \ | |
+ -e '/^#.*<built-in>/d' \ | |
+ -e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 <UU/$file.c | | |
$sed \ | |
-e '/^#.*<stdin>/d' \ | |
@@ -156,21 +159,24 @@ | |
-e 's|\.c\.c|.c|' $uwinfix | \ | |
$uniq | $sort | $uniq >> .deptmp | |
else | |
- $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c | | |
+ $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c >.cout 2>.cerr | |
$sed \ | |
-e '1d' \ | |
-e '/^#.*<stdin>/d' \ | |
- -e '/^#.*<builtin>/d' \ | |
- -e '/^#.*<built-in>/d' \ | |
- -e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<builtin>/d' \ | |
+ -e '/^#.*<built-in>/d' \ | |
+ -e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 <UU/$file.c | | |
$sed \ | |
-e '/^#.*<stdin>/d' \ | |
@@ -147,18 +159,24 @@ | |
-e 's|\.c\.c|.c|' $uwinfix | \ | |
$uniq | $sort | $uniq >> .deptmp | |
else | |
- $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c | | |
+ $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c >.cout 2>.cerr | |
$sed \ | |
-e '1d' \ | |
-e '/^#.*<stdin>/d' \ | |
+ -e '/^#.*<builtin>/d' \ | |
+ -e '/^#.*<built-in>/d' \ | |
+ -e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 <UU/$file.c | | |
$sed \ | |
-e '/^#.*<stdin>/d' \ | |
@@ -151,18 +159,24 @@ | |
-e 's|\.c\.c|.c|' $uwinfix | \ | |
$uniq | $sort | $uniq >> .deptmp | |
else | |
- $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c | | |
+ $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c >.cout 2>.cerr | |
$sed \ | |
-e '1d' \ | |
-e '/^#.*<stdin>/d' \ | |
+ -e '/^#.*<builtin>/d' \ | |
+ -e '/^#.*<built-in>/d' \ | |
+ -e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 <<!GROK!THIS! | |
@@ -33,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 | |
@@ -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 <UU/$file.c | | |
$sed \ | |
-e '/^#.*<stdin>/d' \ | |
@@ -155,18 +159,24 @@ | |
-e 's|\.c\.c|.c|' $uwinfix | \ | |
$uniq | $sort | $uniq >> .deptmp | |
else | |
- $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c | | |
+ $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c >.cout 2>.cerr | |
$sed \ | |
-e '1d' \ | |
-e '/^#.*<stdin>/d' \ | |
+ -e '/^#.*<builtin>/d' \ | |
+ -e '/^#.*<built-in>/d' \ | |
+ -e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 <<!GROK!THIS! | |
@@ -33,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 | |
@@ -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 <UU/$file.c | | |
$sed \ | |
@@ -143,13 +159,16 @@ | |
-e 's|\.c\.c|.c|' $uwinfix | \ | |
$uniq | $sort | $uniq >> .deptmp | |
else | |
- $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c 2>&1 | | |
+ $cppstdin $finc -I. $cppflags $cppminus <UU/$file.c >.cout 2>.cerr | |
$sed \ | |
-e '1d' \ | |
-e '/^#.*<stdin>/d' \ | |
-e '/^#.*<builtin>/d' \ | |
+ -e '/^#.*<built-in>/d' \ | |
-e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 <UU/$file.c | | |
$sed \ | |
@@ -157,7 +166,9 @@ | |
-e '/^#.*<builtin>/d' \ | |
-e '/^#.*<built-in>/d' \ | |
-e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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 '/^#.*<builtin>/d' \ | |
-e '/^#.*<built-in>/d' \ | |
-e '/^#.*<command line>/d' \ | |
+ -e '/^#.*<command-line>/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<Devel::PPort>'s | |
C<buildperl.pl>. | |
It does not build perls, it merely provides an interface to the source patching | |
functionality. | |
=head1 FUNCTION | |
=over | |
=item C<patch_source> | |
Takes two parameters, a C<perl> version and the path to unwrapped perl source for that version. | |
It dies on any errors. | |
If you don't supply a C<perl> version, it will attempt to auto-determine the | |
C<perl> 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<Devel::PPPort> | |
=head1 AUTHOR | |
Chris Williams <[email protected]> | |
=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<hints> file for a particular | |
perl port. This module provides fixed C<hints> files encoded using | |
C<MIME::Base64>. | |
=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<hint_file> | |
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<hints> file suitable for writing straight to a | |
file handle or undef list if there isn't an applicable C<hints> 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<hints> file that | |
will need to be amended, the second item will be a string with the decoded content of the C<hints> file suitable | |
for writing straight to a file handle. Otherwise an empty list will be returned. | |
=back | |
=head1 AUTHOR | |
Chris Williams <[email protected]> | |
=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<xgettext.pl>, 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<translate>, C<maketext>, | |
C<gettext>, C<loc>, C<x>, 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<perl>), but must be specified | |
in full. | |
=item HTML::Mason (plugin: mason) | |
Strings inside C<E<lt>&|/lE<gt>I<...>E<lt>/&E<gt>> and | |
C<E<lt>&|/locE<gt>I<...>E<lt>/&E<gt>> 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<STARTxxx> and C<ENDxxx> 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</"Plugins">, L</"Warnings"> and L</"Verbose"> 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<perl> : L<Locale::Maketext::Extract::Plugin::Perl> | |
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<Locale::Maketext::Extract::Plugin::PPI> | |
=item C<tt2> : L<Locale::Maketext::Extract::Plugin::TT2> | |
=item C<yaml> : L<Locale::Maketext::Extract::Plugin::YAML> | |
=item C<formfu> : L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item C<mason> : L<Locale::Maketext::Extract::Plugin::Mason> | |
=item C<text> : L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item C<generic> : L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
Also, see L<Locale::Maketext::Extract::Plugin::Base> 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<verbose>. 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 (<LEXICON>) { | |
( 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( $_, <LEXICON> ); | |
} | |
# 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 <FH>; | |
$self->extract( $file => $content ); | |
close FH; | |
} | |
=head2 Compilation | |
=head3 compile($entries_are_in_gettext_style?) | |
Merges the C<entries> into C<compiled_entries>. | |
If C<$entries_are_in_gettext_style> is true, the previously extracted entries | |
are assumed to be in the B<Gettext> style (e.g. C<%1>). | |
Otherwise they are assumed to be in B<Maketext> style (e.g. C<[_1]>) and are | |
converted into B<Gettext> style before merging into C<compiled_entries>. | |
The C<entries> are I<not> 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 <EMAIL@ADDRESS>, 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 <EMAIL@ADDRESS>\n" | |
"Language-Team: LANGUAGE <[email protected]>\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{((?<!~)(?:~~)*)\[_([1-9]\d*|\*)\]} | |
{$1%$2}g; | |
$text =~ s{((?<!~)(?:~~)*)\[([A-Za-z#*]\w*),([^\]]+)\]} | |
{"$1%$2(" . _escape($3) . ')'}eg; | |
$text =~ s/~([\~\[\]])/$1/g; | |
return $text; | |
} | |
sub _escape { | |
my $text = shift; | |
$text =~ s/\b_([1-9]\d*)/%$1/g; | |
return $text; | |
} | |
sub _format { | |
my $str = shift; | |
$str =~ s/(?=[\\"])/\\/g; | |
while ( my ( $char, $esc ) = each %Escapes ) { | |
$str =~ s/$esc/$char/g; | |
} | |
return "\"$str\"\n" unless $str =~ /\n/; | |
my $multi_line = ( $str =~ /\n(?!\z)/ ); | |
$str =~ s/\n/\\n"\n"/g; | |
if ( $str =~ /\n"$/ ) { | |
chop $str; | |
} | |
else { | |
$str .= "\"\n"; | |
} | |
return $multi_line ? qq(""\n"$str) : qq("$str); | |
} | |
1; | |
=head1 ACKNOWLEDGMENTS | |
Thanks to Jesse Vincent for contributing to an early version of this | |
module. | |
Also to Alain Barbet, who effectively re-wrote the source parser with a | |
flex-like algorithm. | |
=head1 SEE ALSO | |
L<xgettext.pl>, L<Locale::Maketext>, L<Locale::Maketext::Lexicon> | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2003-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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<file_types()> and C<extract()> 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()> | |
$entries = $plugin->entries; | |
=cut | |
#=================================== | |
sub entries { | |
#=================================== | |
my $self = shift; | |
return $self->{entries}; | |
} | |
=item C<clear()> | |
$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<extract()> | |
=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<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::PPI> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::Mason> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
=head1 AUTHORS | |
Clinton Gormley [DRTECH] E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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<YAML> | |
=head1 NOTES | |
The docs for the YAML module describes it as alpha code. It is not as tolerant | |
of errors as L<YAML::Syck>. 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<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<YAML> | |
=item L<HTML::FormFu> | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::Mason> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
=head1 AUTHORS | |
Clinton Gormley E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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(.*?(?<!\{)\{\{(?!\{)(.*?)\}\})/sg) { | |
my ($vars, $str) = ('', $2); | |
$line += ( () = ($1 =~ /\n/g) ); # cryptocontext! | |
$self->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<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::Mason> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=back | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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<Locale::Maketext::Extract::Plugin::Perl> | |
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 =~ /(?<!\\)(?:\\\\)*[\$\@]/ ); | |
$string = eval qq("$string"); | |
} | |
elsif ( $mode eq 'single' ) { | |
$string =~ s/\\'/'/g; | |
} | |
# $string =~ s/(?<!\\)\\//g; | |
$string =~ s/\\\\/\\/g; | |
# unless $mode eq 'literal'; | |
$final_string .= $string; | |
my $next_op = shift @args; | |
last | |
unless $next_op | |
&& $next_op->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<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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<Locale::Maketext::Extract::Plugin::PPI>) 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<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::PPI> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::Mason> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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<Template> | |
=head1 NOTES | |
=over 4 | |
=item * | |
B<BEWARE> Using the C<loc> form can give false positives if you use the Perl parser | |
plugin on TT files. If you want to use the C<loc> form, then you should | |
specify the file types that you want to the Perl plugin to parse, or enable | |
the default file types, eg: | |
xgetext.pl -P perl .... # default file types | |
xgettext.pl -P perl=pl,pm ... # specified file types | |
=item * | |
The string-to-be-localised must be a string, not a variable. We try not | |
to extract calls to your localise function which contain variables eg: | |
l('string',arg) # extracted | |
l(var,arg) # not extracted | |
This doesn't work for block filters, so don't do that. Eg: | |
[% FILTER l %] | |
string [% var %] # BAD! | |
[% END %] | |
=item * | |
Getting the right line number is difficult in TT. Often it'll be a range | |
of lines, or it may be thrown out by the use of PRE_CHOMP or POST_CHOMP. It will | |
always be within a few lines of the correct location. | |
=item * | |
If you have PRE/POST_CHOMP enabled by default in your templates, then you should | |
extract the strings using the same values. In order to set them, you can | |
use the following wrapper script: | |
#!/usr/bin/perl | |
use Locale::Maketext::Extract::Run qw(xgettext); | |
use Locale::Maketext::Extract::Plugin::TT2(); | |
%Locale::Maketext::Extract::Plugin::TT2::PARSER_OPTIONS = ( | |
PRE_CHOMP => 1, # or 2 | |
POST_CHOMP => 1, # or 2 | |
# Also START/END_TAG, ANYCASE, INTERPOLATE, V1DOLLAR, EVAL_PERL | |
); | |
xgettext(@ARGV); | |
=back | |
=cut | |
# import strip_quotes | |
*strip_quotes | |
= \&Locale::Maketext::Extract::Plugin::TT2::Directive::strip_quotes; | |
our %PARSER_OPTIONS; | |
#=================================== | |
sub file_types { | |
#=================================== | |
return ( qw( tt tt2 html ), qr/\.tt2?\./ ); | |
} | |
my %Escapes = map { ( "\\$_" => eval("qq(\\$_)") ) } qw(t n r f b a e); | |
#=================================== | |
sub extract { | |
#=================================== | |
my $self = shift; | |
my $data = shift; | |
$Template::Directive::PRETTY = 1; | |
my $parser = | |
Locale::Maketext::Extract::Plugin::TT2::Parser->new( | |
%PARSER_OPTIONS, | |
FACTORY => 'Locale::Maketext::Extract::Plugin::TT2::Directive', | |
FILE_INFO => 0, | |
); | |
_init_overrides($parser); | |
$parser->{extracted} = []; | |
$Locale::Maketext::Extract::Plugin::TT2::Directive::PARSER | |
= $parser; # hack | |
$parser->parse($data) | |
|| die $parser->error; | |
foreach my $entry ( @{ $parser->{extracted} } ) { | |
$entry->[2] =~ s/^\((.*)\)$/$1/s; # Remove () from vars | |
$_ =~ s/\\'/'/gs # Unescape \' | |
for @{$entry}[ 0, 2 ]; | |
$entry->[2] =~ s/\\(?!")/\\\\/gs; # Escape all \ not followed by " | |
# Escape argument lists correctly | |
while ( my ( $char, $esc ) = each %Escapes ) { | |
$entry->[2] =~ s/$esc/$char/g; | |
} | |
$entry->[1] =~ s/\D+.*$//; | |
$self->add_entry(@$entry); | |
} | |
} | |
#=================================== | |
sub _init_overrides { | |
#=================================== | |
my $parser = shift; | |
# Override the concatenation sub to return _ instead of . | |
my $states = $parser->{STATES}; | |
foreach my $state ( @{$states} ) { | |
if ( my $CAT_no = $state->{ACTIONS}{CAT} ) { | |
my $CAT_rule_no | |
= $states->[ $states->[$CAT_no]{GOTOS}{expr} ]->{DEFAULT}; | |
# override the TT::Grammar sub which cats two args | |
$parser->{RULES}[ -$CAT_rule_no ][2] = sub { | |
my $first = ( $_[1] ); | |
my $second = ( $_[3] ); | |
if ( strip_quotes($first) && strip_quotes($second) ) { | |
# both are literal | |
return "'${first}${second}'"; | |
} | |
else { | |
# at least one is an ident | |
return "$_[1] _ $_[3]"; | |
} | |
}; | |
last; | |
} | |
} | |
} | |
#=================================== | |
#=================================== | |
package Locale::Maketext::Extract::Plugin::TT2::Parser; | |
#=================================== | |
#=================================== | |
use base 'Template::Parser'; | |
# disabled location() because it was adding unneccessary text | |
# to filter blocks | |
#=================================== | |
sub location {''} | |
#=================================== | |
# Custom TT parser for Locale::Maketext::Lexicon | |
# | |
# Written by Andy Wardley http://wardley.org/ | |
# | |
# 18 September 2008 | |
# | |
#----------------------------------------------------------------------- | |
# custom directive generator to capture filters, variables and | |
# massage a few other elements to make life easy. | |
#----------------------------------------------------------------------- | |
#=================================== | |
#=================================== | |
package Locale::Maketext::Extract::Plugin::TT2::Directive; | |
#=================================== | |
#=================================== | |
use base 'Template::Directive'; | |
our $PARSER; | |
#=================================== | |
sub textblock { | |
#=================================== | |
my ( $class, $text ) = @_; | |
$text =~ s/([\\'])/\\$1/g; | |
return "'$text'"; | |
} | |
#=================================== | |
sub ident { | |
#=================================== | |
my ( $class, $ident ) = @_; | |
return "NULL" unless @$ident; | |
if ( scalar @$ident <= 2 && !$ident->[1] ) { | |
my $var = $ident->[0]; | |
$var =~ s/^'(.+)'$/$1/; | |
return $var; | |
} | |
else { | |
my @source = @$ident; | |
my @dotted; | |
my $first = 1; | |
my $first_literal; | |
while (@source) { | |
my ( $name, $args ) = splice( @source, 0, 2 ); | |
if ($first) { | |
strip_quotes($name); | |
my $first_arg = $args && @$args ? $args->[0] : ''; | |
$first_literal = strip_quotes($first_arg); | |
$first--; | |
} | |
elsif ( !strip_quotes($name) && $name =~ /\D/ ) { | |
$name = '$' . $name; | |
} | |
$name .= join_args($args); | |
push( @dotted, $name ); | |
} | |
if ( $first_literal | |
&& ( $ident->[0] eq "'l'" or $ident->[0] eq "'loc'" ) ) | |
{ | |
my $string = shift @{ $ident->[1] }; | |
strip_quotes($string); | |
$string =~ s/\\\\/\\/g; | |
my $args = join_args( $ident->[1] ); | |
push @{ $PARSER->{extracted} }, | |
[ $string, ${ $PARSER->{LINE} }, $args ]; | |
} | |
return join( '.', @dotted ); | |
} | |
} | |
#=================================== | |
sub text { | |
#=================================== | |
my ( $class, $text ) = @_; | |
$text =~ s/\\/\\\\/g; | |
return "'$text'"; | |
} | |
#=================================== | |
sub quoted { | |
#=================================== | |
my ( $class, $items ) = @_; | |
return '' unless @$items; | |
return ( $items->[0] ) if scalar @$items == 1; | |
return '(' . join( ' _ ', @$items ) . ')'; | |
} | |
#=================================== | |
sub args { | |
#=================================== | |
my ( $class, $args ) = @_; | |
my $hash = shift @$args; | |
push( @$args, '{ ' . join( ', ', @$hash ) . ' }' ) # named params | |
if @$hash; | |
return $args; | |
} | |
#=================================== | |
sub get { | |
#=================================== | |
my ( $class, $expr ) = @_; | |
return $expr; | |
} | |
#=================================== | |
sub filter { | |
#=================================== | |
my ( $class, $lnameargs, $block ) = @_; | |
my ( $name, $args, $alias ) = @$lnameargs; | |
$name = $name->[0]; | |
return '' | |
unless $name eq "'l'" | |
or $name eq "'loc'"; | |
if ( strip_quotes($block) ) { | |
$block =~ s/\\\\/\\/g; | |
$args = join_args( $class->args($args) ); | |
# NOTE: line number is at end of block, and can be a range | |
my ($end) = ( ${ $PARSER->{LINE} } =~ /^(\d+)/ ); | |
my $start = $end; | |
# rewind line count for newlines | |
$start -= $block =~ tr/\n//; | |
my $line = $start == $end ? $start : "$start-$end"; | |
push @{ $PARSER->{extracted} }, [ $block, $line, $args ]; | |
} | |
return ''; | |
} | |
# strips outer single quotes from a string (modifies original string) | |
# returns true if stripped, or false | |
#=================================== | |
sub strip_quotes { | |
#=================================== | |
return scalar $_[0] =~ s/^'(.*)'$/$1/s; | |
} | |
#=================================== | |
sub join_args { | |
#=================================== | |
my $args = shift; | |
return '' unless $args && @$args; | |
my @new_args = (@$args); | |
for (@new_args) { | |
s/\\\\/\\/g; | |
if ( strip_quotes($_) ) { | |
s/"/\\"/g; | |
$_ = qq{"$_"}; | |
} | |
} | |
return '(' . join( ', ', @new_args ) . ')'; | |
} | |
=head1 ACKNOWLEDGEMENTS | |
Thanks to Andy Wardley for writing the Template::Directive subclass which | |
made this possible. | |
=head1 SEE ALSO | |
=over 4 | |
=item L<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::Mason> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=item L<Template::Toolkit> | |
=back | |
=head1 AUTHORS | |
Clinton Gormley E<lt>[email protected]<gt> | |
Andy Wardley http://wardley.org | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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_TT2 | |
$fatpacked{"Locale/Maketext/Extract/Plugin/TextTemplate.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_TEXTTEMPLATE'; | |
package Locale::Maketext::Extract::Plugin::TextTemplate; | |
use strict; | |
use base qw(Locale::Maketext::Extract::Plugin::Base); | |
use vars qw($VERSION); | |
$VERSION = '0.31'; | |
=head1 NAME | |
Locale::Maketext::Extract::Plugin::TextTemplate - Text::Template format parser | |
=head1 SYNOPSIS | |
$plugin = Locale::Maketext::Extract::Plugin::TextTemplate->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 Text::Template files | |
=head1 SHORT PLUGIN NAME | |
text | |
=head1 VALID FORMATS | |
Sentences between STARTxxx and ENDxxx are extracted individually. | |
=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; pos($_) = 0; | |
# Text::Template | |
if ($_=~/^STARTTEXT$/m and $_=~ /^ENDTEXT$/m) { | |
require HTML::Parser; | |
require Lingua::EN::Sentence; | |
{ | |
package Locale::Maketext::Extract::Plugin::TextTemplate::Parser; | |
our @ISA = 'HTML::Parser'; | |
*{'text'} = sub { | |
my ($self, $str, $is_cdata) = @_; | |
my $sentences = Lingua::EN::Sentence::get_sentences($str) or return; | |
$str =~ s/\n/ /g; $str =~ s/^\s+//; $str =~ s/\s+$//; | |
$self->add_entry($str , $line); | |
}; | |
} | |
my $p = Locale::Maketext::Extract::Plugin::TextTemplate::Parser->new; | |
while (m/\G((.*?)^(?:START|END)[A-Z]+$)/smg) { | |
my ($str) = ($2); | |
$line += ( () = ($1 =~ /\n/g) ); # cryptocontext! | |
$p->parse($str); $p->eof; | |
} | |
$_ = ''; | |
} | |
} | |
=head1 SEE ALSO | |
=over 4 | |
=item L<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::YAML> | |
=item L<Locale::Maketext::Extract::Plugin::Mason> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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_TEXTTEMPLATE | |
$fatpacked{"Locale/Maketext/Extract/Plugin/YAML.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_PLUGIN_YAML'; | |
package Locale::Maketext::Extract::Plugin::YAML; | |
use strict; | |
use base qw(Locale::Maketext::Extract::Plugin::Base); | |
=head1 NAME | |
Locale::Maketext::Extract::Plugin::YAML - YAML format parser | |
=head1 SYNOPSIS | |
$plugin = Locale::Maketext::Extract::Plugin::YAML->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 YAML files. | |
=head1 SHORT PLUGIN NAME | |
yaml | |
=head1 VALID FORMATS | |
Valid formats are: | |
=over 4 | |
=item * | |
key: _"string" | |
=item * | |
key: _'string' | |
=item * | |
key: _'string with embedded 'quotes'' | |
=item * | |
key: |- | |
_'my folded | |
string | |
to translate' | |
Note, the left hand side of the folded string must line up with the C<_>, | |
otherwise YAML adds spaces at the beginning of each line. | |
=item * | |
key: |- | |
_'my block | |
string | |
to translate | |
' | |
Note, you must use the trailing C<-> so that YAMl doesn't add a carriage | |
return after your final quote. | |
=back | |
=head1 KNOWN FILE TYPES | |
=over 4 | |
=item .yaml | |
=item .yml | |
=item .conf | |
=back | |
=head1 REQUIRES | |
L<YAML> | |
=head1 NOTES | |
The docs for the YAML module describes it as alpha code. It is not as tolerant | |
of errors as L<YAML::Syck>. 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::YAML::Extractor->new(); | |
$y->load($data); | |
foreach my $entry (@{$y->found}) { | |
$self->add_entry(@$entry) | |
} | |
} | |
package Locale::Maketext::Extract::Plugin::YAML::Extractor; | |
use base qw(YAML::Loader); | |
#=================================== | |
sub new { | |
#=================================== | |
my $class = shift; | |
my $self = $class->SUPER::new(@_); | |
$self->{found} = []; | |
return $self; | |
} | |
#=================================== | |
sub check_scalar { | |
#=================================== | |
my $self = shift; | |
my $node = $_[0]; | |
if ( defined $node && !ref $node && $node =~ /^__?(["'])(.+)\1$/s ) { | |
my $string = $2; | |
my $line = $_[1]; | |
push @{ $self->{found} }, [ $string, $line ]; | |
} | |
return $node; | |
} | |
sub _parse_node { | |
my $self = shift; | |
my $line = $self->{_start_line}||=length($self->preface) ? $self->line - 1 : $self->line; | |
my $node = $self->SUPER::_parse_node(@_); | |
$self->{start_line} = 0; | |
return $self->check_scalar($node,$line); | |
} | |
sub _parse_inline_seq { | |
my $self = shift; | |
my $line = $self->{_start_line}||=$self->line; | |
my $node = $self->SUPER::_parse_inline_seq(@_); | |
foreach (@$node) { | |
$self->check_scalar( $_, $line ); | |
} | |
$self->{start_line} = 0; | |
return $node; | |
} | |
sub _parse_inline_mapping { | |
my $self = shift; | |
my $line = $self->{_start_line}||=$self->line; | |
my $node = $self->SUPER::_parse_inline_mapping(@_); | |
foreach ( values %$node ) { | |
$self->check_scalar( $_, $line ); | |
} | |
$self->{start_line} = 0; | |
return $node; | |
} | |
#=================================== | |
sub _parse_next_line { | |
#=================================== | |
my $self = shift; | |
$self->{_start_line} = $self->line | |
if $_[0] == YAML::Loader::COLLECTION; | |
$self->SUPER::_parse_next_line(@_); | |
} | |
sub found { | |
my $self = shift; | |
return $self->{found}; | |
} | |
=head1 SEE ALSO | |
=over 4 | |
=item L<xgettext.pl> | |
for extracting translatable strings from common template | |
systems and perl source files. | |
=item L<YAML> | |
=item L<Locale::Maketext::Lexicon> | |
=item L<Locale::Maketext::Extract::Plugin::Base> | |
=item L<Locale::Maketext::Extract::Plugin::FormFu> | |
=item L<Locale::Maketext::Extract::Plugin::Perl> | |
=item L<Locale::Maketext::Extract::Plugin::TT2> | |
=item L<Locale::Maketext::Extract::Plugin::Mason> | |
=item L<Locale::Maketext::Extract::Plugin::TextTemplate> | |
=item L<Locale::Maketext::Extract::Plugin::Generic> | |
=back | |
=head1 AUTHORS | |
Clinton Gormley E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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_YAML | |
$fatpacked{"Locale/Maketext/Extract/Run.pm"} = <<'LOCALE_MAKETEXT_EXTRACT_RUN'; | |
package Locale::Maketext::Extract::Run; | |
$Locale::Maketext::Lexicon::Extract::Run::VERSION = '0.35'; | |
use strict; | |
use vars qw( @ISA @EXPORT_OK ); | |
use File::Spec::Functions qw(catfile); | |
=head1 NAME | |
Locale::Maketext::Extract::Run - Module interface to xgettext.pl | |
=head1 SYNOPSIS | |
use Locale::Maketext::Extract::Run 'xgettext'; | |
xgettext(@ARGV); | |
=cut | |
use Cwd; | |
use Config (); | |
use File::Find; | |
use Getopt::Long; | |
use Locale::Maketext::Extract; | |
use Exporter; | |
use constant HAS_SYMLINK => ( $Config::Config{d_symlink} ? 1 : 0 ); | |
@ISA = 'Exporter'; | |
@EXPORT_OK = 'xgettext'; | |
sub xgettext { __PACKAGE__->run(@_) } | |
sub run { | |
my $self = shift; | |
local @ARGV = @_; | |
my %opts; | |
Getopt::Long::Configure("no_ignore_case"); | |
Getopt::Long::GetOptions( \%opts, | |
'f|files-from:s@', | |
'D|directory:s@', | |
'u|use-gettext-style|unescaped', | |
'g|gnu-gettext', | |
'o|output:s@', | |
'd|default-domain:s', | |
'p|output-dir:s@', | |
'P|plugin:s@', | |
'W|wrap!', | |
'w|warnings!', | |
'v|verbose+', | |
'h|help', | |
) or help(); | |
help() if $opts{h}; | |
my %extract_options = %{ $self->_parse_extract_options( \%opts ) }; | |
my @po = @{ $opts{o} || [ ( $opts{d} || 'messages' ) . '.po' ] }; | |
foreach my $file ( @{ $opts{f} || [] } ) { | |
open FILE, $file or die "Cannot open $file: $!"; | |
while (<FILE>) { | |
chomp; | |
push @ARGV, $_ if -r and !-d; | |
} | |
} | |
foreach my $dir ( @{ $opts{D} || [] } ) { | |
File::Find::find( { | |
wanted => sub { | |
if (-d) { | |
$File::Find::prune | |
= /^(\.svn|blib|autogen|var|m4|local|CVS|\.git)$/; | |
return; | |
} | |
# Only extract from non-binary, normal files | |
return unless (-f or -s) and -T; | |
return | |
if (/\.po$|\.bak$|~|,D|,B$/i) | |
|| (/^[\.#]/); | |
push @ARGV, $File::Find::name; | |
}, | |
follow => HAS_SYMLINK, | |
}, | |
$dir | |
); | |
} | |
@ARGV = ('-') unless @ARGV; | |
s!^\.[/\\]!! for @ARGV; | |
my $cwd = getcwd(); | |
my $Ext = Locale::Maketext::Extract->new(%extract_options); | |
foreach my $dir ( @{ $opts{p} || ['.'] } ) { | |
$Ext->extract_file($_) for grep !/\.po$/i, @ARGV; | |
foreach my $po (@po) { | |
$Ext->read_po($po) if -r $po and -s _; | |
$Ext->compile( $opts{u} ) or next; | |
$Ext->write_po( catfile( $dir, $po ), $opts{g} ); | |
} | |
} | |
} | |
sub _parse_extract_options { | |
my $self = shift; | |
my $opts = shift; | |
# If a list of plugins is specified, then we use those modules | |
# plus their default list of file extensionse | |
# and warnings enabled by default | |
my %extract_options | |
= ( verbose => $opts->{v}, wrap => $opts->{W} || 0 ); | |
if ( my $plugin_args = $opts->{P} ) { | |
# file extension with potentially multiple dots eg .tt.html | |
my %plugins; | |
foreach my $param (@$plugin_args) { | |
my ( $plugin, $args ) | |
= ( $param =~ /^([a-z_]\w+(?:::\w+)*)(?:=(.+))?$/i ); | |
die "Couldn't understand plugin option '$param'" | |
unless $plugin; | |
my @extensions; | |
if ($args) { | |
foreach my $arg ( split /,/, $args ) { | |
if ( $arg eq '*' ) { | |
@extensions = ('*'); | |
last; | |
} | |
my ($extension) = ( $arg =~ /^\.?(\w+(?:\.\w+)*)$/ ); | |
die "Couldn't understand '$arg' in plugin '$param'" | |
unless defined $extension; | |
push @extensions, $extension; | |
} | |
} | |
$plugins{$plugin} = \@extensions; | |
} | |
$extract_options{plugins} = \%plugins; | |
$extract_options{warnings} = exists $opts->{w} ? $opts->{w} : 1; | |
} | |
# otherwise we default to the original xgettext.pl modules | |
# with warnings disabled by default | |
else { | |
$extract_options{warnings} = $opts->{w}; | |
} | |
return \%extract_options; | |
} | |
sub help { | |
local $SIG{__WARN__} = sub { }; | |
{ exec "perldoc $0"; } | |
{ exec "pod2text $0"; } | |
} | |
1; | |
=head1 COPYRIGHT | |
Copyright 2003-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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_RUN | |
$fatpacked{"Locale/Maketext/Lexicon.pm"} = <<'LOCALE_MAKETEXT_LEXICON'; | |
package Locale::Maketext::Lexicon; | |
$Locale::Maketext::Lexicon::VERSION = '0.86'; | |
use 5.004; | |
use strict; | |
=head1 NAME | |
Locale::Maketext::Lexicon - Use other catalog formats in Maketext | |
=head1 VERSION | |
This document describes version 0.80 of Locale::Maketext::Lexicon, | |
released December 29, 2008. | |
=head1 SYNOPSIS | |
As part of a localization class, automatically glob for available | |
lexicons: | |
package Hello::I18N; | |
use base 'Locale::Maketext'; | |
use Locale::Maketext::Lexicon { | |
'*' => [Gettext => '/usr/local/share/locale/*/LC_MESSAGES/hello.mo'], | |
### Uncomment to fallback when a key is missing from lexicons | |
# _auto => 1, | |
### Uncomment to decode lexicon entries into Unicode strings | |
# _decode => 1, | |
### Uncomment to load and parse everything right away | |
# _preload => 1, | |
### Uncomment to use %1 / %quant(%1) instead of [_1] / [quant, _1] | |
# _style => 'gettext', | |
}; | |
Explicitly specify languages, during compile- or run-time: | |
package Hello::I18N; | |
use base 'Locale::Maketext'; | |
use Locale::Maketext::Lexicon { | |
de => [Gettext => 'hello_de.po'], | |
fr => [ | |
Gettext => 'hello_fr.po', | |
Gettext => 'local/hello/fr.po', | |
], | |
}; | |
# ... incrementally add new lexicons | |
Locale::Maketext::Lexicon->import({ | |
de => [Gettext => 'local/hello/de.po'], | |
}) | |
Alternatively, as part of a localization subclass: | |
package Hello::I18N::de; | |
use base 'Hello::I18N'; | |
use Locale::Maketext::Lexicon (Gettext => \*DATA); | |
__DATA__ | |
# Some sample data | |
msgid "" | |
msgstr "" | |
"Project-Id-Version: Hello 1.3.22.1\n" | |
"MIME-Version: 1.0\n" | |
"Content-Type: text/plain; charset=iso8859-1\n" | |
"Content-Transfer-Encoding: 8bit\n" | |
#: Hello.pm:10 | |
msgid "Hello, World!" | |
msgstr "Hallo, Welt!" | |
#: Hello.pm:11 | |
msgid "You have %quant(%1,piece) of mail." | |
msgstr "Sie haben %quant(%1,Poststueck,Poststuecken)." | |
=head1 DESCRIPTION | |
This module provides lexicon-handling modules to read from other | |
localization formats, such as I<Gettext>, I<Msgcat>, and so on. | |
If you are unfamiliar with the concept of lexicon modules, please | |
consult L<Locale::Maketext> and the C<webl10n> HTML files in the C<docs/> | |
directory of this module. | |
A command-line utility L<xgettext.pl> is also installed with this | |
module, for extracting translatable strings from source files. | |
=head2 The C<import> function | |
The C<import()> function accepts two forms of arguments: | |
=over 4 | |
=item (I<format> => I<source> ... ) | |
This form takes any number of argument pairs (usually one); | |
I<source> may be a file name, a filehandle, or an array reference. | |
For each such pair, it pass the contents specified by the second | |
argument to B<Locale::Maketext::Lexicon::I<format>>->parse as a | |
plain list, and export its return value as the C<%Lexicon> hash | |
in the calling package. | |
In the case that there are multiple such pairs, the lexicon | |
defined by latter ones overrides earlier ones. | |
=item { I<language> => [ I<format>, I<source> ... ] ... } | |
This form accepts a hash reference. It will export a C<%Lexicon> | |
into the subclasses specified by each I<language>, using the process | |
described above. It is designed to alleviate the need to set up a | |
separate subclass for each localized language, and just use the catalog | |
files. | |
This module will convert the I<language> arguments into lowercase, | |
and replace all C<-> with C<_>, so C<zh_TW> and C<zh-tw> will both | |
map to the C<zh_tw> subclass. | |
If I<language> begins with C<_>, it is taken as an option that | |
controls how lexicons are parsed. See L</Options> for a list | |
of available options. | |
The C<*> is a special I<language>; it must be used in conjunction | |
with a filename that also contains C<*>; all matched files with | |
a valid language code in the place of C<*> will be automatically | |
prepared as a lexicon subclass. If there is multiple C<*> in | |
the filename, the last one is used as the language name. | |
=back | |
=head2 Options | |
=over 4 | |
=item C<_auto> | |
If set to a true value, missing lookups on lexicons are handled | |
silently, as if an C<Auto> lexicon has been appended on all | |
language lexicons. | |
=item C<_decode> | |
If set to a true value, source entries will be converted into | |
utf8-strings (available in Perl 5.6.1 or later). This feature | |
needs the B<Encode> or B<Encode::compat> module. | |
Currently, only the C<Gettext> backend supports this option. | |
=item C<_encoding> | |
This option only has effect when C<_decode> is set to true. | |
It specifies an encoding to store lexicon entries, instead of | |
utf8-strings. | |
If C<_encoding> is set to C<locale>, the encoding from the | |
current locale setting is used. | |
=item C<_preload> | |
By default parsing is delayed until first use of the lexicon, | |
set this option to true value to parse it asap. Increment | |
adding lexicons forces parsing. | |
=back | |
=head2 Subclassing format handlers | |
If you wish to override how sources specified in different data types | |
are handled, please use a subclass that overrides C<lexicon_get_I<TYPE>>. | |
XXX: not documented well enough yet. Patches welcome. | |
=head1 NOTES | |
When you attempt to localize an entry missing in the lexicon, Maketext | |
will throw an exception by default. To inhibit this behaviour, override | |
the C<_AUTO> key in your language subclasses, for example: | |
$Hello::I18N::en::Lexicon{_AUTO} = 1; # autocreate missing keys | |
If you want to implement a new C<Lexicon::*> backend module, please note | |
that C<parse()> takes an array containing the B<source strings> from the | |
specified filehandle or filename, which are I<not> C<chomp>ed. Although | |
if the source is an array reference, its elements will probably not contain | |
any newline characters anyway. | |
The C<parse()> function should return a hash reference, which will be | |
assigned to the I<typeglob> (C<*Lexicon>) of the language module. All | |
it amounts to is that if the returned reference points to a tied hash, | |
the C<%Lexicon> will be aliased to the same tied hash if it was not | |
initialized previously. | |
=cut | |
our %Opts; | |
sub option { shift if ref( $_[0] ); $Opts{ lc $_[0] } } | |
sub set_option { shift if ref( $_[0] ); $Opts{ lc $_[0] } = $_[1] } | |
sub encoding { | |
my $encoding = option( @_, 'encoding' ) or return; | |
return $encoding unless lc($encoding) eq 'locale'; | |
local $^W; # no warnings 'uninitialized', really. | |
my ( $country_language, $locale_encoding ); | |
local $@; | |
eval { | |
require I18N::Langinfo; | |
$locale_encoding | |
= I18N::Langinfo::langinfo( I18N::Langinfo::CODESET() ); | |
} | |
or eval { | |
require Win32::Console; | |
$locale_encoding = 'cp' . Win32::Console::OutputCP(); | |
}; | |
if ( !$locale_encoding ) { | |
foreach my $key (qw( LANGUAGE LC_ALL LC_MESSAGES LANG )) { | |
$ENV{$key} =~ /^([^.]+)\.([^.:]+)/ or next; | |
( $country_language, $locale_encoding ) = ( $1, $2 ); | |
last; | |
} | |
} | |
if ( defined $locale_encoding | |
&& lc($locale_encoding) eq 'euc' | |
&& defined $country_language ) | |
{ | |
if ( $country_language =~ /^ja_JP|japan(?:ese)?$/i ) { | |
$locale_encoding = 'euc-jp'; | |
} | |
elsif ( $country_language =~ /^ko_KR|korean?$/i ) { | |
$locale_encoding = 'euc-kr'; | |
} | |
elsif ( $country_language =~ /^zh_CN|chin(?:a|ese)?$/i ) { | |
$locale_encoding = 'euc-cn'; | |
} | |
elsif ( $country_language =~ /^zh_TW|taiwan(?:ese)?$/i ) { | |
$locale_encoding = 'euc-tw'; | |
} | |
} | |
return $locale_encoding; | |
} | |
sub import { | |
my $class = shift; | |
return unless @_; | |
my %entries; | |
if ( UNIVERSAL::isa( $_[0], 'HASH' ) ) { | |
# a hashref with $lang as keys, [$format, $src ...] as values | |
%entries = %{ $_[0] }; | |
} | |
elsif ( @_ % 2 == 0 ) { | |
%entries = ( '' => [ splice @_, 0, 2 ], @_ ); | |
} | |
# expand the wildcard entry | |
if ( my $wild_entry = delete $entries{'*'} ) { | |
while ( my ( $format, $src ) = splice( @$wild_entry, 0, 2 ) ) { | |
next if ref($src); # XXX: implement globbing for the 'Tie' backend | |
my $pattern = quotemeta($src); | |
$pattern =~ s/\\\*(?=[^*]+$)/\([-\\w]+\)/g or next; | |
$pattern =~ s/\\\*/.*?/g; | |
$pattern =~ s/\\\?/./g; | |
$pattern =~ s/\\\[/[/g; | |
$pattern =~ s/\\\]/]/g; | |
$pattern =~ s[\\\{(.*?)\\\\}][ | |
'(?:'.join('|', split(/,/, $1)).')' | |
]eg; | |
require File::Glob; | |
foreach my $file ( File::Glob::bsd_glob($src) ) { | |
$file =~ /$pattern/ or next; | |
push @{ $entries{$1} }, ( $format => $file ) if $1; | |
} | |
delete $entries{$1} | |
unless !defined($1) | |
or exists $entries{$1} and @{ $entries{$1} }; | |
} | |
} | |
%Opts = (); | |
foreach my $key ( grep /^_/, keys %entries ) { | |
set_option( lc( substr( $key, 1 ) ) => delete( $entries{$key} ) ); | |
} | |
my $OptsRef = {%Opts}; | |
while ( my ( $lang, $entry ) = each %entries ) { | |
my $export = caller; | |
if ( length $lang ) { | |
# normalize language tag to Maketext's subclass convention | |
$lang = lc($lang); | |
$lang =~ s/-/_/g; | |
$export .= "::$lang"; | |
} | |
my @pairs = @{ $entry || [] } or die "no format specified"; | |
while ( my ( $format, $src ) = splice( @pairs, 0, 2 ) ) { | |
if ( defined($src) and !ref($src) and $src =~ /\*/ ) { | |
unshift( @pairs, $format => $_ ) | |
for File::Glob::bsd_glob($src); | |
next; | |
} | |
my @content | |
= eval { $class->lexicon_get( $src, scalar caller(1), $lang ); }; | |
next if $@ and $@ =~ /^next\b/; | |
die $@ if $@; | |
no strict 'refs'; | |
eval "use $class\::$format; 1" or die $@; | |
if ( %{"$export\::Lexicon"} ) { | |
my $lexicon = \%{"$export\::Lexicon"}; | |
if ( my $obj = tied %$lexicon ) { | |
# if it's our tied hash then force loading | |
# otherwise late load will rewrite | |
$obj->_force if $obj->isa(__PACKAGE__); | |
} | |
# clear the memoized cache for old entries: | |
Locale::Maketext->clear_isa_scan; | |
my $new = "$class\::$format"->parse(@content); | |
# avoid hash rebuild, on big sets | |
@{$lexicon}{ keys %$new } = values %$new; | |
} | |
else { | |
local $^W if $] >= 5.009; # no warnings 'once', really. | |
tie %{"$export\::Lexicon"}, __PACKAGE__, | |
{ | |
Opts => $OptsRef, | |
Export => "$export\::Lexicon", | |
Class => "$class\::$format", | |
Content => \@content, | |
}; | |
tied( %{"$export\::Lexicon"} )->_force | |
if $OptsRef->{'preload'}; | |
} | |
length $lang or next; | |
# Avoid re-entry | |
my $caller = caller(); | |
next if $export->isa($caller); | |
push( @{"$export\::ISA"}, scalar caller ); | |
if ( my $style = option('style') ) { | |
my $cref | |
= $class->can( lc("_style_$style") ) | |
->( $class, $export->can('maketext') ) | |
or die "Unknown style: $style"; | |
# Avoid redefinition warnings | |
local $SIG{__WARN__} = sub {1}; | |
*{"$export\::maketext"} = $cref; | |
} | |
} | |
} | |
} | |
sub _style_gettext { | |
my ( $self, $orig ) = @_; | |
require Locale::Maketext::Lexicon::Gettext; | |
sub { | |
my $lh = shift; | |
my $str = shift; | |
return $orig->( | |
$lh, | |
Locale::Maketext::Lexicon::Gettext::_gettext_to_maketext($str), @_ | |
); | |
} | |
} | |
sub TIEHASH { | |
my ( $class, $args ) = @_; | |
return bless( $args, $class ); | |
} | |
{ | |
no strict 'refs'; | |
sub _force { | |
my $args = shift; | |
unless ( $args->{'Done'} ) { | |
$args->{'Done'} = 1; | |
local *Opts = $args->{Opts}; | |
*{ $args->{Export} } | |
= $args->{Class}->parse( @{ $args->{Content} } ); | |
$args->{'Export'}{'_AUTO'} = 1 | |
if option('auto'); | |
} | |
return $args->{'Export'}; | |
} | |
sub FETCH { _force( $_[0] )->{ $_[1] } } | |
sub EXISTS { _force( $_[0] )->{ $_[1] } } | |
sub DELETE { delete _force( $_[0] )->{ $_[1] } } | |
sub SCALAR { scalar %{ _force( $_[0] ) } } | |
sub STORE { _force( $_[0] )->{ $_[1] } = $_[2] } | |
sub CLEAR { %{ _force( $_[0] )->{ $_[1] } } = () } | |
sub NEXTKEY { each %{ _force( $_[0] ) } } | |
sub FIRSTKEY { | |
my $hash = _force( $_[0] ); | |
my $a = scalar keys %$hash; | |
each %$hash; | |
} | |
} | |
sub lexicon_get { | |
my ( $class, $src, $caller, $lang ) = @_; | |
return unless defined $src; | |
foreach my $type ( qw(ARRAY HASH SCALAR GLOB), ref($src) ) { | |
next unless UNIVERSAL::isa( $src, $type ); | |
my $method = 'lexicon_get_' . lc($type); | |
die "cannot handle source $type for $src: no $method defined" | |
unless $class->can($method); | |
return $class->$method( $src, $caller, $lang ); | |
} | |
# default handler | |
return $class->lexicon_get_( $src, $caller, $lang ); | |
} | |
# for scalarrefs and arrayrefs we just dereference the $src | |
sub lexicon_get_scalar { ${ $_[1] } } | |
sub lexicon_get_array { @{ $_[1] } } | |
sub lexicon_get_hash { | |
my ( $class, $src, $caller, $lang ) = @_; | |
return map { $_ => $src->{$_} } sort keys %$src; | |
} | |
sub lexicon_get_glob { | |
my ( $class, $src, $caller, $lang ) = @_; | |
no strict 'refs'; | |
local $^W if $] >= 5.009; # no warnings 'once', really. | |
# be extra magical and check for DATA section | |
if ( eof($src) and $src eq \*{"$caller\::DATA"} | |
or $src eq \*{"main\::DATA"} ) | |
{ | |
# okay, the *DATA isn't initiated yet. let's read. | |
# | |
require FileHandle; | |
my $fh = FileHandle->new; | |
my $package = ( ( $src eq \*{"main\::DATA"} ) ? 'main' : $caller ); | |
if ( $package eq 'main' and -e $0 ) { | |
$fh->open($0) or die "Can't open $0: $!"; | |
} | |
else { | |
my $level = 1; | |
while ( my ( $pkg, $filename ) = caller( $level++ ) ) { | |
next unless $pkg eq $package; | |
next unless -e $filename; | |
next; | |
$fh->open($filename) or die "Can't open $filename: $!"; | |
last; | |
} | |
} | |
while (<$fh>) { | |
# okay, this isn't foolproof, but good enough | |
last if /^__DATA__$/; | |
} | |
return <$fh>; | |
} | |
# fh containing the lines | |
my $pos = tell($src); | |
my @lines = <$src>; | |
seek( $src, $pos, 0 ); | |
return @lines; | |
} | |
# assume filename - search path, open and return its contents | |
sub lexicon_get_ { | |
my ( $class, $src, $caller, $lang ) = @_; | |
$src = $class->lexicon_find( $src, $caller, $lang ); | |
defined $src or die 'next'; | |
require FileHandle; | |
my $fh = FileHandle->new; | |
$fh->open($src) or die "Cannot read $src (called by $caller): $!"; | |
binmode($fh); | |
return <$fh>; | |
} | |
sub lexicon_find { | |
my ( $class, $src, $caller, $lang ) = @_; | |
return $src if -e $src; | |
require File::Spec; | |
my @path = split '::', $caller; | |
push @path, $lang if length $lang; | |
while (@path) { | |
foreach (@INC) { | |
my $file = File::Spec->catfile( $_, @path, $src ); | |
return $file if -e $file; | |
} | |
pop @path; | |
} | |
return undef; | |
} | |
1; | |
=head1 ACKNOWLEDGMENTS | |
Thanks to Jesse Vincent for suggesting this module to be written. | |
Thanks also to Sean M. Burke for coming up with B<Locale::Maketext> | |
in the first place, and encouraging me to experiment with alternative | |
Lexicon syntaxes. | |
Thanks also to Yi Ma Mao for providing the MO file parsing subroutine, | |
as well as inspiring me to implement file globbing and transcoding | |
support. | |
See the F<AUTHORS> file in the distribution for a list of people who | |
have sent helpful patches, ideas or comments. | |
=head1 SEE ALSO | |
L<xgettext.pl> for extracting translatable strings from common template | |
systems and perl source files. | |
L<Locale::Maketext>, L<Locale::Maketext::Lexicon::Auto>, | |
L<Locale::Maketext::Lexicon::Gettext>, L<Locale::Maketext::Lexicon::Msgcat>, | |
L<Locale::Maketext::Lexicon::Tie> | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002-2008 by Audrey Tang E<lt>[email protected]<gt>. | |
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_LEXICON | |
$fatpacked{"Locale/Maketext/Lexicon/Auto.pm"} = <<'LOCALE_MAKETEXT_LEXICON_AUTO'; | |
package Locale::Maketext::Lexicon::Auto; | |
$Locale::Maketext::Lexicon::Auto::VERSION = '0.10'; | |
use strict; | |
=head1 NAME | |
Locale::Maketext::Lexicon::Auto - Auto fallback lexicon for Maketext | |
=head1 SYNOPSIS | |
package Hello::I18N; | |
use base 'Locale::Maketext'; | |
use Locale::Maketext::Lexicon { | |
en => ['Auto'], | |
# ... other languages | |
}; | |
=head1 DESCRIPTION | |
This module builds a simple Lexicon hash that contains nothing but | |
C<( '_AUTO' =E<gt> 1)>, which tells C<Locale::Maketext> that no | |
localizing is needed -- just use the lookup key as the returned string. | |
It is especially useful if you're starting to prototype a program, and | |
do not want to deal with the localization files yet. | |
=head1 CAVEATS | |
If the key to C<-E<gt>maketext> begins with a C<_>, C<Locale::Maketext> | |
will still throw an exception. See L<Locale::Maketext/CONTROLLING LOOKUP | |
FAILURE> for how to prevent it. | |
=cut | |
sub parse { | |
+{ _AUTO => 1 }; | |
} | |
1; | |
=head1 SEE ALSO | |
L<Locale::Maketext>, L<Locale::Maketext::Lexicon> | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002, 2003, 2004, 2007 by Audrey Tang E<lt>[email protected]<gt>. | |
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_LEXICON_AUTO | |
$fatpacked{"Locale/Maketext/Lexicon/Gettext.pm"} = <<'LOCALE_MAKETEXT_LEXICON_GETTEXT'; | |
package Locale::Maketext::Lexicon::Gettext; | |
$Locale::Maketext::Lexicon::Gettext::VERSION = '0.17'; | |
use strict; | |
=head1 NAME | |
Locale::Maketext::Lexicon::Gettext - PO and MO file parser for Maketext | |
=head1 SYNOPSIS | |
Called via B<Locale::Maketext::Lexicon>: | |
package Hello::I18N; | |
use base 'Locale::Maketext'; | |
use Locale::Maketext::Lexicon { | |
de => [Gettext => 'hello/de.mo'], | |
}; | |
Directly calling C<parse()>: | |
use Locale::Maketext::Lexicon::Gettext; | |
my %Lexicon = %{ Locale::Maketext::Lexicon::Gettext->parse(<DATA>) }; | |
__DATA__ | |
#: Hello.pm:10 | |
msgid "Hello, World!" | |
msgstr "Hallo, Welt!" | |
#: Hello.pm:11 | |
msgid "You have %quant(%1,piece) of mail." | |
msgstr "Sie haben %quant(%1,Poststueck,Poststuecken)." | |
=head1 DESCRIPTION | |
This module implements a perl-based C<Gettext> parser for | |
B<Locale::Maketext>. It transforms all C<%1>, C<%2>, <%*>... sequences | |
to C<[_1]>, C<[_2]>, C<[_*]>, and so on. It accepts either plain PO | |
file, or a MO file which will be handled with a pure-perl parser | |
adapted from Imacat's C<Locale::Maketext::Gettext>. | |
Since version 0.03, this module also looks for C<%I<function>(I<args...>)> | |
in the lexicon strings, and transform it to C<[I<function>,I<args...>]>. | |
Any C<%1>, C<%2>... sequences inside the I<args> will have their percent | |
signs (C<%>) replaced by underscores (C<_>). | |
The name of I<function> above should begin with a letter or underscore, | |
followed by any number of alphanumeric characters and/or underscores. | |
As an exception, the function name may also consist of a single asterisk | |
(C<*>) or pound sign (C<#>), which are C<Locale::Maketext>'s shorthands | |
for C<quant> and C<numf>, respectively. | |
As an additional feature, this module also parses MIME-header style | |
metadata specified in the null msgstr (C<"">), and add them to the | |
C<%Lexicon> with a C<__> prefix. For example, the example above will | |
set C<__Content-Type> to C<text/plain; charset=iso8859-1>, without | |
the newline or the colon. | |
Any normal entry that duplicates a metadata entry takes precedence. | |
Hence, a C<msgid "__Content-Type"> line occurs anywhere should override | |
the above value. | |
=head1 OPTIONS | |
=head2 use_fuzzy | |
When parsing PO files, fuzzy entries (entries marked with C<#, fuzzy>) | |
are silently ignored. If you wish to use fuzzy entries, specify a true | |
value to the C<_use_fuzzy> option: | |
use Locale::Maketext::Lexicon { | |
de => [Gettext => 'hello/de.mo'], | |
_use_fuzzy => 1, | |
}; | |
=head2 allow_empty | |
When parsing PO files, empty entries (entries with C<msgstr "">) are | |
silently ignored. If you wish to allow empty entries, specify a true | |
value to the C<_allow_empty> option: | |
use Locale::Maketext::Lexicon { | |
de => [Gettext => 'hello/de.mo'], | |
_allow_empty => 1, | |
}; | |
=cut | |
my ( $InputEncoding, $OutputEncoding, $DoEncoding ); | |
sub input_encoding {$InputEncoding} | |
sub output_encoding {$OutputEncoding} | |
sub parse { | |
my $self = shift; | |
my ( %var, $key, @ret ); | |
my @metadata; | |
my @comments; | |
my @fuzzy; | |
$InputEncoding = $OutputEncoding = $DoEncoding = undef; | |
use Carp; | |
Carp::cluck "Undefined source called\n" unless defined $_[0]; | |
# Check for magic string of MO files | |
return parse_mo( join( '', @_ ) ) | |
if ( $_[0] =~ /^\x95\x04\x12\xde/ or $_[0] =~ /^\xde\x12\x04\x95/ ); | |
local $^W; # no 'uninitialized' warnings, please. | |
require Locale::Maketext::Lexicon; | |
my $KeepFuzzy = Locale::Maketext::Lexicon::option('keep_fuzzy'); | |
my $UseFuzzy = $KeepFuzzy | |
|| Locale::Maketext::Lexicon::option('use_fuzzy'); | |
my $AllowEmpty = Locale::Maketext::Lexicon::option('allow_empty'); | |
my $process = sub { | |
if ( length( $var{msgstr} ) and ( $UseFuzzy or !$var{fuzzy} ) ) { | |
push @ret, ( map transform($_), @var{ 'msgid', 'msgstr' } ); | |
} | |
elsif ($AllowEmpty) { | |
push @ret, ( transform( $var{msgid} ), '' ); | |
} | |
if ( $var{msgid} eq '' ) { | |
push @metadata, parse_metadata( $var{msgstr} ); | |
} | |
else { | |
push @comments, $var{msgid}, $var{msgcomment}; | |
} | |
if ( $KeepFuzzy && $var{fuzzy} ) { | |
push @fuzzy, $var{msgid}, 1; | |
} | |
%var = (); | |
}; | |
# Parse PO files | |
foreach (@_) { | |
s/[\015\012]*\z//; # fix CRLF issues | |
/^(msgid|msgstr) +"(.*)" *$/ | |
? do { # leading strings | |
$var{$1} = $2; | |
$key = $1; | |
} | |
: | |
/^"(.*)" *$/ | |
? do { # continued strings | |
$var{$key} .= $1; | |
} | |
: | |
/^# (.*)$/ | |
? do { # user comments | |
$var{msgcomment} .= $1 . "\n"; | |
} | |
: | |
/^#, +(.*) *$/ | |
? do { # control variables | |
$var{$_} = 1 for split( /,\s+/, $1 ); | |
} | |
: | |
/^ *$/ && %var | |
? do { # interpolate string escapes | |
$process->($_); | |
} | |
: (); | |
} | |
# do not silently skip last entry | |
$process->() if keys %var != 0; | |
push @ret, map { transform($_) } @var{ 'msgid', 'msgstr' } | |
if length $var{msgstr}; | |
push @metadata, parse_metadata( $var{msgstr} ) | |
if $var{msgid} eq ''; | |
return wantarray | |
? ( { @metadata, @ret }, {@comments}, {@fuzzy} ) | |
: ( { @metadata, @ret } ); | |
} | |
sub parse_metadata { | |
return map { | |
(/^([^\x00-\x1f\x80-\xff :=]+):\s*(.*)$/) | |
? ( $1 eq 'Content-Type' ) | |
? do { | |
my $enc = $2; | |
if ( $enc =~ /\bcharset=\s*([-\w]+)/i ) { | |
$InputEncoding = $1 || ''; | |
$OutputEncoding | |
= Locale::Maketext::Lexicon::encoding() | |
|| ''; | |
$InputEncoding = 'utf8' | |
if $InputEncoding =~ /^utf-?8$/i; | |
$OutputEncoding = 'utf8' | |
if $OutputEncoding =~ /^utf-?8$/i; | |
if ( Locale::Maketext::Lexicon::option('decode') | |
and ( !$OutputEncoding | |
or $InputEncoding ne $OutputEncoding ) | |
) | |
{ | |
require Encode::compat if $] < 5.007001; | |
require Encode; | |
$DoEncoding = 1; | |
} | |
} | |
( "__Content-Type", $enc ); | |
} | |
: ( "__$1", $2 ) | |
: (); | |
} split( /\r*\n+\r*/, transform(pop) ); | |
} | |
sub transform { | |
my $str = shift; | |
if ( $DoEncoding and $InputEncoding ) { | |
$str | |
= ( $InputEncoding eq 'utf8' ) | |
? Encode::decode_utf8($str) | |
: Encode::decode( $InputEncoding, $str ); | |
} | |
$str =~ s/\\([0x]..|c?.)/qq{"\\$1"}/eeg; | |
if ( $DoEncoding and $OutputEncoding ) { | |
$str | |
= ( $OutputEncoding eq 'utf8' ) | |
? Encode::encode_utf8($str) | |
: Encode::encode( $OutputEncoding, $str ); | |
} | |
return _gettext_to_maketext($str); | |
} | |
sub _gettext_to_maketext { | |
my $str = shift; | |
$str =~ s{([\~\[\]])}{~$1}g; | |
$str =~ s{ | |
([%\\]%) # 1 - escaped sequence | |
| | |
% (?: | |
([A-Za-z#*]\w*) # 2 - function call | |
\(([^\)]*)\) # 3 - arguments | |
| | |
([1-9]\d*|\*) # 4 - variable | |
) | |
}{ | |
$1 ? $1 | |
: $2 ? "\[$2,"._unescape($3)."]" | |
: "[_$4]" | |
}egx; | |
$str; | |
} | |
sub _unescape { | |
join( ',', | |
map { /\A(\s*)%([1-9]\d*|\*)(\s*)\z/ ? "$1_$2$3" : $_ } | |
split( /,/, $_[0] ) ); | |
} | |
# This subroutine was derived from Locale::Maketext::Gettext::readmo() | |
# under the Perl License; the original author is Yi Ma Mao (IMACAT). | |
sub parse_mo { | |
my $content = shift; | |
my $tmpl = ( substr( $content, 0, 4 ) eq "\xde\x12\x04\x95" ) ? 'V' : 'N'; | |
# Check the MO format revision number | |
# There is only one revision now: revision 0. | |
return if unpack( $tmpl, substr( $content, 4, 4 ) ) > 0; | |
my ( $num, $offo, $offt ); | |
# Number of strings | |
$num = unpack $tmpl, substr( $content, 8, 4 ); | |
# Offset to the beginning of the original strings | |
$offo = unpack $tmpl, substr( $content, 12, 4 ); | |
# Offset to the beginning of the translated strings | |
$offt = unpack $tmpl, substr( $content, 16, 4 ); | |
my ( @metadata, @ret ); | |
for ( 0 .. $num - 1 ) { | |
my ( $len, $off, $stro, $strt ); | |
# The first word is the length of the string | |
$len = unpack $tmpl, substr( $content, $offo + $_ * 8, 4 ); | |
# The second word is the offset of the string | |
$off = unpack $tmpl, substr( $content, $offo + $_ * 8 + 4, 4 ); | |
# Original string | |
$stro = substr( $content, $off, $len ); | |
# The first word is the length of the string | |
$len = unpack $tmpl, substr( $content, $offt + $_ * 8, 4 ); | |
# The second word is the offset of the string | |
$off = unpack $tmpl, substr( $content, $offt + $_ * 8 + 4, 4 ); | |
# Translated string | |
$strt = substr( $content, $off, $len ); | |
# Hash it | |
push @metadata, parse_metadata($strt) if $stro eq ''; | |
push @ret, ( map transform($_), $stro, $strt ) if length $strt; | |
} | |
return { @metadata, @ret }; | |
} | |
1; | |
=head1 SEE ALSO | |
L<Locale::Maketext>, L<Locale::Maketext::Lexicon> | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002, 2003, 2004, 2007 by Audrey Tang E<lt>[email protected]<gt>. | |
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_LEXICON_GETTEXT | |
$fatpacked{"Locale/Maketext/Lexicon/Msgcat.pm"} = <<'LOCALE_MAKETEXT_LEXICON_MSGCAT'; | |
package Locale::Maketext::Lexicon::Msgcat; | |
$Locale::Maketext::Lexicon::Msgcat::VERSION = '0.03'; | |
use strict; | |
=head1 NAME | |
Locale::Maketext::Lexicon::Msgcat - Msgcat catalog parser Maketext | |
=head1 SYNOPSIS | |
package Hello::I18N; | |
use base 'Locale::Maketext'; | |
use Locale::Maketext::Lexicon { | |
en => ['Msgcat', 'en_US/hello.pl.m'], | |
}; | |
package main; | |
my $lh = Hello::I18N->get_handle('en'); | |
print $lh->maketext(1,2); # set 1, msg 2 | |
print $lh->maketext("1,2"); # same thing | |
=head1 DESCRIPTION | |
This module parses one or more Msgcat catalogs in plain text format, | |
and returns a Lexicon hash, which may be looked up either with a | |
two-argument form (C<$set_id, $msg_id>) or as a single string | |
(C<"$set_id,$msg_id">). | |
=head1 NOTES | |
All special characters (C<[>, C<]> and C<~>) in catalogs will be | |
escaped so they lose their magic meanings. That means C<-E<gt>maketext> | |
calls to this lexicon will I<not> take any additional arguments. | |
=cut | |
sub parse { | |
my $set = 0; | |
my $msg = undef; | |
my ($qr, $qq, $qc) = (qr//, '', ''); | |
my @out; | |
# Set up the msgcat handler | |
{ | |
no strict 'refs'; | |
no warnings 'once'; | |
*{Locale::Maketext::msgcat} = \&_msgcat; | |
} | |
# Parse *.m files; Locale::Msgcat objects and *.cat are not yet supported. | |
foreach (@_) { | |
s/[\015\012]*\z//; # fix CRLF issues | |
/^\$set (\d+)/ | |
? do { # set_id | |
$set = int($1); | |
push @out, $1, "[msgcat,$1,_1]"; | |
} | |
: | |
/^\$quote (.)/ | |
? do { # quote character | |
$qc = $1; | |
$qq = quotemeta($1); | |
$qr = qr/$qq?/; | |
} | |
: | |
/^(\d+) ($qr)(.*?)\2(\\?)$/ | |
? do { # msg_id and msg_str | |
local $^W; | |
push @out, "$set," . int($1); | |
if ($4) { | |
$msg = $3; | |
} | |
else { | |
push @out, unescape($qq, $qc, $3); | |
undef $msg; | |
} | |
} | |
: | |
(defined $msg and /^($qr)(.*?)\1(\\?)$/) | |
? do { # continued string | |
local $^W; | |
if ($3) { | |
$msg .= $2; | |
} | |
else { | |
push @out, unescape($qq, $qc, $msg . $2); | |
undef $msg; | |
} | |
} | |
: (); | |
} | |
push @out, '' if defined $msg; | |
return {@out}; | |
} | |
sub _msgcat { | |
my ($self, $set_id, $msg_id, @args) = @_; | |
return $self->maketext(int($set_id) . ',' . int($msg_id), @args); | |
} | |
sub unescape { | |
my ($qq, $qc, $str) = @_; | |
$str =~ s/(\\([ntvbrf\\$qq]))/($2 eq $qc) ? $qc : eval qq("$1")/e; | |
$str =~ s/([\~\[\]])/~$1/g; | |
return $str; | |
} | |
1; | |
=head1 SEE ALSO | |
L<Locale::Maketext>, L<Locale::Maketext::Lexicon> | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002, 2003, 2004, 2007 by Audrey Tang E<lt>[email protected]<gt>. | |
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_LEXICON_MSGCAT | |
$fatpacked{"Locale/Maketext/Lexicon/Tie.pm"} = <<'LOCALE_MAKETEXT_LEXICON_TIE'; | |
package Locale::Maketext::Lexicon::Tie; | |
$Locale::Maketext::Lexicon::Tie::VERSION = '0.05'; | |
use strict; | |
use Symbol (); | |
=head1 NAME | |
Locale::Maketext::Lexicon::Tie - Use tied hashes as lexicons for Maketext | |
=head1 SYNOPSIS | |
package Hello::I18N; | |
use base 'Locale::Maketext'; | |
use Locale::Maketext::Lexicon { | |
en => [ Tie => [ DB_File => 'en.db' ] ], | |
}; | |
=head1 DESCRIPTION | |
This module lets you easily C<tie> the C<%Lexicon> hash to a database | |
or other data sources. It takes an array reference of arguments, and | |
passes them directly to C<tie()>. | |
Entries will then be fetched whenever it is used; this module does not | |
cache them. | |
=cut | |
sub parse { | |
my $self = shift; | |
my $mod = shift; | |
my $sym = Symbol::gensym(); | |
# Load the target module into memory | |
{ | |
no strict 'refs'; | |
eval "use $mod; 1" or die $@ unless %{"$mod\::"}; | |
} | |
# Perform the actual tie | |
tie %{*$sym}, $mod, @_; | |
# Returns the GLOB reference, so %Lexicon will be tied too | |
return $sym; | |
} | |
1; | |
=head1 SEE ALSO | |
L<Locale::Maketext>, L<Locale::Maketext::Lexicon> | |
=head1 AUTHORS | |
Audrey Tang E<lt>[email protected]<gt> | |
=head1 COPYRIGHT | |
Copyright 2002, 2003, 2004, 2007 by Audrey Tang E<lt>[email protected]<gt>. | |
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_LEXICON_TIE | |
$fatpacked{"darwin-2level/version.pm"} = <<'DARWIN-2LEVEL_VERSION'; | |
#!perl -w | |
package version; | |
use 5.005_04; | |
use strict; | |
use vars qw(@ISA $VERSION $CLASS $STRICT $LAX *declare *qv); | |
$VERSION = 0.88; | |
$CLASS = 'version'; | |
#--------------------------------------------------------------------------# | |
# Version regexp components | |
#--------------------------------------------------------------------------# | |
# Fraction part of a decimal version number. This is a common part of | |
# both strict and lax decimal versions | |
my $FRACTION_PART = qr/\.[0-9]+/; | |
# First part of either decimal or dotted-decimal strict version number. | |
# Unsigned integer with no leading zeroes (except for zero itself) to | |
# avoid confusion with octal. | |
my $STRICT_INTEGER_PART = qr/0|[1-9][0-9]*/; | |
# First part of either decimal or dotted-decimal lax version number. | |
# Unsigned integer, but allowing leading zeros. Always interpreted | |
# as decimal. However, some forms of the resulting syntax give odd | |
# results if used as ordinary Perl expressions, due to how perl treats | |
# octals. E.g. | |
# version->new("010" ) == 10 | |
# version->new( 010 ) == 8 | |
# version->new( 010.2) == 82 # "8" . "2" | |
my $LAX_INTEGER_PART = qr/[0-9]+/; | |
# Second and subsequent part of a strict dotted-decimal version number. | |
# Leading zeroes are permitted, and the number is always decimal. | |
# Limited to three digits to avoid overflow when converting to decimal | |
# form and also avoid problematic style with excessive leading zeroes. | |
my $STRICT_DOTTED_DECIMAL_PART = qr/\.[0-9]{1,3}/; | |
# Second and subsequent part of a lax dotted-decimal version number. | |
# Leading zeroes are permitted, and the number is always decimal. No | |
# limit on the numerical value or number of digits, so there is the | |
# possibility of overflow when converting to decimal form. | |
my $LAX_DOTTED_DECIMAL_PART = qr/\.[0-9]+/; | |
# Alpha suffix part of lax version number syntax. Acts like a | |
# dotted-decimal part. | |
my $LAX_ALPHA_PART = qr/_[0-9]+/; | |
#--------------------------------------------------------------------------# | |
# Strict version regexp definitions | |
#--------------------------------------------------------------------------# | |
# Strict decimal version number. | |
my $STRICT_DECIMAL_VERSION = | |
qr/ $STRICT_INTEGER_PART $FRACTION_PART? /x; | |
# Strict dotted-decimal version number. Must have both leading "v" and | |
# at least three parts, to avoid confusion with decimal syntax. | |
my $STRICT_DOTTED_DECIMAL_VERSION = | |
qr/ v $STRICT_INTEGER_PART $STRICT_DOTTED_DECIMAL_PART{2,} /x; | |
# Complete strict version number syntax -- should generally be used | |
# anchored: qr/ \A $STRICT \z /x | |
$STRICT = | |
qr/ $STRICT_DECIMAL_VERSION | $STRICT_DOTTED_DECIMAL_VERSION /x; | |
#--------------------------------------------------------------------------# | |
# Lax version regexp definitions | |
#--------------------------------------------------------------------------# | |
# Lax decimal version number. Just like the strict one except for | |
# allowing an alpha suffix or allowing a leading or trailing | |
# decimal-point | |
my $LAX_DECIMAL_VERSION = | |
qr/ $LAX_INTEGER_PART (?: \. | $FRACTION_PART $LAX_ALPHA_PART? )? | |
| | |
$FRACTION_PART $LAX_ALPHA_PART? | |
/x; | |
# Lax dotted-decimal version number. Distinguished by having either | |
# leading "v" or at least three non-alpha parts. Alpha part is only | |
# permitted if there are at least two non-alpha parts. Strangely | |
# enough, without the leading "v", Perl takes .1.2 to mean v0.1.2, | |
# so when there is no "v", the leading part is optional | |
my $LAX_DOTTED_DECIMAL_VERSION = | |
qr/ | |
v $LAX_INTEGER_PART (?: $LAX_DOTTED_DECIMAL_PART+ $LAX_ALPHA_PART? )? | |
| | |
$LAX_INTEGER_PART? $LAX_DOTTED_DECIMAL_PART{2,} $LAX_ALPHA_PART? | |
/x; | |
# Complete lax version number syntax -- should generally be used | |
# anchored: qr/ \A $LAX \z /x | |
# | |
# The string 'undef' is a special case to make for easier handling | |
# of return values from ExtUtils::MM->parse_version | |
$LAX = | |
qr/ undef | $LAX_DECIMAL_VERSION | $LAX_DOTTED_DECIMAL_VERSION /x; | |
#--------------------------------------------------------------------------# | |
eval "use version::vxs $VERSION"; | |
if ( $@ ) { # don't have the XS version installed | |
eval "use version::vpp $VERSION"; # don't tempt fate | |
die "$@" if ( $@ ); | |
push @ISA, "version::vpp"; | |
local $^W; | |
*version::qv = \&version::vpp::qv; | |
*version::declare = \&version::vpp::declare; | |
*version::_VERSION = \&version::vpp::_VERSION; | |
if ($] >= 5.009000 && $] < 5.011004) { | |
no strict 'refs'; | |
*version::stringify = \&version::vpp::stringify; | |
*{'version::(""'} = \&version::vpp::stringify; | |
*version::new = \&version::vpp::new; | |
*version::parse = \&version::vpp::parse; | |
} | |
} | |
else { # use XS module | |
push @ISA, "version::vxs"; | |
local $^W; | |
*version::declare = \&version::vxs::declare; | |
*version::qv = \&version::vxs::qv; | |
*version::_VERSION = \&version::vxs::_VERSION; | |
*version::vcmp = \&version::vxs::VCMP; | |
if ($] >= 5.009000 && $] < 5.011004) { | |
no strict 'refs'; | |
*version::stringify = \&version::vxs::stringify; | |
*{'version::(""'} = \&version::vxs::stringify; | |
*version::new = \&version::vxs::new; | |
*version::parse = \&version::vxs::parse; | |
} | |
} | |
# Preloaded methods go here. | |
sub import { | |
no strict 'refs'; | |
my ($class) = shift; | |
# Set up any derived class | |
unless ($class eq 'version') { | |
local $^W; | |
*{$class.'::declare'} = \&version::declare; | |
*{$class.'::qv'} = \&version::qv; | |
} | |
my %args; | |
if (@_) { # any remaining terms are arguments | |
map { $args{$_} = 1 } @_ | |
} | |
else { # no parameters at all on use line | |
%args = | |
( | |
qv => 1, | |
'UNIVERSAL::VERSION' => 1, | |
); | |
} | |
my $callpkg = caller(); | |
if (exists($args{declare})) { | |
*{$callpkg.'::declare'} = | |
sub {return $class->declare(shift) } | |
unless defined(&{$callpkg.'::declare'}); | |
} | |
if (exists($args{qv})) { | |
*{$callpkg.'::qv'} = | |
sub {return $class->qv(shift) } | |
unless defined(&{$callpkg.'::qv'}); | |
} | |
if (exists($args{'UNIVERSAL::VERSION'})) { | |
local $^W; | |
*UNIVERSAL::VERSION | |
= \&version::_VERSION; | |
} | |
if (exists($args{'VERSION'})) { | |
*{$callpkg.'::VERSION'} = \&version::_VERSION; | |
} | |
if (exists($args{'is_strict'})) { | |
*{$callpkg.'::is_strict'} = \&version::is_strict | |
unless defined(&{$callpkg.'::is_strict'}); | |
} | |
if (exists($args{'is_lax'})) { | |
*{$callpkg.'::is_lax'} = \&version::is_lax | |
unless defined(&{$callpkg.'::is_lax'}); | |
} | |
} | |
sub is_strict { defined $_[0] && $_[0] =~ qr/ \A $STRICT \z /x } | |
sub is_lax { defined $_[0] && $_[0] =~ qr/ \A $LAX \z /x } | |
1; | |
DARWIN-2LEVEL_VERSION | |
$fatpacked{"darwin-2level/version/vxs.pm"} = <<'DARWIN-2LEVEL_VERSION_VXS'; | |
#!perl -w | |
package version::vxs; | |
use 5.005_03; | |
use strict; | |
use vars qw(@ISA $VERSION $CLASS ); | |
$VERSION = 0.88; | |
$CLASS = 'version::vxs'; | |
eval { | |
require XSLoader; | |
local $^W; # shut up the 'redefined' warning for UNIVERSAL::VERSION | |
XSLoader::load('version::vxs', $VERSION); | |
1; | |
} or do { | |
require DynaLoader; | |
push @ISA, 'DynaLoader'; | |
local $^W; # shut up the 'redefined' warning for UNIVERSAL::VERSION | |
bootstrap version::vxs $VERSION; | |
}; | |
# Preloaded methods go here. | |
1; | |
DARWIN-2LEVEL_VERSION_VXS | |
s/^ //mg for values %fatpacked; | |
unshift @INC, sub { | |
if (my $fat = $fatpacked{$_[1]}) { | |
open my $fh, '<', \$fat | |
or die "FatPacker error loading $_[1] (could be a perl installation issue?)"; | |
return $fh; | |
} | |
return | |
}; | |
} # END OF FATPACK CODE | |
package patchperl; | |
# ABSTRACT: patch a perl source tree | |
use strict; | |
use warnings; | |
use Devel::PatchPerl; | |
Devel::PatchPerl->patch_source(undef, $ARGV[0]); | |
__END__ | |
=pod | |
=head1 NAME | |
patchperl - patch a perl source tree | |
=head1 VERSION | |
version 0.32 | |
=head1 AUTHOR | |
Chris Williams <[email protected]> | |
=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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment