#========================================================
# 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;