伦敦Perl和Raku研讨会将于2024年10月26日举行。如果您的公司依赖Perl,请考虑赞助和/或参加.
#--------------------------------------------------------------------------##这是.pm 0.9909版本的修改副本,专为#ExtUtils::Makemaker的使用及其对引导的依赖性#version.pm不可用。普通模块不应使用它。#--------------------------------------------------------------------------#包ExtUtils::MakeMaker::charstar;#在Perl中模拟C char*语义的小助手类#以便prescan_version可以使用与C中相同的代码使用过载('“”'=>\&thischar,“0+”=>\&thischar,'++'=>\&增量,“--”=>\&减量,“+”=>“+”,'-'=>\&减号,'*'=>乘法,“cmp”=>\&cmp,“<=>”=>太空船,“bool”=>\&thischar,'='=>\&克隆,);sub新{my($self,$string)=@_;my$class=ref($self)||$self;我的$obj={string=>[split(//,$string)],电流=>0,};返回祝福$obj,$class;}sub-thischar(子字符){my($self)=@_;我的$last=${$self->{string}};我的$curr=$self->{current};if($curr>=0&&$curr<=$last){返回$self->{字符串}->[$curr];}其他{返回“”;}}次增量{my($self)=@_;$self->{current}++;}减量{my($self)=@_;$自我->{当前}--;}次级加号{my($self,$offset)=@_;我的$rself=$self->克隆;$rself->{current}+=$offset;返回$rself;}减去{my($self,$offset)=@_;我的$rself=$self->克隆;$rself->{current}-=$offset;返回$rself;}次乘法{my($left,$right,$swapped)=@_;my$char=$left->thischar();返回$char*$right;}潜艇{my($left,$right,$swapped)=@_;除非(ref($right)){#已经不是对象$right=$left->new($right);}返回$left->{current}<=>$right->{current};}次级cmp{my($left,$right,$swapped)=@_;除非(ref($right)){#已经不是对象if(长度($right)==1){#仅比较单个字符返回$left->thischar cmp$right;}$right=$left->new($right);}return$left->currstr-cmp$right->curstr;}亚布尔{my($self)=@_;my$char=$self->thischar;返回($char ne“”);}子克隆{my($left,$right,$swapped)=@_;$右={string=>[@{$left->{string}}],当前=>$left->{current},};返回祝福$right,ref($left);}次级电流{my($self,$s)=@_;我的$curr=$self->{current};我的$last=${$self->{string}};if(定义的($s)&&$s->{current}<$last){$last=$s->{current};}我的$string=连接('',@{$self->{string}}[$cur..$last]);返回$string;}包ExtUtils::MakeMaker::version::vpp;使用5.006001;使用严格;使用警告;使用配置;使用vars qw($VERSION$CLASS@ISA$LAX$STRICT);$VERSION=“7.70”;$版本=~tr/_//d;$CLASS=“ExtUtils::MakeMaker::version::vpp”;需要ExtUtils::MakeMaker::version::regex;*ExtUtils::MakeMaker::version::vpp::is_strict=\&ExtUtils::MakeMaker::版本::regex::is_strict;*ExtUtils::MakeMaker::version::vpp::is_lax=\&ExtUtils::MakeMaker::版本::regex::is_nax;*LAX=\$ExtUtils::MakeMaker::version::regex::LAX;*STRICT=\$ExtUtils::MakeMaker::version::regex::STRICT;使用过载('“”'=>字符串,“0+”=>\&numify,'cmp'=>\&vcmp,“<=>”=>\&vcmp,'bool'=>\&vbool,'+'=>\&vnoop,'-'=>\&vnoop,'*'=>\&vnoop,'/'=>\&vnoop,'+='=>\&vnoop,'-='=>\&vnoop,'*='=>\&vnoop,'/='=>\&vnoop,“abs”=>vnoop,);eval“使用警告”;如果($@){评估'包裹警告;子启用{return$^W;}1;';}次级进口{没有严格的“参考”;my($class)=移位;#设置任何派生类除非($class eq$class){无警告;*{$class.'::声明'}=\&{$class.'::declare'};*{$class.'::qv'}=\&{$class.'::qv'};}我的%args;if(@_){#剩余的任何项都是参数映射{$args{$}=1}@_}else{#在使用行上根本没有参数%参数=(qv=>1,“通用::版本”=>1,);}我的$callpkg=调用者();if(存在($args{declare})){*{$callpkg.“::declare”}=sub{return$class->declare(shift)}除非已定义(&{$callpkg.'::declare'});}if(存在($args{qv})){*{$callpkg.'::qv'}=sub{return$class->qv(shift)}除非已定义(&{$callpkg。'::qv'});}if(存在($args{'UNIVERSAL::VERSION'})){无警告;*通用::版本=\&{$CLASS.'::_VERSION'};}if(存在($args{'VERSION'})){*{$callpkg.'::VERSION'}=\&{$CLASS.'::_VERSION'};}if(存在($args{'isstrict'}){*{$callpkg.'::is_strict'}=\&{$CLASS.'::is _strict'}除非已定义(&{$callpkg.'::is_strict'});}if(存在($args{'is_lax'}){*{$callpkg.'::is_max'}=\&{$CLASS.'::is _ max'}除非已定义(&{$callpkg.'::is_max'});}}我的$VERSION_MAX=0x7FFFFFFF;#尽可能靠近C版本实现prescan_version使用常量TRUE=>1;使用常量FALSE=>0;sub is数字{my($char)=shift->thischar();返回($char=~/\d/);}sub isALPHA公司{my($char)=shift->thischar();返回($char=~/[a-zA-Z]/);}子isSPACE{my($char)=shift->thischar();返回($char=~/\s/);}子BADVERSION{my($s,$errstr,$error)=@_;if($errstr){$$errstr=$error;}返回$s;}子预扫描版本{my($s,$strict,$errstr,$sqv,$ssaw_decimal,$swidth,$salpha)=@_;my$qv=定义的$sqv$$sqv:错误;my$saw_decimal=定义的$ssaw_decimal$$ssaw_decimal:0;my$width=定义的$swidth$$宽度:3;my$alpha=定义的$salpha$$salpha:错误;我的$d=$s;if($qv&&isDIGIT($d)){转到dotted_cimal_version;}if($d eq'v'){#显式v-string$d++;if(isDIGIT($d)){$qv=真;}else{#退化v-string#需要v1.2.3return BADVERSION($s,$errstr,“无效的版本格式(dotted-decimal版本至少需要三个部分)”);}dotted_decimal_version(dotted_decimal_version):if($strict&&$d等于“0”&&isDIGIT($d+1)){#不允许前导零return BADVERSION($s,$errstr,“版本格式无效(没有前导零)”);}while(isDIGIT($d)){#整数部分$d++;}if($d等式“.”){$saw_decimal++;$d++;#小数点}其他的{if($strict){#要求v1.2.3return BADVERSION($s,$errstr,“无效的版本格式(dotted-decimal版本至少需要三个部分)”);}其他{转到版本_重新扫描_完成;}}{我的$i=0;我的$j=0;while(isDIGIT($d)){#继续阅读$i++;while(isDIGIT($d)){$d++$j++;#小数点之间最多3位数如果($strict&&$j>3){return BADVERSION($s,$errstr,“版本格式无效(小数之间最多3位数字)”);}}如果($d等于‘_’){if($strict){return BADVERSION($s,$errstr,“版本格式无效(无下划线)”);}if($alpha){return BADVERSION($s,$errstr,“版本格式无效(多下划线)”);}$d++;$alpha=真;}elsif($d eq‘.’){if($alpha){return BADVERSION($s,$errstr,“版本格式无效(小数点前下划线)”);}$saw_decimal++;$d++;}elsif(!isDIGIT($d)){最后;}$j=0;}if($strict&&$i<2){#需要v1.2.3return BADVERSION($s,$errstr,“无效的版本格式(带点小数的版本至少需要三部分)”);}}}#end if dotted-decimal其他的{#十进制版本我的$j=0;#领先的特殊$strict案例或“0”if($strict){if($d等式“.”){return BADVERSION($s,$errstr,“版本格式无效(需要小数点前0)”);}if($d eq“0”&&isDIGIT($d+1)){return BADVERSION($s,$errstr,“版本格式无效(没有前导零)”);}}#我们从不支持负面版本号如果($d eq‘-’){return BADVERSION($s,$errstr,“版本格式无效(负版本号)”);}#消耗所有整数部分而(isDIGIT($d)){$d++;}#寻找一个分数部分if($d等式“.”){#我们找到了,就把它吃掉$saw_decimal++;$d++;}elsif(!$d||$d eq';'||isSPACE($d)||$d eq'}'){如果($d==$s){#什么都没找到return BADVERSION($s,$errstr,“无效的版本格式(需要版本)”);}#只找到一个整数转到版本_重新扫描_完成;}elsif($d==$s){#找不到整数或句点return BADVERSION($s,$errstr,“版本格式无效(非数字数据)”);}elsif($d eq‘_’){#整数部分后面不能有下划线if($strict){return BADVERSION($s,$errstr,“版本格式无效(无下划线)”);}elsif(isDIGIT($d+1)){return BADVERSION($s,$errstr,“版本格式无效(alpha不带小数)”);}其他{return BADVERSION($s,$errstr,“版本格式无效(下划线位置错误)”);}}elsif($d){#整数部分之后的任何其他内容都是无效数据return BADVERSION($s,$errstr,“版本格式无效(非数字数据)”);}#扫描小数点后的小数部分if($d&&!isDIGIT($d)&&($strict||!($d eq';'||isSPACE($d)||$d eq'}')){#$strict或lax-but-not-the-endreturn BADVERSION($s,$errstr,“版本格式无效(需要小数部分)”);}while(isDIGIT($d)){$d++$j++;if($d eq'.'和isDIGIT($d-1)){if($alpha){return BADVERSION($s,$errstr,“版本格式无效(小数点前下划线)”);}if($strict){return BADVERSION($s,$errstr,“版本格式无效(dotted-decimal versions必须以‘v’开头)”);}$d=$s;#重新开始$qv=真;转到dotted_cimal_version;}如果($d等于‘_’){if($strict){return BADVERSION($s,$errstr,“版本格式无效(无下划线)”);}if($alpha){return BADVERSION($s,$errstr,“版本格式无效(多下划线)”);}如果(!isDIGIT($d+1)){return BADVERSION($s,$errstr,“版本格式无效(下划线位置错误)”);}$width=$j;$d++;$alpha=真;}}}版本_重新扫描_完成:while(isSPACE($d)){$d++;}if($d&&!isDIGIT($d)&&(!($d eq';'|$d eq'}')){#尾随非数字数据return BADVERSION($s,$errstr,“版本格式无效(非数字数据)”);}if(定义为$sqv){$$sqv=$qv;}if(定义为$swidth){$$swidth=$width;}if(定义的$ssaw_decimal){$$ssaw_decimal=$saw_decimal;}if(定义为$salpha){$$salpha=$alpha;}返回$d;}子扫描_版本{my($s,$rv,$qv)=@_;我的$start;我的$pos;我的$last;我的$errstr;我的$saw_decimal=0;我的$width=3;my$alpha=FALSE;my$vinf=FALSE;我的@av;$s=新ExtUtils::MakeMaker::charstar$s;while(isSPACE($s)){#前导空格可以$s++;}$last=预扫描版本($s,FALSE,\$errstr,\$qv,\$saw_decimal,\$width,\$alpha);if($errstr){#“undef”是特殊情况,不是错误if($s ne‘undef’){需要鲤鱼;鲤鱼::嘎嘎($errstr);}}$start=$s;if($等于‘v’){$s++;}$pos=$s;if($qv){$$rv->{qv}=$qv;}if($alpha){$$rv->{alpha}=$alpha;}如果(!$qv&&$width<3){$$rv->{width}=$width;}while(isDIGIT($pos)){$位置++;}if(!isALPHA($pos)){我的$rev;用于(;;){$rev=0;{#这是用下划线分隔的atoi()我的$end=$pos;我的$mult=1;我的$orev;#以下if()只在小数点后为true#最初使用裸创建的版本的点#浮点数,即不以任何方式引用#如果(!$qv&&$s>$start&&$saw_decimal==1){$mult*=100;while($s<$end){$orev=$rev;$rev+=$s*$mult;$mult/=10;如果((abs($orev)>abs($rev))||(绝对值($rev)>$VERSION_MAX)){warn(“版本%d中的整数溢出”,$VERSION_MAX);$s=$end-1;$rev=$VERSION_MAX;$vinf=1;}$s++;如果($s eq'_'){$s++;}}}其他{while(--$end>=$s){$orev=$rev;$rev+=$end*$mult;$mult*=10;如果((abs($orev)>abs($rev))||(绝对值($rev)>$VERSION_MAX)){warn(“版本中整数溢出”);$end=$s-1;$rev=$VERSION_MAX;$vinf=1;}}}}#附加修订推送@av,$rev;如果($vinf){$s=$last;最后;}elsif($pos等式“.”){$s=++$pos;}elsif($pos eq“_”&&isDIGIT($pos+1)){$s=++$pos;}elsif($pos eq“,”&&isDIGIT($pos+1)){$s=++$pos;}elsif(isDIGIT($pos)){$s=$pos;}其他{$s=$pos;最后;}if($qv){while(isDIGIT($pos)){$位置++;}}其他{我的$数字=0;while((isDIGIT($pos)||$pos eq'_')&&$数字<3){if($位置'_'){$位数++;}$位置++;}}}}if($qv){引用的版本总是至少有三个术语我的$len=$#av;#这个for循环似乎触发了OSX上的编译器错误,因为#无限循环。是的,len是负数。不,这毫无意义。#有问题的编译器是:#gcc版本3.3 20030304(Apple Computer,Inc.构建1640)#对于(len=2-len;len>0;len--)#av_push(MUTABLE_av(sv),新SViv(0));#$len=2-$len;while($len-->0){按@av,0;}}#需要保存当前版本字符串以备以后使用如果($vinf){$$rv->{original}=“v.Inf”;$$rv->{vinf}=1;}elsif($s>$start){$$rv->{original}=$start->currstr($s);if($qv&&$saw_decimal==1&&$start ne‘v’){#需要插入v以保持一致$$rv->{original}='v'$$rv->{原始};}}其他{$$rv->{original}=“0”;推(@av,0);}#最后,将AV存储在散列中$$rv->{version}=\@av;#修复RT#19517-特殊情况“undef”作为字符串if($s eq‘undef’){$s+=5;}返回$s;}sub新{my$class=班次;除非(定义的$class或$#_>1){需要鲤鱼;鲤鱼::croak('用法:version::new(class,version)');}my$self=祝福({},ref($class)||$classes);my$qv=FALSE;if($#_==1){#必须是CVS-style$qv=真;}我的$value=pop;#总是最后一个元素if(ref($value)&&eval('$value->isa(“版本”)')){#可以直接复制元素$self->{version}=[@{$value->{version}];如果$value->{qv},$self->{qv}=1;$self->{alpha}=1,如果$value->{alfa};$self->{original}=''$value->{original};return$self;}if(未定义$value或$value=~/^undef$/){#RT#19517-undef比较的特殊情况#或者有人忘记传递值按@{$self->{version}},0;$self->{original}=“0”;返回($self);}if(ref($value)=~m/ARRAY|HASH/){需要鲤鱼;Carp::croak(“无效版本格式(非数字数据)”);}$value=_un_vstring($value);if($Config{d_setlocale}&&eval{requirePOSIX}){需要区域设置;my$currlocale=POSIX::setlocale(&POSIX::LC_ALL);#如果当前区域设置使用逗号作为小数点,我们#只需将逗号替换为小数位,而不是更改#区域设置if(POSIX::localeconv()->{decimal_point}eq','){$值=~tr/,/./;}}#指数记数法如果($value=~/\d+.?\d*e[-+]?\d+/){$value=sprintf(“%.9f”,$value);$value=~s/(0+)$//;#修剪尾随零}my$s=扫描版本($value,\$self,$qv);if($s){#必须是剩余的内容警告(“版本字符串“%s”包含无效数据;”.“忽略:'%s'”,$value,$s);}返回($self);}*parse=\&new;亚numify{my($self)=@_;除非(_verify($self)){需要鲤鱼;Carp::croak(“无效版本对象”);}my$width=$self->{width}|3;我的$alpha=$self->{alpha}||“”;我的$len=${$self->{version}};我的$digit=$self->{version}[0];my$string=sprintf(“%d”,$digit);对于(我的$i=1;$i<$len;$i++){$digit=$self->{version}[$i];if($width<3){我的$denom=10**(3-$width);我的$quot=int($digit/$denom);my$rem=$digital-($quot*$denom);$string.=sprintf(“%0”.$width.“d_%d”,$quot,$rem);}其他{$string.=sprintf(“%03d”,$digit);}}如果($len>0){$digit=$self->{version}[$len];if($alpha&&$width==3){$string.="_";}$string.=sprintf(“%0”.$width.“d”,$digit);}其他#$len=0{$string.=sprintf(“000”);}返回$string;}亚常态{my($self)=@_;除非(_verify($self)){需要鲤鱼;Carp::croak(“无效版本对象”);}我的$alpha=$self->{alpha}||“”;我的$len=${$self->{version}};我的$digit=$self->{version}[0];my$string=sprintf(“v%d”,$digit);对于(我的$i=1;$i<$len;$i++){$digital=$self->{版本}[$i];$string.=sprintf(“.%d”,$digit);}如果($len>0){$digit=$self->{version}[$len];if($alpha){$string.=sprintf(“_%0d”,$digit);}其他{$string.=sprintf(“.%0d”,$digit);}}如果($len<=2){对于($len=2-$len;$len!=0;$len--){$string.=sprintf(“.%0d”,0);}}返回$string;}亚串性{my($self)=@_;除非(_verify($self)){需要鲤鱼;Carp::croak(“无效版本对象”);}返回存在$self->{original}? $self->{original}:存在$self->{qv}? $自我->正常:$self->numify;}子vcmp{需要环球公司;my($left,$right,$swap)=@_;my$class=ref($left);除非(UNIVERSAL::isa($right,$class)){$right=$class->new($right);}if($swap){($left,$right)=($right,$left);}除非(_verify($left)){需要鲤鱼;Carp::croak(“无效版本对象”);}除非(_verify($right)){需要鲤鱼;Carp::croak(“无效版本格式”);}my$l=$#{$left->{version}};我的$r=${$right->{version}};我的$m=$l<$r$l:$r;我的$lalpha=$left->is_alpha;我的$ralpha=$right->是alpha;我的$retval=0;我的$i=0;while($i<=$m&&$retval==0){$retval=$left->{version}[$i]<=>$right->{版本}[$i];$i++;}#具有相同术语的alpha的tiebreaker如果($retval==0&&$l==$r&&$left->{version}[$m]==$right->{版本}[$m]&&($lalpha ||$ralpha){如果($lalpha&&!$ralpha){$retval=-1;}埃尔西夫($ralpha&&!$lalpha){$retval=+1;}}#可能的匹配,尾随0除外if($retval==0&&$l!=$r){如果($1<$r){while($i<=$r&&$retval==0){if($right->{version}[$i]!=0){$retval=-1;#毕竟不是一场比赛}$i++;}}其他{while($i<=$l&&$retval==0){if($left->{version}[$i]!=0){$retval=+1;#毕竟不是一场比赛}$i++;}}}返回$retval;}子vbool{my($self)=@_;return vcmp($self,$self->new(“0”),1);}sub-vnoop公司{需要鲤鱼;Carp::croak(“版本对象不支持操作”);}子is_alpha{my($self)=@_;return(存在$self->{alpha});}子qv{my$value=移位;my$class=$class;如果(@_){$class=ref($value)||$value;$value=移位;}$value=_un_vstring($value);$value=“v”$除非$value=~/(^v|\d+\.\d+\.\d)/;my$obj=$CLASS->new($value);返回祝福$obj,$class;}*声明=\&qv;子is_qv{my($self)=@_;return(存在$self->{qv});}订阅验证(_V){my($self)=@_;if(参考($self)&&eval{exists$self->{version}}&&ref($self->{version})eq“数组”) {返回1;}其他{返回0;}}子_非_字母数字{my$s=班次;$s=新的ExtUtils::MakeMaker::charstar$s;while(美元){如果isSPACE($s),则返回0;#提前退出返回1,除非(isALPHA($s)||isDIGIT($s)||$s=~/[.-]/);$s++;}返回0;}sub _ un _ v字符串{my$value=移位;#可能是v字串if(长度($value)>=3&$value!~/[._]/&&_非_字母数字($值){我的价值;如果(“$]”>=5.008_001){$t值=_find_magic_vstring($value);$value=$tvalue,如果长度为$tvalue;}elsif(“$]”>=5.006_000){$tvalue=sprintf(“v%vd”,$value);如果($t值=~/^v\d+(\.\d+){2,}$/){#必须是v字串$value=$t值;}}}返回$value;}sub _ find _ magic_v字符串{my$value=移位;my$t值=“”;要求B;我的$sv=B::svref_2object(\$value);my$magic=ref($sv)eq‘B::PVMG’$sv->魔法:未定义;while($magic){if($magic->类型eq‘V’){$t值=$magic->PTR;$t值=~s/^v?(.+)美元/v美元1/;最后;}其他{$magic=$magic->MOREMAGIC;}}返回$tvalue;}子版本(_V){my($obj,$req)=@_;my$class=ref($obj)||$obj;没有严格的“参考”;if(存在$INC{“$class.pm”},而不存在%{“$class\:”}和“$]”>=5.008){#文件但没有包需要鲤鱼;Carp::croak(“$class既没有定义包也没有定义版本”.“--版本检查失败”);}my$version=eval“\$$class\::version”;if(定义的$version){如果“$]”<=5.008,则为本地$^W;$version=ExtUtils::MakeMaker::version::vpp->new($version);}if(定义$req){除非(定义的$版本){需要鲤鱼;我的$msg=“$]”<5.006? “需要$class版本$req--这是唯一的版本”:“$class未定义\$$class\::VERSION”.“--版本检查失败”;if($ENV{VERSION_DEBUG}){鲤鱼::坦白($msg);}其他{鲤鱼::croak($msg);}}$req=ExtUtils::MakeMaker::version::vpp->new($req);如果($req>$version){需要鲤鱼;if($req->isqv){鲤鱼::嘎嘎(sprintf(“需要%s版本%s--”)。“这只是版本%s”,$class,$req->正常,$version->正常));}其他{鲤鱼::呱呱(sprintf(“需要%s版本%s--”)。“这只是版本%s”,$class,$req->stringify,$version->strigify));}}}返回定义的$version$版本->字符串:undef;}1; #这一行很重要,它将帮助模块返回一个真值