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

Last change on this file since 32096 was 31919, checked in by kjdon, 7 years ago

small tidy up to parsing. remove - if there, but allow the arg to not have -. Don't put the - back on to the extra arg as it will probably be the collection name.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.3 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 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 $self->{"default_$strArgName"} = 1;
347
348 }
349 else
350 {
351 if($hashOneArg->{"type"} eq "flag"){
352 $self->{"$strArgName"} = 0;
353 $self->{"default_$strArgName"} = 1;
354 }
355 else {
356 # all other cases, use "" as default
357 $self->{"$strArgName"} = "";
358 $self->{"default_$strArgName"} = 1;
359 }
360 }
361 }
362 }
363
364 # If allow_extra_options is set, then return the number of arguments left in the argument list.
365 if($blnAllowExtraOptions eq "true")
366 {
367 return scalar(@$aryptUserArguList);
368 }
369 else
370 {
371 return 0;
372 }
373}
374
3751;
Note: See TracBrowser for help on using the repository browser.