charnames.pm

来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PM 代码 · 共 550 行 · 第 1/2 页

PM
550
字号
package charnames;use strict;use warnings;use File::Spec;our $VERSION = '1.06';use bytes ();		# for $bytes::hint_bitsmy %alias1 = (		# Icky 3.2 names with parentheses.		'LINE FEED'		=> 'LINE FEED (LF)',		'FORM FEED'		=> 'FORM FEED (FF)',		'CARRIAGE RETURN'	=> 'CARRIAGE RETURN (CR)',		'NEXT LINE'		=> 'NEXT LINE (NEL)',		# Convenience.		'LF'			=> 'LINE FEED (LF)',		'FF'			=> 'FORM FEED (FF)',		'CR'			=> 'CARRIAGE RETURN (CR)',		'NEL'			=> 'NEXT LINE (NEL)',	        # More convenience.  For futher convencience,	        # it is suggested some way using using the NamesList		# aliases is implemented.	        'ZWNJ'			=> 'ZERO WIDTH NON-JOINER',	        'ZWJ'			=> 'ZERO WIDTH JOINER',		'BOM'			=> 'BYTE ORDER MARK',	    );my %alias2 = (		# Pre-3.2 compatibility (only for the first 256 characters).		'HORIZONTAL TABULATION'	=> 'CHARACTER TABULATION',		'VERTICAL TABULATION'	=> 'LINE TABULATION',		'FILE SEPARATOR'	=> 'INFORMATION SEPARATOR FOUR',		'GROUP SEPARATOR'	=> 'INFORMATION SEPARATOR THREE',		'RECORD SEPARATOR'	=> 'INFORMATION SEPARATOR TWO',		'UNIT SEPARATOR'	=> 'INFORMATION SEPARATOR ONE',		'PARTIAL LINE DOWN'	=> 'PARTIAL LINE FORWARD',		'PARTIAL LINE UP'	=> 'PARTIAL LINE BACKWARD',	    );my %alias3 = (		# User defined aliasses. Even more convenient :)	    );my $txt;sub croak{  require Carp; goto &Carp::croak;} # croaksub carp{  require Carp; goto &Carp::carp;} # carpsub alias (@){  @_ or return %alias3;  my $alias = ref $_[0] ? $_[0] : { @_ };  @alias3{keys %$alias} = values %$alias;} # aliassub alias_file ($){  my ($arg, $file) = @_;  if (-f $arg && File::Spec->file_name_is_absolute ($arg)) {    $file = $arg;  }  elsif ($arg =~ m/^\w+$/) {    $file = "unicore/${arg}_alias.pl";  }  else {    croak "Charnames alias files can only have identifier characters";  }  if (my @alias = do $file) {    @alias == 1 && !defined $alias[0] and      croak "$file cannot be used as alias file for charnames";    @alias % 2 and      croak "$file did not return a (valid) list of alias pairs";    alias (@alias);    return (1);  }  0;} # alias_file# This is not optimized in any way yetsub charnames{  my $name = shift;  if (exists $alias1{$name}) {    $name = $alias1{$name};  }  elsif (exists $alias2{$name}) {    require warnings;    warnings::warnif('deprecated', qq{Unicode character name "$name" is deprecated, use "$alias2{$name}" instead});    $name = $alias2{$name};  }  elsif (exists $alias3{$name}) {    $name = $alias3{$name};  }  my $ord;  my @off;  my $fname;  if ($name eq "BYTE ORDER MARK") {    $fname = $name;    $ord = 0xFEFF;  } else {    ## Suck in the code/name list as a big string.    ## Lines look like:    ##     "0052\t\tLATIN CAPITAL LETTER R\n"    $txt = do "unicore/Name.pl" unless $txt;    ## @off will hold the index into the code/name string of the start and    ## end of the name as we find it.    ## If :full, look for the name exactly    if ($^H{charnames_full} and $txt =~ /\t\t\Q$name\E$/m) {      @off = ($-[0], $+[0]);    }    ## If we didn't get above, and :short allowed, look for the short name.    ## The short name is like "greek:Sigma"    unless (@off) {      if ($^H{charnames_short} and $name =~ /^(.+?):(.+)/s) {	my ($script, $cname) = ($1, $2);	my $case = $cname =~ /[[:upper:]]/ ? "CAPITAL" : "SMALL";	if ($txt =~ m/\t\t\U$script\E (?:$case )?LETTER \U\Q$cname\E$/m) {	  @off = ($-[0], $+[0]);	}      }    }    ## If we still don't have it, check for the name among the loaded    ## scripts.    if (not @off) {      my $case = $name =~ /[[:upper:]]/ ? "CAPITAL" : "SMALL";      for my $script (@{$^H{charnames_scripts}}) {	if ($txt =~ m/\t\t$script (?:$case )?LETTER \U\Q$name\E$/m) {	  @off = ($-[0], $+[0]);	  last;	}      }    }    ## If we don't have it by now, give up.    unless (@off) {      carp "Unknown charname '$name'";      return "\x{FFFD}";    }    ##    ## Now know where in the string the name starts.    ## The code, in hex, is before that.    ##    ## The code can be 4-6 characters long, so we've got to sort of    ## go look for it, just after the newline that comes before $off[0].    ##    ## This would be much easier if unicore/Name.pl had info in    ## a name/code order, instead of code/name order.    ##    ## The +1 after the rindex() is to skip past the newline we're finding,    ## or, if the rindex() fails, to put us to an offset of zero.    ##    my $hexstart = rindex($txt, "\n", $off[0]) + 1;    ## we know where it starts, so turn into number -    ## the ordinal for the char.    $ord = CORE::hex substr($txt, $hexstart, $off[0] - $hexstart);  }  if ($^H & $bytes::hint_bits) {	# "use bytes" in effect?    use bytes;    return chr $ord if $ord <= 255;    my $hex = sprintf "%04x", $ord;    if (not defined $fname) {      $fname = substr $txt, $off[0] + 2, $off[1] - $off[0] - 2;    }    croak "Character 0x$hex with name '$fname' is above 0xFF";  }  no warnings 'utf8'; # allow even illegal characters  return pack "U", $ord;} # charnamessub import{  shift; ## ignore class name  if (not @_) {    carp("`use charnames' needs explicit imports list");  }  $^H{charnames} = \&charnames ;  ##  ## fill %h keys with our @_ args.  ##  my ($promote, %h, @args) = (0);  while (my $arg = shift) {    if ($arg eq ":alias") {      @_ or	croak ":alias needs an argument in charnames";      my $alias = shift;      if (ref $alias) {	ref $alias eq "HASH" or	  croak "Only HASH reference supported as argument to :alias";	alias ($alias);	next;      }      if ($alias =~ m{:(\w+)$}) {	$1 eq "full" || $1 eq "short" and	  croak ":alias cannot use existing pragma :$1 (reversed order?)";	alias_file ($1) and $promote = 1;	next;      }      alias_file ($alias);      next;    }    if (substr($arg, 0, 1) eq ':' and ! ($arg eq ":full" || $arg eq ":short")) {      warn "unsupported special '$arg' in charnames";      next;    }    push @args, $arg;  }  @args == 0 && $promote and @args = (":full");  @h{@args} = (1) x @args;  $^H{charnames_full} = delete $h{':full'};  $^H{charnames_short} = delete $h{':short'};  $^H{charnames_scripts} = [map uc, keys %h];  ##  ## If utf8? warnings are enabled, and some scripts were given,  ## see if at least we can find one letter of each script.  ##  if (warnings::enabled('utf8') && @{$^H{charnames_scripts}}) {    $txt = do "unicore/Name.pl" unless $txt;    for my $script (@{$^H{charnames_scripts}}) {      if (not $txt =~ m/\t\t$script (?:CAPITAL |SMALL )?LETTER /) {	warnings::warn('utf8',  "No such script: '$script'");      }    }  }} # importmy %viacode;sub viacode{  if (@_ != 1) {    carp "charnames::viacode() expects one argument";    return;  }  my $arg = shift;  # this comes actually from Unicode::UCD, where it is the named  # function _getcode (), but it avoids the overhead of loading it  my $hex;  if ($arg =~ /^[1-9]\d*$/) {    $hex = sprintf "%04X", $arg;  } elsif ($arg =~ /^(?:[Uu]\+|0[xX])?([[:xdigit:]]+)$/) {    $hex = $1;  } else {    carp("unexpected arg \"$arg\" to charnames::viacode()");    return;  }  # checking the length first is slightly faster  if (length($hex) > 5 && hex($hex) > 0x10FFFF) {    carp "Unicode characters only allocated up to U+10FFFF (you asked for U+$hex)";    return;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?