字符串操作符 .用于连接字符串 use warning 开启per内置的警告信息,或者用-w参数 use diagnostics 查看更多编译信息或者用-Mdiagnostics参数
读到文件结尾end-of-line时,返回undef标志,用defined函数是否是undef状态。 标量都是单数(singular),列表与数组代表复数(plural) 列表(list)指的是标量的有序集合,而数组(array)则是存储列表的变量 或者说列表指的是数据,而数组指的是变量
$rocks[$#rocks] $rocks[-1]等效 都指最后一个
("aaa","bbb","ccc","ddd") qw(aaa,bbb,ccc,ddd)两等效
Perl允许使用任何标点符号作为定界符,常用的有: qw! aaa bbb ccc ddd ! qw/ aaa bbb ccc ddd / qw# aaa bbb ccc ddd #
@arrayname 引用整个数组 push-pop操作数组尾和shift-unshift操作数组首 splice @array = qw(aaa,ddd,eee); @removed = splice @array,2; #@removed变成qw(ccc,ddd) #@array变成qw(aaa,bbb)
foreach(1..10){ print "this num is $_!n"# $_ 默认变量 }
state来声明为当前子程序的持有性私有变量,并且多次调用这个子程序期间保留该变量的值。
chomp;#不加参数,默认用默认参数$_
@ARGV #命令行默认参数
6个特殊文件句柄是Perl保留的,STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT
数组用方括号,哈希用花括号 $hash{ 'index1' } = 'index1value';
哈希函数 $reverhash = revers %hash my @k = keys %hash; my @v = values %hash; while(($key,$value) = each %hash) {} exists/delete
%ENV print "PATH is $ENV{PATH}n"
正则表达式 $_ = "yabba dabba doo"; if( /abba/ ) {..}
Unicode属性,Unicode字符能够理解自身含义,它们包含字节组合之外,还附带着属性信息。 if(/q{Space}/){} if(/q{Digit}/){}
元字符 点号(.)是能匹配任意一个字符的通配符,换行符除外。 /3.14159/这个模式中点号就不是表示通配的元字符 星号(*)正是用来匹配前面的条目零次或任意多次的 /abbt*bbb/匹配abbtbbb abbttbbb /aaa.*bbb因此会匹配任意字符零次到无限多次 加号(+)也是量词,会匹配前一个条目一次以上 问号(?),前面条目可出现一次或不出现 模式分组 /fred*/匹配freddddd /(fred)*/ 匹配fredfred 反向引用来引用圆括号中的模式所柳丁的文字,这个行为我们称为捕获组, 比如12表示相应顺序的捕获组 $_ = "abb"; if(/(.)1/){}#匹配 ‘bb' /y(.)(.)21/ #匹配’abba' “aa11bb" 111是指111,而不是1或11, Perl尽可能往多的原则靠 if(/(.)g{1}11/)指1解决反引用与直接量部分的二义性 if(/(.)111/)指111 if(/(.)(.)g{-1}11/相对自己的位置来找编号 择一匹配 /fred(|t)+barney/ 字符集,指的是一组可能出现的字符,通过写在方括号([])内表示。 [abcwxyx]匹配7个字符内任意一个 [ 00-177] 将匹配任意一个7位的ASCII字符 [^def]会匹配这三个字符以外的任何字符^ 脱字符
字符集的简写 比如表示任意一个数字的字符集的简写是d s简写能匹配任意空白符,所以效果上大抵等同于Unicode属性p{Space} Perl5.6之前,s仅能匹配5个 换页符,水平制表符,换行符,回车符,空格 h只匹配水平空白符 v只匹配垂直空白符 R简写能匹配任意一种断行符 w能匹配的字符并不是严格意义上的单词字符 [^d],[^w],[^s] 非数字,非单词或者非空白符 [D],[W],[S] 大写版本表示否定意义
[dD],表示任何数字或非数字,也就是匹配任意字符(包含换行符),而点号不匹配换行符
正则表达式进行匹配 用m//进行匹配 /i进行大小写无关的匹配 /s匹配任意字符 点号无法匹配换行符,对单行点号就适用了 $_ = "I saw Barneyndown at the bowling alleynwith frednlast night.n" if(/Barney.*Fred/s){}没有/s修饰符,匹配会失败。 /x加入空白符 /-?[0-9]+.?[0-9]*/ / -? [0-9]+ .? [0-9]* /x#这样便于阅读,理解,但原来的空白和制表本身需要用空格和t 组合选项修饰符 if(/barney.*fred/is){}
三种字符解释方式:ASCII(/a),Unicode(/u)和locale(l),locale经常会引发问题。
锚位,可以让模式仅在字符串指定位置匹配。 A锚位匹配字符串的绝对开头,如果开头位置不匹配,是不会顺移到下一个位置继续尝试的。 m{Ahttps?://}i#判断字符串是否以https开头 m{.pngz}i#匹配以.png结尾的
字符串的绝对末尾,强调后面再无任何其他东西。 Z允许后面出现换行符 while(<STDIN>){ print if /.pngZ/; }
while(<STDIN>){ chomp; print "$_n" if /.pngz/; }
可以用$锚位和/m修饰符表示对多行内容进行匹配。 /fred$/m 单词锚位 /bfredb/可匹配fred,但无法匹配frederick,alfred,manfredss。b是单词边界锚位,也称为”整词匹配“
绑定操作符=~ 默认情况下模式匹配的操作对象是$_,绑定操作符(=~) 告诉perl用右边的模式来匹配左边的字符串。
模式中的内插 my $what = "larry"; while(<>){#每次读一行输入 if(/A($what)/){#模式的锚位被定在字符串的开头 print "We saw $what in beginning of $_"; } } 除非while循环的条件表达式中只有整行输入操作符(<STDIN>),否则输入行不会被 PERL自动存入$_.
捕获变量 捕获组会把匹配圆括号中模式的字符串保存到相应的地方$1,$2,$3
$_ = "Hello there,neighbor"; if(/(S+) (S+),(S+)/){ print "word were $1 $2 $3n"; } 运行结果是:words were Hello there neighbor. 捕获变量的存续期, 它们能戚到下次成功匹配为止。失败的匹配不会改动上次成功匹配时捕获的内容。
不捕获模式:用?:修饰的圆括号不会将捕获部分的匹配字符串放到捕获变量中 if(/(?:bronto)?saurs (steak|burger){ print "Fred wants a $1n"; }
命名捕获 my $names = 'Fred or Barney'; if( $names =~ m/(?<name1>w+) (?:and|or) (?<name2>w+/){ say "i saw $+{name1} and $+{name2}"; }
自动捕获变量:$&,$`,$'免费但影响运行速度 字符串里实际匹配模式的部分会被自动在存进$&里 if( "Hello there,neighbor" =~ /s(w+),/){ print "That actually matched '$&'.n"; } $1保存there $&保存there, 匹配区段之前的内容会存到$`里,匹配区段之后的内容则会存到$'里
用/p修饰符则可用${^PREMATCH},${^MATCH}和${^POSTMATCH}表示。
用正则表达式处理文本 用s///进行替换 $_ = "He's out bowling with Barney tonight."; s/Barney/Fred/;#把Barney替换为Fred print "$_n";
s/Barney/Fred/g;#/g 全局替换 my @filelds = split /separator/,$string; my @fields = split /:/,"abc:def:g:h";#得到("abc","def","g","h")
join函数功能与split相反 my $result = join $glue,@pieces; my $x = join ":",4,6,8,10,12;# $x为"4:6:8:10:12"
$_ = "Hello there,neighbor"; my($first,$second,$third) = /(S+) (S+),(S+)/; print "$second is my $thirdn";
贪婪量词 /fred.+barney/#要求能匹配的字符串越长越好 非贪婪量词 /fred.+?barney/#要求能匹配的字符串越短越好
if(flag){...}#flag为真时才执行 unless(flag){...}#flag为假时才执行
while(flag){...}#flag为真时才执行 until(flag){...}#flag为假时才执行
last操作符能立即中止循环的执行,相当C语言中的"break" next相当continue redo操作符返回到当前循环块的顶端,而不经过任何条件测试,也不会进入下一次循环迭代。
LINE:while(<>){ foreach(split){ last LINE if /__END__/; ... } }
die "Oops! A file called '$filename' already exist.n" if -e $filename;
PERL 模块 perldoc CGI 打开模块文档 perl自带cpan命令查看所有模块: $cpan -a
模块使用MakeMaker $perl Makefile.PL $make install
使用Module::Build $perl Build.PL $./Build install
perl自带的path::class模块则提供了更友好的操作界面: my $dir=dir( qw(Users fred lib) ); my $subdir= $dir ->subdir( 'perl5' );# Users/fred/lib/perl5
DateTime处理日期和时间的模块
chdir操作符来改变当前的工作目录
my @all_files = <*>; my @all_files = glob "*";
Perl里面,可以使用unlink操作符,并指定要删除的文件列表。 rename函数 chmod函数类似unix的chmod命令 chmod 0755,'fred','barney';
字符串与排序 $where = index($big,$small); $big = "Howdy world!"; $where = index($big,"wor");# $where is 6
my $part = substr($string,$initial_position,$length); 省略第三参数将取到字符串结尾 $initial_position 负数表示从后数起 substr($string,-20) =~ s/fred/barney/g;# 将后面20字符所有fred换成barney
sprintf函数与printf有相同的参数 my $date_tag = sprintf "%4d/%02d",$yr,$mo;
hex('DEA') oct('0377')
智能匹配 use 5.010001 say "I found Fred in the name!" if $name ~~ /Fred/; 等价以下: my $flag = 0; foreach my $key (keys %names ){ next unless $key =~ /Fred/; $flag = $key; last; } print "I found Fred in the name!" if $flag;
given-when类似switch
given ( $ARGV[0] ){ when ( 'Fred' ){say 'Name is Fred' } when ( /fred/i ){say 'Name has fred in it' } defalut{say 'ss'} }
进程管理 system 'date'; # perl调用unix的date命令。 exec
捕获错误 eval { $barney = $fred / $dino }; eval只是一个表达式,末尾加”;" 捕获到错误eval将返回undef,如果没有错误发生,$@就是空的 exit操作符会立即终止程度运行。
异常机制 die抛出异常 eval { ...; die "An unexpected exception message" if $unexpected; die "Bad denominator" if $dino == 0; $barney = $fred / $dino; } if( $@ =~ /unexpected/ ){ ...; } elsif( $@ =~ /denominator/ ){ ...; }
{ local $@;#不干扰高层错误 ... }
foreach( 1..1000){ push @odd_numbers,$_ if $_ % 2; } 等价 my @odd_numbers = grep { $_ % 2 } 1..1000;
my @matching_lines = grep /bfredb/i,<$fh>; my $line_count = @matching_lines;
my $line_count = grep /bfredb/i,<$fh>;
<!ELEMENT NXRMClientConfiguration (LocationArray,Log)> <!ATTLIST NXRMClientConfiguration SchemaVersion CDATA #REQUIRED> <!ATTLIST NXRMClientConfiguration SN CDATA #REQUIRED> <!ATTLIST NXRMClientConfiguration Name CDATA #REQUIRED> <!ATTLIST NXRMClientConfiguration UpdateDate CDATA #REQUIRED> <!ELEMENT LocationArray (Location+)> <!ELEMENT Location (#PCDATA)> <!ATTLIST Location Name CDATA #Default> <!ATTLIST Location Desc CDATA #REQUIRED> <!ELEMENT Log (#PCDATA)> <!ATTLIST Log MaxLogSize CDATA #REQUIRED>
#!/usr/bin/perl -w
#this sub function parser sub elment #usage: #$result = [];$subelement = "(A | (B,(C | (D,E))) | F)"; #Subelementparser($result,$subelement); #return $result = AB,CB,D,EF sub Subelementparser{ my($res,$temp)=@_; my($prematch,$match,$postmatch); my(@items); $temp =~ s/s*//g;# delete space $temp =~ s/^((.*))$/$1/e;#delete outside bracket
unless($temp =~ /(/){#case inside bracket if($temp =~ /|/){ @items = split(/|/,$temp); foreach (@items){ push @$res,$_; } } else{ push @$res,$temp; } } else{#case:there exist is one or more bracket $temp =~ m/((.*))/; $prematch = ${^PREMATCH}; $match = ${^MATCH}; $postmatch = ${^POSTMATCH}; $flag = "false"; if($prematch =~ /,/){ $flag = "true"; } if($flag =~ /true/){#case: B,(D|E) my($tempres) = []; Subelementparser($tempres,$match); foreach (@$tempres){ push @$res,"${prematch}$_";# $prematch = "B," } } else{ @items = split(/|/,$prematch); foreach (@items){ push @$res,"$_"; } if($match =~ /./){ Subelementparser($res,$match); } } @items = split(/|/,$postmatch); foreach (@items){ if(/./){ push @$res,$_; } } } }
sub ProcElement { my($cname,$expan)=@_; my($cinterdef,$cimpheader,$cimpcpp); my($construc,$parser); my($mem); my($headerfile,$class_name);
my($subelements) = []; Subelementparser($subelements,$expan);
# here start generate .h file without attribute part and } end part $cinterdef = "// <!ELEMENT ${cname} ${expan}>n"; $cinterdef .= "class I$cnamen{npublic:n"; $cinterdef .= "tvirtual bool WriteToXML(const std::string& XMLPath) = 0;n"; $cinterdef .= "tvirtual bool ReadFromXML(const std::string& XMLPath) = 0;n"; $cinterdef .= "tvirtual void Reset(void) = 0;n"; $cinterdef .= "tvirtual void Release(void) = 0;nn"; $construc = ""; $cimpheader = "class $cname : public I$cnamen{npublic:n"; $cimpheader .= "t$cname(void);n"; $cimpheader .= "t$cname(const Node& node);n"; $cimpheader .= "t~$cname(void);n"; $cimpheader .= "tbool WriteToXML(const std::string& XMLPath);n"; $cimpheader .= "tbool ReadFromXML(const std::string& XMLPath);n"; $cimpheader .= "tvoid Reset(void);n"; $cimpheader .= "tvoid Release(void);nn";
$cimpcpp = "${cname}::${cname}() : m_node(Node())n{ntm_node.SetNodeName("${cname}");n}nn"; $cimpcpp .= "${cname}::${cname}(const Node& node) : m_node(node)n{ntm_node.SetNodeName("${cname}");n}nn"; $cimpcpp .= "${cname}::~${cname}(void)n{n}nn"; $cimpcpp .= "bool ${cname}::WriteToXML(const std::string& XMLPath)n{ntreturn m_node.Print(XMLPath);n}nn"; $cimpcpp .= "bool ${cname}::ReadFromXML(const std::string& XMLPath)n{ntm_node = Node(XMLPath);ntreturn true;n}nn"; $cimpcpp .= "void ${cname}::Reset(void)n{ntm_node = Node();ntm_node.SetNodeName("${cname}");n}nn"; $cimpcpp .= "void ${cname}::Release(void)n{ntdelete this;n}nn"; foreach (@$subelements){ @subclass = split(/,/,$_); #$cdef .= "t$cname("; #$flag = "false"; foreach $mem (@subclass){ if($mem =~ /[?*+]/){ $mem =~ s/[*+?]//g; $cinterdef .= "t//Element $memn"; $cinterdef .= "tvirtual unsigned int GetElem${mem}(void) = 0;n"; $cinterdef .= "tvirtual I${mem}* GetElem${mem}At(unsigned int index) = 0;n"; $cinterdef .= "tvirtual void AddElem${mem}(I${mem}* NewElem) = 0;n"; $cinterdef .= "tvirtual void AddElem${mem}At(unsigned int index,I${mem}* NewElem) = 0;n"; $cinterdef .= "tvirtual void RemoveElem${mem}At(unsigned int index) = 0;n"; $cinterdef .= "tvirtual void RemoveAllElem${mem}(void) = 0;nn"; $cimpheader .= "t//Element $memn"; $cimpheader .= "tunsigned int GetElem${mem}(void);n"; $cimpheader .= "tI${mem}* GetElem${mem}At(unsigned int index);n"; $cimpheader .= "tvoid AddElem${mem}(I${mem}* NewElem);n"; $cimpheader .= "tvoid AddElem${mem}At(unsigned int index,I${mem}* NewElem);n"; $cimpheader .= "tvoid RemoveElem${mem}At(unsigned int index);n"; $cimpheader .= "tvoid RemoveAllElem${mem}(void);nn"; $cimpcpp .= "//Element $memn"; $cimpcpp .= "unsigned int ${cname}::GetElem${mem}(void)n{ntreturn m_node.NumChilds();n}nn"; $cimpcpp .= "I${mem}* ${cname}::GetElem${mem}At(unsigned int index)n{n"; $cimpcpp .= "t${mem} *temp = NULL;ntunsigned int total = m_node.NumChilds();ntif(index < total)nt{n"; $cimpcpp .= "tttemp = new ${mem}(m_node.GetChildAt(index));nt}ntreturn temp;n}nn"; $cimpcpp .= "void ${cname}::AddElem${mem}(I${mem}* NewElem)n{ntm_node.AppendChild(static_cast<${mem}*>(NewElem)->m_node);n}nn"; $cimpcpp .= "void ${cname}::AddElem${mem}At(unsigned int index,I${mem}* NewElem)n{ntm_node.AppendChildAt(index,static_cast<${mem}*>(NewElem)->m_node);n}nn"; $cimpcpp .= "void ${cname}::RemoveElem${mem}At(unsigned int index)n{ntm_node.RemoveChildAt(index);n}nn"; $cimpcpp .= "void ${cname}::RemoveAllElem${mem}(void)n{ntm_node.RemoveChilds();n}nn"; } elsif($mem =~ /#PCDATA/){ } else{ $cinterdef .= "t//Element $memn"; $cinterdef .= "tvirtual I${mem}* GetElem${mem}(void) = 0;n"; $cinterdef .= "tvirtual void SetElem${mem}(I${mem}* ElemName) = 0;nn"; $cimpheader .= "t//Element $memn"; $cimpheader .= "tI${mem}* GetElem${mem}(void);n"; $cimpheader .= "tvoid SetElem${mem}(I${mem}* ElemName);nn"; $cimpcpp .= "//Element $memn"; $cimpcpp .= "I${mem}* ${cname}::GetElem${mem}(void)n{ntreturn new ${mem}(m_node.GetFirstChild());n}nn"; $cimpcpp .= "void ${cname}::SetElem${mem}(I${mem}* ElemName)n{ntm_node.AppendChild(static_cast<${mem}*>(ElemName)->m_node);n}nn"; } } } my(%hash) = (); undef %hash; foreach (@$subelements){ @subclass = split(/,$_); foreach $mem (@subclass){ if(/#PCDATA/){ #$cdef .= "tvoid addData( const std::string& data );n"; } else{ unless(exists( $hash{ $mem} )) { #$cdef .= "tvoid addNode( $mem *the_$mem );n"; $mem =~ s/[*+?]//g; $headerfile .= "#include "${mem}.h"n"; $class_name .= "class I${mem};n"; $hash{$mem} = 1; } } } } if($rootflag =~ /false/) { $construc .= "nconst char* dtdData = "$tempdtd";nn"; #$cdef .= "tbool Validate() const;n"; #$cdef .= "t$cname(const std::string& XMLFile);n"; } #$cdef .= "};nn";#wait for attribute # here start generate .cpp file
undef %hash; foreach (@$subelements){ $construc .= "${cname}::${cname}("; @subclass = split(/,$_); $flag = "false"; foreach $mem (@subclass){ if( $flag =~ /true/ ){ $construc .= ","; } if(/#PCDATA/){ $construc .= " const std::string& data"; $parser.= "void ${cname}::addData(const std::string& data)n{n"; $parser .= "tSetData(data);n}nn"; } else{ $construc .= " $mem *the_$mem"; unless(exists( $hash{ $mem} )) { $parser.= "void ${cname}::addNode($mem *the_$mem)n{n"; $parser.= "tAppendChild(*the_$mem);n}nn"; $hash{$mem} = 1; } } if( $flag =~ /false/ ){ $flag = "true"; } } if($rootflag =~ /false/) { $parser .= "bool ${cname}::Validate() constn{n"; $parser .= "treturn ValidateDTD(dtdData);n"; $parser .= "}nn"; $parser .= "${cname}::${cname}(const std::string& XMLFile):Node(XMLFile)n{n"; $parser .= "}nn"; $rootflag = "true"; } $construc .= " ):Node()n{n"; $construc .= "tSetNodeName("${cname}");n"; foreach $mem (@subclass){ if(/#PCDATA/){ $construc .= "taddData(data);n"; } else{ $construc .= "tAppendChild(*the_$mem);n"; } } $construc .= "}nn"; }
push(@classes,$cname); $interfacefile{ $cname } = $cinterdef; $implementheaderfile{ $cname } = $cimpheader; $implementcppfile { $cname } = $cimpcpp; #$constructors{ $name } = $construc; #$parsersvec{ $name } = $parser; $headerlist{ $cname } = $headerfile; $classdeflist{ $cname } = $class_name; }
sub ProcAttList { my($name,$attribs)=@_; my($attrib,$atype,$ctype,$condit,$options,$deft); my(@options); my($builder); my($elemtype,$arrlen,$subparse,$req);
die "ATTLIST $name without ELEMENTn" if(!defined($interfacefile{ $name }));
# bin some whitespace $attribs =~ s/^s*//; $attribs =~ s/s*$//;
while(1){ if($attribs =~ /^(w+)s+(w+)s+#(w+)s*(.*)/){# basic; whatever type $attrib=$1; $atype=$2; $condit=$3; $attribs=$4;
$interfacefile{ $name} .= "t//Get/Set functions for attribute $attribn"; $interfacefile{ $name} .= "tvirtual std::string Get$attrib(void) = 0;n"; $interfacefile{ $name} .= "tvirtual void Set$attrib( const std::string& value ) = 0;n"; $implementheaderfile{ $name} .= "t//Get/Set functions for attribute $attribn"; $implementheaderfile{ $name} .= "tstd::string Get$attrib(void);n"; $implementheaderfile{ $name} .= "tvoid Set$attrib( const std::string& value );n"; $implementcppfile{ $name} .= "//Get/Set functions for attribute $attribn"; $implementcppfile{ $name} .= "std::string ${name}::Get$attrib(void)n{ntreturn m_node.GetAttribute("$attrib");n}nn"; $implementcppfile{ $name} .= "void ${name}::Set$attrib( const std::string& value )n{ntm_node.SetAttribute("$attrib",value);n}nn"; $builder .= "void ${name}::Set$attrib( const std::string& value ){ntSetAttribute("$attrib",value);n}nn";
#$attributparser{ $name } .= $builder; } else{ last; } } }
# dtd on command line $flag = "false"; $dtdf = undef(); my($curdir) = `pwd`; chomp($curdir); my($outdir) = undef();
my($cppfilename) = "xml_nxl";
$count = @ARGV; if($count == 1){ if($ARGV[0] =~ m{.dtdz}i){ $dtdf = $ARGV[0]; } else{ $flag = "true"; } } elsif($count == 3){ if($ARGV[0] =~ m{A-o}i){ $outdir = $ARGV[1]; $dtdf = $ARGV[2]; } else{ $flag = "true"; } } else{ $flag = "true"; }
die "Usage: dtd2cpp.pl [switches] <document> -o <directory> Outputdir - specify output directory -h Help - Show Class Generator usage helpn" if ($flag =~ /true/);
if(defined($outdir)){ die "the directory ${outdir} don't exist!!!n" unless(-e ${outdir}); if($outdir =~ m{/z}){ mkdir "${outdir}/include",0700; mkdir "${outdir}/src",0700; } else{ mkdir "${outdir}/include",0700; } } else{ if($dtdf =~ /(.*)/(.*)/){ $outdir = $1; mkdir "${outdir}/include",0700; } else{ $outdir = $curdir; mkdir "${outdir}/include",0700; } }
# input filename open(DTD,$dtdf) || die "can't read $dtdf: $!n"; $dtd=join('',<DTD>); close(DTD);
$namespacename = "NxconInterface"; @classes=();
%interfacefile=(); %implementheaderfile=(); %implementcppfile=();
#%constructors=(); #%attributparser=(); #%parsersvec=(); #%headerlist=(); %classdeflist=();
$rootflag = "false";
sub GenerateTargetFile{ my($oriname)=@_; my($intername) = (); my($headername) = (); my($cppname) = ();
# here generate interface header file $intername = "I$oriname"; open (${intername},">${intername}.h") || die "Can't write ${intername}.h: $!n"; print ${intername} "// this is generated code,do not editn"; print ${intername} "#pragma oncenn"; print ${intername} "#include <string>nn"; #print ${name} "#include "nxl_xml_node.h"n"; print ${intername} $headerlist{ $oriname } if defined($headerlist{ $oriname }); print ${intername} "namespace ${namespacename}n{n"; #debug output message print "${intername}n"; print ${intername} "$classdeflist{ $oriname }n" if defined($classdeflist{ $oriname }); print ${intername} $interfacefile{ $oriname } . "};nn"; print ${intername} "extern "C" ${intername}* ${intername}_CreateNewInstance(void);nn}n"; close(${intername}); # here generate implement header file $headername = "$oriname"; open (${headername},">${headername}.h") || die "Can't write ${headername}.h: $!n"; print ${headername} "// this is generated code,do not editn"; print ${headername} "#pragma oncenn"; print ${headername} "#include "I${headername}.h"n"; print ${headername} "#include "nxl_xml_node.h"n"; print ${headername} "namespace ${namespacename}n{n"; print ${headername} $implementheaderfile{ $headername }; #print ${headername} "nprivate:ntNode m_node;n};nn}n"; print ${headername} "ntNode m_node;n};nn}n"; close(${headername}); $cppname = $oriname; # here generate implement cpp file open (${cppname},">${cppname}.cpp") || die "Can't write ${cppname}.cpp: $!n"; print ${cppname} "// this is generated code,do not editnnn"; print ${cppname} "#include "${cppname}.h"nn"; print ${cppname} "namespace ${namespacename}n{n"; #print ${name} $constructors{ ${name} } ; #print ${name} $parsersvec{ ${name} } ; #print ${name} $attributparser{ ${name} } if(defined($attributparser{ ${name} })); print ${cppname} $implementcppfile{ ${cppname} }; print ${cppname} "nI${cppname}* I${cppname}_CreateNewInstance(void)n{ntreturn new ${cppname}();n}n"; print ${cppname} "};n"; close(${cppname}); use File::Copy ; use strict ; move("${curdir}/${intername}.h","${outdir}/include/${intername}.h")||warn "could not copy files :$!" ; move("${curdir}/${headername}.h","${outdir}/include/${headername}.h")||warn "could not copy files :$!" ; move("${curdir}/${cppname}.cpp","${outdir}/src/${cppname}.cpp")||warn "could not copy files :$!" ; } $tempdtd = $dtd; $tempdtd =~ s/rn//g; $dtd =~ s/n/''/ge;
# run thru the DTD while(1){ $dtd =~ s/^(.*?)</</; #$dtd =~ s/[*+?]//g; if($dtd =~ /^<(.*?)>(.*)$/){ $elem=$1; $dtd=$2; if($elem =~ /^!s+(w+)s+(.*)/){ print "==>ELEMENT $1,$2n"; ProcElement($1,$2); } elsif($elem =~ /^!s+(w+)s+(.*)/){ #print "ATTLIST $1n"; ProcAttList($1,$2); } elsif($elem =~ /^!--.*--$/){ #print "commentn"; } else { print "2222222222111n"; warn "can't understand $elemn"; } } else{ print "parser overn" if defined($elem); last; } }
# class declarations & code for(@classes){ GenerateTargetFile($_); }
# generate Makefile file open(MAKEFILE,">Makefile") || die "Can't write Makefile: $!n"; print MAKEFILE "# # ! Don't modify this file # Modify Makefile.inc instead # ifeq ($(NLBUILDROOT),) $(error NLBUILDROOT undefined.) endif
ifeq ($(NLEXTERNALDIR),) $(error NLEXTERNALDIR undefined.) endif
# # Following master make file can be included: # - master.cxx.mak # - master.csharp.mak # - master.java.mak # $(info Include master makefile: $(NLBUILDROOT)/scripts/make/master.cxx.mak) include $(NLBUILDROOT)/scripts/make/master.cxx.mak "; close(MAKEFILE); move("${curdir}/Makefile","${outdir}/Makefile")||warn "could not copy files :$!" ;
# generate Makefile.inc file open(MAKEFILEINC,">Makefile.inc") || die "Can't write Makefile: $!n"; print MAKEFILEINC " ############################################################################## # # The Makefile.inc will be used by master Makefile # under NLBUILDROOT/scripts/make directory. # ##############################################################################
# # The name of the target # TARGET_NAME=nxxmlconfig $(info Makefile.inc for project $(TARGET_NAME))
# # VERSION # VERSION_PRODUCT= $(VERSION_PRODUCT_RMP) VERSION_MAJOR= $(VERSION_MAJOR_RMP) VERSION_MINOR= $(VERSION_MINOR_RMP) VERSION_MAINTENANCE = $(VERSION_MAINTENANCE_RMP) VERSION_PATCH= $(VERSION_PATCH_RMP)
# # The type of target,could be one of following values: # - exe: An executable file # - lib: A static library (user/kernel mode) # - dll: A dynamic link library (user/kernel mode) # - sys: A kernel driver # TARGET_TYPE=dll
# # The run mode of target # - kernel # - user # TARGET_MODE=user
# Make sure the sys target run at kernel mode ifeq ($(TARGET_TYPE),sys) ifeq ($(TARGET_MODE),user) $(error A sys target must run at kernel mode.) endif endif
# # Additional settings for EXE # ifeq ($(TARGET_TYPE),exe)
# Application type: CONSOLE or WIN32 # console: this is a console application # win32: this is a win32 application EXE_TYPE = console # # Do we need to elevate privilege? # - Invoke # - Administrator # EXE_PRIVILEGE = Invoke # # Is this a test app? # - yes # - no or empty # #EXE_TESTAPP = yes endif
# # Source file # SRC = "; foreach (@classes){ print MAKEFILEINC " src/$_.cpp"; }
print MAKEFILEINC " src/nxl_xml_node.cpp
# # Resource file # If this variable is empty,a default rc file will be used automatically # RCSRC =
# # Additional include directories # INCPATH += $(NLEXTERNALDIR)/libxml2-2.7.8.win32/include $(NLEXTERNALDIR)/libxml2-2.7.8.win32/include/libxml $(NLEXTERNALDIR)/boost/boost_1_55_0
# # Additional library directories # LIBPATH += $(NLEXTERNALDIR)/libxml2-2.7.8.win32/lib $(NLEXTERNALDIR)/boost/boost_1_55_0/libs/$(BINDIR) $(NLBUILDROOT)/bin/$(BINDIR)
# # Additional librarys # LIBS += libxml2
"; close(MAKEFILEINC); move("${curdir}/Makefile.inc","${outdir}/Makefile.inc")||warn "could not copy files :$!" ;
# generate nxxmlconfig.def file open(DEFFILE,">nxxmlconfig.def") || die "Can't write nxxmlconfig.def: $!n"; print DEFFILE "EXPORTSn"; foreach $tem(@classes){ print DEFFILE "tI${tem}_CreateNewInstancen"; } close(DEFFILE); move("${curdir}/nxxmlconfig.def","${outdir}/src/nxxmlconfig.def")||warn "could not copy files :$!" ;
# generate nxxmlconfig_helper.h file open(HELPERFILE,">nxxmlconfig_helper.h") || die "Can't write nxxmlconfig_helper.h: $!n"; print HELPERFILE "#pragma oncenn"; foreach (@classes){ print HELPERFILE "#include "I$_.h"n"; } close(HELPERFILE); move("${curdir}/nxxmlconfig_helper.h","${outdir}/include/nxxmlconfig_helper.h")||warn "could not copy files :$!" ;
#testtest only for test need,copy main.cpp nxl_xml_node.cpp nxl_xml_node.h copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/nxl_xml_node.cpp","${outdir}/src/nxl_xml_node.cpp" ) || warn "could not copy files:$!"; copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/nxl_xml_node.h","${outdir}/include/nxl_xml_node.h" ) || warn "could not copy files:$!"; #testtest copy libxml dlls unless ( -e "${outdir}/debug_win_x86" ){ mkdir "${outdir}/debug_win_x86",0700; } copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/iconv.dll","${outdir}/debug_win_x86/iconv.dll" ) || warn "could not copy files:$!"; copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/zlib1.dll","${outdir}/debug_win_x86/zlib1.dll" ) || warn "could not copy files:$!"; copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/libxml2.dll","${outdir}/debug_win_x86/libxml2.dll" ) || warn "could not copy files:$!"; (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|