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

Last change on this file since 31191 was 28700, checked in by kjdon, 10 years ago

when parsing the args, if we are setting the value based on the default, set also default_argname, so that later on we can tell the difference between a default value explicitly set by the user, or one just from the default in the arg description. This means that we cna now set all defaults in the args data structure, rather than leaving them empty and setting the default in the code.

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