diff options
author | Charles Bailey <bailey@newman.upenn.edu> | 2000-08-04 01:18:46 +0000 |
---|---|---|
committer | bailey <bailey@newman.upenn.edu> | 2000-08-04 01:18:46 +0000 |
commit | 4b19af017623bfa3bb72bb164598a517f586e0d3 (patch) | |
tree | ba3232ffa110ce6bfc48de096d48b00ae6788077 /lib | |
parent | 674d6c381cbfa67bc93fd195278b889049c14bba (diff) | |
download | perl-4b19af017623bfa3bb72bb164598a517f586e0d3.tar.gz |
YA resync with mainstem, including VMS patches from others
p4raw-id: //depot/vmsperl@6514
Diffstat (limited to 'lib')
82 files changed, 4368 insertions, 457 deletions
diff --git a/lib/AutoLoader.pm b/lib/AutoLoader.pm index 8fd7d3b8fe..c26db72394 100644 --- a/lib/AutoLoader.pm +++ b/lib/AutoLoader.pm @@ -140,6 +140,11 @@ sub import { } } +sub unimport { + my $callpkg = caller; + eval "package $callpkg; sub AUTOLOAD;"; +} + 1; __END__ @@ -259,6 +264,12 @@ the package namespace. Variables pre-declared with this pragma will be visible to any autoloaded routines (but will not be invisible outside the package, unfortunately). +=head2 Not Using AutoLoader + +You can stop using AutoLoader by simply + + no AutoLoader; + =head2 B<AutoLoader> vs. B<SelfLoader> The B<AutoLoader> is similar in purpose to B<SelfLoader>: both delay the diff --git a/lib/AutoSplit.pm b/lib/AutoSplit.pm index 0be3ae6765..8640576cc7 100644 --- a/lib/AutoSplit.pm +++ b/lib/AutoSplit.pm @@ -6,6 +6,7 @@ use Config qw(%Config); use Carp qw(carp); use File::Basename (); use File::Path qw(mkpath); +use File::Spec::Functions qw(curdir catfile); use strict; our($VERSION, @ISA, @EXPORT, @EXPORT_OK, $Verbose, $Keep, $Maxlen, $CheckForAutoloader, $CheckModTime); @@ -173,16 +174,23 @@ sub autosplit_lib_modules{ my(@modules) = @_; # list of Module names while(defined($_ = shift @modules)){ - s#::#/#g; # incase specified as ABC::XYZ + while (m#(.*?[^:])::([^:].*)#) { # in case specified as ABC::XYZ + $_ = catfile($1, $2); + } s|\\|/|g; # bug in ksh OS/2 s#^lib/##s; # incase specified as lib/*.pm + my($lib) = catfile(curdir(), "lib"); + if ($Is_VMS) { # may need to convert VMS-style filespecs + $lib =~ s#^\[\]#.\/#; + } + s#^$lib\W+##s; # incase specified as ./lib/*.pm if ($Is_VMS && /[:>\]]/) { # may need to convert VMS-style filespecs my ($dir,$name) = (/(.*])(.*)/s); $dir =~ s/.*lib[\.\]]//s; $dir =~ s#[\.\]]#/#g; $_ = $dir . $name; } - autosplit_file("lib/$_", "lib/auto", + autosplit_file(catfile($lib, $_), catfile($lib, "auto"), $Keep, $CheckForAutoloader, $CheckModTime); } 0; @@ -199,7 +207,7 @@ sub autosplit_file { local($/) = "\n"; # where to write output files - $autodir ||= "lib/auto"; + $autodir ||= catfile(curdir(), "lib", "auto"); if ($Is_VMS) { ($autodir = VMS::Filespec::unixpath($autodir)) =~ s|/\z||; $filename = VMS::Filespec::unixify($filename); # may have dirs @@ -245,6 +253,9 @@ sub autosplit_file { $def_package or die "Can't find 'package Name;' in $filename\n"; my($modpname) = _modpname($def_package); + if ($Is_VMS) { + $modpname = VMS::Filespec::unixify($modpname); # may have dirs + } # this _has_ to match so we have a reasonable timestamp file die "Package $def_package ($modpname.pm) does not ". @@ -264,11 +275,12 @@ sub autosplit_file { } } - print "AutoSplitting $filename ($autodir/$modpname)\n" + my($modnamedir) = catfile($autodir, $modpname); + print "AutoSplitting $filename ($modnamedir)\n" if $Verbose; - unless (-d "$autodir/$modpname"){ - mkpath("$autodir/$modpname",0,0777); + unless (-d "$modnamedir"){ + mkpath("$modnamedir",0,0777); } # We must try to deal with some SVR3 systems with a limit of 14 @@ -311,9 +323,10 @@ sub autosplit_file { push(@subnames, $fq_subname); my($lname, $sname) = ($subname, substr($subname,0,$maxflen-3)); $modpname = _modpname($this_package); - mkpath("$autodir/$modpname",0,0777); - my($lpath) = "$autodir/$modpname/$lname.al"; - my($spath) = "$autodir/$modpname/$sname.al"; + my($modnamedir) = catfile($autodir, $modpname); + mkpath("$modnamedir",0,0777); + my($lpath) = catfile($modnamedir, "$lname.al"); + my($spath) = catfile($modnamedir, "$sname.al"); my $path; if (!$Is83 and open(OUT, ">$lpath")){ $path=$lpath; @@ -379,7 +392,7 @@ EOT opendir(OUTDIR,$dir); foreach (sort readdir(OUTDIR)){ next unless /\.al\z/; - my($file) = "$dir/$_"; + my($file) = catfile($dir, $_); $file = lc $file if $Is83 or $Is_VMS; next if $outfiles{$file}; print " deleting $file\n" if ($Verbose>=2); @@ -418,7 +431,9 @@ sub _modpname ($) { if ($^O eq 'MSWin32') { $modpname =~ s#::#\\#g; } else { - $modpname =~ s#::#/#g; + while ($modpname =~ m#(.*?[^:])::([^:].*)#) { + $modpname = catfile($1, $2); + } } $modpname; } diff --git a/lib/CGI/Util.pm b/lib/CGI/Util.pm index 0a5c48b6f3..cb6dd8a9e2 100644 --- a/lib/CGI/Util.pm +++ b/lib/CGI/Util.pm @@ -1,5 +1,13 @@ package CGI::Util; +=pod + +=head1 NAME + +CGI::Util - various utilities + +=cut + use strict; use vars '$VERSION','@EXPORT_OK','@ISA','$EBCDIC','@A2E'; require Exporter; diff --git a/lib/Cwd.pm b/lib/Cwd.pm index 9a92829da5..d86428cdb8 100644 --- a/lib/Cwd.pm +++ b/lib/Cwd.pm @@ -70,7 +70,7 @@ kept up to date if all packages which use chdir import it from Cwd. use Carp; -$VERSION = '2.02'; +$VERSION = '2.03'; require Exporter; @ISA = qw(Exporter); @@ -200,63 +200,39 @@ sub chdir { 1; } -# Taken from Cwd.pm It is really getcwd with an optional -# parameter instead of '.' -# -sub abs_path -{ - my $start = @_ ? shift : '.'; - my($dotdots, $cwd, @pst, @cst, $dir, @tst); +# By Jeff "japhy" Pinyan (07/23/2000) +# usage: abs_path(PATHNAME) +# see the docs + +sub abs_path { + my $base = @_ ? $_[0] : "."; + my $path = ""; + my $file; + + do { + my @devino = (stat($base))[0,1] or + carp("stat($base): $!"), return; - unless (@cst = stat( $start )) - { - carp "stat($start): $!"; - return ''; + $base .= "/.."; + + opendir PREV, $base or carp("opendir($base): $!"), return; + while (defined($file = readdir PREV)) { + next if $file eq "." or $file eq ".."; + my @entry = (lstat("$base/$file"))[0,1] or + carp("lstat($base/$file): $!"), return; + last if $devino[0] == $entry[0] and $devino[1] == $entry[1]; } - $cwd = ''; - $dotdots = $start; - do - { - $dotdots .= '/..'; - @pst = @cst; - unless (opendir(PARENT, $dotdots)) - { - carp "opendir($dotdots): $!"; - return ''; - } - unless (@cst = stat($dotdots)) - { - carp "stat($dotdots): $!"; - closedir(PARENT); - return ''; - } - if ($pst[0] == $cst[0] && $pst[1] == $cst[1]) - { - $dir = undef; - } - else - { - do - { - unless (defined ($dir = readdir(PARENT))) - { - carp "readdir($dotdots): $!"; - closedir(PARENT); - return ''; - } - $tst[0] = $pst[0]+1 unless (@tst = lstat("$dotdots/$dir")) - } - while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] || - $tst[1] != $pst[1]); - } - $cwd = (defined $dir ? "$dir" : "" ) . "/$cwd" ; - closedir(PARENT); - } while (defined $dir); - chop($cwd) unless $cwd eq '/'; # drop the trailing / - $cwd; + closedir PREV; + + $path = (defined $file and $file) . "/$path"; + } while defined $file; + + length($path) > 1 and chop $path; + return $path; } + # added function alias for those of us more # used to the libc function. --tchrist 27-Jan-00 *realpath = \&abs_path; diff --git a/lib/English.pm b/lib/English.pm index f38c313beb..1ebc3de11d 100644 --- a/lib/English.pm +++ b/lib/English.pm @@ -9,6 +9,7 @@ English - use nice English (or awk) names for ugly punctuation variables =head1 SYNOPSIS + use English qw( -no_match_vars ) ; # Avoids regex performance penalty use English; ... if ($ERRNO =~ /denied/) { ... } @@ -27,29 +28,52 @@ $INPUT_RECORD_SEPARATOR if you are using the English module. See L<perlvar> for a complete list of these. -=head1 BUGS +=head1 PERFORMANCE -This module provokes sizeable inefficiencies for regular expressions, -due to unfortunate implementation details. If performance matters, -consider avoiding English. +This module can provoke sizeable inefficiencies for regular expressions, +due to unfortunate implementation details. If performance matters in +your application and you don't need $PREMATCH, $MATCH, or $POSTMATCH, +try doing + + use English qw( -no_match_vars ) ; + +. B<It is especially important to do this in modules to avoid penalizing +all applications which use them.> =cut no warnings; +my $globbed_match ; + # Grandfather $NAME import sub import { my $this = shift; - my @list = @_; + my @list = grep { ! /^-no_match_vars$/ } @_ ; local $Exporter::ExportLevel = 1; + if ( @_ == @list ) { + *EXPORT = \@COMPLETE_EXPORT ; + $globbed_match ||= ( + eval q{ + *MATCH = *& ; + *PREMATCH = *` ; + *POSTMATCH = *' ; + 1 ; + } + || do { + require Carp ; + Carp::croak "Can't create English for match leftovers: $@" ; + } + ) ; + } + else { + *EXPORT = \@MINIMAL_EXPORT ; + } Exporter::import($this,grep {s/^\$/*/} @list); } -@EXPORT = qw( +@MINIMAL_EXPORT = qw( *ARG - *MATCH - *PREMATCH - *POSTMATCH *LAST_PAREN_MATCH *INPUT_LINE_NUMBER *NR @@ -102,15 +126,21 @@ sub import { @LAST_MATCH_END ); + +@MATCH_EXPORT = qw( + *MATCH + *PREMATCH + *POSTMATCH +); + +@COMPLETE_EXPORT = ( @MINIMAL_EXPORT, @MATCH_EXPORT ) ; + # The ground of all being. @ARG is deprecated (5.005 makes @_ lexical) *ARG = *_ ; # Matching. - *MATCH = *& ; - *PREMATCH = *` ; - *POSTMATCH = *' ; *LAST_PAREN_MATCH = *+ ; *LAST_MATCH_START = *-{ARRAY} ; *LAST_MATCH_END = *+{ARRAY} ; diff --git a/lib/ExtUtils/MM_Unix.pm b/lib/ExtUtils/MM_Unix.pm index da2255271f..8e337d97fa 100644 --- a/lib/ExtUtils/MM_Unix.pm +++ b/lib/ExtUtils/MM_Unix.pm @@ -457,7 +457,7 @@ EOT push(@otherfiles, qw[./blib $(MAKE_APERL_FILE) $(INST_ARCHAUTODIR)/extralibs.all perlmain.c mon.out core core.*perl.*.? *perl.core so_locations pm_to_blib - *~ */*~ */*/*~ *$(OBJ_EXT) *$(LIB_EXT) perl.exe + *$(OBJ_EXT) *$(LIB_EXT) perl.exe $(BOOTSTRAP) $(BASEEXT).bso $(BASEEXT).def $(BASEEXT).exp ]); @@ -1249,11 +1249,6 @@ eval 'exec $interpreter $arg -S \$0 \${1+"\$\@"}' next; } my($dev,$ino,$mode) = stat FIXIN; - # If they override perm_rwx, we won't notice it during fixin, - # because fixin is run through a new instance of MakeMaker. - # That is why we must run another CHMOD later. - $mode = oct($self->perm_rwx) unless $dev; - chmod $mode, $file; # Print out the new #! line (or equivalent). local $\; @@ -1261,7 +1256,15 @@ eval 'exec $interpreter $arg -S \$0 \${1+"\$\@"}' print FIXOUT $shb, <FIXIN>; close FIXIN; close FIXOUT; - # can't rename open files on some DOSISH platforms + + # can't rename/chmod open files on some DOSISH platforms + + # If they override perm_rwx, we won't notice it during fixin, + # because fixin is run through a new instance of MakeMaker. + # That is why we must run another CHMOD later. + $mode = oct($self->perm_rwx) unless $dev; + chmod $mode, $file; + unless ( rename($file, "$file.bak") ) { warn "Can't rename $file to $file.bak: $!"; next; @@ -1276,6 +1279,7 @@ eval 'exec $interpreter $arg -S \$0 \${1+"\$\@"}' } unlink "$file.bak"; } continue { + close(FIXIN) if fileno(FIXIN); chmod oct($self->perm_rwx), $file or die "Can't reset permissions for $file: $!\n"; system("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';; diff --git a/lib/ExtUtils/MM_VMS.pm b/lib/ExtUtils/MM_VMS.pm index 1e6c61a4c8..d21a56acba 100644 --- a/lib/ExtUtils/MM_VMS.pm +++ b/lib/ExtUtils/MM_VMS.pm @@ -626,7 +626,7 @@ INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR} if ($self->has_link_code()) { push @m,' INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT)$(LIB_EXT) -INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT) +INST_DYNAMIC = $(INST_ARCHAUTODIR)$(DLBASE).$(DLEXT) INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs '; } else { diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index 9906fd5383..bef12b54da 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -82,7 +82,7 @@ if ($Is_OS2) { require ExtUtils::MM_OS2; } if ($Is_Mac) { - require ExtUtils::MM_Mac; + require ExtUtils::MM_MacOS; } if ($Is_Win32) { require ExtUtils::MM_Win32; diff --git a/lib/ExtUtils/typemap b/lib/ExtUtils/typemap index a34cd4f9ea..0260678570 100644 --- a/lib/ExtUtils/typemap +++ b/lib/ExtUtils/typemap @@ -1,4 +1,3 @@ -# $Header: /home/rmb1/misc/CVS/perl5.005_61/lib/ExtUtils/typemap,v 1.3 1999/09/13 09:46:43 rmb1 Exp $ # basic C types int T_IV unsigned T_UV diff --git a/lib/ExtUtils/xsubpp b/lib/ExtUtils/xsubpp index 5a71e89636..1e9ff45cc9 100755 --- a/lib/ExtUtils/xsubpp +++ b/lib/ExtUtils/xsubpp @@ -288,7 +288,7 @@ $END = "!End!\n\n"; # "impossible" keyword (multiple newline) # Match an XS keyword $BLOCK_re= '\s*(' . join('|', qw( REQUIRE BOOT CASE PREINIT INPUT INIT CODE PPCODE OUTPUT - CLEANUP ALIAS PROTOTYPES PROTOTYPE VERSIONCHECK INCLUDE + CLEANUP ALIAS ATTRS PROTOTYPES PROTOTYPE VERSIONCHECK INCLUDE SCOPE INTERFACE INTERFACE_MACRO C_ARGS POSTCALL )) . "|$END)\\s*:"; @@ -573,6 +573,15 @@ sub GetAliases if $line ; } +sub ATTRS_handler () +{ + for (; !/^$BLOCK_re/o; $_ = shift(@line)) { + next unless /\S/; + TrimWhitespace($_) ; + push @Attributes, $_; + } +} + sub ALIAS_handler () { for (; !/^$BLOCK_re/o; $_ = shift(@line)) { @@ -847,7 +856,14 @@ EOM print("#line 1 \"$filename\"\n") if $WantLineNumbers; +firstmodule: while (<$FH>) { + if (/^=/) { + do { + next firstmodule if /^=cut\s*$/; + } while (<$FH>); + &Exit; + } last if ($Module, $Package, $Prefix) = /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/; @@ -886,6 +902,16 @@ sub fetch_para { } for(;;) { + # Skip embedded PODs + while ($lastline =~ /^=/) { + while ($lastline = <$FH>) { + last if ($lastline =~ /^=cut\s*$/); + } + death ("Error: Unterminated pod") unless $lastline; + $lastline = <$FH>; + chomp $lastline; + $lastline =~ s/^\s+$//; + } if ($lastline !~ /^\s*#/ || # CPP directives: # ANSI: if ifdef ifndef elif else endif define undef @@ -1039,7 +1065,7 @@ while (fetch_para()) { last; } $XSStack[$XSS_work_idx]{functions}{$Full_func_name} ++ ; - %XsubAliases = %XsubAliasValues = %Interfaces = (); + %XsubAliases = %XsubAliasValues = %Interfaces = @Attributes = (); $DoSetMagic = 1; $orig_args =~ s/\\\s*/ /g; # process line continuations @@ -1210,7 +1236,7 @@ EOF $gotRETVAL = 0; INPUT_handler() ; - process_keyword("INPUT|PREINIT|INTERFACE_MACRO|C_ARGS|ALIAS|PROTOTYPE|SCOPE") ; + process_keyword("INPUT|PREINIT|INTERFACE_MACRO|C_ARGS|ALIAS|ATTRS|PROTOTYPE|SCOPE") ; print Q<<"EOF" if $ScopeThisXSUB; # ENTER; @@ -1252,7 +1278,7 @@ EOF } print $deferred; - process_keyword("INIT|ALIAS|PROTOTYPE|INTERFACE_MACRO|INTERFACE|C_ARGS") ; + process_keyword("INIT|ALIAS|ATTRS|PROTOTYPE|INTERFACE_MACRO|INTERFACE|C_ARGS") ; if (check_keyword("PPCODE")) { print_section(); @@ -1296,7 +1322,7 @@ EOF # $wantRETVAL set if 'RETVAL =' autogenerated ($wantRETVAL, $ret_type) = (0, 'void') if $RETVAL_no_return; undef %outargs ; - process_keyword("POSTCALL|OUTPUT|ALIAS|PROTOTYPE"); + process_keyword("POSTCALL|OUTPUT|ALIAS|ATTRS|PROTOTYPE"); # all OUTPUT done, so now push the return value on the stack if ($gotRETVAL && $RETVAL_code) { @@ -1341,7 +1367,7 @@ EOF generate_output($var_types{$_}, $num++, $_, 0, 1) for @in_out; # do cleanup - process_keyword("CLEANUP|ALIAS|PROTOTYPE") ; + process_keyword("CLEANUP|ALIAS|ATTRS|PROTOTYPE") ; print Q<<"EOF" if $ScopeThisXSUB; # ]] @@ -1431,6 +1457,12 @@ EOF EOF } } + elsif (@Attributes) { + push(@InitFileCode, Q<<"EOF"); +# cv = newXS(\"$pname\", XS_$Full_func_name, file); +# apply_attrs_string("$Package", cv, "@Attributes", 0); +EOF + } elsif ($interface) { while ( ($name, $value) = each %Interfaces) { $name = "$Package\::$name" unless $name =~ /::/; diff --git a/lib/File/Find.pm b/lib/File/Find.pm index ac73f1b5eb..a9f190c722 100644 --- a/lib/File/Find.pm +++ b/lib/File/Find.pm @@ -373,7 +373,7 @@ sub _find_opt { $name = $abs_dir . $_; - &$wanted_callback; + { &$wanted_callback }; # protect against wild "next" } @@ -429,7 +429,7 @@ sub _find_dir($$$) { $_= ($no_chdir ? $dir_name : $dir_rel ); # prune may happen here $prune= 0; - &$wanted_callback; + { &$wanted_callback }; # protect against wild "next" next if $prune; } @@ -472,7 +472,7 @@ sub _find_dir($$$) { $name = $dir_pref . $FN; $_ = ($no_chdir ? $name : $FN); - &$wanted_callback; + { &$wanted_callback }; # protect against wild "next" } } @@ -496,13 +496,13 @@ sub _find_dir($$$) { else { $name = $dir_pref . $FN; $_= ($no_chdir ? $name : $FN); - &$wanted_callback; + { &$wanted_callback }; # protect against wild "next" } } else { $name = $dir_pref . $FN; $_= ($no_chdir ? $name : $FN); - &$wanted_callback; + { &$wanted_callback }; # protect against wild "next" } } } @@ -528,7 +528,7 @@ sub _find_dir($$$) { if ( substr($_,-2) eq '/.' ) { s|/\.$||; } - &$wanted_callback; + { &$wanted_callback }; # protect against wild "next" } else { push @Stack,[$CdLvl,$p_dir,$dir_rel,-1] if $bydepth; last; @@ -584,13 +584,25 @@ sub _find_dir_symlnk($$$) { while (defined $SE) { unless ($bydepth) { + # change to parent directory + unless ($no_chdir) { + my $udir = $pdir_loc; + if ($untaint) { + $udir = $1 if $pdir_loc =~ m|$untaint_pat|; + } + unless (chdir $udir) { + warn "Can't cd to $udir: $!\n"; + next; + } + } $dir= $p_dir; $name= $dir_name; $_= ($no_chdir ? $dir_name : $dir_rel ); $fullname= $dir_loc; # prune may happen here $prune= 0; - &$wanted_callback; + lstat($_); # make sure file tests with '_' work + { &$wanted_callback }; # protect against wild "next" next if $prune; } @@ -640,7 +652,7 @@ sub _find_dir_symlnk($$$) { $fullname = $new_loc; $name = $dir_pref . $FN; $_ = ($no_chdir ? $name : $FN); - &$wanted_callback; + { &$wanted_callback }; # protect against wild "next" } } @@ -673,7 +685,8 @@ sub _find_dir_symlnk($$$) { s|/\.$||; } - &$wanted_callback; + lstat($_); # make sure file tests with '_' work + { &$wanted_callback }; # protect against wild "next" } else { push @Stack,[$dir_loc, $pdir_loc, $p_dir, $dir_rel,-1] if $bydepth; last; @@ -721,7 +734,8 @@ if ($^O eq 'VMS') { } $File::Find::dont_use_nlink = 1 - if $^O eq 'os2' || $^O eq 'dos' || $^O eq 'amigaos' || $^O eq 'MSWin32'; + if $^O eq 'os2' || $^O eq 'dos' || $^O eq 'amigaos' || $^O eq 'MSWin32' || + $^O eq 'cygwin'; # Set dont_use_nlink in your hint file if your system's stat doesn't # report the number of links in a directory as an indication diff --git a/lib/File/Spec.pm b/lib/File/Spec.pm index ed26d76a56..40503c467f 100644 --- a/lib/File/Spec.pm +++ b/lib/File/Spec.pm @@ -3,7 +3,7 @@ package File::Spec; use strict; use vars qw(@ISA $VERSION); -$VERSION = '0.81'; +$VERSION = 0.82 ; my %module = (MacOS => 'Mac', MSWin32 => 'Win32', diff --git a/lib/File/Spec/Mac.pm b/lib/File/Spec/Mac.pm index 5315d9220f..9ef55ec84a 100644 --- a/lib/File/Spec/Mac.pm +++ b/lib/File/Spec/Mac.pm @@ -4,7 +4,7 @@ use strict; use vars qw(@ISA $VERSION); require File::Spec::Unix; -$VERSION = '1.1'; +$VERSION = '1.2'; @ISA = qw(File::Spec::Unix); @@ -192,12 +192,16 @@ folder named "HD" in the current working directory on a drive named "HD"), relative wins. Use ":" in the appropriate place in the path if you want to distinguish unambiguously. +As a special case, the file name '' is always considered to be absolute. + =cut sub file_name_is_absolute { my ($self,$file) = @_; if ($file =~ /:/) { return ($file !~ m/^:/s); + } elsif ( $file eq '' ) { + return 1 ; } else { return (! -e ":$file"); } @@ -307,6 +311,12 @@ sub catpath { =item abs2rel +See L<File::Spec::Unix/abs2rel> for general documentation. + +Unlike C<File::Spec::Unix->abs2rel()>, this function will make +checks against the local filesystem if necessary. See +L</file_name_is_absolute> for details. + =cut sub abs2rel { @@ -344,31 +354,15 @@ sub abs2rel { =item rel2abs -Converts a relative path to an absolute path. - - $abs_path = File::Spec->rel2abs( $destination ) ; - $abs_path = File::Spec->rel2abs( $destination, $base ) ; - -If $base is not present or '', then L<cwd()> is used. If $base is relative, -then it is converted to absolute form using L</rel2abs()>. This means that it -is taken to be relative to L<cwd()>. - -On systems with the concept of a volume, this assumes that both paths -are on the $base volume, and ignores the $destination volume. - -On systems that have a grammar that indicates filenames, this ignores the -$base filename as well. Otherwise all path components are assumed to be -directories. - -If $path is absolute, it is cleaned up and returned using L</canonpath()>. - -Based on code written by Shigio Yamaguchi. +See L<File::Spec::Unix/rel2abs> for general documentation. -No checks against the filesystem are made. +Unlike C<File::Spec::Unix->rel2abs()>, this function will make +checks against the local filesystem if necessary. See +L</file_name_is_absolute> for details. =cut -sub rel2abs($;$;) { +sub rel2abs { my ($self,$path,$base ) = @_; if ( ! $self->file_name_is_absolute( $path ) ) { diff --git a/lib/File/Spec/Unix.pm b/lib/File/Spec/Unix.pm index 6ca26d74ce..a81c533235 100644 --- a/lib/File/Spec/Unix.pm +++ b/lib/File/Spec/Unix.pm @@ -3,7 +3,7 @@ package File::Spec::Unix; use strict; use vars qw($VERSION); -$VERSION = '1.1'; +$VERSION = '1.2'; use Cwd; @@ -165,7 +165,12 @@ sub case_tolerant { =item file_name_is_absolute -Takes as argument a path and returns true, if it is an absolute path. +Takes as argument a path and returns true if it is an absolute path. + +This does not consult the local filesystem on Unix, Win32, or OS/2. It +does sometimes on MacOS (see L<File::Spec::MacOS/file_name_is_absolute>). +It does consult the working environment for VMS (see +L<File::Spec::VMS/file_name_is_absolute>). =cut @@ -311,8 +316,8 @@ sub catpath { Takes a destination path and an optional base path returns a relative path from the base path to the destination path: - $rel_path = File::Spec->abs2rel( $destination ) ; - $rel_path = File::Spec->abs2rel( $destination, $base ) ; + $rel_path = File::Spec->abs2rel( $path ) ; + $rel_path = File::Spec->abs2rel( $path, $base ) ; If $base is not present or '', then L<cwd()> is used. If $base is relative, then it is converted to absolute form using L</rel2abs()>. This means that it @@ -328,9 +333,13 @@ directories. If $path is relative, it is converted to absolute form using L</rel2abs()>. This means that it is taken to be relative to L<cwd()>. -Based on code written by Shigio Yamaguchi. +No checks against the filesystem are made on most systems. On MacOS, +the filesystem may be consulted (see +L<File::Spec::MacOS/file_name_is_absolute>). On VMS, there is +interaction with the working environment, as logicals and +macros are expanded. -No checks against the filesystem are made. +Based on code written by Shigio Yamaguchi. =cut @@ -388,15 +397,15 @@ sub abs2rel { Converts a relative path to an absolute path. - $abs_path = File::Spec->rel2abs( $destination ) ; - $abs_path = File::Spec->rel2abs( $destination, $base ) ; + $abs_path = File::Spec->rel2abs( $path ) ; + $abs_path = File::Spec->rel2abs( $path, $base ) ; If $base is not present or '', then L<cwd()> is used. If $base is relative, then it is converted to absolute form using L</rel2abs()>. This means that it is taken to be relative to L<cwd()>. On systems with the concept of a volume, this assumes that both paths -are on the $base volume, and ignores the $destination volume. +are on the $base volume, and ignores the $path volume. On systems that have a grammar that indicates filenames, this ignores the $base filename as well. Otherwise all path components are assumed to be @@ -404,13 +413,17 @@ directories. If $path is absolute, it is cleaned up and returned using L</canonpath()>. -Based on code written by Shigio Yamaguchi. +No checks against the filesystem are made on most systems. On MacOS, +the filesystem may be consulted (see +L<File::Spec::MacOS/file_name_is_absolute>). On VMS, there is +interaction with the working environment, as logicals and +macros are expanded. -No checks against the filesystem are made. +Based on code written by Shigio Yamaguchi. =cut -sub rel2abs($;$;) { +sub rel2abs { my ($self,$path,$base ) = @_; # Clean up $path diff --git a/lib/File/Spec/VMS.pm b/lib/File/Spec/VMS.pm index cc06ca636d..60b0ec8e50 100644 --- a/lib/File/Spec/VMS.pm +++ b/lib/File/Spec/VMS.pm @@ -265,7 +265,7 @@ sub rootdir { Returns a string representation of the first writable directory from the following list or '' if none are writable: - sys$scratch + sys$scratch: $ENV{TMPDIR} =cut @@ -273,7 +273,7 @@ from the following list or '' if none are writable: my $tmpdir; sub tmpdir { return $tmpdir if defined $tmpdir; - foreach ('sys$scratch', $ENV{TMPDIR}) { + foreach ('sys$scratch:', $ENV{TMPDIR}) { next unless defined && -d && -w _; $tmpdir = $_; last; @@ -451,7 +451,7 @@ Use VMS syntax when converting filespecs. =cut -sub rel2abs($;$;) { +sub rel2abs { my $self = shift ; return vmspath(File::Spec::Unix::rel2abs( $self, @_ )) if ( join( '', @_ ) =~ m{/} ) ; diff --git a/lib/File/Spec/Win32.pm b/lib/File/Spec/Win32.pm index b8fe37bbdb..f5d6cda2bc 100644 --- a/lib/File/Spec/Win32.pm +++ b/lib/File/Spec/Win32.pm @@ -5,7 +5,7 @@ use Cwd; use vars qw(@ISA $VERSION); require File::Spec::Unix; -$VERSION = '1.1'; +$VERSION = '1.2'; @ISA = qw(File::Spec::Unix); @@ -242,34 +242,6 @@ sub catpath { } -=item abs2rel - -Takes a destination path and an optional base path returns a relative path -from the base path to the destination path: - - $rel_path = File::Spec->abs2rel( $destination ) ; - $rel_path = File::Spec->abs2rel( $destination, $base ) ; - -If $base is not present or '', then L</cwd()> is used. If $base is relative, -then it is converted to absolute form using L</rel2abs()>. This means that it -is taken to be relative to L<cwd()>. - -On systems with the concept of a volume, this assumes that both paths -are on the $destination volume, and ignores the $base volume. - -On systems that have a grammar that indicates filenames, this ignores the -$base filename as well. Otherwise all path components are assumed to be -directories. - -If $path is relative, it is converted to absolute form using L</rel2abs()>. -This means that it is taken to be relative to L</cwd()>. - -Based on code written by Shigio Yamaguchi. - -No checks against the filesystem are made. - -=cut - sub abs2rel { my($self,$path,$base) = @_; @@ -339,33 +311,8 @@ sub abs2rel { ) ; } -=item rel2abs - -Converts a relative path to an absolute path. - - $abs_path = File::Spec->rel2abs( $destination ) ; - $abs_path = File::Spec->rel2abs( $destination, $base ) ; - -If $base is not present or '', then L<cwd()> is used. If $base is relative, -then it is converted to absolute form using L</rel2abs()>. This means that it -is taken to be relative to L</cwd()>. - -Assumes that both paths are on the $base volume, and ignores the -$destination volume. - -On systems that have a grammar that indicates filenames, this ignores the -$base filename as well. Otherwise all path components are assumed to be -directories. - -If $path is absolute, it is cleaned up and returned using L</canonpath()>. - -Based on code written by Shigio Yamaguchi. - -No checks against the filesystem are made. - -=cut -sub rel2abs($;$;) { +sub rel2abs { my ($self,$path,$base ) = @_; if ( ! $self->file_name_is_absolute( $path ) ) { diff --git a/lib/File/Temp.pm b/lib/File/Temp.pm index 736ef3fdb3..aac8b7a93c 100644 --- a/lib/File/Temp.pm +++ b/lib/File/Temp.pm @@ -92,6 +92,10 @@ use File::Path qw/ rmtree /; use Fcntl 1.03; use Errno qw( EEXIST ENOENT ENOTDIR EINVAL ); +# Need the Symbol package if we are running older perl +require Symbol if $] < 5.006; + + # use 'our' on v5.6.0 use vars qw($VERSION @EXPORT_OK %EXPORT_TAGS $DEBUG); @@ -99,8 +103,6 @@ $DEBUG = 0; # We are exporting functions -#require Exporter; -#@ISA = qw/Exporter/; use base qw/Exporter/; # Export list - to allow fine tuning of export table @@ -111,7 +113,7 @@ use base qw/Exporter/; tmpnam tmpfile mktemp - mkstemp + mkstemp mkstemps mkdtemp unlink0 @@ -129,13 +131,13 @@ Exporter::export_tags('POSIX','mktemp'); # Version number -$VERSION = '0.07'; +$VERSION = '0.09'; # This is a list of characters that can be used in random filenames my @CHARS = (qw/ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z - 0 1 2 3 4 5 6 7 8 9 _ + 0 1 2 3 4 5 6 7 8 9 _ /); # Maximum number of tries to make a temp file before failing @@ -155,12 +157,25 @@ use constant STANDARD => 0; use constant MEDIUM => 1; use constant HIGH => 2; +# OPENFLAGS. If we defined the flag to use with Sysopen here this gives +# us an optimisation when many temporary files are requested + +my $OPENFLAGS = O_CREAT | O_EXCL | O_RDWR; + +for my $oflag (qw/FOLLOW BINARY LARGEFILE EXLOCK NOINHERIT TEMPORARY/) { + my ($bit, $func) = (0, "Fcntl::O_" . $oflag); + no strict 'refs'; + $OPENFLAGS |= $bit if eval { $bit = &$func(); 1 }; +} + + + # INTERNAL ROUTINES - not to be used outside of package # Generic routine for getting a temporary filename # modelled on OpenBSD _gettemp() in mktemp.c -# The template must contain X's that are to be replaced +# The template must contain X's that are to be replaced # with the random values # Arguments: @@ -216,7 +231,7 @@ sub _gettemp { # Read the options and merge with defaults %options = (%options, @_) if @_; - + # Can not open the file and make a directory in a single call if ($options{"open"} && $options{"mkdir"}) { carp "File::Temp::_gettemp: doopen and domkdir can not both be true\n"; @@ -268,11 +283,16 @@ sub _gettemp { $parent = File::Spec->curdir; } else { - # Put it back together without the last one - $parent = File::Spec->catdir(@dirs[0..$#dirs-1]); + if ($^O eq 'VMS') { # need volume to avoid relative dir spec + $parent = File::Spec->catdir($volume, @dirs[0..$#dirs-1]); + } else { - # ...and attach the volume (no filename) - $parent = File::Spec->catpath($volume, $parent, ''); + # Put it back together without the last one + $parent = File::Spec->catdir(@dirs[0..$#dirs-1]); + + # ...and attach the volume (no filename) + $parent = File::Spec->catpath($volume, $parent, ''); + } } @@ -296,7 +316,7 @@ sub _gettemp { # that does not exist or is not writable unless (-d $parent && -w _) { - carp "File::Temp::_gettemp: Parent directory ($parent) is not a directory" + carp "File::Temp::_gettemp: Parent directory ($parent) is not a directory" . " or is not writable\n"; return (); } @@ -320,19 +340,18 @@ sub _gettemp { # Calculate the flags that we wish to use for the sysopen # Some of these are not always available - my $openflags; - if ($options{"open"}) { +# my $openflags; +# if ($options{"open"}) { # Default set - $openflags = O_CREAT | O_EXCL | O_RDWR; +# $openflags = O_CREAT | O_EXCL | O_RDWR; - for my $oflag (qw/FOLLOW BINARY LARGEFILE EXLOCK NOINHERIT TEMPORARY/) { - my ($bit, $func) = (0, "Fcntl::O_" . $oflag); - no strict 'refs'; - $openflags |= $bit if eval { $bit = &$func(); 1 }; - } +# for my $oflag (qw/FOLLOW BINARY LARGEFILE EXLOCK NOINHERIT TEMPORARY/) { +# my ($bit, $func) = (0, "Fcntl::O_" . $oflag); +# no strict 'refs'; +# $openflags |= $bit if eval { $bit = &$func(); 1 }; +# } - } - +# } # Now try MAX_TRIES time to open the file for (my $i = 0; $i < MAX_TRIES; $i++) { @@ -343,7 +362,6 @@ sub _gettemp { # If we are running before perl5.6.0 we can not auto-vivify if ($] < 5.006) { - require Symbol; $fh = &Symbol::gensym; } @@ -359,7 +377,7 @@ sub _gettemp { umask(066); # Attempt to open the file - if ( sysopen($fh, $path, $openflags, 0600) ) { + if ( sysopen($fh, $path, $OPENFLAGS, 0600) ) { # Reset umask umask($umask); @@ -419,10 +437,10 @@ sub _gettemp { return (undef, $path) unless -e $path; - # Try again until MAX_TRIES + # Try again until MAX_TRIES } - + # Did not successfully open the tempfile/dir # so try again with a different set of random letters # No point in trying to increment unless we have only @@ -449,7 +467,7 @@ sub _gettemp { # Check for out of control looping if ($counter > $MAX_GUESS) { - carp "Tried to get a new temp name different to the previous value$MAX_GUESS times.\nSomething wrong with template?? ($template)"; + carp "Tried to get a new temp name different to the previous value $MAX_GUESS times.\nSomething wrong with template?? ($template)"; return (); } @@ -469,6 +487,10 @@ sub _gettemp { # No arguments. Return value is the random character +# No longer called since _replace_XX runs a few percent faster if +# I inline the code. This is important if we are creating thousands of +# temporary files. + sub _randchar { $CHARS[ int( rand( $#CHARS ) ) ]; @@ -497,18 +519,18 @@ sub _replace_XX { # Don't want to always use substr when not required though. if ($ignore) { - substr($path, 0, - $ignore) =~ s/X(?=X*\z)/_randchar()/ge; + substr($path, 0, - $ignore) =~ s/X(?=X*\z)/$CHARS[ int( rand( $#CHARS ) ) ]/ge; } else { - $path =~ s/X(?=X*\z)/_randchar()/ge; + $path =~ s/X(?=X*\z)/$CHARS[ int( rand( $#CHARS ) ) ]/ge; } return $path; } # internal routine to check to see if the directory is safe -# First checks to see if the directory is not owned by the +# First checks to see if the directory is not owned by the # current user or root. Then checks to see if anyone else -# can write to the directory and if so, checks to see if +# can write to the directory and if so, checks to see if # it has the sticky bit set # Will not work on systems that do not support sticky bit @@ -530,6 +552,7 @@ sub _is_safe { # Stat path my @info = stat($path); return 0 unless scalar(@info); + return 1 if $^O eq 'VMS'; # owner delete control at file level # Check to see whether owner is neither superuser (or a system uid) nor me # Use the real uid from the $< variable @@ -567,6 +590,7 @@ sub _is_verysafe { require POSIX; my $path = shift; + return 1 if $^O eq 'VMS'; # owner delete control at file level # Should Get the value of _PC_CHOWN_RESTRICTED if it is defined # and If it is not there do the extensive test @@ -626,19 +650,48 @@ sub _is_verysafe { # platform for files that are currently open. # Returns true if we can, false otherwise. -# Currently WinNT can not unlink an opened file +# Currently WinNT, OS/2 and VMS can not unlink an opened file +# On VMS this is because the O_EXCL flag is used to open the +# temporary file. Currently I do not know enough about the issues +# on VMS to decide whether O_EXCL is a requirement. sub _can_unlink_opened_file { - - $^O ne 'MSWin32' ? 1 : 0; + if ($^O eq 'MSWin32' || $^O eq 'os2' || $^O eq 'VMS') { + return 0; + } else { + return 1; + } } +# internal routine to decide which security levels are allowed +# see safe_level() for more information on this + +# Controls whether the supplied security level is allowed + +# $cando = _can_do_level( $level ) + +sub _can_do_level { + + # Get security level + my $level = shift; + + # Always have to be able to do STANDARD + return 1 if $level == STANDARD; + + # Currently, the systems that can do HIGH or MEDIUM are identical + if ( $^O eq 'MSWin32' || $^O eq 'os2') { + return 0; + } else { + return 1; + } + +} # This routine sets up a deferred unlinking of a specified # filename and filehandle. It is used in the following cases: -# - Called by unlink0 if an opend file can not be unlinked +# - Called by unlink0 if an opened file can not be unlinked # - Called by tempfile() if files are to be removed on shutdown # - Called by tempdir() if directories are to be removed on shutdown @@ -650,71 +703,84 @@ sub _can_unlink_opened_file { # - isdir (flag to indicate that we are being given a directory) # [and hence no filehandle] -# Status is not referred since all the magic is done with END blocks +# Status is not referred to since all the magic is done with and END block -sub _deferred_unlink { +{ + # Will set up two lexical variables to contain all the files to be + # removed. One array for files, another for directories + # They will only exist in this block + # This means we only have to set up a single END block to remove all files + # @files_to_unlink contains an array ref with the filehandle and filename + my (@files_to_unlink, @dirs_to_unlink); + + # Set up an end block to use these arrays + END { + # Files + foreach my $file (@files_to_unlink) { + # close the filehandle without checking its state + # in order to make real sure that this is closed + # if its already closed then I dont care about the answer + # probably a better way to do this + close($file->[0]); # file handle is [0] + + if (-f $file->[1]) { # file name is [1] + unlink $file->[1] or warn "Error removing ".$file->[1]; + } + } + # Dirs + foreach my $dir (@dirs_to_unlink) { + if (-d $dir) { + rmtree($dir, $DEBUG, 1); + } + } - croak 'Usage: _deferred_unlink($fh, $fname, $isdir)' - unless scalar(@_) == 3; - my ($fh, $fname, $isdir) = @_; + } - warn "Setting up deferred removal of $fname\n" - if $DEBUG; + # This is the sub called to register a file for deferred unlinking + # This could simply store the input parameters and defer everything + # until the END block. For now we do a bit of checking at this + # point in order to make sure that (1) we have a file/dir to delete + # and (2) we have been called with the correct arguments. + sub _deferred_unlink { - # If we have a directory, check that it is a directory - if ($isdir) { + croak 'Usage: _deferred_unlink($fh, $fname, $isdir)' + unless scalar(@_) == 3; - if (-d $fname) { + my ($fh, $fname, $isdir) = @_; - # Directory exists so set up END block - # (quoted to preserve lexical variables) - eval q{ - END { - if (-d $fname) { - rmtree($fname, $DEBUG, 1); - } - } - 1; - } || die; + warn "Setting up deferred removal of $fname\n" + if $DEBUG; - } else { - carp "Request to remove directory $fname could not be completed since it does not exists!\n"; - } + # If we have a directory, check that it is a directory + if ($isdir) { + if (-d $fname) { - } else { + # Directory exists so store it + push (@dirs_to_unlink, $fname); - if (-f $fname) { - - # dile exists so set up END block - # (quoted to preserve lexical variables) - eval q{ - END { - # close the filehandle without checking its state - # in order to make real sure that this is closed - # if its already closed then I dont care about the answer - # probably a better way to do this - close($fh); - - if (-f $fname) { - unlink $fname - || warn "Error removing $fname"; - } - } - 1; - } || die; + } else { + carp "Request to remove directory $fname could not be completed since it does not exists!\n"; + } } else { - carp "Request to remove file $fname could not be completed since it is not there!\n"; - } + if (-f $fname) { + + # file exists so store handle and name for later removal + push(@files_to_unlink, [$fh, $fname]); + + } else { + carp "Request to remove file $fname could not be completed since it is not there!\n"; + } + + } - } -} +} =head1 FUNCTIONS @@ -807,7 +873,7 @@ sub tempfile { } - # Construct the template + # Construct the template # Have a choice of trying to work around the mkstemp/mktemp/tmpnam etc # functions or simply constructing a template and using _gettemp() @@ -829,11 +895,11 @@ sub tempfile { $template = File::Spec->catfile($options{"DIR"}, TEMPXXX); } else { - + $template = File::Spec->catfile(File::Spec->tmpdir, TEMPXXX); } - + } # Now add a suffix @@ -846,13 +912,13 @@ sub tempfile { "open" => $options{'OPEN'}, "mkdir"=> 0 , "suffixlen" => length($options{'SUFFIX'}), - ) ); + ) ); # Set up an exit handler that can do whatever is right for the # system. Do not check return status since this is all done with # END blocks _deferred_unlink($fh, $path, 0) if $options{"UNLINK"}; - + # Return if (wantarray()) { @@ -867,7 +933,7 @@ sub tempfile { # Unlink the file. It is up to unlink0 to decide what to do with # this (whether to unlink now or to defer until later) unlink0($fh, $path) or croak "Error unlinking file $path using unlink0"; - + # Return just the filehandle. return $fh; } @@ -985,26 +1051,31 @@ sub tempdir { $template = File::Spec->catdir($options{"DIR"}, TEMPXXX); } else { - + $template = File::Spec->catdir(File::Spec->tmpdir, TEMPXXX); } - + } # Create the directory my $tempdir; + my $suffixlen = 0; + if ($^O eq 'VMS') { # dir names can end in delimiters + $template =~ m/([\.\]:>]+)$/; + $suffixlen = length($1); + } croak "Error in tempdir() using $template" unless ((undef, $tempdir) = _gettemp($template, - "open" => 0, + "open" => 0, "mkdir"=> 1 , - "suffixlen" => 0, - ) ); - + "suffixlen" => $suffixlen, + ) ); + # Install exit handler; must be dynamic to get lexical - if ( $options{'CLEANUP'} && -d $tempdir) { + if ( $options{'CLEANUP'} && -d $tempdir) { _deferred_unlink(undef, $tempdir, 1); - } + } # Return the dir name return $tempdir; @@ -1046,8 +1117,8 @@ sub mkstemp { my ($fh, $path); croak "Error in mkstemp using $template" - unless (($fh, $path) = _gettemp($template, - "open" => 1, + unless (($fh, $path) = _gettemp($template, + "open" => 1, "mkdir"=> 0 , "suffixlen" => 0, ) ); @@ -1085,7 +1156,7 @@ sub mkstemps { my $suffix = shift; $template .= $suffix; - + my ($fh, $path); croak "Error in mkstemps using $template" unless (($fh, $path) = _gettemp($template, @@ -1122,15 +1193,19 @@ sub mkdtemp { croak "Usage: mkdtemp(template)" if scalar(@_) != 1; - - my $template = shift; + my $template = shift; + my $suffixlen = 0; + if ($^O eq 'VMS') { # dir names can end in delimiters + $template =~ m/([\.\]:>]+)$/; + $suffixlen = length($1); + } my ($junk, $tmpdir); croak "Error creating temp directory from template $template\n" unless (($junk, $tmpdir) = _gettemp($template, - "open" => 0, + "open" => 0, "mkdir"=> 1 , - "suffixlen" => 0, + "suffixlen" => $suffixlen, ) ); return $tmpdir; @@ -1158,7 +1233,7 @@ sub mktemp { my ($tmpname, $junk); croak "Error getting name to temp file from template $template\n" unless (($junk, $tmpname) = _gettemp($template, - "open" => 0, + "open" => 0, "mkdir"=> 0 , "suffixlen" => 0, ) ); @@ -1217,7 +1292,7 @@ sub tmpnam { # Use a ten character template and append to tmpdir my $template = File::Spec->catfile($tmpdir, TEMPXXX); - + if (wantarray() ) { return mkstemp($template); } else { @@ -1320,11 +1395,11 @@ occasions this is not required. On some platforms, for example Windows NT, it is not possible to unlink an open file (the file must be closed first). On those -platforms, the actual unlinking is deferred until the program ends -and good status is returned. A check is still performed to make sure that -the filehandle and filename are pointing to the same thing (but not at the time -the end block is executed since the deferred removal may not have access to -the filehandle). +platforms, the actual unlinking is deferred until the program ends and +good status is returned. A check is still performed to make sure that +the filehandle and filename are pointing to the same thing (but not at +the time the end block is executed since the deferred removal may not +have access to the filehandle). Additionally, on Windows NT not all the fields returned by stat() can be compared. For example, the C<dev> and C<rdev> fields seem to be different @@ -1334,6 +1409,10 @@ C<stat(filename)>, presumably because of caching issues even when using autoflush (this is usually overcome by waiting a while after writing to the tempfile before attempting to C<unlink0> it). +Finally, on NFS file systems the link count of the file handle does +not always go to zero immediately after unlinking. Currently, this +command is expected to fail on NFS disks. + =cut sub unlink0 { @@ -1352,7 +1431,7 @@ sub unlink0 { if ($fh[3] > 1 && $^W) { carp "unlink0: fstat found too many links; SB=@fh"; - } + } # Stat the path my @path = stat $path; @@ -1360,12 +1439,12 @@ sub unlink0 { unless (@path) { carp "unlink0: $path is gone already" if $^W; return; - } + } # this is no longer a file, but may be a directory, or worse unless (-f _) { confess "panic: $path is no longer a file: SB=@fh"; - } + } # Do comparison of each member of the array # On WinNT dev and rdev seem to be different @@ -1375,17 +1454,22 @@ sub unlink0 { my @okstat = (0..$#fh); # Use all by default if ($^O eq 'MSWin32') { @okstat = (1,2,3,4,5,7,8,9,10); + } elsif ($^O eq 'os2') { + @okstat = (0, 2..$#fh); } # Now compare each entry explicitly by number for (@okstat) { print "Comparing: $_ : $fh[$_] and $path[$_]\n" if $DEBUG; - unless ($fh[$_] == $path[$_]) { + # Use eq rather than == since rdev, blksize, and blocks (6, 11, + # and 12) will be '' on platforms that do not support them. This + # is fine since we are only comparing integers. + unless ($fh[$_] eq $path[$_]) { warn "Did not match $_ element of stat\n" if $DEBUG; return 0; } } - + # attempt remove the file (does not work on some platforms) if (_can_unlink_opened_file()) { # XXX: do *not* call this on a directory; possible race @@ -1468,7 +1552,21 @@ run with MEDIUM or HIGH security. This is simply because the safety tests use functions from L<Fcntl|Fcntl> that are not available in older versions of perl. The problem is that the version number for Fcntl is the same in perl 5.6.0 and in 5.005_03 even though -they are different versions..... +they are different versions. + +On systems that do not support the HIGH or MEDIUM safety levels +(for example Win NT or OS/2) any attempt to change the level will +be ignored. The decision to ignore rather than raise an exception +allows portable programs to be written with high security in mind +for the systems that can support this without those programs failing +on systems where the extra tests are irrelevant. + +If you really need to see whether the change has been accepted +simply examine the return value of C<safe_level>. + + $newlevel = File::Temp->safe_level( File::Temp::HIGH ); + die "Could not change to high security" + if $newlevel != File::Temp::HIGH; =cut @@ -1482,11 +1580,14 @@ they are different versions..... if (($level != STANDARD) && ($level != MEDIUM) && ($level != HIGH)) { carp "safe_level: Specified level ($level) not STANDARD, MEDIUM or HIGH - ignoring\n"; } else { + # Dont allow this on perl 5.005 or earlier if ($] < 5.006 && $level != STANDARD) { # Cant do MEDIUM or HIGH checks croak "Currently requires perl 5.006 or newer to do the safe checks"; } - $LEVEL = $level; + # Check that we are allowed to change level + # Silently ignore if we can not. + $LEVEL = $level if _can_do_level($level); } } return $LEVEL; diff --git a/lib/IPC/Open3.pm b/lib/IPC/Open3.pm index 46ebd68cef..5c9c69ad02 100644 --- a/lib/IPC/Open3.pm +++ b/lib/IPC/Open3.pm @@ -44,6 +44,9 @@ by an autogenerated filehandle. If so, you must pass a valid lvalue in the parameter slot so it can be overwritten in the caller, or an exception will be raised. +The filehandles may also be integers, in which case they are understood +as file descriptors. + open3() returns the process ID of the child process. It doesn't return on failure: it just raises an exception matching C</^open3:/>. However, C<exec> failures in the child are not detected. You'll have to @@ -84,6 +87,7 @@ The order of arguments differs from that of open2(). # fixed for 5.001 by Ulrich Kunitz <kunitz@mai-koeln.com> # ported to Win32 by Ron Schmidt, Merrill Lynch almost ended my career # fixed for autovivving FHs, tchrist again +# allow fd numbers to be used, by Frank Tobin # # $Id: open3.pl,v 1.1 1993/11/23 06:26:15 marc Exp $ # @@ -136,6 +140,15 @@ sub xclose { close $_[0] or croak "$Me: close($_[0]) failed: $!"; } +sub fh_is_fd { + return $_[0] =~ /\A=?(\d+)\z/; +} + +sub xfileno { + return $1 if $_[0] =~ /\A=?(\d+)\z/; # deal with fh just being an fd + return fileno $_[0]; +} + my $do_spawn = $^O eq 'os2' || $^O eq 'MSWin32'; sub _open3 { @@ -164,9 +177,9 @@ sub _open3 { $dup_err = ($dad_err =~ s/^[<>]&//); # force unqualified filehandles into caller's package - $dad_wtr = qualify $dad_wtr, $package; - $dad_rdr = qualify $dad_rdr, $package; - $dad_err = qualify $dad_err, $package; + $dad_wtr = qualify $dad_wtr, $package unless fh_is_fd($dad_wtr); + $dad_rdr = qualify $dad_rdr, $package unless fh_is_fd($dad_rdr); + $dad_err = qualify $dad_err, $package unless fh_is_fd($dad_err); my $kid_rdr = gensym; my $kid_wtr = gensym; @@ -181,20 +194,20 @@ sub _open3 { # If she wants to dup the kid's stderr onto her stdout I need to # save a copy of her stdout before I put something else there. if ($dad_rdr ne $dad_err && $dup_err - && fileno($dad_err) == fileno(STDOUT)) { + && xfileno($dad_err) == fileno(STDOUT)) { my $tmp = gensym; xopen($tmp, ">&$dad_err"); $dad_err = $tmp; } if ($dup_wtr) { - xopen \*STDIN, "<&$dad_wtr" if fileno(STDIN) != fileno($dad_wtr); + xopen \*STDIN, "<&$dad_wtr" if fileno(STDIN) != xfileno($dad_wtr); } else { xclose $dad_wtr; xopen \*STDIN, "<&=" . fileno $kid_rdr; } if ($dup_rdr) { - xopen \*STDOUT, ">&$dad_rdr" if fileno(STDOUT) != fileno($dad_rdr); + xopen \*STDOUT, ">&$dad_rdr" if fileno(STDOUT) != xfileno($dad_rdr); } else { xclose $dad_rdr; xopen \*STDOUT, ">&=" . fileno $kid_wtr; @@ -204,8 +217,8 @@ sub _open3 { # I have to use a fileno here because in this one case # I'm doing a dup but the filehandle might be a reference # (from the special case above). - xopen \*STDERR, ">&" . fileno $dad_err - if fileno(STDERR) != fileno($dad_err); + xopen \*STDERR, ">&" . xfileno($dad_err) + if fileno(STDERR) != xfileno($dad_err); } else { xclose $dad_err; xopen \*STDERR, ">&=" . fileno $kid_err; diff --git a/lib/Net/Ping.pm b/lib/Net/Ping.pm index 2713383a00..40da9f3817 100644 --- a/lib/Net/Ping.pm +++ b/lib/Net/Ping.pm @@ -442,7 +442,11 @@ hosts on a network. A ping object is first created with optional parameters, a variable number of hosts may be pinged multiple times and then the connection is closed. -You may choose one of three different protocols to use for the ping. +You may choose one of three different protocols to use for the +ping. The "udp" protocol is the default. Note that a live remote host +may still fail to be pingable by one or more of these protocols. For +example, www.microsoft.com is generally alive but not pingable. + With the "tcp" protocol the ping() method attempts to establish a connection to the remote host's echo port. If the connection is successfully established, the remote host is considered reachable. No diff --git a/lib/Pod/Html.pm b/lib/Pod/Html.pm index 89e3d0f432..346495f3de 100644 --- a/lib/Pod/Html.pm +++ b/lib/Pod/Html.pm @@ -1438,8 +1438,10 @@ sub process_text1($$;$$){ } elsif( $func eq 'E' ){ # E<x> - convert to character - $$rstr =~ s/^(\w+)>//; - $res = "&$1;"; + $$rstr =~ s/^([^>]*)>//; + my $escape = $1; + $escape =~ s/^(\d+|X[\dA-F]+)$/#$1/i; + $res = "&$escape;"; } elsif( $func eq 'F' ){ # F<filename> - italizice @@ -1940,7 +1942,7 @@ sub depod1($;$$){ $res .= $$rstr; } elsif( $func eq 'E' ){ # E<x> - convert to character - $$rstr =~ s/^(\w+)>//; + $$rstr =~ s/^([^>]*)>//; $res .= $E2c{$1} || ""; } elsif( $func eq 'X' ){ # X<> - ignore diff --git a/lib/Pod/LaTeX.pm b/lib/Pod/LaTeX.pm new file mode 100644 index 0000000000..8adb58921c --- /dev/null +++ b/lib/Pod/LaTeX.pm @@ -0,0 +1,1567 @@ +package Pod::LaTeX; + +# Copyright (C) 2000 by Tim Jenness <t.jenness@jach.hawaii.edu> +# All Rights Reserved. + +=head1 NAME + +Pod::LaTeX - Convert Pod data to formatted Latex + +=head1 SYNOPSIS + + use Pod::LaTeX; + my $parser = Pod::LaTeX->new ( ); + + $parser->parse_from_filehandle; + + $parser->parse_from_file ('file.pod', 'file.tex'); + +=head1 DESCRIPTION + +C<Pod::LaTeX> is a module to convert documentation in the Pod format +into Latex. The L<B<pod2latex>|pod2latex> X<pod2latex> command uses +this module for translation. + +C<Pod::LaTeX> is a derived class from L<Pod::Select|Pod::Select>. + +=cut + + +use strict; +require Pod::ParseUtils; +use base qw/ Pod::Select /; + +# use Data::Dumper; # for debugging +use Carp; + +use vars qw/ $VERSION %HTML_Escapes @LatexSections /; + +$VERSION = '0.52'; + +# Definitions of =headN -> latex mapping +@LatexSections = (qw/ + chapter + section + subsection + subsubsection + paragraph + subparagraph + /); + +# Standard escape sequences converted to Latex +# Up to "yuml" these are taken from the original pod2latex +# command written by Taro Kawagish (kawagish@imslab.co.jp) + +%HTML_Escapes = ( + 'amp' => '&', # ampersand + 'lt' => '$<$', # ' left chevron, less-than + 'gt' => '$>$', # ' right chevron, greater-than + 'quot' => '"', # double quote + + "Aacute" => "\\'{A}", # capital A, acute accent + "aacute" => "\\'{a}", # small a, acute accent + "Acirc" => "\\^{A}", # capital A, circumflex accent + "acirc" => "\\^{a}", # small a, circumflex accent + "AElig" => '\\AE', # capital AE diphthong (ligature) + "aelig" => '\\ae', # small ae diphthong (ligature) + "Agrave" => "\\`{A}", # capital A, grave accent + "agrave" => "\\`{a}", # small a, grave accent + "Aring" => '\\u{A}', # capital A, ring + "aring" => '\\u{a}', # small a, ring + "Atilde" => '\\~{A}', # capital A, tilde + "atilde" => '\\~{a}', # small a, tilde + "Auml" => '\\"{A}', # capital A, dieresis or umlaut mark + "auml" => '\\"{a}', # small a, dieresis or umlaut mark + "Ccedil" => '\\c{C}', # capital C, cedilla + "ccedil" => '\\c{c}', # small c, cedilla + "Eacute" => "\\'{E}", # capital E, acute accent + "eacute" => "\\'{e}", # small e, acute accent + "Ecirc" => "\\^{E}", # capital E, circumflex accent + "ecirc" => "\\^{e}", # small e, circumflex accent + "Egrave" => "\\`{E}", # capital E, grave accent + "egrave" => "\\`{e}", # small e, grave accent + "ETH" => '\\OE', # capital Eth, Icelandic + "eth" => '\\oe', # small eth, Icelandic + "Euml" => '\\"{E}', # capital E, dieresis or umlaut mark + "euml" => '\\"{e}', # small e, dieresis or umlaut mark + "Iacute" => "\\'{I}", # capital I, acute accent + "iacute" => "\\'{i}", # small i, acute accent + "Icirc" => "\\^{I}", # capital I, circumflex accent + "icirc" => "\\^{i}", # small i, circumflex accent + "Igrave" => "\\`{I}", # capital I, grave accent + "igrave" => "\\`{i}", # small i, grave accent + "Iuml" => '\\"{I}', # capital I, dieresis or umlaut mark + "iuml" => '\\"{i}', # small i, dieresis or umlaut mark + "Ntilde" => '\\~{N}', # capital N, tilde + "ntilde" => '\\~{n}', # small n, tilde + "Oacute" => "\\'{O}", # capital O, acute accent + "oacute" => "\\'{o}", # small o, acute accent + "Ocirc" => "\\^{O}", # capital O, circumflex accent + "ocirc" => "\\^{o}", # small o, circumflex accent + "Ograve" => "\\`{O}", # capital O, grave accent + "ograve" => "\\`{o}", # small o, grave accent + "Oslash" => "\\O", # capital O, slash + "oslash" => "\\o", # small o, slash + "Otilde" => "\\~{O}", # capital O, tilde + "otilde" => "\\~{o}", # small o, tilde + "Ouml" => '\\"{O}', # capital O, dieresis or umlaut mark + "ouml" => '\\"{o}', # small o, dieresis or umlaut mark + "szlig" => '\\ss{}', # small sharp s, German (sz ligature) + "THORN" => '\\L', # capital THORN, Icelandic + "thorn" => '\\l',, # small thorn, Icelandic + "Uacute" => "\\'{U}", # capital U, acute accent + "uacute" => "\\'{u}", # small u, acute accent + "Ucirc" => "\\^{U}", # capital U, circumflex accent + "ucirc" => "\\^{u}", # small u, circumflex accent + "Ugrave" => "\\`{U}", # capital U, grave accent + "ugrave" => "\\`{u}", # small u, grave accent + "Uuml" => '\\"{U}', # capital U, dieresis or umlaut mark + "uuml" => '\\"{u}', # small u, dieresis or umlaut mark + "Yacute" => "\\'{Y}", # capital Y, acute accent + "yacute" => "\\'{y}", # small y, acute accent + "yuml" => '\\"{y}', # small y, dieresis or umlaut mark + + # Added by TimJ + + "iexcl" => '!`', # inverted exclamation mark +# "cent" => ' ', # cent sign + "pound" => '\pounds', # (UK) pound sign +# "curren" => ' ', # currency sign +# "yen" => ' ', # yen sign +# "brvbar" => ' ', # broken vertical bar + "sect" => '\S', # section sign + "uml" => '\"{}', # diaresis + "copy" => '\copyright', # Copyright symbol +# "ordf" => ' ', # feminine ordinal indicator + "laquo" => '$\ll$', # ' # left pointing double angle quotation mark + "not" => '$\neg$', # ' # not sign + "shy" => '-', # soft hyphen +# "reg" => ' ', # registered trademark + "macr" => '$^-$', # ' # macron, overline + "deg" => '$^\circ$', # ' # degree sign + "plusmn" => '$\pm$', # ' # plus-minus sign + "sup2" => '$^2$', # ' # superscript 2 + "sup3" => '$^3$', # ' # superscript 3 + "acute" => "\\'{}", # acute accent + "micro" => '$\mu$', # micro sign + "para" => '\P', # pilcrow sign = paragraph sign + "middot" => '$\cdot$', # middle dot = Georgian comma + "cedil" => '\c{}', # cedilla + "sup1" => '$^1$', # ' # superscript 1 +# "ordm" => ' ', # masculine ordinal indicator + "raquo" => '$\gg$', # ' # right pointing double angle quotation mark + "frac14" => '$\frac{1}{4}$', # ' # vulgar fraction one quarter + "frac12" => '$\frac{1}{2}$', # ' # vulgar fraction one half + "frac34" => '$\frac{3}{4}$', # ' # vulgar fraction three quarters + "iquest" => "?'", # inverted question mark + "times" => '$\times$', # ' # multiplication sign + "divide" => '$\div$', # division sign + + # Greek letters using HTML codes + "alpha" => '$\alpha$', # ' + "beta" => '$\beta$', # ' + "gamma" => '$\gamma$', # ' + "delta" => '$\delta$', # ' + "epsilon"=> '$\epsilon$', # ' + "zeta" => '$\zeta$', # ' + "eta" => '$\eta$', # ' + "theta" => '$\theta$', # ' + "iota" => '$\iota$', # ' + "kappa" => '$\kappa$', # ' + "lambda" => '$\lambda$', # ' + "mu" => '$\mu$', # ' + "nu" => '$\nu$', # ' + "xi" => '$\xi$', # ' + "omicron"=> '$o$', # ' + "pi" => '$\pi$', # ' + "rho" => '$\rho$', # ' + "sigma" => '$\sigma$', # ' + "tau" => '$\tau$', # ' + "upsilon"=> '$\upsilon$', # ' + "phi" => '$\phi$', # ' + "chi" => '$\chi$', # ' + "psi" => '$\psi$', # ' + "omega" => '$\omega$', # ' + + "Alpha" => '$A$', # ' + "Beta" => '$B$', # ' + "Gamma" => '$\Gamma$', # ' + "Delta" => '$\Delta$', # ' + "Epsilon"=> '$E$', # ' + "Zeta" => '$Z$', # ' + "Eta" => '$H$', # ' + "Theta" => '$\Theta$', # ' + "Iota" => '$I$', # ' + "Kappa" => '$K$', # ' + "Lambda" => '$\Lambda$', # ' + "Mu" => '$M$', # ' + "Nu" => '$N$', # ' + "Xi" => '$\Xi$', # ' + "Omicron"=> '$O$', # ' + "Pi" => '$\Pi$', # ' + "Rho" => '$R$', # ' + "Sigma" => '$\Sigma$', # ' + "Tau" => '$T$', # ' + "Upsilon"=> '$\Upsilon$', # ' + "Phi" => '$\Phi$', # ' + "Chi" => '$X$', # ' + "Psi" => '$\Psi$', # ' + "Omega" => '$\Omega$', # ' + + +); + + +=head1 OBJECT METHODS + +The following methods are provided in this module. Methods inherited +from C<Pod::Select> are not described in the public interface. + +=over 4 + +=begin __PRIVATE__ + +=item C<initialize> + +Initialise the object. This method is subclassed from C<Pod::Parser>. +The base class method is invoked. This method defines the default +behaviour of the object unless overridden by supplying arguments to +the constructor. + +Internal settings are defaulted as well as the public instance data. +Internal hash values are accessed directly (rather than through +a method) and start with an underscore. + +This method should not be invoked by the user directly. + +=end __PRIVATE__ + +=cut + + + +# - An array for nested lists + +# Arguments have already been read by this point + +sub initialize { + my $self = shift; + + # print Dumper($self); + + # Internals + $self->{_Lists} = []; # For nested lists + $self->{_suppress_all_para} = 0; # For =begin blocks + $self->{_suppress_next_para} = 0; # For =for blocks + $self->{_dont_modify_any_para}=0; # For =begin blocks + $self->{_dont_modify_next_para}=0; # For =for blocks + $self->{_CURRENT_HEAD1} = ''; # Name of current HEAD1 section + + # Options - only initialise if not already set + + # Cause the '=head1 NAME' field to be treated specially + # The contents of the NAME paragraph will be converted + # to a section title. All subsequent =head1 will be converted + # to =head2 and down. Will not affect =head1's prior to NAME + # Assumes: 'Module - purpose' format + # Also creates a purpose field + # The name is used for Labeling of the subsequent subsections + $self->{ReplaceNAMEwithSection} = 0 + unless exists $self->{ReplaceNAMEwithSection}; + $self->{AddPreamble} = 1 # make full latex document + unless exists $self->{AddPreamble}; + $self->{StartWithNewPage} = 0 # Start new page for pod section + unless exists $self->{StartWithNewPage}; + $self->{TableOfContents} = 0 # Add table of contents + unless exists $self->{TableOfContents}; # only relevent if AddPreamble=1 + $self->{AddPostamble} = 1 # Add closing latex code at end + unless exists $self->{AddPostamble}; # effectively end{document} and index + $self->{MakeIndex} = 1 # Add index (only relevant AddPostamble + unless exists $self->{MakeIndex}; # and AddPreamble) + + $self->{UniqueLabels} = 1 # Use label unique for each pod + unless exists $self->{UniqueLabels}; # either based on the filename + # or supplied + + # Control the level of =head1. default is \section + # + $self->{Head1Level} = 1 # Offset in latex sections + unless exists $self->{Head1Level}; # 0 is chapter, 2 is subsection + + # Control at which level numbering of sections is turned off + # ie subsection becomes subsection* + # The numbering is relative to the latex sectioning commands + # and is independent of Pod heading level + # default is to number \section but not \subsection + $self->{LevelNoNum} = 2 + unless exists $self->{LevelNoNum}; + + # Label to be used as prefix to all internal section names + # If not defined will attempt to derive it from the filename + # This can not happen when running parse_from_filehandle though + # hence the ability to set the label externally + # The label could then be Pod::Parser_DESCRIPTION or somesuch + + $self->{Label} = undef # label to be used as prefix + unless exists $self->{Label}; # to all internal section names + + # These allow the caller to add arbritrary latex code to + # start and end of document. AddPreamble and AddPostamble are ignored + # if these are set. + # Also MakeIndex and TableOfContents are also ignored. + $self->{UserPreamble} = undef # User supplied start (AddPreamble =1) + unless exists $self->{Label}; + $self->{UserPostamble} = undef # Use supplied end (AddPostamble=1) + unless exists $self->{Label}; + + # Run base initialize + $self->SUPER::initialize; + +} + +=back + +=head2 Data Accessors + +The following methods are provided for accessing instance data. These +methods should be used for accessing configuration parameters rather +than assuming the object is a hash. + +Default values can be supplied by using these names as keys to a hash +of arguments when using the C<new()> constructor. + +=over 4 + +=item B<AddPreamble> + +Logical to control whether a C<latex> preamble is to be written. +If true, a valid C<latex> preamble is written before the pod data is written. +This is similar to: + + \documentclass{article} + \begin{document} + +but will be more complicated if table of contents and indexing are required. +Can be used to set or retrieve the current value. + + $add = $parser->AddPreamble(); + $parser->AddPreamble(1); + +If used in conjunction with C<AddPostamble> a full latex document will +be written that could be immediately processed by C<latex>. + +=cut + +sub AddPreamble { + my $self = shift; + if (@_) { + $self->{AddPreamble} = shift; + } + return $self->{AddPreamble}; +} + +=item B<AddPostamble> + +Logical to control whether a standard C<latex> ending is written to the output +file after the document has been processed. +In its simplest form this is simply: + + \end{document} + +but can be more complicated if a index is required. +Can be used to set or retrieve the current value. + + $add = $parser->AddPostamble(); + $parser->AddPostamble(1); + +If used in conjunction with C<AddPreaamble> a full latex document will +be written that could be immediately processed by C<latex>. + +=cut + +sub AddPostamble { + my $self = shift; + if (@_) { + $self->{AddPostamble} = shift; + } + return $self->{AddPostamble}; +} + +=item B<Head1Level> + +The C<latex> sectioning level that should be used to correspond to +a pod C<=head1> directive. This can be used, for example, to turn +a C<=head1> into a C<latex> C<subsection>. This should hold a number +corresponding to the required position in an array containing the +following elements: + + [0] chapter + [1] section + [2] subsection + [3] subsubsection + [4] paragraph + [5] subparagraph + +Can be used to set or retrieve the current value: + + $parser->Head1Level(2); + $sect = $parser->Head1Level; + +Setting this number too high can result in sections that may not be reproducible +in the expected way. For example, setting this to 4 would imply that C<=head3> +do not have a corresponding C<latex> section (C<=head1> would correspond to +a C<paragraph>). + +A check is made to ensure that the supplied value is an integer in the +range 0 to 5. + +Default is for a value of 1 (i.e. a C<section>). + +=cut + +sub Head1Level { + my $self = shift; + if (@_) { + my $arg = shift; + if ($arg =~ /^\d$/ && $arg <= $#LatexSections) { + $self->{Head1Level} = $arg; + } else { + carp "Head1Level supplied ($arg) must be integer in range 0 to ".$#LatexSections . "- Ignoring\n"; + } + } + return $self->{Head1Level}; +} + +=item B<Label> + +This is the label that is prefixed to all C<latex> label and index +entries to make them unique. In general, pods have similarly titled +sections (NAME, DESCRIPTION etc) and a C<latex> label will be multiply +defined if more than one pod document is to be included in a single +C<latex> file. To overcome this, this label is prefixed to a label +whenever a label is required (joined with an underscore) or to an +index entry (joined by an exclamation mark which is the normal index +separator). For example, C<\label{text}> becomes C<\label{Label_text}>. + +Can be used to set or retrieve the current value: + + $label = $parser->Label; + $parser->Label($label); + +This label is only used if C<UniqueLabels> is true. +Its value is set automatically from the C<NAME> field +if C<ReplaceNAMEwithSection> is true. If this is not the case +it must be set manually before starting the parse. + +Default value is C<undef>. + +=cut + +sub Label { + my $self = shift; + if (@_) { + $self->{Label} = shift; + } + return $self->{Label}; +} + +=item B<LevelNoNum> + +Control the point at which C<latex> section numbering is turned off. +For example, this can be used to make sure that C<latex> sections +are numbered but subsections are not. + +Can be used to set or retrieve the current value: + + $lev = $parser->LevelNoNum; + $parser->LevelNoNum(2); + +The argument must be an integer between 0 and 5 and is the same as the +number described in C<Head1Level> method description. The number has +nothing to do with the pod heading number, only the C<latex> sectioning. + +Default is 2. (i.e. C<latex> subsections are written as C<subsection*> +but sections are numbered). + +=cut + +sub LevelNoNum { + my $self = shift; + if (@_) { + $self->{LevelNoNum} = shift; + } + return $self->{LevelNoNum}; +} + +=item B<MakeIndex> + +Controls whether C<latex> commands for creating an index are to be inserted +into the preamble and postamble + + $makeindex = $parser->MakeIndex; + $parser->MakeIndex(0); + +Irrelevant if both C<AddPreamble> and C<AddPostamble> are false (or equivalently, +C<UserPreamble> and C<UserPostamble> are set). + +Default is for an index to be created. + +=cut + +sub MakeIndex { + my $self = shift; + if (@_) { + $self->{MakeIndex} = shift; + } + return $self->{MakeIndex}; +} + +=item B<ReplaceNAMEwithSection> + +This controls whether the C<NAME> section in the pod is to be translated +literally or converted to a slightly modified output where the section +name is the pod name rather than "NAME". + +If true, the pod segment + + =head1 NAME + + pod::name - purpose + + =head1 SYNOPSIS + +is converted to the C<latex> + + \section{pod::name\label{pod_name}\index{pod::name}} + + Purpose + + \subsection*{SYNOPSIS\label{pod_name_SYNOPSIS}% + \index{pod::name!SYNOPSIS}} + +(dependent on the value of C<Head1Level> and C<LevelNoNum>). Note that +subsequent C<head1> directives translate to subsections rather than +sections and that the labels and index now include the pod name (dependent +on the value of C<UniqueLabels>). + +The C<Label> is set from the pod name regardless of any current value +of C<Label>. + + $mod = $parser->ReplaceNAMEwithSection; + $parser->ReplaceNAMEwithSection(0); + +Default is to translate the pod literally. + +=cut + +sub ReplaceNAMEwithSection { + my $self = shift; + if (@_) { + $self->{ReplaceNAMEwithSection} = shift; + } + return $self->{ReplaceNAMEwithSection}; +} + +=item B<StartWithNewPage> + +If true, each pod translation will begin with a C<latex> +C<\clearpage>. + + $parser->StartWithNewPage(1); + $newpage = $parser->StartWithNewPage; + +Default is false. + +=cut + +sub StartWithNewPage { + my $self = shift; + if (@_) { + $self->{StartWithNewPage} = shift; + } + return $self->{StartWithNewPage}; +} + +=item B<TableOfContents> + +If true, a table of contents will be created. +Irrelevant if C<AddPreamble> is false or C<UserPreamble> +is set. + + $toc = $parser->TableOfContents; + $parser->TableOfContents(1); + +Default is false. + +=cut + +sub TableOfContents { + my $self = shift; + if (@_) { + $self->{TableOfContents} = shift; + } + return $self->{TableOfContents}; +} + +=item B<UniqueLabels> + +If true, the translator will attempt to make sure that +each C<latex> label or index entry will be uniquely identified +by prefixing the contents of C<Label>. This allows +multiple documents to be combined without clashing +common labels such as C<DESCRIPTION> and C<SYNOPSIS> + + $parser->UniqueLabels(1); + $unq = $parser->UniqueLabels; + +Default is true. + +=cut + +sub UniqueLabels { + my $self = shift; + if (@_) { + $self->{UniqueLabels} = shift; + } + return $self->{UniqueLabels}; +} + +=item B<UserPreamble> + +User supplied C<latex> preamble. Added before the pod translation +data. + +If set, the contents will be prepended to the output file before the translated +data regardless of the value of C<AddPreamble>. +C<MakeIndex> and C<TableOfContents> will also be ignored. + +=cut + +sub UserPreamble { + my $self = shift; + if (@_) { + $self->{UserPreamble} = shift; + } + return $self->{UserPreamble}; +} + +=item B<UserPostamble> + +User supplied C<latex> postamble. Added after the pod translation +data. + +If set, the contents will be prepended to the output file after the translated +data regardless of the value of C<AddPostamble>. +C<MakeIndex> will also be ignored. + +=cut + +sub UserPostamble { + my $self = shift; + if (@_) { + $self->{UserPostamble} = shift; + } + return $self->{UserPostamble}; +} + +=begin __PRIVATE__ + +=item B<Lists> + +Contains details of the currently active lists. + The array contains C<Pod::List> objects. A new C<Pod::List> +object is created each time a list is encountered and it is +pushed onto this stack. When the list context ends, it +is popped from the stack. The array will be empty if no +lists are active. + +Returns array of list information in array context +Returns array ref in scalar context + +=cut + + + +sub lists { + my $self = shift; + return @{ $self->{_Lists} } if wantarray(); + return $self->{_Lists}; +} + +=end __PRIVATE__ + +=back + +=begin __PRIVATE__ + +=head2 Subclassed methods + +The following methods override methods provided in the C<Pod::Select> +base class. See C<Pod::Parser> and C<Pod::Select> for more information +on what these methods require. + +=over 4 + +=cut + +######### END ACCESSORS ################### + +# Opening pod + +=item B<begin_pod> + +Writes the C<latex> preamble if requested. + +=cut + +sub begin_pod { + my $self = shift; + + # Get the pod identification + # This should really come from the '=head1 NAME' paragraph + + my $infile = $self->input_file; + my $class = ref($self); + my $date = gmtime(time); + + # Comment message to say where this came from + my $comment = << "__TEX_COMMENT__"; +%% Latex generated from POD in document $infile +%% Using the perl module $class +%% Converted on $date +__TEX_COMMENT__ + + # Write the preamble + # If the caller has supplied one then we just use that + + my $preamble = ''; + if (defined $self->UserPreamble) { + + $preamble = $self->UserPreamble; + + # Add the description of where this came from + $preamble .= "\n$comment"; + + + } elsif ($self->AddPreamble) { + # Write our own preamble + + # Code to initialise index making + # Use an array so that we can prepend comment if required + my @makeidx = ( + '\usepackage{makeidx}', + '\makeindex', + ); + + unless ($self->MakeIndex) { + foreach (@makeidx) { + $_ = '%% ' . $_; + } + } + my $makeindex = join("\n",@makeidx) . "\n"; + + + # Table of contents + my $tableofcontents = '\tableofcontents'; + + $tableofcontents = '%% ' . $tableofcontents + unless $self->TableOfContents; + + # Roll our own + $preamble = << "__TEX_HEADER__"; +\\documentclass{article} + +$comment + +$makeindex + +\\begin{document} + +$tableofcontents + +__TEX_HEADER__ + + } + + # Write the header (blank if none) + $self->_output($preamble); + + # Start on new page if requested + $self->_output("\\clearpage\n") if $self->StartWithNewPage; + +} + + +=item B<end_pod> + +Write the closing C<latex> code. + +=cut + +sub end_pod { + my $self = shift; + + # End string + my $end = ''; + + # Use the user version of the postamble if deinfed + if (defined $self->UserPostamble) { + $end = $self->UserPostamble; + + $self->_output($end); + + } elsif ($self->AddPostamble) { + + # Check for index + my $makeindex = '\printindex'; + + $makeindex = '%% '. $makeindex unless $self->MakeIndex; + + $end = "$makeindex\n\n\\end{document}\n"; + } + + + $self->_output($end); + +} + +=item B<command> + +Process basic pod commands. + +=cut + +sub command { + my $self = shift; + my ($command, $paragraph, $line_num, $parobj) = @_; + + # return if we dont care + return if $command eq 'pod'; + + $paragraph = $self->_replace_special_chars($paragraph); + + # Interpolate pod sequences in paragraph + $paragraph = $self->interpolate($paragraph, $line_num); + + $paragraph =~ s/\s+$//; + + # Now run the command + if ($command eq 'over') { + + $self->begin_list($paragraph, $line_num); + + } elsif ($command eq 'item') { + + $self->add_item($paragraph, $line_num); + + } elsif ($command eq 'back') { + + $self->end_list($line_num); + + } elsif ($command eq 'head1') { + + # Store the name of the section + $self->{_CURRENT_HEAD1} = $paragraph; + + # Print it + $self->head(1, $paragraph, $parobj); + + } elsif ($command eq 'head2') { + + $self->head(2, $paragraph, $parobj); + + } elsif ($command eq 'head3') { + + $self->head(3, $paragraph, $parobj); + + } elsif ($command eq 'head4') { + + $self->head(4, $paragraph, $parobj); + + } elsif ($command eq 'head5') { + + $self->head(5, $paragraph, $parobj); + + } elsif ($command eq 'head6') { + + $self->head(6, $paragraph, $parobj); + + } elsif ($command eq 'begin') { + + # pass through if latex + if ($paragraph =~ /^latex/i) { + # Make sure that subsequent paragraphs are not modfied before printing + $self->{_dont_modify_any_para} = 1; + + } else { + # Suppress all subsequent paragraphs unless + # it is explcitly intended for latex + $self->{_suppress_all_para} = 1; + } + + } elsif ($command eq 'for') { + + # pass through if latex + if ($paragraph =~ /^latex/i) { + # Make sure that next paragraph is not modfied before printing + $self->{_dont_modify_next_para} = 1; + + } else { + # Suppress the next paragraph unless it is latex + $self->{_suppress_next_para} = 1 + } + + } elsif ($command eq 'end') { + + # Reset suppression + $self->{_suppress_all_para} = 0; + $self->{_dont_modify_any_para} = 0; + + } elsif ($command eq 'pod') { + + # Do nothing + + } else { + carp "Command $command not recognised at line $line_num\n"; + } + +} + +=item B<verbatim> + +Verbatim text + +=cut + +sub verbatim { + my $self = shift; + my ($paragraph, $line_num, $parobj) = @_; + + # Expand paragraph unless in =for or =begin block + if ($self->{_dont_modify_any_para} || $self->{_dont_modify_next_para}) { + # Just print as is + $self->_output($paragraph); + + # Reset flag if in =for + $self->{_dont_modify_next_para} = 0; + + } else { + + return if $paragraph =~ /^\s+$/; + + # Clean trailing space + $paragraph =~ s/\s+$//; + + $self->_output('\begin{verbatim}' . "\n$paragraph\n". '\end{verbatim}'."\n"); + } +} + +=item B<textblock> + +Plain text paragraph. + +=cut + +sub textblock { + my $self = shift; + my ($paragraph, $line_num, $parobj) = @_; + + # print Dumper($self); + + # Expand paragraph unless in =for or =begin block + if ($self->{_dont_modify_any_para} || $self->{_dont_modify_next_para}) { + # Just print as is + $self->_output($paragraph); + + # Reset flag if in =for + $self->{_dont_modify_next_para} = 0; + + return; + } + + + # Escape latex special characters + $paragraph = $self->_replace_special_chars($paragraph); + + # Interpolate interior sequences + my $expansion = $self->interpolate($paragraph, $line_num); + $expansion =~ s/\s+$//; + + + # If we are replacing 'head1 NAME' with a section + # we need to look in the paragraph and rewrite things + # Need to make sure this is called only on the first paragraph + # following 'head1 NAME' and not on subsequent paragraphs that may be + # present. + if ($self->{_CURRENT_HEAD1} =~ /^NAME/i && $self->ReplaceNAMEwithSection()) { + + # Strip white space from start and end + $paragraph =~ s/^\s+//; + $paragraph =~ s/\s$//; + + # Split the string into 2 parts + my ($name, $purpose) = split(/\s+-\s+/, $expansion,2); + + # Now prevent this from triggering until a new head1 NAME is set + $self->{_CURRENT_HEAD1} = '_NAME'; + + # Might want to clear the Label() before doing this (CHECK) + + # Print the heading + $self->head(1, $name, $parobj); + + # Set the labeling in case we want unique names later + $self->Label( $self->_create_label( $name, 1 ) ); + + # Raise the Head1Level by one so that subsequent =head1 appear + # as subsections of the main name section unless we are already + # at maximum [Head1Level() could check this itself - CHECK] + $self->Head1Level( $self->Head1Level() + 1) + unless $self->Head1Level == $#LatexSections; + + # Now write out the new latex paragraph + $purpose = ucfirst($purpose); + $self->_output("\n\n$purpose\n\n"); + + } else { + # Just write the output + $self->_output("\n\n$expansion\n\n"); + } + +} + +=item B<interior_sequence> + +Interior sequence expansion + +=cut + +sub interior_sequence { + my $self = shift; + + my ($seq_command, $seq_argument, $pod_seq) = @_; + + if ($seq_command eq 'B') { + return "\\textbf{$seq_argument}"; + + } elsif ($seq_command eq 'I') { + return "\\textit{$seq_argument}"; + + } elsif ($seq_command eq 'E') { + + # If it is simply a number + if ($seq_argument =~ /^\d+$/) { + return chr($seq_argument); + # Look up escape in hash table + } elsif (exists $HTML_Escapes{$seq_argument}) { + return $HTML_Escapes{$seq_argument}; + + } else { + my ($file, $line) = $pod_seq->file_line(); + warn "Escape sequence $seq_argument not recognised at line $line of file $file\n"; + return; + } + + } elsif ($seq_command eq 'Z') { + + # Zero width space + return '$\!$'; # ' + + } elsif ($seq_command eq 'C') { + return "\\texttt{$seq_argument}"; + + } elsif ($seq_command eq 'F') { + return "\\emph{$seq_argument}"; + + } elsif ($seq_command eq 'S') { + # non breakable spaces + my $nbsp = '$\:$'; #' + + $seq_argument =~ s/\s/$nbsp/g; + return $seq_argument; + + } elsif ($seq_command eq 'L') { + + my $link = new Pod::Hyperlink($seq_argument); + + # undef on failure + unless (defined $link) { + carp $@; + return; + } + + # Handle internal links differently + my $type = $link->type; + my $page = $link->page; + + if ($type eq 'section' && $page eq '') { + # Use internal latex reference + my $node = $link->node; + + # Convert to a label + $node = $self->_create_label($node); + + return "\\S\\ref{$node}"; + + } else { + # Use default markup for external references + # (although Starlink would use \xlabel) + my $markup = $link->markup; + + my ($file, $line) = $pod_seq->file_line(); + + return $self->interpolate($link->markup, $line); + } + + + + } elsif ($seq_command eq 'P') { + # Special markup for Pod::Hyperlink + # Replace :: with / + my $link = $seq_argument; + $link =~ s/::/\//g; + + my $ref = "\\emph{$seq_argument}"; + return $ref; + + } elsif ($seq_command eq 'Q') { + # Special markup for Pod::Hyperlink + return "\\textsf{$seq_argument}\n"; + + } elsif ($seq_command eq 'X') { + # Index entries + + # use \index command + # I will let '!' go through for now + # not sure how sub categories are handled in X<> + my $index = $self->_create_index($seq_argument); + return "\\index{$index}\n"; + + } else { + carp "Unknown sequence $seq_command<$seq_argument>"; + } + +} + +=back + +=head2 List Methods + +Methods used to handle lists. + +=over 4 + +=item B<begin_list> + +Called when a new list is found (via the C<over> directive). +Creates a new C<Pod::List> object and stores it on the +list stack. + + $parser->begin_list($indent, $line_num); + +=cut + +sub begin_list { + my $self = shift; + my $indent = shift; + my $line_num = shift; + + # Indicate that a list should be started for the next item + # need to do this to work out the type of list + push ( @{$self->lists}, new Pod::List(-indent => $indent, + -start => $line_num, + -file => $self->input_file, + ) + ); + +} + +=item B<end_list> + +Called when the end of a list is found (the C<back> directive). +Pops the C<Pod::List> object off the stack of lists and writes +the C<latex> code required to close a list. + + $parser->end_list($line_num); + +=cut + +sub end_list { + my $self = shift; + my $line_num = shift; + + unless (defined $self->lists->[-1]) { + my $file = $self->input_file; + warn "No list is active at line $line_num (file=$file). Missing =over?\n"; + return; + } + + # What to write depends on list type + my $type = $self->lists->[-1]->type; + + # Dont write anything if the list type is not set + # iomplying that a list was created but no entries were + # placed in it (eg because of a =begin/=end combination) + $self->_output("\\end{$type}\n") + if (defined $type && length($type) > 0); + + # Clear list + pop(@{ $self->lists}); + +} + +=item B<add_item> + +Add items to the list. The first time an item is encountered +(determined from the state of the current C<Pod::List> object) +the type of list is determined (ordered, unnumbered or description) +and the relevant latex code issued. + + $parser->add_item($paragraph, $line_num); + +=cut + +sub add_item { + my $self = shift; + my $paragraph = shift; + my $line_num = shift; + + unless (defined $self->lists->[-1]) { + my $file = $self->input_file; + warn "List has already ended by line $line_num of file $file. Missing =over?\n"; + # Replace special chars +# $paragraph = $self->_replace_special_chars($paragraph); + $self->_output("$paragraph\n\n"); + return; + } + + # If paragraphs printing is turned off via =begin/=end or whatver + # simply return immediately + return if ($self->{_suppress_all_para} || $self->{_suppress_next_para}); + + # Check to see whether we are starting a new lists + if (scalar($self->lists->[-1]->item) == 0) { + + # Examine the paragraph to determine what type of list + # we have + $paragraph =~ s/\s+$//; + $paragraph =~ s/^\s+//; + + my $type; + if ($paragraph eq '*') { + $type = 'itemize'; + } elsif ($paragraph =~ /^\d/) { + $type = 'enumerate'; + } else { + $type = 'description'; + } + $self->lists->[-1]->type($type); + + $self->_output("\\begin{$type}\n"); + + } + + my $type = $self->lists->[-1]->type; + + if ($type eq 'description') { + + $self->_output("\\item[$paragraph] \\mbox{}"); + } else { + $self->_output('\item '); + } + + # Store the item name in the object. Required so that + # we can tell if the list is new or not + $self->lists->[-1]->item($paragraph); + +} + +=back + +=head2 Methods for headings + +=over 4 + +=item B<head> + +Print a heading of the required level. + + $parser->head($level, $paragraph, $parobj); + +The first argument is the pod heading level. The second argument +is the contents of the heading. The 3rd argument is a Pod::Paragraph +object so that the line number can be extracted. + +=cut + +sub head { + my $self = shift; + my $num = shift; + my $paragraph = shift; + my $parobj = shift; + + # If we are replace 'head1 NAME' with a section + # we return immediately if we get it + return + if ($self->{_CURRENT_HEAD1} =~ /^NAME/i && $self->ReplaceNAMEwithSection()); + + # Create a label + my $label = $self->_create_label($paragraph); + + # Create an index entry + my $index = $self->_create_index($paragraph); + + # Work out position in the above array taking into account + # that =head1 is equivalent to $self->Head1Level + + my $level = $self->Head1Level() - 1 + $num; + + # Warn if heading to large + if ($num > $#LatexSections) { + my $line = $parobj->file_line; + my $file = $self->input_file; + warn "Heading level too large ($level) for LaTeX at line $line of file $file\n"; + $level = $#LatexSections; + } + + # Check to see whether section should be unnumbered + my $star = ($level >= $self->LevelNoNum ? '*' : ''); + + # Section + $self->_output("\\" .$LatexSections[$level] .$star ."{$paragraph\\label{".$label ."}\\index{".$index."}}"); + +} + + +=back + +=end __PRIVATE__ + +=begin __PRIVATE__ + +=head2 Internal methods + +Internal routines are described in this section. They do not form part of the +public interface. All private methods start with an underscore. + +=over 4 + +=item B<_output> + +Output text to the output filehandle. This method must be always be called +to output parsed text. + + $parser->_output($text); + +Does not write anything if a =begin or =for is active that should be +ignored. + +=cut + +sub _output { + my $self = shift; + my $text = shift; + + print { $self->output_handle } $text + unless $self->{_suppress_all_para} || + $self->{_suppress_next_para}; + + # Reset pargraph stuff for =for + $self->{_suppress_next_para} = 0 + if $self->{_suppress_next_para}; +} + + +=item B<_replace_special_chars> + +Subroutine to replace characters that are special in C<latex> +with the escaped forms + + $escaped = $parser->_replace_special_chars($paragraph); + +Need to call this routine before interior_sequences are munged but +not if verbatim. + +Special characters and the C<latex> equivalents are: + + } \} + { \{ + _ \_ + $ \$ + % \% + & \& + \ $\backslash$ + ^ \^{} + +=cut + +sub _replace_special_chars { + my $self = shift; + my $paragraph = shift; + + # Replace a \ with $\backslash$ + # This is made more complicated because the dollars will be escaped + # by the subsequent replacement. Easiest to add \backslash + # now and then add the dollars + $paragraph =~ s/\\/\\backslash/g; + + # Must be done after escape of \ since this command adds latex escapes + # Replace characters that can be escaped + $paragraph =~ s/([\$\#&%_{}])/\\$1/g; + + # Replace ^ characters with \^{} so that $^F works okay + $paragraph =~ s/(\^)/\\$1\{\}/g; + + # Now add the dollars around each \backslash + $paragraph =~ s/(\\backslash)/\$$1\$/g; + + return $paragraph; +} + + +=item B<_create_label> + +Return a string that can be used as an internal reference +in a C<latex> document (i.e. accepted by the C<\label> command) + + $label = $parser->_create_label($string) + +If UniqueLabels is true returns a label prefixed by Label() +This can be suppressed with an optional second argument. + + $label = $parser->_create_label($string, $suppress); + +If a second argument is supplied (of any value including undef) +the Label() is never prefixed. This means that this routine can +be called to create a Label() without prefixing a previous setting. + +=cut + +sub _create_label { + my $self = shift; + my $paragraph = shift; + my $suppress = (@_ ? 1 : 0 ); + + # Remove latex commands + $paragraph = $self->_clean_latex_commands($paragraph); + + # Remove non alphanumerics from the label and replace with underscores + # want to protect '-' though so use negated character classes + $paragraph =~ s/[^-:\w]/_/g; + + # Multiple underscores will look unsightly so remove repeats + # This will also have the advantage of tidying up the end and + # start of string + $paragraph =~ s/_+/_/g; + + # If required need to make sure that the label is unique + # since it is possible to have multiple pods in a single + # document + if (!$suppress && $self->UniqueLabels() && defined $self->Label) { + $paragraph = $self->Label() .'_'. $paragraph; + } + + return $paragraph; +} + + +=item B<_create_index> + +Similar to C<_create_label> except an index entry is created. +If C<UniqueLabels> is true, the index entry is prefixed by +the current C<Label> and an exclamation mark. + + $ind = $parser->_create_index($paragraph); + +An exclamation mark is used by C<makeindex> to generate +sub-entries in an index. + +=cut + +sub _create_index { + my $self = shift; + my $paragraph = shift; + my $suppress = (@_ ? 1 : 0 ); + + # Remove latex commands + $paragraph = $self->_clean_latex_commands($paragraph); + + # If required need to make sure that the index entry is unique + # since it is possible to have multiple pods in a single + # document + if (!$suppress && $self->UniqueLabels() && defined $self->Label) { + $paragraph = $self->Label() .'!'. $paragraph; + } + + # Need to replace _ with space + $paragraph =~ s/_/ /g; + + return $paragraph; + +} + +=item B<_clean_latex_commands> + +Removes latex commands from text. The latex command is assumed to be of the +form C<\command{ text }>. "C<text>" is retained + + $clean = $parser->_clean_latex_commands($text); + +=cut + +sub _clean_latex_commands { + my $self = shift; + my $paragraph = shift; + + # Remove latex commands of the form \text{ } + # and replace with the contents of the { } + # need to make this non-greedy so that it can handle + # "\text{a} and \text2{b}" + # without converting it to + # "a} and \text2{b" + # This match will still get into trouble if \} is present + # This is not vital since the subsequent replacement of non-alphanumeric + # characters will tidy it up anyway + $paragraph =~ s/\\\w+{(.*?)}/$1/g; + + return $paragraph +} + +=back + +=end __PRIVATE__ + +=head1 NOTES + +Compatible with C<latex2e> only. Can not be used with C<latex> v2.09 +or earlier. + +A subclass of C<Pod::Select> so that specific pod sections can be +converted to C<latex> by using the C<select> method. + +Some HTML escapes are missing and many have not been tested. + +=head1 SEE ALSO + +L<Pod::Parser>, L<Pod::Select>, L<pod2latex> + +=head1 AUTHORS + +Tim Jenness E<lt>t.jenness@jach.hawaii.eduE<gt> + +=head1 COPYRIGHT + +Copyright (C) 2000 Tim Jenness. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=begin __PRIVATE__ + +=head1 REVISION + +$Id: LaTeX.pm,v 1.4 2000/05/16 01:26:55 timj Exp $ + +=end __PRIVATE__ + +=cut diff --git a/lib/Pod/Man.pm b/lib/Pod/Man.pm index 8673ba4795..439b22c35b 100644 --- a/lib/Pod/Man.pm +++ b/lib/Pod/Man.pm @@ -194,6 +194,8 @@ $PREAMBLE = <<'----END OF PREAMBLE----'; 'lt' => '<', # left chevron, less-than 'gt' => '>', # right chevron, greater-than 'quot' => '"', # double quote + 'sol' => '/', # solidus + 'verbar' => '|', # vertical bar 'Aacute' => "A\\*'", # capital A, acute accent 'aacute' => "a\\*'", # small a, acute accent diff --git a/lib/Pod/Text.pm b/lib/Pod/Text.pm index f5c1e3d0cf..47dcee584f 100644 --- a/lib/Pod/Text.pm +++ b/lib/Pod/Text.pm @@ -53,6 +53,8 @@ $VERSION = 2.04; 'lt' => '<', # left chevron, less-than 'gt' => '>', # right chevron, greater-than 'quot' => '"', # double quote + 'sol' => '/', # solidus + 'verbar' => '|', # vertical bar "Aacute" => "\xC1", # capital A, acute accent "aacute" => "\xE1", # small a, acute accent diff --git a/lib/Pod/Usage.pm b/lib/Pod/Usage.pm index aa8f712dcf..571588ebd2 100644 --- a/lib/Pod/Usage.pm +++ b/lib/Pod/Usage.pm @@ -211,7 +211,7 @@ convenient to use as an innocent looking error message handling function: ## Check for too many filenames pod2usage("$0: Too many files given.\n") if (@ARGV > 1); -Some user's however may feel that the above "economy of expression" is +Some users however may feel that the above "economy of expression" is not particularly readable nor consistent and may instead choose to do something more like the following: diff --git a/lib/SelfLoader.pm b/lib/SelfLoader.pm index 99372f2630..3b9c52d912 100644 --- a/lib/SelfLoader.pm +++ b/lib/SelfLoader.pm @@ -3,7 +3,7 @@ package SelfLoader; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(AUTOLOAD); -$VERSION = "1.0901"; +$VERSION = "1.0902"; sub Version {$VERSION} $DEBUG = 0; @@ -20,6 +20,7 @@ sub croak { require Carp; goto &Carp::croak } AUTOLOAD { print STDERR "SelfLoader::AUTOLOAD for $AUTOLOAD\n" if $DEBUG; my $SL_code = $Cache{$AUTOLOAD}; + my $save = $@; # evals in both AUTOLOAD and _load_stubs can corrupt $@ unless ($SL_code) { # Maybe this pack had stubs before __DATA__, and never initialized. # Or, this maybe an automatic DESTROY method call when none exists. @@ -31,11 +32,13 @@ AUTOLOAD { croak "Undefined subroutine $AUTOLOAD" unless $SL_code; } print STDERR "SelfLoader::AUTOLOAD eval: $SL_code\n" if $DEBUG; + eval $SL_code; if ($@) { $@ =~ s/ at .*\n//; croak $@; } + $@ = $save; defined(&$AUTOLOAD) || die "SelfLoader inconsistency error"; delete $Cache{$AUTOLOAD}; goto &$AUTOLOAD diff --git a/lib/Symbol.pm b/lib/Symbol.pm index a842c1cd7b..a95383a5d6 100644 --- a/lib/Symbol.pm +++ b/lib/Symbol.pm @@ -129,8 +129,15 @@ sub delete_package ($) { my $stem_symtab = *{$stem}{HASH}; return unless defined $stem_symtab and exists $stem_symtab->{$leaf}; - my $leaf_glob = $stem_symtab->{$leaf}; - my $leaf_symtab = *{$leaf_glob}{HASH}; + + # free all the symbols in the package + + my $leaf_symtab = *{$stem_symtab->{$leaf}}{HASH}; + foreach my $name (keys %$leaf_symtab) { + undef *{$pkg . $name}; + } + + # delete the symbol table %$leaf_symtab = (); delete $stem_symtab->{$leaf}; diff --git a/lib/Test/Harness.pm b/lib/Test/Harness.pm index f913478643..a17bdbfd72 100644 --- a/lib/Test/Harness.pm +++ b/lib/Test/Harness.pm @@ -8,7 +8,7 @@ use FileHandle; use strict; our($VERSION, $verbose, $switches, $have_devel_corestack, $curtest, - @ISA, @EXPORT, @EXPORT_OK); + $columns, @ISA, @EXPORT, @EXPORT_OK); $have_devel_corestack = 0; $VERSION = "1.1604"; @@ -27,36 +27,18 @@ my $subtests_skipped = 0; @EXPORT= qw(&runtests); @EXPORT_OK= qw($verbose $switches); -format STDOUT_TOP = -Failed Test Status Wstat Total Fail Failed List of failed -------------------------------------------------------------------------------- -. - -format STDOUT = -@<<<<<<<<<<<<<< @>> @>>>> @>>>> @>>> ^##.##% ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -{ $curtest->{name}, - $curtest->{estat}, - $curtest->{wstat}, - $curtest->{max}, - $curtest->{failed}, - $curtest->{percent}, - $curtest->{canon} -} -~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - $curtest->{canon} -. - - $verbose = 0; $switches = "-w"; +$columns = $ENV{HARNESS_COLUMNS} || $ENV{COLUMNS} || 80; sub globdir { opendir DIRH, shift; my @f = readdir DIRH; closedir DIRH; @f } sub runtests { my(@tests) = @_; local($|) = 1; - my($test,$te,$ok,$next,$max,$pct,$totok,$totbonus,@failed,%failedtests); + my($test,$te,$ok,$next,$max,$pct,$totbonus,@failed,%failedtests); my $totmax = 0; + my $totok = 0; my $files = 0; my $bad = 0; my $good = 0; @@ -157,12 +139,12 @@ sub runtests { $bonus++, $totbonus++ if $todo{$this}; } if ($this > $next) { - # warn "Test output counter mismatch [test $this]\n"; + # print "Test output counter mismatch [test $this]\n"; # no need to warn probably push @failed, $next..$this-1; } elsif ($this < $next) { #we have seen more "ok" lines than the number suggests - warn "Confused test output: test $this answered after test ", $next-1, "\n"; + print "Confused test output: test $this answered after test ", $next-1, "\n"; $next = $this; } $next = $this + 1; @@ -229,7 +211,7 @@ sub runtests { } if (@failed) { my ($txt, $canon) = canonfailed($max,$skipped,@failed); - print $txt; + print "${ml}$txt"; $failedtests{$test} = { canon => $canon, max => $max, failed => scalar @failed, name => $test, percent => 100*(scalar @failed)/$max, @@ -303,7 +285,54 @@ sub runtests { $pct = sprintf("%.2f", $good / $total * 100); my $subpct = sprintf " %d/%d subtests failed, %.2f%% okay.", $totmax - $totok, $totmax, 100*$totok/$totmax; + # Create formats + # First, figure out max length of test names + my $failed_str = "Failed Test"; + my $middle_str = " Status Wstat Total Fail Failed "; + my $list_str = "List of Failed"; + my $max_namelen = length($failed_str); my $script; + foreach $script (keys %failedtests) { + $max_namelen = + (length $failedtests{$script}->{name} > $max_namelen) ? + length $failedtests{$script}->{name} : $max_namelen; + } + my $list_len = $columns - length($middle_str) - $max_namelen; + if ($list_len < length($list_str)) { + $list_len = length($list_str); + $max_namelen = $columns - length($middle_str) - $list_len; + if ($max_namelen < length($failed_str)) { + $max_namelen = length($failed_str); + $columns = $max_namelen + length($middle_str) + $list_len; + } + } + + my $fmt_top = "format STDOUT_TOP =\n" + . sprintf("%-${max_namelen}s", $failed_str) + . $middle_str + . $list_str . "\n" + . "-" x $columns + . "\n.\n"; + my $fmt = "format STDOUT =\n" + . "@" . "<" x ($max_namelen - 1) + . " @>> @>>>> @>>>> @>>> ^##.##% " + . "^" . "<" x ($list_len - 1) . "\n" + . '{ $curtest->{name}, $curtest->{estat},' + . ' $curtest->{wstat}, $curtest->{max},' + . ' $curtest->{failed}, $curtest->{percent},' + . ' $curtest->{canon}' + . "\n}\n" + . "~~" . " " x ($columns - $list_len - 2) . "^" + . "<" x ($list_len - 1) . "\n" + . '$curtest->{canon}' + . "\n.\n"; + + eval $fmt_top; + die $@ if $@; + eval $fmt; + die $@ if $@; + + # Now write to formats for $script (sort keys %failedtests) { $curtest = $failedtests{$script}; write; @@ -322,16 +351,9 @@ sub runtests { my $tried_devel_corestack; sub corestatus { my($st) = @_; - my($ret); eval {require 'wait.ph'}; - if ($@) { - SWITCH: { - $ret = ($st & 0200); # Tim says, this is for 90% - } - } else { - $ret = WCOREDUMP($st); - } + my $ret = defined &WCOREDUMP ? WCOREDUMP($st) : $st & 0200; eval { require Devel::CoreStack; $have_devel_corestack++ } unless $tried_devel_corestack++; @@ -515,6 +537,12 @@ switches used to invoke perl on each test. For example, setting C<HARNESS_PERL_SWITCHES> to "-W" will run all tests with all warnings enabled. +If C<HARNESS_COLUMNS> is set, then this value will be used for the +width of the terminal. If it is not set then it will default to +C<COLUMNS>. If this is not set, it will default to 80. Note that users +of Bourne-sh based shells will need to C<export COLUMNS> for this +module to use that variable. + Harness sets C<HARNESS_ACTIVE> before executing the individual tests. This allows the tests to determine if they are being executed through the harness or by any other means. diff --git a/lib/Text/Wrap.pm b/lib/Text/Wrap.pm index 5f95edb69c..04efe19296 100644 --- a/lib/Text/Wrap.pm +++ b/lib/Text/Wrap.pm @@ -6,7 +6,7 @@ require Exporter; @EXPORT = qw(wrap fill); @EXPORT_OK = qw($columns $break $huge); -$VERSION = 98.112902; +$VERSION = 2000.06292219; #GMT use vars qw($VERSION $columns $debug $break $huge); use strict; @@ -33,7 +33,7 @@ sub wrap my $remainder = ""; while ($t !~ /^\s*$/) { - if ($t =~ s/^([^\n]{0,$ll})($break|\Z(?!\n))//xm) { + if ($t =~ s/^([^\n]{0,$ll})($break|\Z(?!\n))//x) { $r .= unexpand($nl . $lead . $1); $remainder = $2; } elsif ($huge eq 'wrap' && $t =~ s/^([^\n]{$ll})//) { diff --git a/lib/Win32.pod b/lib/Win32.pod new file mode 100644 index 0000000000..bd1d06581e --- /dev/null +++ b/lib/Win32.pod @@ -0,0 +1,284 @@ +=head1 NAME + +Win32 - Interfaces to some Win32 API Functions + +=head1 DESCRIPTION + +Perl on Win32 contains several functions to access Win32 APIs. Some +are included in Perl itself (on Win32) and some are only available +after explicitly requesting the Win32 module with: + + use Win32; + +The builtin functions are marked as [CORE] and the other ones +as [EXT] in the following alphabetical listing. The C<Win32> module +is not part of the Perl source distribution; it is distributed in +the libwin32 bundle of Win32::* modules on CPAN. The module is +already preinstalled in binary distributions like ActivePerl. + +=head2 Alphabetical Listing of Win32 Functions + +=over + +=item Win32::AbortSystemShutdown(MACHINE) + +[EXT] Aborts a system shutdown (started by the +InitiateSystemShutdown function) on the specified MACHINE. + +=item Win32::BuildNumber() + +[CORE] Returns the ActivePerl build number. This function is +only available in the ActivePerl binary distribution. + +=item Win32::CopyFile(FROM, TO, OVERWRITE) + +[CORE] The Win32::CopyFile() function copies an existing file to a new +file. All file information like creation time and file attributes will +be copied to the new file. However it will B<not> copy the security +information. If the destination file already exists it will only be +overwritten when the OVERWRITE parameter is true. But even this will +not overwrite a read-only file; you have to unlink() it first +yourself. + +=item Win32::DomainName() + +[CORE] Returns the name of the Microsoft Network domain that the +owner of the current perl process is logged into. + +=item Win32::ExpandEnvironmentStrings(STRING) + +[EXT] Takes STRING and replaces all referenced environment variable +names with their defined values. References to environment variables +take the form C<%VariableName%>. Case is ignored when looking up the +VariableName in the environment. If the variable is not found then the +original C<%VariableName%> text is retained. Has the same effect +as the following: + + $string =~ s/%([^%]*)%/$ENV{$1} || "%$1%"/eg + +=item Win32::FormatMessage(ERRORCODE) + +[CORE] Converts the supplied Win32 error number (e.g. returned by +Win32::GetLastError()) to a descriptive string. Analogous to the +perror() standard-C library function. Note that C<$^E> used +in a string context has much the same effect. + + C:\> perl -e "$^E = 26; print $^E;" + The specified disk or diskette cannot be accessed + +=item Win32::FsType() + +[CORE] Returns the name of the filesystem of the currently active +drive (like 'FAT' or 'NTFS'). In list context it returns three values: +(FSTYPE, FLAGS, MAXCOMPLEN). FSTYPE is the filesystem type as +before. FLAGS is a combination of values of the following table: + + 0x00000001 supports case-sensitive filenames + 0x00000002 preserves the case of filenames + 0x00000004 supports Unicode in filenames + 0x00000008 preserves and enforces ACLs + 0x00000010 supports file-based compression + 0x00000020 supports disk quotas + 0x00000040 supports sparse files + 0x00000080 supports reparse points + 0x00000100 supports remote storage + 0x00008000 is a compressed volume (e.g. DoubleSpace) + 0x00010000 supports object identifiers + 0x00020000 supports the Encrypted File System (EFS) + +MAXCOMPLEN is the maximum length of a filename component (the part +between two backslashes) on this file system. + +=item Win32::FreeLibrary(HANDLE) + +[EXT] Unloads a previously loaded dynamic-link library. The HANDLE is +no longer valid after this call. See L<LoadLibrary|Win32::LoadLibrary(LIBNAME)> +for information on dynamically loading a library. + +=item Win32::GetArchName() + +[EXT] Use of this function is deprecated. It is equivalent with +$ENV{PROCESSOR_ARCHITECTURE}. This might not work on Win9X. + +=item Win32::GetChipName() + +[EXT] Returns the processor type: 386, 486 or 586 for Intel processors, +21064 for the Alpha chip. + +=item Win32::GetCwd() + +[CORE] Returns the current active drive and directory. This function +does not return a UNC path, since the functionality required for such +a feature is not available under Windows 95. + +=item Win32::GetFullPathName(FILENAME) + +[CORE] GetFullPathName combines the FILENAME with the current drive +and directory name and returns a fully qualified (aka, absolute) +path name. In list context it returns two elements: (PATH, FILE) where +PATH is the complete pathname component (including trailing backslash) +and FILE is just the filename part. Note that no attempt is made to +convert 8.3 components in the supplied FILENAME to longnames or +vice-versa. Compare with Win32::GetShortPathName and +Win32::GetLongPathName. + +This function has been added for Perl 5.6. + +=item Win32::GetLastError() + +[CORE] Returns the last error value generated by a call to a Win32 API +function. Note that C<$^E> used in a numeric context amounts to the +same value. + +=item Win32::GetLongPathName(PATHNAME) + +[CORE] Returns a representation of PATHNAME composed of longname +components (if any). The result may not necessarily be longer +than PATHNAME. No attempt is made to convert PATHNAME to the +absolute path. Compare with Win32::GetShortPathName and +Win32::GetFullPathName. + +This function has been added for Perl 5.6. + +=item Win32::GetNextAvailDrive() + +[CORE] Returns a string in the form of "<d>:" where <d> is the first +available drive letter. + +=item Win32::GetOSVersion() + +[CORE] Returns the array (STRING, MAJOR, MINOR, BUILD, ID), where +the elements are, respectively: An arbitrary descriptive string, the +major version number of the operating system, the minor version +number, the build number, and a digit indicating the actual operating +system. For ID, the values are 0 for Win32s, 1 for Windows 9X and 2 +for Windows NT. In scalar context it returns just the ID. + +=item Win32::GetShortPathName(PATHNAME) + +[CORE] Returns a representation of PATHNAME composed only of +short (8.3) path components. The result may not necessarily be +shorter than PATHNAME. Compare with Win32::GetFullPathName and +Win32::GetLongPathName. + +=item Win32::GetProcAddress(INSTANCE, PROCNAME) + +[EXT] Returns the address of a function inside a loaded library. The +information about what you can do with this address has been lost in +the mist of time. Use the Win32::API module instead of this deprecated +function. + +=item Win32::GetTickCount() + +[CORE] Returns the number of milliseconds elapsed since the last +system boot. Resolution is limited to system timer ticks (about 10ms +on WinNT and 55ms on Win9X). + +=item Win32::InitiateSystemShutdown(MACHINE, MESSAGE, TIMEOUT, FORCECLOSE, REBOOT) + +[EXT] Shutsdown the specified MACHINE, notifying users with the +supplied MESSAGE, within the specified TIMEOUT interval. Forces +closing of all documents without prompting the user if FORCECLOSE is +true, and reboots the machine if REBOOT is true. This function works +only on WinNT. + +=item Win32::IsWinNT() + +[CORE] Returns non zero if the Win32 subsystem is Windows NT. + +=item Win32::IsWin95() + +[CORE] Returns non zero if the Win32 subsystem is Windows 95. + +=item Win32::LoadLibrary(LIBNAME) + +[EXT] Loads a dynamic link library into memory and returns its module +handle. This handle can be used with Win32::GetProcAddress and +Win32::FreeLibrary. This function is deprecated. Use the Win32::API +module instead. + +=item Win32::LoginName() + +[CORE] Returns the username of the owner of the current perl process. + +=item Win32::LookupAccountName(SYSTEM, ACCOUNT, DOMAIN, SID, SIDTYPE) + +[EXT] Looks up ACCOUNT on SYSTEM and returns the domain name the SID and +the SID type. + +=item Win32::LookupAccountSID(SYSTEM, SID, ACCOUNT, DOMAIN, SIDTYPE) + +[EXT] Looks up SID on SYSTEM and returns the account name, domain name, +and the SID type. + +=item Win32::MsgBox(MESSAGE [, FLAGS [, TITLE]]) + +[EXT] Create a dialogbox containing MESSAGE. FLAGS specifies the +required icon and buttons according to the following table: + + 0 = OK + 1 = OK and Cancel + 2 = Abort, Retry, and Ignore + 3 = Yes, No and Cancel + 4 = Yes and No + 5 = Retry and Cancel + + MB_ICONSTOP "X" in a red circle + MB_ICONQUESTION question mark in a bubble + MB_ICONEXCLAMATION exclamation mark in a yellow triangle + MB_ICONINFORMATION "i" in a bubble + +TITLE specifies an optional window title. The default is "Perl". + +The function returns the menu id of the selected push button: + + 0 Error + + 1 OK + 2 Cancel + 3 Abort + 4 Retry + 5 Ignore + 6 Yes + 7 No + +=item Win32::NodeName() + +[CORE] Returns the Microsoft Network node-name of the current machine. + +=item Win32::RegisterServer(LIBRARYNAME) + +[EXT] Loads the DLL LIBRARYNAME and calls the function DllRegisterServer. + +=item Win32::SetCwd(NEWDIRECTORY) + +[CORE] Sets the current active drive and directory. This function does not +work with UNC paths, since the functionality required to required for +such a feature is not available under Windows 95. + +=item Win32::SetLastError(ERROR) + +[CORE] Sets the value of the last error encountered to ERROR. This is +that value that will be returned by the Win32::GetLastError() +function. This functions has been added for Perl 5.6. + +=item Win32::Sleep(TIME) + +[CORE] Pauses for TIME milliseconds. The timeslices are made available +to other processes and threads. + +=item Win32::Spawn(COMMAND, ARGS, PID) + +[CORE] Spawns a new process using the supplied COMMAND, passing in +arguments in the string ARGS. The pid of the new process is stored in +PID. This function is deprecated. Please use the Win32::Process module +instead. + +=item Win32::UnregisterServer(LIBRARYNAME) + +[EXT] Loads the DLL LIBRARYNAME and calls the function +DllUnregisterServer. + +=back + +=cut diff --git a/lib/lib.pm b/lib/lib_pm.PL index 98e2f733cb..0d2a73b842 100644 --- a/lib/lib.pm +++ b/lib/lib_pm.PL @@ -1,12 +1,36 @@ +use Config; +use File::Basename qw(&basename &dirname); +use File::Spec; +use Cwd; + +my $origdir = cwd; +chdir dirname($0); +my $file = basename($0, '.PL'); +$file =~ s!_(pm)$!.$1!i; + +my $Config_archname = defined($Config{'archname'}) ? $Config{'archname'} : ''; +my $Config_ver = defined($Config{'version'}) ? $Config{'version'} : ''; +my @Config_inc_version_list = defined($Config{'inc_version_list'}) ? + reverse split / /, $Config{'inc_version_list'} : (); + +open OUT,">$file" or die "Can't create $file: $!"; + +print "Extracting $file (with variable substitutions)\n"; + +# In this section, perl variables will be expanded during extraction. +# You can use $Config{...} to use Configure variables. + +print OUT <<"!GROK!THIS!"; package lib; use 5.005_64; -use Config; -my $archname = defined($Config{'archname'}) ? $Config{'archname'} : ''; -my $ver = defined($Config{'version'}) ? $Config{'version'} : ''; -my @inc_version_list = defined($Config{'inc_version_list'}) ? - reverse split / /, $Config{'inc_version_list'} : (); +my \$archname = "$Config_archname"; +my \$ver = "$Config_ver"; +my \@inc_version_list = qw(@Config_inc_version_list); + +!GROK!THIS! +print OUT <<'!NO!SUBS!'; our @ORIG_INC = @INC; # take a handy copy of 'original' value our $VERSION = '0.5564'; @@ -131,3 +155,7 @@ FindBin - optional module which deals with paths relative to the source file. Tim Bunce, 2nd June 1995. =cut +!NO!SUBS! + +close OUT or die "Can't close $file: $!"; +chdir $origdir; diff --git a/lib/perl5db.pl b/lib/perl5db.pl index 41430ac188..cc6a405823 100644 --- a/lib/perl5db.pl +++ b/lib/perl5db.pl @@ -980,18 +980,18 @@ EOP next CMD; }; $cmd =~ /^<\s*(.*)/ && do { unless ($1) { - print OUT "All < actions cleared.\n"; + print $OUT "All < actions cleared.\n"; $pre = []; next CMD; } if ($1 eq '?') { unless (@$pre) { - print OUT "No pre-prompt Perl actions.\n"; + print $OUT "No pre-prompt Perl actions.\n"; next CMD; } - print OUT "Perl commands run before each prompt:\n"; + print $OUT "Perl commands run before each prompt:\n"; for my $action ( @$pre ) { - print "\t< -- $action\n"; + print $OUT "\t< -- $action\n"; } next CMD; } @@ -999,18 +999,18 @@ EOP next CMD; }; $cmd =~ /^>\s*(.*)/ && do { unless ($1) { - print OUT "All > actions cleared.\n"; + print $OUT "All > actions cleared.\n"; $post = []; next CMD; } if ($1 eq '?') { unless (@$post) { - print OUT "No post-prompt Perl actions.\n"; + print $OUT "No post-prompt Perl actions.\n"; next CMD; } - print OUT "Perl commands run after each prompt:\n"; + print $OUT "Perl commands run after each prompt:\n"; for my $action ( @$post ) { - print "\t> -- $action\n"; + print $OUT "\t> -- $action\n"; } next CMD; } @@ -1018,7 +1018,7 @@ EOP next CMD; }; $cmd =~ /^\{\{\s*(.*)/ && do { if ($cmd =~ /^\{.*\}$/ && unbalanced(substr($cmd,2))) { - print OUT "{{ is now a debugger command\n", + print $OUT "{{ is now a debugger command\n", "use `;{{' if you mean Perl code\n"; $cmd = "h {{"; redo CMD; @@ -1027,23 +1027,23 @@ EOP next CMD; }; $cmd =~ /^\{\s*(.*)/ && do { unless ($1) { - print OUT "All { actions cleared.\n"; + print $OUT "All { actions cleared.\n"; $pretype = []; next CMD; } if ($1 eq '?') { unless (@$pretype) { - print OUT "No pre-prompt debugger actions.\n"; + print $OUT "No pre-prompt debugger actions.\n"; next CMD; } - print OUT "Debugger commands run before each prompt:\n"; + print $OUT "Debugger commands run before each prompt:\n"; for my $action ( @$pretype ) { - print "\t{ -- $action\n"; + print $OUT "\t{ -- $action\n"; } next CMD; } if ($cmd =~ /^\{.*\}$/ && unbalanced(substr($cmd,1))) { - print OUT "{ is now a debugger command\n", + print $OUT "{ is now a debugger command\n", "use `;{' if you mean Perl code\n"; $cmd = "h {"; redo CMD; @@ -1814,7 +1814,7 @@ sub readline { local $frame = 0; local $doret = -2; if (ref $OUT and UNIVERSAL::isa($OUT, 'IO::Socket::INET')) { - print $OUT @_; + $OUT->write(join('', @_)); my $stuff; $IN->recv( $stuff, 2048 ); # XXX: what's wrong with sysread? $stuff; diff --git a/lib/unicode/Is/BidiAL.pl b/lib/unicode/Is/BidiAL.pl new file mode 100644 index 0000000000..e04f2f562d --- /dev/null +++ b/lib/unicode/Is/BidiAL.pl @@ -0,0 +1,25 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +061b +061f +0621 063a +0640 064a +066d +0671 06d5 +06e5 06e6 +06fa 06fe +0700 070d +0710 +0712 072c +0780 07a5 +fb50 fbb1 +fbd3 fd3d +fd50 fd8f +fd92 fdc7 +fdf0 fdfb +fe70 fe72 +fe74 +fe76 fefc +END diff --git a/lib/unicode/Is/BidiBN.pl b/lib/unicode/Is/BidiBN.pl new file mode 100644 index 0000000000..795a4a9f40 --- /dev/null +++ b/lib/unicode/Is/BidiBN.pl @@ -0,0 +1,15 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +0000 0008 +000e 001b +007f 0084 +0086 009f +070f +180b 180e +200b 200d +206a 206f +feff +fff9 fffb +END diff --git a/lib/unicode/Is/BidiLRE.pl b/lib/unicode/Is/BidiLRE.pl new file mode 100644 index 0000000000..ef2a6e462f --- /dev/null +++ b/lib/unicode/Is/BidiLRE.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +202a +END diff --git a/lib/unicode/Is/BidiLRO.pl b/lib/unicode/Is/BidiLRO.pl new file mode 100644 index 0000000000..e9958c4b81 --- /dev/null +++ b/lib/unicode/Is/BidiLRO.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +202d +END diff --git a/lib/unicode/Is/BidiNSM.pl b/lib/unicode/Is/BidiNSM.pl new file mode 100644 index 0000000000..191bc052a9 --- /dev/null +++ b/lib/unicode/Is/BidiNSM.pl @@ -0,0 +1,97 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +0300 034e +0360 0362 +0483 0486 +0488 0489 +0591 05a1 +05a3 05b9 +05bb 05bd +05bf +05c1 05c2 +05c4 +064b 0655 +0670 +06d6 06e4 +06e7 06e8 +06ea 06ed +0711 +0730 074a +07a6 07b0 +0901 0902 +093c +0941 0948 +094d +0951 0954 +0962 0963 +0981 +09bc +09c1 09c4 +09cd +09e2 09e3 +0a02 +0a3c +0a41 0a42 +0a47 0a48 +0a4b 0a4d +0a70 0a71 +0a81 0a82 +0abc +0ac1 0ac5 +0ac7 0ac8 +0acd +0b01 +0b3c +0b3f +0b41 0b43 +0b4d +0b56 +0b82 +0bc0 +0bcd +0c3e 0c40 +0c46 0c48 +0c4a 0c4d +0c55 0c56 +0cbf +0cc6 +0ccc 0ccd +0d41 0d43 +0d4d +0dca +0dd2 0dd4 +0dd6 +0e31 +0e34 0e3a +0e47 0e4e +0eb1 +0eb4 0eb9 +0ebb 0ebc +0ec8 0ecd +0f18 0f19 +0f35 +0f37 +0f39 +0f71 0f7e +0f80 0f84 +0f86 0f87 +0f90 0f97 +0f99 0fbc +0fc6 +102d 1030 +1032 +1036 1037 +1039 +1058 1059 +17b7 17bd +17c6 +17c9 17d3 +18a9 +20d0 20e3 +302a 302f +3099 309a +fb1e +fe20 fe23 +END diff --git a/lib/unicode/Is/BidiPDF.pl b/lib/unicode/Is/BidiPDF.pl new file mode 100644 index 0000000000..4a3eedd564 --- /dev/null +++ b/lib/unicode/Is/BidiPDF.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +202c +END diff --git a/lib/unicode/Is/BidiRLE.pl b/lib/unicode/Is/BidiRLE.pl new file mode 100644 index 0000000000..d789246ddb --- /dev/null +++ b/lib/unicode/Is/BidiRLE.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +202b +END diff --git a/lib/unicode/Is/BidiRLO.pl b/lib/unicode/Is/BidiRLO.pl new file mode 100644 index 0000000000..fcb81acc93 --- /dev/null +++ b/lib/unicode/Is/BidiRLO.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +202e +END diff --git a/lib/unicode/Is/Cf.pl b/lib/unicode/Is/Cf.pl new file mode 100644 index 0000000000..896c3e6cd6 --- /dev/null +++ b/lib/unicode/Is/Cf.pl @@ -0,0 +1,12 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +070f +180b 180e +200c 200f +202a 202e +206a 206f +feff +fff9 fffb +END diff --git a/lib/unicode/Is/Cn.pl b/lib/unicode/Is/Cn.pl index ec287c456a..3c686154c1 100644 --- a/lib/unicode/Is/Cn.pl +++ b/lib/unicode/Is/Cn.pl @@ -2,4 +2,358 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +0220 0221 +0234 024f +02ae 02af +02ef 02ff +034f 035f +0363 0373 +0376 0379 +037b 037d +037f 0383 +038b +038d +03a2 +03cf +03d8 03d9 +03f4 03ff +0487 +048a 048b +04c5 04c6 +04c9 04ca +04cd 04cf +04f6 04f7 +04fa 0530 +0557 0558 +0560 +0588 +058b 0590 +05a2 +05ba +05c5 05cf +05eb 05ef +05f5 060b +060d 061a +061c 061e +0620 +063b 063f +0656 065f +066e 066f +06ee 06ef +06ff +070e +072d 072f +074b 077f +07b1 0900 +0904 +093a 093b +094e 094f +0955 0957 +0971 0980 +0984 +098d 098e +0991 0992 +09a9 +09b1 +09b3 09b5 +09ba 09bb +09bd +09c5 09c6 +09c9 09ca +09ce 09d6 +09d8 09db +09de +09e4 09e5 +09fb 0a01 +0a03 0a04 +0a0b 0a0e +0a11 0a12 +0a29 +0a31 +0a34 +0a37 +0a3a 0a3b +0a3d +0a43 0a46 +0a49 0a4a +0a4e 0a58 +0a5d +0a5f 0a65 +0a75 0a80 +0a84 +0a8c +0a8e +0a92 +0aa9 +0ab1 +0ab4 +0aba 0abb +0ac6 +0aca +0ace 0acf +0ad1 0adf +0ae1 0ae5 +0af0 0b00 +0b04 +0b0d 0b0e +0b11 0b12 +0b29 +0b31 +0b34 0b35 +0b3a 0b3b +0b44 0b46 +0b49 0b4a +0b4e 0b55 +0b58 0b5b +0b5e +0b62 0b65 +0b71 0b81 +0b84 +0b8b 0b8d +0b91 +0b96 0b98 +0b9b +0b9d +0ba0 0ba2 +0ba5 0ba7 +0bab 0bad +0bb6 +0bba 0bbd +0bc3 0bc5 +0bc9 +0bce 0bd6 +0bd8 0be6 +0bf3 0c00 +0c04 +0c0d +0c11 +0c29 +0c34 +0c3a 0c3d +0c45 +0c49 +0c4e 0c54 +0c57 0c5f +0c62 0c65 +0c70 0c81 +0c84 +0c8d +0c91 +0ca9 +0cb4 +0cba 0cbd +0cc5 +0cc9 +0cce 0cd4 +0cd7 0cdd +0cdf +0ce2 0ce5 +0cf0 0d01 +0d04 +0d0d +0d11 +0d29 +0d3a 0d3d +0d44 0d45 +0d49 +0d4e 0d56 +0d58 0d5f +0d62 0d65 +0d70 0d81 +0d84 +0d97 0d99 +0db2 +0dbc +0dbe 0dbf +0dc7 0dc9 +0dcb 0dce +0dd5 +0dd7 +0de0 0df1 +0df5 0e00 +0e3b 0e3e +0e5c 0e80 +0e83 +0e85 0e86 +0e89 +0e8b 0e8c +0e8e 0e93 +0e98 +0ea0 +0ea4 +0ea6 +0ea8 0ea9 +0eac +0eba +0ebe 0ebf +0ec5 +0ec7 +0ece 0ecf +0eda 0edb +0ede 0eff +0f48 +0f6b 0f70 +0f8c 0f8f +0f98 +0fbd +0fcd 0fce +0fd0 0fff +1022 +1028 +102b +1033 1035 +103a 103f +105a 109f +10c6 10cf +10f7 10fa +10fc 10ff +115a 115e +11a3 11a7 +11fa 11ff +1207 +1247 +1249 +124e 124f +1257 +1259 +125e 125f +1287 +1289 +128e 128f +12af +12b1 +12b6 12b7 +12bf +12c1 +12c6 12c7 +12cf +12d7 +12ef +130f +1311 +1316 1317 +131f +1347 +135b 1360 +137d 139f +13f5 1400 +1677 167f +169d 169f +16f1 177f +17dd 17df +17ea 17ff +180f +181a 181f +1878 187f +18aa 1dff +1e9c 1e9f +1efa 1eff +1f16 1f17 +1f1e 1f1f +1f46 1f47 +1f4e 1f4f +1f58 +1f5a +1f5c +1f5e +1f7e 1f7f +1fb5 +1fc5 +1fd4 1fd5 +1fdc +1ff0 1ff1 +1ff5 +1fff +2047 +204e 2069 +2071 2073 +208f 209f +20b0 20cf +20e4 20ff +213b 2152 +2184 218f +21f4 21ff +22f2 22ff +237c +239b 23ff +2427 243f +244b 245f +24eb 24ff +2596 259f +25f8 25ff +2614 2618 +2672 2700 +2705 +270a 270b +2728 +274c +274e +2753 2755 +2757 +275f 2760 +2768 2775 +2795 2797 +27b0 +27bf 27ff +2900 2e7f +2e9a +2ef4 2eff +2fd6 2fef +2ffc 2fff +303b 303d +3040 +3095 3098 +309f 30a0 +30ff 3104 +312d 3130 +318f +31b8 31ff +321d 321f +3244 325f +327c 327e +32b1 32bf +32cc 32cf +32ff +3377 337a +33de 33df +33ff +4db6 4dff +9fa6 9fff +a48d a48f +a4a2 a4a3 +a4b4 +a4c1 +a4c5 +a4c7 abff +d7a4 d7ff +fa2e faff +fb07 fb12 +fb18 fb1c +fb37 +fb3d +fb3f +fb42 +fb45 +fbb2 fbd2 +fd40 fd4f +fd90 fd91 +fdc8 fdef +fdfc fe1f +fe24 fe2f +fe45 fe48 +fe53 +fe67 +fe6c fe6f +fe73 +fe75 +fefd fefe +ff00 +ff5f ff60 +ffbf ffc1 +ffc8 ffc9 +ffd0 ffd1 +ffd8 ffd9 +ffdd ffdf +ffe7 +ffef fff8 END diff --git a/lib/unicode/Is/Cs.pl b/lib/unicode/Is/Cs.pl new file mode 100644 index 0000000000..8888fb5f3c --- /dev/null +++ b/lib/unicode/Is/Cs.pl @@ -0,0 +1,8 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +d800 db7f +db80 dbff +dc00 dfff +END diff --git a/lib/unicode/Is/DCfraction.pl b/lib/unicode/Is/DCfraction.pl new file mode 100644 index 0000000000..fc2dd6755d --- /dev/null +++ b/lib/unicode/Is/DCfraction.pl @@ -0,0 +1,7 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +00bc 00be +2153 215f +END diff --git a/lib/unicode/Is/Graph.pl b/lib/unicode/Is/Graph.pl index 9c94bb722c..156f1711af 100644 --- a/lib/unicode/Is/Graph.pl +++ b/lib/unicode/Is/Graph.pl @@ -265,7 +265,8 @@ return <<'END'; 1fdd 1fef 1ff2 1ff4 1ff6 1ffe -2000 200b +2000 2008 +200b 2010 2029 202f 2046 2048 204d diff --git a/lib/unicode/Is/Me.pl b/lib/unicode/Is/Me.pl new file mode 100644 index 0000000000..00f446d87d --- /dev/null +++ b/lib/unicode/Is/Me.pl @@ -0,0 +1,9 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +0488 0489 +06dd 06de +20dd 20e0 +20e2 20e3 +END diff --git a/lib/unicode/Is/Nl.pl b/lib/unicode/Is/Nl.pl new file mode 100644 index 0000000000..8f1af469bb --- /dev/null +++ b/lib/unicode/Is/Nl.pl @@ -0,0 +1,9 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +2160 2183 +3007 +3021 3029 +3038 303a +END diff --git a/lib/unicode/Is/Pc.pl b/lib/unicode/Is/Pc.pl new file mode 100644 index 0000000000..342efac344 --- /dev/null +++ b/lib/unicode/Is/Pc.pl @@ -0,0 +1,12 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +005f +203f 2040 +30fb +fe33 fe34 +fe4d fe4f +ff3f +ff65 +END diff --git a/lib/unicode/Is/Pf.pl b/lib/unicode/Is/Pf.pl new file mode 100644 index 0000000000..166c64bbb6 --- /dev/null +++ b/lib/unicode/Is/Pf.pl @@ -0,0 +1,9 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +00bb +2019 +201d +203a +END diff --git a/lib/unicode/Is/Pi.pl b/lib/unicode/Is/Pi.pl new file mode 100644 index 0000000000..7f2243d5d8 --- /dev/null +++ b/lib/unicode/Is/Pi.pl @@ -0,0 +1,10 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +00ab +2018 +201b 201c +201f +2039 +END diff --git a/lib/unicode/Is/Punct.pl b/lib/unicode/Is/Punct.pl index 8fd1e8e183..9e8684d6fc 100644 --- a/lib/unicode/Is/Punct.pl +++ b/lib/unicode/Is/Punct.pl @@ -8,45 +8,45 @@ return <<'END'; 003a 003b 003f 0040 005b 005d -005f -007b -007d -00a1 -00ab -00ad -00b7 -00bb -00bf -037e -0387 +005f +007b +007d +00a1 +00ab +00ad +00b7 +00bb +00bf +037e +0387 055a 055f 0589 058a -05be -05c0 -05c3 +05be +05c0 +05c3 05f3 05f4 -060c -061b -061f +060c +061b +061f 066a 066d -06d4 +06d4 0700 070d 0964 0965 -0970 -0df4 -0e4f +0970 +0df4 +0e4f 0e5a 0e5b 0f04 0f12 0f3a 0f3d -0f85 +0f85 104a 104f -10fb +10fb 1361 1368 166d 166e 169b 169c 16eb 16ed 17d4 17da -17dc +17dc 1800 180a 2010 2027 2030 2043 @@ -58,14 +58,14 @@ return <<'END'; 3001 3003 3008 3011 3014 301f -3030 -30fb +3030 +30fb fd3e fd3f fe30 fe44 fe49 fe52 fe54 fe61 -fe63 -fe68 +fe63 +fe68 fe6a fe6b ff01 ff03 ff05 ff0a @@ -73,8 +73,8 @@ ff0c ff0f ff1a ff1b ff1f ff20 ff3b ff3d -ff3f -ff5b -ff5d +ff3f +ff5b +ff5d ff61 ff65 END diff --git a/lib/unicode/Is/Sk.pl b/lib/unicode/Is/Sk.pl new file mode 100644 index 0000000000..b5f6e591a7 --- /dev/null +++ b/lib/unicode/Is/Sk.pl @@ -0,0 +1,27 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +005e +0060 +00a8 +00af +00b4 +00b8 +02b9 02ba +02c2 02cf +02d2 02df +02e5 02ed +0374 0375 +0384 0385 +1fbd +1fbf 1fc1 +1fcd 1fcf +1fdd 1fdf +1fed 1fef +1ffd 1ffe +309b 309c +ff3e +ff40 +ffe3 +END diff --git a/lib/unicode/Is/Space.pl b/lib/unicode/Is/Space.pl index 4121ef49b8..701329ff82 100644 --- a/lib/unicode/Is/Space.pl +++ b/lib/unicode/Is/Space.pl @@ -2,13 +2,13 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; -0009 000a -000c 000d -0020 -00a0 -1680 +0009 000d +0020 +0085 +00a0 +1680 2000 200b 2028 2029 -202f -3000 +202f +3000 END diff --git a/lib/unicode/Is/SylA.pl b/lib/unicode/Is/SylA.pl index ec287c456a..be1107822d 100644 --- a/lib/unicode/Is/SylA.pl +++ b/lib/unicode/Is/SylA.pl @@ -2,4 +2,157 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1203 +120b +1213 +121b +1223 +122b +1233 +123b +1243 +1253 +1263 +126b +1273 +127b +1283 +1293 +129b +12a3 +12ab +12bb +12cb +12d3 +12db +12e3 +12eb +12f3 +12fb +1303 +130b +131b +1323 +132b +1333 +133b +1343 +134b +1353 +13a0 +13a6 13a7 +13ad +13b3 +13b9 +13be 13bf +13c6 +13cc +13d3 13d4 +13dc 13dd +13e3 +13e9 +13ef +140a +1438 +1455 +146a +1472 +1490 +14aa +14c7 +14da +14f4 +1515 +152d +154b +154d +1559 +1566 +156e +1573 +1579 +1583 +1589 +158d +1593 +159a +159e +15a4 +15ac +15b3 +15b7 +15bb +15bf +15c3 +15c9 +15cf +15d5 +15e1 +15e7 +15ed +15f4 +15fa +1600 +1607 +160d +1613 +161b +1621 +1627 +162d +1633 +1639 +163f +1645 +164d +1653 +1659 +1660 +1666 +166c +1675 +30a1 30a2 +30ab 30ac +30b5 30b6 +30bf 30c0 +30ca +30cf 30d1 +30de +30e3 30e4 +30e9 +30ee 30ef +30f5 +30f7 +32d0 +32d5 +32da +32df +32e4 +32e9 +32ee +32f3 +32f6 +32fb +ff67 +ff6c +ff71 +ff76 +ff7b +ff80 +ff85 +ff8a +ff8f +ff94 +ff97 +ff9c +3041 3042 +304b 304c +3055 3056 +305f 3060 +306a +306f 3071 +307e +3083 3084 +3089 +308e 308f END diff --git a/lib/unicode/Is/SylAA.pl b/lib/unicode/Is/SylAA.pl new file mode 100644 index 0000000000..45d6692de7 --- /dev/null +++ b/lib/unicode/Is/SylAA.pl @@ -0,0 +1,25 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +140b +1439 +1456 +1473 +1491 +14ab +14c8 +14db +14f5 +1516 +152e +154c +155a +1567 +157a +1584 +1594 +15a5 +15ad +1676 +END diff --git a/lib/unicode/Is/SylAAI.pl b/lib/unicode/Is/SylAAI.pl new file mode 100644 index 0000000000..a8b03d4c6c --- /dev/null +++ b/lib/unicode/Is/SylAAI.pl @@ -0,0 +1,19 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1402 +1430 +144d +146c +148a +14a4 +14c1 +14d4 +14ee +1527 +1545 +1554 +157e +158e +END diff --git a/lib/unicode/Is/SylAI.pl b/lib/unicode/Is/SylAI.pl new file mode 100644 index 0000000000..b70d793bc6 --- /dev/null +++ b/lib/unicode/Is/SylAI.pl @@ -0,0 +1,7 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +141c +166f 1670 +END diff --git a/lib/unicode/Is/SylC.pl b/lib/unicode/Is/SylC.pl index ec287c456a..e2a1601dd3 100644 --- a/lib/unicode/Is/SylC.pl +++ b/lib/unicode/Is/SylC.pl @@ -2,4 +2,69 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1205 +120d +1215 +121d +1225 +122d +1235 +123d +1245 +1255 +1265 +126d +1275 +127d +1285 +1295 +129d +12a5 +12ad +12bd +12cd +12d5 +12dd +12e5 +12ed +12f5 +12fd +1305 +130d +131d +1325 +132d +1335 +133d +1345 +134d +1355 +13c0 +13cd +141d +142b 142e +1449 144b +1466 +1483 +1485 1488 +14a1 +14bb 14bf +14d0 14d2 +14ea 14ec +1505 1506 +1508 150b +1525 +153e 1540 +1550 1552 +155d +156a +156f +157b 157d +1585 +1595 1596 +159f +15a6 +15ae 15af +30f3 +ff9d END diff --git a/lib/unicode/Is/SylE.pl b/lib/unicode/Is/SylE.pl index ec287c456a..b3c3e60437 100644 --- a/lib/unicode/Is/SylE.pl +++ b/lib/unicode/Is/SylE.pl @@ -2,4 +2,146 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1204 +120c +1214 +121c +1224 +122c +1234 +123c +1244 +1254 +1264 +126c +1274 +127c +1284 +1294 +129c +12a4 +12ac +12bc +12cc +12d4 +12dc +12e4 +12ec +12f4 +12fc +1304 +130c +131c +1324 +132c +1334 +133c +1344 +134c +1354 +13a1 +13a8 +13ae +13b4 +13ba +13c1 +13c7 +13ce +13d5 13d6 +13de +13e4 +13ea +13f0 +1401 +142f +144c +1467 +146b +1489 +14a3 +14c0 +14d3 +14ed +1510 +1526 +1542 1544 +1553 +155e 155f +156b +1570 +1574 +1586 +158a +1597 +159b +15a7 +15b0 +15b4 +15b8 +15bc +15c0 +15c6 +15cc +15d2 +15de +15e4 +15ea +15f1 +15f7 +15fd +1604 +160a +1610 +1617 +161e +1624 +162a +1630 +1636 +163c +1642 +164a +1650 +1656 +165d +1663 +1669 +30a7 30a8 +30b1 30b2 +30bb 30bc +30c6 30c7 +30cd +30d8 30da +30e1 +30ec +30f1 +30f6 +30f9 +32d3 +32d8 +32dd +32e2 +32e7 +32ec +32f1 +32f9 +32fd +ff6a +ff74 +ff79 +ff7e +ff83 +ff88 +ff8d +ff92 +ff9a +3047 3048 +3051 3052 +305b 305c +3066 3067 +306d +3078 307a +3081 +308c +3091 END diff --git a/lib/unicode/Is/SylEE.pl b/lib/unicode/Is/SylEE.pl new file mode 100644 index 0000000000..0a22f78f65 --- /dev/null +++ b/lib/unicode/Is/SylEE.pl @@ -0,0 +1,34 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1408 +1436 +1453 +15c7 +15cd +15d3 +15df +15e5 +15eb +15f2 +15f8 +15fe +1605 +160b +1611 +1618 +161f +1625 +162b +1631 +1637 +163d +1643 +164b +1651 +1657 +165e +1664 +166a +END diff --git a/lib/unicode/Is/SylI.pl b/lib/unicode/Is/SylI.pl index ec287c456a..f80790ce44 100644 --- a/lib/unicode/Is/SylI.pl +++ b/lib/unicode/Is/SylI.pl @@ -2,4 +2,153 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1202 +120a +1212 +121a +1222 +122a +1232 +123a +1242 +1252 +1262 +126a +1272 +127a +1282 +1292 +129a +12a2 +12aa +12ba +12ca +12d2 +12da +12e2 +12ea +12f2 +12fa +1302 +130a +131a +1322 +132a +1332 +133a +1342 +134a +1352 +13a2 +13a9 +13af +13b5 +13bb +13c2 +13c8 +13cf +13d7 13d8 +13df +13e5 +13eb +13f1 +1403 +1409 +1431 +1437 +144e +1454 +1468 +146d +148b +14a5 +14c2 +14d5 +14ef +1511 +1528 +1541 +1546 +1555 +1560 1561 +156c +1571 +1575 +157f +1587 +158b +158f +1598 +159c +15a0 +15a8 +15b1 +15b5 +15b9 +15bd +15c1 +15c8 +15ce +15d4 +15e0 +15e6 +15ec +15f3 +15f9 +15ff +1606 +160c +1612 +1619 161a +1620 +1626 +162c +1632 +1638 +163e +1644 +164c +1652 +1658 +165f +1665 +166b +1671 +30a3 30a4 +30ad 30ae +30b7 30b8 +30c1 30c2 +30cb +30d2 30d4 +30df +30ea +30f0 +30f8 +32d1 +32d6 +32db +32e0 +32e5 +32ea +32ef +32f7 +32fc +ff68 +ff72 +ff77 +ff7c +ff81 +ff86 +ff8b +ff90 +ff98 +3043 3044 +304d 304e +3057 3058 +3061 3062 +306b +3072 3074 +307f +308a +3090 END diff --git a/lib/unicode/Is/SylII.pl b/lib/unicode/Is/SylII.pl new file mode 100644 index 0000000000..4516d7a32a --- /dev/null +++ b/lib/unicode/Is/SylII.pl @@ -0,0 +1,25 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1404 +1432 +144f +146e +148c +14a6 +14c3 +14d6 +14f0 +1512 +1529 +1547 +1556 +1562 1563 +1576 +1580 +1590 +15a1 +15a9 +1672 +END diff --git a/lib/unicode/Is/SylN.pl b/lib/unicode/Is/SylN.pl new file mode 100644 index 0000000000..215463fb7f --- /dev/null +++ b/lib/unicode/Is/SylN.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +3093 +END diff --git a/lib/unicode/Is/SylO.pl b/lib/unicode/Is/SylO.pl index ec287c456a..a0a6f7dd01 100644 --- a/lib/unicode/Is/SylO.pl +++ b/lib/unicode/Is/SylO.pl @@ -2,4 +2,156 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1206 +120e +1216 +121e +1226 +122e +1236 +123e +1246 +1256 +1266 +126e +1276 +127e +1286 +1296 +129e +12a6 +12ae +12be +12ce +12d6 +12de +12e6 +12ee +12f6 +12fe +1306 +130e +131e +1326 +132e +1336 +133e +1346 +134e +1356 +13a3 +13aa +13b0 +13b6 +13bc +13c3 +13c9 +13d0 +13d9 +13e0 +13e6 +13ec +13f2 +1405 +1433 +1450 +1469 +146f +148d +14a7 +14c4 +14d7 +14f1 +1513 +152a +1548 +154a +1557 +1564 +156d +1572 +1577 +1581 +1588 +158c +1591 +1599 +159d +15a2 +15aa +15b2 +15b6 +15ba +15be +15c2 +15c5 +15cb +15d1 +15dd +15e3 +15e9 +15f0 +15f6 +15fc +1603 +1609 +160f +1616 +161d +1623 +1629 +162f +1635 +163b +1641 +1649 +164f +1655 +165c +1662 +1668 +1673 +30a9 30aa +30b3 30b4 +30bd 30be +30c8 30c9 +30ce +30db 30dd +30e2 +30e7 30e8 +30ed +30f2 +30fa +32d4 +32d9 +32de +32e3 +32e8 +32ed +32f2 +32f5 +32fa +32fe +ff66 +ff6b +ff6e +ff75 +ff7a +ff7f +ff84 +ff89 +ff8e +ff93 +ff96 +ff9b +3049 304a +3053 3054 +305d 305e +3068 3069 +306e +307b 307d +3082 +3087 3088 +308d +3092 END diff --git a/lib/unicode/Is/SylOO.pl b/lib/unicode/Is/SylOO.pl new file mode 100644 index 0000000000..12280534b1 --- /dev/null +++ b/lib/unicode/Is/SylOO.pl @@ -0,0 +1,25 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1406 1407 +1434 1435 +1451 1452 +1470 1471 +148e 148f +14a8 14a9 +14c5 14c6 +14d8 14d9 +14f2 14f3 +1514 +152b 152c +1549 +1558 +1565 +1578 +1582 +1592 +15a3 +15ab +1674 +END diff --git a/lib/unicode/Is/SylU.pl b/lib/unicode/Is/SylU.pl index ec287c456a..c458382f25 100644 --- a/lib/unicode/Is/SylU.pl +++ b/lib/unicode/Is/SylU.pl @@ -2,4 +2,121 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1201 +1209 +1211 +1219 +1221 +1229 +1231 +1239 +1241 +1251 +1261 +1269 +1271 +1279 +1281 +1291 +1299 +12a1 +12a9 +12b9 +12c9 +12d1 +12d9 +12e1 +12e9 +12f1 +12f9 +1301 +1309 +1319 +1321 +1329 +1331 +1339 +1341 +1349 +1351 +13a4 +13ab +13b1 +13b7 +13bd +13c4 +13ca +13d1 +13da +13e1 +13e7 +13ed +13f3 +15c4 +15ca +15d0 +15dc +15e2 +15e8 +15ef +15f5 +15fb +1602 +1608 +160e +1614 1615 +161c +1622 +1628 +162e +1634 +163a +1640 +1648 +164e +1654 +165b +1661 +1667 +30a5 30a6 +30af 30b0 +30b9 30ba +30c3 30c5 +30cc +30d5 30d7 +30e0 +30e5 30e6 +30eb +30f4 +32d2 +32d7 +32dc +32e1 +32e6 +32eb +32f0 +32f4 +32f8 +ff69 +ff6d +ff6f +ff73 +ff78 +ff7d +ff82 +ff87 +ff8c +ff91 +ff95 +ff99 +3045 3046 +304f 3050 +3059 305a +3063 3065 +306c +3075 3077 +3080 +3085 3086 +308b +3094 END diff --git a/lib/unicode/Is/SylV.pl b/lib/unicode/Is/SylV.pl index ec287c456a..b6e76f81b9 100644 --- a/lib/unicode/Is/SylV.pl +++ b/lib/unicode/Is/SylV.pl @@ -2,4 +2,53 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1200 +1208 +1210 +1218 +1220 +1228 +1230 +1238 +1240 +1250 +1260 +1268 +1270 +1278 +1280 +1290 +1298 +12a0 +12a8 +12b8 +12c8 +12d0 +12d8 +12e0 +12e8 +12f0 +12f8 +1300 +1308 +1318 +1320 +1328 +1330 +1338 +1340 +1348 +1350 +13a5 +13ac +13b2 +13b8 +13c5 +13cb +13d2 +13db +13e2 +13e8 +13ee +13f4 END diff --git a/lib/unicode/Is/SylWA.pl b/lib/unicode/Is/SylWA.pl index ec287c456a..9bb529ed01 100644 --- a/lib/unicode/Is/SylWA.pl +++ b/lib/unicode/Is/SylWA.pl @@ -2,4 +2,48 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +120f +1217 +121f +1227 +122f +1237 +123f +124b +125b +1267 +126f +1277 +127f +128b +1297 +129f +12a7 +12b3 +12c3 +12df +12e7 +12f7 +12ff +1307 +1313 +1327 +132f +1337 +133f +134f +1357 +1417 1418 +1444 1445 +1461 1462 +147e 147f +149c 149d +14b6 14b7 +14cb 14cc +14e6 14e7 +1500 1501 +150c 150f +1521 1522 +1539 153a +15db END diff --git a/lib/unicode/Is/SylWAA.pl b/lib/unicode/Is/SylWAA.pl new file mode 100644 index 0000000000..5f3b784d0c --- /dev/null +++ b/lib/unicode/Is/SylWAA.pl @@ -0,0 +1,19 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1419 141b +1446 1448 +1463 1465 +1480 1482 +149e 14a0 +14b8 14ba +14cd 14cf +14e8 14e9 +1502 1504 +1523 1524 +153b 153d +154e 154f +155b 155c +1568 1569 +END diff --git a/lib/unicode/Is/SylWC.pl b/lib/unicode/Is/SylWC.pl index ec287c456a..3ad968c505 100644 --- a/lib/unicode/Is/SylWC.pl +++ b/lib/unicode/Is/SylWC.pl @@ -2,4 +2,12 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +124d +125d +128d +12b5 +12c5 +1315 +1484 +1507 END diff --git a/lib/unicode/Is/SylWE.pl b/lib/unicode/Is/SylWE.pl index ec287c456a..9e32c0e602 100644 --- a/lib/unicode/Is/SylWE.pl +++ b/lib/unicode/Is/SylWE.pl @@ -2,4 +2,22 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +124c +125c +128c +12b4 +12c4 +1314 +140c 140d +143a 143b +1457 1458 +1474 1475 +1492 1493 +14ac 14ad +14c9 14ca +14dc 14dd +14f6 14f7 +1517 1518 +152f 1530 +15d8 END diff --git a/lib/unicode/Is/SylWEE.pl b/lib/unicode/Is/SylWEE.pl new file mode 100644 index 0000000000..c4bccb5240 --- /dev/null +++ b/lib/unicode/Is/SylWEE.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +15d9 +END diff --git a/lib/unicode/Is/SylWI.pl b/lib/unicode/Is/SylWI.pl index ec287c456a..4cd6c6789c 100644 --- a/lib/unicode/Is/SylWI.pl +++ b/lib/unicode/Is/SylWI.pl @@ -2,4 +2,21 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +124a +125a +128a +12b2 +12c2 +1312 +140e 140f +143c 143d +1459 145a +1476 1477 +1494 1495 +14ae 14af +14de 14df +14f8 14f9 +1519 151a +1531 1532 +15da END diff --git a/lib/unicode/Is/SylWII.pl b/lib/unicode/Is/SylWII.pl new file mode 100644 index 0000000000..bd68aeadf5 --- /dev/null +++ b/lib/unicode/Is/SylWII.pl @@ -0,0 +1,15 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1410 1411 +143e 143f +145b 145c +1478 1479 +1496 1497 +14b0 14b1 +14e0 14e1 +14fa 14fb +151b 151c +1533 1534 +END diff --git a/lib/unicode/Is/SylWO.pl b/lib/unicode/Is/SylWO.pl new file mode 100644 index 0000000000..7676564130 --- /dev/null +++ b/lib/unicode/Is/SylWO.pl @@ -0,0 +1,16 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1412 1413 +1440 1441 +145d 145e +147a 147b +1498 1499 +14b2 14b3 +14e2 14e3 +14fc 14fd +151d 151e +1535 1536 +15d7 +END diff --git a/lib/unicode/Is/SylWOO.pl b/lib/unicode/Is/SylWOO.pl new file mode 100644 index 0000000000..0ab766a553 --- /dev/null +++ b/lib/unicode/Is/SylWOO.pl @@ -0,0 +1,15 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +1414 1416 +1442 1443 +145f 1460 +147c 147d +149a 149b +14b4 14b5 +14e4 14e5 +14fe 14ff +151f 1520 +1537 1538 +END diff --git a/lib/unicode/Is/SylWU.pl b/lib/unicode/Is/SylWU.pl new file mode 100644 index 0000000000..76af7aefad --- /dev/null +++ b/lib/unicode/Is/SylWU.pl @@ -0,0 +1,6 @@ +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by mktables.PL from e.g. Unicode.300. +# Any changes made here will be lost! +return <<'END'; +15d6 +END diff --git a/lib/unicode/Is/SylWV.pl b/lib/unicode/Is/SylWV.pl index ec287c456a..8bd8849042 100644 --- a/lib/unicode/Is/SylWV.pl +++ b/lib/unicode/Is/SylWV.pl @@ -2,4 +2,10 @@ # This file is built by mktables.PL from e.g. Unicode.300. # Any changes made here will be lost! return <<'END'; +1248 +1258 +1288 +12b0 +12c0 +1310 END diff --git a/lib/unicode/Is/Upper.pl b/lib/unicode/Is/Upper.pl index 8dde2742d0..4fda655dc4 100644 --- a/lib/unicode/Is/Upper.pl +++ b/lib/unicode/Is/Upper.pl @@ -86,9 +86,9 @@ return <<'END'; 01b5 01b7 01b8 01bc -01c4 -01c7 -01ca +01c4 01c5 +01c7 01c8 +01ca 01cb 01cd 01cf 01d1 @@ -106,7 +106,7 @@ return <<'END'; 01ea 01ec 01ee -01f1 +01f1 01f2 01f4 01f6 01f8 01fa @@ -355,11 +355,14 @@ return <<'END'; 1f5d 1f5f 1f68 1f6f -1fb8 1fbb -1fc8 1fcb +1f88 1f8f +1f98 1f9f +1fa8 1faf +1fb8 1fbc +1fc8 1fcc 1fd8 1fdb 1fe8 1fec -1ff8 1ffb +1ff8 1ffc 2102 2107 210b 210d diff --git a/lib/unicode/Makefile b/lib/unicode/Makefile index c68fa3af00..af5e77b47b 100644 --- a/lib/unicode/Makefile +++ b/lib/unicode/Makefile @@ -1,6 +1,5 @@ all: - ./mktables.PL - ./MakeEthiopicSyllables.PL + ../../miniperl -I../../lib ./mktables.PL clean: rm -f *.pl */*.pl diff --git a/lib/unicode/mktables.PL b/lib/unicode/mktables.PL index 4f705a4016..241d2e6bb3 100755 --- a/lib/unicode/mktables.PL +++ b/lib/unicode/mktables.PL @@ -1,6 +1,11 @@ #!../../miniperl +use bytes; + $UnicodeData = "Unicode.300"; +$SyllableData = "syllables.txt"; +$PropData = "Props.txt"; + # Note: we try to keep filenames unique within first 8 chars. Using # subdirectories for the following helps. @@ -14,16 +19,15 @@ mkdir "To", 0777; ['IsWord', '$cat =~ /^L[ulot]|^Nd/ or $code eq "005F"', ''], ['IsAlnum', '$cat =~ /^L[ulot]|^Nd/', ''], ['IsAlpha', '$cat =~ /^L[ulot]/', ''], - # XXX broken: recursive definition (/\s/ will look up IsSpace in future) - ['IsSpace', '$cat =~ /^Z/ or $code lt "0020" and chr(hex $code) =~ /^\s/', ''], + ['IsSpace', 'White space', $PropData], ['IsDigit', '$cat =~ /^Nd$/', ''], - ['IsUpper', '$cat =~ /^Lu$/', ''], + ['IsUpper', '$cat =~ /^L[ut]$/', ''], ['IsLower', '$cat =~ /^Ll$/', ''], ['IsASCII', 'hex $code <= 127', ''], ['IsCntrl', '$cat =~ /^C/', ''], - ['IsGraph', '$cat =~ /^[^C]/ and $code ne "0020"', ''], + ['IsGraph', '$cat =~ /^[^C]/ and ($cat !~ /^Z/ and $code ne "0020" or chr(hex $code) !~ /^\s/)', ''], ['IsPrint', '$cat =~ /^[^C]/', ''], - ['IsPunct', '$cat =~ /^P/', ''], + ['IsPunct', 'Punctuation', $PropData], ['IsXDigit', '$code =~ /^00(3[0-9]|[46][1-6])$/', ''], ['ToUpper', '$up', '$up'], ['ToLower', '$down', '$down'], @@ -43,12 +47,14 @@ mkdir "To", 0777; ['IsM', '$cat =~ /^M/', ''], # Mark ['IsMn', '$cat eq "Mn"', ''], # Mark, Non-Spacing ['IsMc', '$cat eq "Mc"', ''], # Mark, Combining + ['IsMe', '$cat eq "Me"', ''], # Mark, Enclosing ['IsN', '$cat =~ /^N/', ''], # Number ['IsNd', '$cat eq "Nd"', ''], # Number, Decimal Digit ['IsNo', '$cat eq "No"', ''], # Number, Other + ['IsNl', '$cat eq "Nl"', ''], # Number, Letter - ['IsZ', '$cat =~ /^Z/', ''], # Zeparator + ['IsZ', '$cat =~ /^Z/', ''], # Separator ['IsZs', '$cat eq "Zs"', ''], # Separator, Space ['IsZl', '$cat eq "Zl"', ''], # Separator, Line ['IsZp', '$cat eq "Zp"', ''], # Separator, Paragraph @@ -57,6 +63,9 @@ mkdir "To", 0777; ['IsCc', '$cat eq "Cc"', ''], # Other, Control or Format ['IsCo', '$cat eq "Co"', ''], # Other, Private Use ['IsCn', '$cat eq "Cn"', ''], # Other, Not Assigned + ['IsCf', '$cat eq "Cf"', ''], # Other, Format + ['IsCs', '$cat eq "Cs"', ''], # Other, Surrogate + ['IsCn', 'Unassigned Code Value',$PropData], # Other, Not Assigned # Informative @@ -72,9 +81,13 @@ mkdir "To", 0777; ['IsPs', '$cat eq "Ps"', ''], # Punctuation, Open ['IsPe', '$cat eq "Pe"', ''], # Punctuation, Close ['IsPo', '$cat eq "Po"', ''], # Punctuation, Other + ['IsPc', '$cat eq "Pc"', ''], # Punctuation, Connector + ['IsPi', '$cat eq "Pi"', ''], # Punctuation, Initial quote + ['IsPf', '$cat eq "Pf"', ''], # Punctuation, Final quote ['IsS', '$cat =~ /^S/', ''], # Symbol ['IsSm', '$cat eq "Sm"', ''], # Symbol, Math + ['IsSk', '$cat eq "Sk"', ''], # Symbol, Modifier ['IsSc', '$cat eq "Sc"', ''], # Symbol, Currency ['IsSo', '$cat eq "So"', ''], # Symbol, Other @@ -95,6 +108,15 @@ mkdir "To", 0777; # and punctuation specific to # those scripts + ['IsBidiLRE', '$bid eq "LRE"', ''], # Left-to-Right Embedding + ['IsBidiLRO', '$bid eq "LRO"', ''], # Left-to-Right Override + ['IsBidiAL', '$bid eq "AL"', ''], # Right-to-Left Arabic + ['IsBidiRLE', '$bid eq "RLE"', ''], # Right-to-Left Embedding + ['IsBidiRLO', '$bid eq "RLO"', ''], # Right-to-Left Override + ['IsBidiPDF', '$bid eq "PDF"', ''], # Pop Directional Format + ['IsBidiNSM', '$bid eq "NSM"', ''], # Non-Spacing Mark + ['IsBidiBN', '$bid eq "BN"', ''], # Boundary Neutral + # Weak types: ['IsBidiEN','$bid eq "EN"', ''], # European Number @@ -134,6 +156,7 @@ mkdir "To", 0777; ['IsDCnarrow', '$decomp =~ /^<narrow>/', ''], ['IsDCsmall', '$decomp =~ /^<small>/', ''], ['IsDCsquare', '$decomp =~ /^<square>/', ''], + ['IsDCfraction', '$decomp =~ /^<fraction>/', ''], ['IsDCcompat', '$decomp =~ /^<compat>/', ''], # Number @@ -155,19 +178,8 @@ mkdir "To", 0777; # Syllables - ['IsSylV', '$syl eq "V"', ''], - ['IsSylU', '$syl eq "U"', ''], - ['IsSylI', '$syl eq "I"', ''], - ['IsSylA', '$syl eq "A"', ''], - ['IsSylE', '$syl eq "E"', ''], - ['IsSylC', '$syl eq "C"', ''], - ['IsSylO', '$syl eq "O"', ''], - ['IsSylWV', '$syl eq "V"', ''], - ['IsSylWI', '$syl eq "I"', ''], - ['IsSylWA', '$syl eq "A"', ''], - ['IsSylWE', '$syl eq "E"', ''], - ['IsSylWC', '$syl eq "C"', ''], - + syllable_defs(), + # Line break properties - Normative ['IsLbrkBK','$brk eq "BK"', ''], # Mandatory Break @@ -232,8 +244,8 @@ END exit if @ARGV and not grep { $_ eq Block } @ARGV; print "Block\n"; -open(UD, 'Blocks.txt') or die "Can't open blocks.txt: $!\n"; -open(OUT, ">Block.pl") or die "Can't create $table.pl: $!\n"; +open(UD, 'Blocks.txt') or die "Can't open Blocks.txt: $!\n"; +open(OUT, ">Block.pl") or die "Can't create Block.pl: $!\n"; print OUT <<EOH; # !!!!!!! DO NOT EDIT THIS FILE !!!!!!! # This file is built by $0 from e.g. $UnicodeData. @@ -277,6 +289,8 @@ sub proplist { my $out; my $split; + return listFromPropFile($wanted) if $val eq $PropData; + if ($table =~ /^Arab/) { open(UD, "ArabShap.txt") or warn "Can't open $table: $!"; @@ -288,7 +302,7 @@ sub proplist { $split = '($code, $short, $name) = split(/; */); $code =~ s/^U\+//;'; } elsif ($table =~ /^IsSyl/) { - open(UD, "syllables.txt") or warn "Can't open $table: $!"; + open(UD, $SyllableData) or warn "Can't open $table: $!"; $split = '($code, $short, $syl) = split(/; */); $code =~ s/^U\+//;'; } @@ -308,8 +322,8 @@ sub proplist { eval <<"END"; while (<UD>) { next if /^#/; - next if /^\s/; - chop; + next if /^\\s/; + s/\\s+\$//; $split if ($wanted) { push(\@wanted, [hex \$code, hex $val, \$name =~ /, First>\$/]); @@ -343,7 +357,7 @@ END eval <<"END"; while (<UD>) { next if /^#/; - next if /^\s*\$/; + next if /^\\s*\$/; chop; $split if ($wanted) { @@ -376,4 +390,44 @@ END $out; } +sub listFromPropFile { + my ($wanted) = @_; + my $out; + + open (UD, $PropData) or die "Can't open $PropData: $!\n"; + local($/) = "\n" . '*' x 43 . "\n\nProperty dump for:"; # not 42? + + <UD>; + while (<UD>) { + chomp; + if (s/0x[\d\w]+\s+\((.*?)\)// and $wanted eq $1) { + s/\(\d+ chars\)//g; + s/^\s+//mg; + s/\s+$//mg; + s/\.\./\t/g; + $out = lc $_; + last; + } + } + close (UD); + "$out\n"; +} + +sub syllable_defs { + my @defs; + my %seen; + + open (SD, $SyllableData) or die "Can't open $SyllableData: $!\n"; + while (<SD>) { + next if /^\s*(#|$)/; + s/\s+$//; + ($code, $name, $syl) = split /; */; + next unless $syl; + push (@defs, ["IsSyl$syl", qq{\$syl eq "$syl"}, '']) + unless $seen{$syl}++; + } + close (SD); + return (@defs); +} + # eof diff --git a/lib/warnings.pm b/lib/warnings.pm index 11558d50d4..ac6d919954 100644 --- a/lib/warnings.pm +++ b/lib/warnings.pm @@ -60,7 +60,7 @@ will be used. =back -See L<perlmod/Pragmatic Modules> and L<perllexwarn>. +See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>. =cut diff --git a/lib/warnings/register.pm b/lib/warnings/register.pm index da6be97952..f98075a5ee 100644 --- a/lib/warnings/register.pm +++ b/lib/warnings/register.pm @@ -1,5 +1,13 @@ package warnings::register ; +=pod + +=head1 NAME + +warnings::register - warnings import function + +=cut + require warnings ; sub mkMask |