source: main/trunk/greenstone2/perllib/parse3.pm@ 32221

Last change on this file since 32221 was 27303, checked in by jmt12, 11 years ago

Replacing hardcoded additions to INC and PATH environment variables with conditional ones - this allows us to use the order of values in these variables for precedence, thus allows better support for extensions that override classifiers, plugins etc. ENV and PATH functions already exists in util, but augmentINC() is a new function

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