source: main/tags/2.52/gsdl/perllib/parsargv.pm@ 25422

Last change on this file since 25422 was 2359, checked in by sjboddie, 23 years ago

Altered the help text a little for mkcol.pl, import.pl, buildcol.pl, and
build so that they now suggest using the "more" pager if the help text
scrolls off the screen (brought about by usability studies under DOS).
Note that this means some debug info that was once printed to STDERR is
now being printed to STDOUT.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 5.5 KB
Line 
1###########################################################################
2#
3# parseargv.pm --
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26package parsargv;
27#
28# parse(ARGVREF, [SPEC, VARREF] ...)
29#
30# Parse command line arguments.
31#
32# ARGVREF is an array reference, usually to @ARGV. The remaining
33# arguments are paired (SPEC, VARREF). SPEC is a specification string
34# for a particular argument; VARREF is a variable reference that will
35# receive the argument.
36#
37# SPEC is in one of the following forms:
38#
39# ARG/REGEX/DEFAULT ARG is the name of command line argument. REGEX is
40# a regular expression that gives legal values for the argument.
41# DEFAULT is the default value assigned to VARREF if the option does
42# not appear on the command line. Example
43#
44#
45# ARG/REGEX ARG and REGEX are as above. Since no default is given, ARG
46# must appear on the command line; if it doesn't, parse() returns 0.
47#
48# ARG ARG is as above. ARG is a boolean option. VARREF is assigned 0 if ARG
49# is not on the command line; 1 otherwise.
50#
51# SPEC may start with a punctuation character, in which case this
52# character will be used instead of '/' as a delimiter. Useful when '/'
53# is needed in the REGEX part.
54#
55# VARREF is a reference to a scalar or an array. If VARREF is an array
56# reference, then multiple command line options are allowed an append. Example:
57#
58# Command line: -day mon -day fri
59#
60# parse(\@ARGV, "day/(mon|tue|wed|thu|fri)", \@days)
61#
62# days => ('mon', 'fri')
63#
64# Returns 0 if there was an error, nonzero otherwise.
65#
66
67
68 sub parse
69{
70 my $arglist = shift;
71 my ($spec, $var);
72 my %option;
73
74 my @rest = @_;
75
76
77 # if the last argument is the string "allow_extra_options" then options
78 # in \@rest without a corresponding SPEC will be ignored (i.e. the "$arg is
79 # not a valid option" error won't occur)\n";
80 my $allow_extra_options = pop @rest;
81 if (defined ($allow_extra_options)) {
82 if ($allow_extra_options eq "allow_extra_options") {
83 $allow_extra_options = 1;
84 } else {
85 # put it back where we got it
86 push (@rest, $allow_extra_options);
87 $allow_extra_options = 0;
88 }
89 } else {
90 $allow_extra_options = 0;
91 }
92
93 while (($spec, $var) = splice(@rest, 0, 2))
94 {
95
96 die "Variable for $spec is not a valid type."
97 unless ref($var) eq 'SCALAR' || ref($var) eq 'ARRAY';
98
99 my $delimiter;
100 if ($spec !~ /^\w/)
101 {
102 $delimiter = substr($spec, 0, 1);
103 $spec = substr($spec, 1);
104 }
105 else
106 {
107 $delimiter = '/';
108 }
109 my ($name, $regex, $default) = split(/$delimiter/, $spec, 3);
110
111
112 if ($name)
113 {
114 if ($default && $default !~ /$regex/)
115 {
116 die "Default value for $name doesn't match regex ($spec).";
117 }
118 $option{$name} = {'name' => $name,
119 'regex' => $regex,
120 'default' => $default,
121 'varref' => $var,
122 'set' => 0};
123 }
124 else
125 {
126 die "Invalid argument ($spec) for parsargv.";
127 }
128 }
129
130 my @argv;
131 my $arg;
132 my $parse_options = 1;
133 my $errors = 0;
134
135 while ($arg = shift(@$arglist))
136 {
137 if ($parse_options && $arg eq '--')
138 {
139 $parse_options = 0;
140 next;
141 }
142
143 if ($parse_options && $arg =~ /^-+\w/)
144 {
145 $arg =~ s/^-+//;
146
147 if (defined $option{$arg})
148 {
149 &process_arg($option{$arg}, $arglist, \$errors);
150 }
151 elsif (!$allow_extra_options)
152 {
153 print STDOUT "$arg is not a valid option.\n";
154 $errors++;
155 }
156 }
157 else
158 {
159 push(@argv, $arg);
160 }
161 }
162 @$arglist = @argv;
163
164 foreach $arg (keys %option)
165 {
166 if ($option{$arg}->{'set'} == 0)
167 {
168 if (defined $option{$arg}->{'default'})
169 {
170 &set_var($option{$arg}, $option{$arg}->{'default'});
171 }
172 elsif (!$option{$arg}->{'regex'})
173 {
174 &set_var($option{$arg}, 0)
175 }
176 elsif (ref($option{$arg}->{'varref'}) ne 'ARRAY')
177 {
178 print STDOUT "Missing command line argument -$arg.\n";
179 $errors++;
180 }
181 }
182 }
183 return $errors == 0;
184}
185
186sub process_arg
187{
188 my ($option, $arglist, $errors) = @_;
189
190 if ($option->{'regex'} && @$arglist > 0 && $arglist->[0] !~ /^-+\w/)
191 {
192 if ($arglist->[0] =~ /$option->{'regex'}/)
193 {
194 &set_var($option, shift(@$arglist));
195 }
196 else
197 {
198 print STDOUT "Bad value for -$option->{'name'} argument.\n";
199 $$errors++;
200 }
201 }
202 elsif (!$option->{'regex'})
203 {
204 &set_var($option, 1);
205 }
206 else
207 {
208 print STDOUT "No value given for -$option->{'name'}.\n";
209 $$errors++;
210 }
211}
212
213sub set_var
214{
215 my ($option, $value) = @_;
216 my $type = ref($option->{'varref'});
217
218 if ($type eq 'SCALAR')
219 {
220 ${$option->{'varref'}} = $value;
221 }
222 elsif ($type eq 'ARRAY')
223 {
224 push(@{$option->{'varref'}}, $value);
225 }
226 $option->{'set'} = 1;
227}
228
2291;
230
231
232
233
234
235
236
237
Note: See TracBrowser for help on using the repository browser.