source: main/trunk/greenstone2/perllib/parse2.pm@ 24950

Last change on this file since 24950 was 22732, checked in by mdewsnip, 14 years ago

Added copyright header to perllib/parse2.pm.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.1 KB
Line 
1###########################################################################
2#
3# parse2.pm --
4#
5# A component of the Greenstone digital library software
6# from the New Zealand Digital Library Project at the
7# University of Waikato, New Zealand.
8#
9# Copyright (C) 2005-2010 New Zealand Digital Library Project
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24#
25###########################################################################
26
27
28#Last: Keeping doing the processArg for handing different type of arguments
29
30#parse2(\@_,$arguments,$self )
31
32package parse2;
33
34BEGIN {
35 die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
36 die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
37 unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
38 unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
39}
40
41use strict;
42use util;
43
44
45
46#--Local Util Functions----------------------------
47#-----------------------------------------
48# Name: transformArg
49# Parameters: 1.(Array pointer of plugin pre-defined argument list)
50# Pre-condition: Call this function and pass a array pointer of argument list.
51# Post-condition: This function will transform the array to a hash table
52# with "Argument name" as its key
53# Return value: Return a hash table of plugin pre-defined argument
54# list with "argument name" as the key
55#-----------------------------------------
56sub transformArg
57{
58 my ($aryptSysArguList) = @_;
59 my %hashArg;
60
61 foreach my $hashOneArg (@{$aryptSysArguList})
62 {
63 if(!(defined $hashArg{$hashOneArg->{"name"}}))
64 {
65 $hashArg{$hashOneArg->{"name"}} = $hashOneArg;
66 }
67 }
68 return %hashArg;
69}
70
71sub checkRange
72{
73 my ($strRange,$intInputArg,$strArgName) = @_;
74 my @aryRange = split(",",$strRange);
75 if(defined $aryRange[0])
76 {
77 if($intInputArg < $aryRange[0])
78 {
79 print STDERR " Parameter Parsing Error (Incorrect Range): when parse argument parameter for \"-$strArgName\"\n";
80 return 0;
81 }
82 else
83 {
84 if(scalar(@aryRange) == 2)
85 {
86 if($intInputArg > $aryRange[1])
87 {
88 print STDERR " Parameter Parsing Error (Incorrect Range): when parse argument parameter for \"-$strArgName\"\n";
89 return 0;
90 }
91 }
92 }
93 }
94 else{ die " System error: minimum range is not defined. Possible mistyping in Argument list for $strArgName\n";}
95 return 1;
96}
97
98sub checkCharLength
99{
100 my ($intCharLength,$intInputArg,$strArgName) = @_;
101 if($intCharLength =~ m/\d/)
102 {
103 if(length($intInputArg) != $intCharLength)
104 {
105 print STDERR " Parameter Parsing Error (Incorrect Char_Length): when parse argument parameter for \"-$strArgName\"\n";
106 return 0;
107 }
108 }
109 else
110 {
111 die " System error: incorrect char_length. Possible mistyping in Argument list for $strArgName\n";
112 }
113 return 1;
114}
115#-----------------------------------------
116# Name: processArg
117# Parameters: 1.(Hash pointer of one argument)
118# 2.(Array pointer of the user given argument)
119# 3.(Hash pointer of user given arguments' values)
120# Pre-condition: Given a argument ($hashOneArg)
121# Post-condition: System will check whether it need to get parameter
122# from $aryptInputArguList or not, and also check the
123# given parameter is following the argument description
124# Return value: 1 is parsing successful, 0 is failed.
125#-----------------------------------------
126sub processArg
127{
128 my ($hashOneArg,$aryptInputArguList,$hashInputArg) = @_;
129
130 # Since these two variables are going to be
131 # used a lot, store them with some better names.
132 my $strArgName = $hashOneArg->{"name"};
133 my $strArgType = $hashOneArg->{"type"};
134
135 # If the argument type is "flag" then
136 # set it to 1(which is "true")
137 if($strArgType eq "flag")
138 {
139 $hashInputArg->{$strArgName} = 1;
140 }
141
142 # If the argument type is "int" then
143 # gets the next argument from $aryptInputArguList
144 # and check whether it is a digit
145 # TODO: check its "range" and "char_length"
146 elsif($strArgType eq "int")
147 {
148 my $intInputArg = shift(@{$aryptInputArguList});
149 if ($intInputArg =~ /\d+/)
150 {
151 $hashInputArg->{$strArgName} = $intInputArg;
152 }
153 else
154 {
155 print STDERR " Error: occur in parse2.pm::processArg()\n Unmatched Argument: -$strArgName with type $strArgType\n";
156 return 0;
157 }
158 }
159
160 # If the argument type is "enum" then
161 elsif($strArgType eq "enum")
162 {
163 if(defined $hashOneArg->{"list"})
164 {
165 my $aryptList = $hashOneArg->{"list"};
166 my $blnCheckInList = "false";
167 my $strInputArg = shift(@{$aryptInputArguList});
168 foreach my $hashEachItem (@$aryptList)
169 {
170 if($strInputArg eq $hashEachItem->{"name"})
171 {
172 $blnCheckInList = "true";
173 }
174 last if($blnCheckInList eq "true");
175 }
176 if($blnCheckInList ne "true")
177 {
178 print STDERR " Error: occur in parse2.pm::processArg()\n Unknown Enum List Type: -$strArgName with parameter: $strInputArg\n";
179 return 0;
180 } else {
181 $hashInputArg->{$strArgName} = $strInputArg;
182 }
183
184 }
185 else
186 {
187 print STDERR " Error: occur in parse2.pm::processArg(2)\n Unknown Type: -$strArgName with type $strArgType\n";
188 return 0;
189 }
190 }
191
192 # If the argument type is "string" or "metadata" or "quotestr" then
193 # just shift the next argument from $aryptInputArguList
194 # TODO: make sure if there is any checking required for this two types
195 elsif($strArgType eq "string" || $strArgType eq "enumstring" || $strArgType eq "quotestr" || $strArgType eq "metadata" || $strArgType eq "regexp" || $strArgType eq "url")
196 {
197 $hashInputArg->{$strArgName}= shift(@{$aryptInputArguList});
198 }
199
200 # Report any undefined types
201 else
202 {
203 print STDERR " Error: occur in parse2.pm::processArg(3)\n Unknown Type: -$strArgName with type $strArgType\n";
204 return 0;
205 }
206
207 return 1;
208}
209
210#--Main Parsing Function----------------------------
211#-----------------------------------------
212# Name: parse
213# Parameters: 1.(Array pointer of the user given argument)
214# 2.(Array pointer of plugin pre-defined argument list)
215# 3.(Hash pointer, where we store all the argument value)
216# Pre-condition: Plugin gives the parameters to parse function in parse2
217# Post-condition: Store all the default or user given values to the hash->{$ArgumentName}.
218# Since hash may be a plugin $self, plugin will have every values we set.
219# 4. Optional "allow_extra_options" argument. If this is set, then
220# its ok to have arguments that are not in the predefined list
221# Return value: -1 if parsing is unsuccessful
222# other value for success. This will be 0 unless "allow_extra_options" is set, in which case it will be the number of extra arguments found.
223#-----------------------------------------
224sub parse
225{
226 # Get the user supplied arguments pointer "\@_"
227 my $aryptUserArguList = shift;
228
229 # Check if allow extra arguments
230 my $blnAllowExtraOptions = "false";
231
232 if(scalar(@_) == 3)
233 {
234 my $strAllowExtraOptions = pop @_;
235
236 if ($strAllowExtraOptions eq "allow_extra_options")
237 {
238 $blnAllowExtraOptions = "true";
239 }
240 }
241
242 my ($aryptSysArguList,$self) = @_;
243 my %hashArg;
244 my %hashInputArg;
245 my @ExtraOption;
246
247 # Transform the system argument (predefined the code)
248 # from array to hash table for increasing performance
249 %hashArg = &transformArg($aryptSysArguList);
250
251 # Process each User input argument and store the
252 # information into hashInputArg
253 while (my $strOneArg = shift(@{$aryptUserArguList}))
254 {
255 # Check whether it start with a "-" sign
256 if ($strOneArg =~ /^-+\w/)
257 {
258 # If it is start with a "-" sign then take it off
259 $strOneArg =~ s/^-+//;
260
261 # If the inputed argument is defined in the argument
262 # list from this plugin then process
263
264 if(defined $hashArg{$strOneArg})
265 {
266 #$%^
267 #print "($strOneArg) is processed\n";
268 # Process this argument and store the related
269 # information in %hashInputArg
270 if(processArg($hashArg{$strOneArg},$aryptUserArguList,\%hashInputArg) == 0){
271 print STDERR "<BadArgumentValue a=$strOneArg>\n";
272 return -1;}
273 }
274
275 # Else check if it allows extra options, if yes
276 # then push it to a new array, else return fault
277 else
278 {
279 if($blnAllowExtraOptions eq "true")
280 {
281 push(@ExtraOption,"-$strOneArg");
282 }
283 else
284 {
285 print STDERR "<BadArgument a=$strOneArg>\n";
286 print STDERR " Error: occur in parse2.pm::parse()\n Extra Arguments: $strOneArg\n";
287 return -1;
288 }
289 }
290 }
291
292 # This part follow the previous parsing system.
293 # It doesn't return error message even user
294 # gave a invalid argument.
295 else
296 {
297 if($blnAllowExtraOptions eq "true")
298 {
299 push(@ExtraOption,$strOneArg);
300 }
301 else
302 {
303 print STDERR " Error: occur in parse2.pm::parse()\n Invalid Argument: $strOneArg\n";
304 return -1;
305 }
306 }
307 }
308
309 # Store the extra option back
310 # to the user given argument list.
311 @$aryptUserArguList = @ExtraOption;
312
313 # Now we go through all the pre defined arguments,
314 # if the user has specified the arguments then just
315 # set to whatever they set. Otherwise use the default value
316 foreach my $hashOneArg (@{$aryptSysArguList})
317 {
318 my $strArgName = $hashOneArg->{"name"};
319
320 # If the strArgName has defined in the %hashInputArg,
321 # this means users has give this argument, store the
322 # user given to self->{"$strArgName"}
323 if(defined $hashInputArg{$strArgName})
324 {
325 if(defined $hashOneArg->{"range"})
326 {
327 if(checkRange($hashOneArg->{"range"},$hashInputArg{$strArgName},$strArgName) == 0){ return -1;}
328 }
329 if(defined $hashOneArg->{"char_length"})
330 {
331 if(checkCharLength($hashOneArg->{"char_length"},$hashInputArg{$strArgName},$strArgName) == 0){ return -1;}
332 }
333 $self->{"$strArgName"} = $hashInputArg{"$strArgName"};
334 }
335 elsif (!defined $self->{$strArgName})
336 {
337 # don't want to override default with superclass value
338
339 # Else use the default value of the arguments,
340 # if there is no default value, then it must be a flag,
341 # then set it to 0 (which is false)
342
343 if(defined $hashOneArg->{"deft"})
344 {
345 $self->{"$strArgName"} = $hashOneArg->{"deft"};
346 }
347 else
348 {
349 if($hashOneArg->{"type"} eq "flag"){
350 $self->{"$strArgName"} = 0;
351 }
352 else {
353 # all other cases, use "" as default
354 $self->{"$strArgName"} = "";
355 }
356 }
357 }
358 }
359
360 # If allow_extra_options is set, then return the number of arguments left in the argument list.
361 if($blnAllowExtraOptions eq "true")
362 {
363 return scalar(@$aryptUserArguList);
364 }
365 else
366 {
367 return 0;
368 }
369}
370
3711;
Note: See TracBrowser for help on using the repository browser.