#======================================================== # GetArg #======================================================== package GetArg; use Common; @ISA = qw(Common); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; use Utils; #============================================================ # 変数等取得関数 #============================================================ sub App { return shift->{'Application'}; } sub Application { return shift->{'Application'}; } sub SetApplication { my ($this,$app)=@_; return $this->{'Application'} = $app; } sub AllowedArgs { return shift->{'pAllowedArgs'}; } sub Explanations { return shift->{'pExplanations'}; } sub ArgArray { return shift->{'pArgArray'}; } sub FileNameArray { return shift->{'pFileNameArray'}; } sub AppName { return shift->{'AppName'}; } sub SetAppName { my ($this, $name) = @_; return $this->{'AppName'} = $name; } sub CGIForm { my ($this) = @_; if($this->{'CGIForm'}) { $this->{'CGIForm'} = new CGI; } return $this->{'CGIForm'}; } sub SetCGIForm { my ($this,$f)=@_; return $this->{'CGIForm'} = $f; } sub pIn { return shift->{pIn}; } sub GetArgHash { my ($this) = @_; my %Args; #CGIフォーム変数 my $pIn = $this->pIn(); if($pIn) { foreach my $key (keys %$pIn) { $Args{$key} = $pIn->{$key}; } } #CGIフォーム変数 my $form = $this->CGIForm(); if($form) { my @params = $form->all_parameters(); print "params: ", @params, "
\n"; foreach my $key (@params) { $Args{$key} = $form->param($key); print "$key: $Args{$key}
\n"; } } #起動時引数 foreach my $key (keys %ARGV) { $Args{$key} = $ARGV{$key}; } my $pArgs = $this->ArgArray(); if($pArgs) { foreach my $key (keys %$pArgs) { if($pArgs->{$key}) { $Args{$key} = $pArgs->{$key}; } elsif($pArgs->{"--$key"}) { $Args{$key} = $pArgs->{"--$key"}; } } } foreach my $k (keys %Args) { if($k =~ /^--(.*)$/) { $Args{$1} = $Args{$k}; } } return %Args; } sub MergeArgs { my ($this) = @_; my %hash; #最初に$thisに格納されている連想配列を抽出 foreach my $k (keys %$this) { $hash{$k} = $this->{$k}; } #CGIに格納されている連想配列を抽出 my $pIn = $this->pIn(); if($pIn) { foreach my $key (keys %$pIn) { $hash{$key} = $pIn->{$key}; } } my $form = $this->CGIForm(); if($form) { my @params = $form->all_parameters(); foreach my $key (@params) { $hash{$key} = $form->param($key); } } #起動時引数に格納されている連想配列を抽出 foreach my $key (keys %ARGV) { $hash{$key} = $ARGV{$key}; } my $args = $this->ArgArray(); if($args) { foreach my $key (keys %$args) { $hash{$key} = $args->{$key}; } } #ファイル名を連想配列に追加 my $files = $this->FileNameArray(); if($files) { for(my $i = 0 ; $i < @$files ; $i++) { my $f = $files->[$i]; $hash{"File$i"} = $f; } } return \%hash; } #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module, $app) = @_; my $this = {}; bless $this; $this->InitializeArgs(); $this->SetApplication($app) if($app); return $this; } sub DESTROY { my $this = shift; } #============================================================ # 一般関数 #============================================================ sub InitializeArgs { my ($this) = @_; $this->{'pAllowedArgs'} = {}; $this->{'pExplanations'} = {}; $this->{'pArgArray'} = {}; $this->{pIn}; # = {}; $this->InitializeFiles(); $this->{CheckAllowedArgs} = 1; } sub InitializeFiles { my ($this) = @_; $this->{'pFileNameArray'} = []; } #============================================================ # 一般関数 #============================================================ # parseInput(encoding) # encoding: 日本語コード(jis|sjis|euc) # Name=>Val のハッシュ(グロブ) # sub parseInput { my ($this, $charcode) = @_; my ($method) = $ENV{'REQUEST_METHOD'}; my ($query, @in, $key, $val); my %in; #二重読み込みを防止する # return $this->{pIn} if(defined $this->{pIn}); # GETメソッドかPOSTメソッドかを判別する if ($method eq 'GET') { $query = $ENV{QUERY_STRING}; } elsif ($method eq 'POST') { # read(STDIN, $query, $ENV{CONTENT_LENGTH}); #print "query: [$query]
\n"; #Utils::InitHTML(); #print "

Error in GetArg::parseInput: POST does not work propery.

\n"; } # 入力データを分解する my (@query) = split(/&/, $query); # Name=Val を $in{'Name'} = 'Val' のハッシュにする。 foreach (@query) { # + を空白文字に変換 tr/+/ /; # Name=Val を分ける ($key, $val) = split(/=/); #print "key: $key: $val
\n"; # %HH形式を元の文字にデコードする。 $key =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge; $val =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge; $val =~ s/\r\n/\n/g; # 日本語コードが指定されている場合は変換する。 Jcode::convert(\$key, $charcode) if ($charcode); Jcode::convert(\$val, $charcode) if ($charcode); # 連想配列(ハッシュ)にセット $in{$key} = $val; } # 連想配列のリファレンスを返す return $this->{pIn} = \%in; } sub Usage { my ($this) = @_; my $AppName = $this->AppName(); $AppName = 'Application' unless($AppName); print "\n"; print "usage: $AppName [options] File_Names\n"; print " Options:\n"; my $allowed = $this->AllowedArgs(); my $expl = $this->Explanations(); my @key = keys %$allowed; for(my $i = 0 ; $i < @key ; $i++) { my $s = $key[$i]; my $e = $expl->{$s}; $e = $s unless($e); print " $e\n"; } } sub SetCheckAllowedArgs { my ($this, $f) = @_; return $this->{CheckAllowedArgs} = $f; } sub CheckAllowedArgs { my ($this) = @_; $this->{CheckAllowedArgs} = 1 if(!defined $this->{CheckAllowedArgs}); return $this->{CheckAllowedArgs}; } sub IsIncluded { my ($this, $varname) = @_; my $allowed = $this->AllowedArgs(); $varname =~ s/^--//; # $varname = uc $varname; foreach my $s (keys %$allowed) { $s =~ s/^--//; # $s = uc $s; # return 1 if($varname eq $s); return 1 if($varname =~ /^$s$/i); } return 0; } sub BuildCommandLine { my ($this) = @_; my $args = $this->ArgArray(); my $App = $this->App(); my $command = $App->ProgramPath(); $command = '' unless($command); foreach my $s (keys %$args) { my $v = $args->{$s}; if(defined $v and $v ne '') { $command = "$command --$s=$v"; } else { $command = "$command --$s"; } } Utils::DelSpace($command); return $command; } sub ShowArgs { my ($this) = @_; my $args = $this->MergeArgs(); # my %hash = $this->GetArgHash(); # my $args = \%hash; $this->print("Arguments in command line:\n"); foreach my $s (keys %$args) { my $v = $args->{$s}; $this->print(" $s=$v\n") unless($v =~ /ARRAY\(0x/ or $v =~ /HASH\(0x/); } } #コマンドライン引数の文字列と値を設定する sub SetArgument { my ($this, $varname, $val) = @_; return undef unless($varname); my $args = $this->ArgArray(); #print "set v: $varname val: $val\n"; return $args->{$varname} = $val; } sub GetGetArg { my ($this, $varname0) = @_; my $varname = $varname0; $varname =~ s/^--//; #CGIフォーム変数 my $pIn = $this->pIn(); if($pIn) { my $val = $pIn->{$varname}; return $val if(defined $val); } #CGIフォーム変数 my $form = $this->CGIForm(); if($form) { my $val = $form->param($varname); return $val if(defined $val); } #起動時引数 my $args = $this->ArgArray(); # 引数が整数だけのとき:ファイル名を返す if($varname0 =~ /^\d+$/) { my $pFiles = $this->FileNameArray(); return $pFiles->[$varname0]; } # その他:オプションを返す my $val = $args->{$varname}; $val = $args->{"--$varname"} unless(defined $val); #print "get v: $varname val: $val\n"; return $val; } sub GetFileNameArray { my ($this, $varname) = @_; my $files = $this->FileNameArray(); return @$files; } #受け取る引数の文字列を追加する sub AddArgument { my ($this, $arg, $explanation, $defval) = @_; my $allowed = $this->AllowedArgs(); $defval = '' unless(defined $defval); $allowed->{$arg} = $defval; my $expl = $this->Explanations(); $expl->{$arg} = $explanation; } sub Read { my ($this, $pArgs, $StopFlag) = @_; $StopFlag = 1 unless(defined $StopFlag); my @args = @$pArgs; @args = @ARGV if(@args == 0); my $allowed = $this->AllowedArgs(); my $files = $this->FileNameArray(); for(my $i = 0 ; $i < @args ; $i++) { my $s = $args[$i]; my ($name, $d, $val); if( ($name, $d, $val) = ( $s =~ /^--([^=]*)(=(.*))?$/ ) ) { Utils::DelSpace($name); $val = '' unless(defined $val); Utils::DelSpace($val); #print "name: $name val: $val\n"; if($this->CheckAllowedArgs()) { #print "Check: $name val: $val\n"; if($name and $this->IsIncluded($name)) { $this->SetArgument($name, $val); next; } elsif($StopFlag) { print "\n"; print "Error: Invalid argument: $s\n"; $this->Usage(); return -1; } } else { $this->SetArgument($name, $val); next; } } push(@$files, $s); } if(defined $this->GetGetArg("help")) { $this->Usage(); exit 2; } return 1; } 1;