source: trunk/gsdl/perllib/parsargv.pm@ 14

Last change on this file since 14 was 4, checked in by sjboddie, 26 years ago

Initial revision

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 3.9 KB
Line 
1package parsargv;
2#
3# parse(ARGVREF, [SPEC, VARREF] ...)
4#
5# Parse command line arguments.
6#
7# ARGVREF is an array reference, usually to @ARGV. The remaining
8# arguments are paired (SPEC, VARREF). SPEC is a specification string
9# for a particular argument; VARREF is a variable reference that will
10# receive the argument.
11#
12# SPEC is in one of the following forms:
13#
14# ARG/REGEX/DEFAULT ARG is the name of command line argument. REGEX is
15# a regular expression that gives legal values for the argument.
16# DEFAULT is the default value assigned to VARREF if the option does
17# not appear on the command line. Example
18#
19#
20# ARG/REGEX ARG and REGEX are as above. Since no default is given, ARG
21# must appear on the command line; if it doesn't, parse() returns 0.
22#
23# ARG ARG is as above. ARG is a boolean option. VARREF is assigned 0 if ARG
24# is not on the command line; 1 otherwise.
25#
26# SPEC may start with a punctuation character, in which case this
27# character will be used instead of '/' as a delimiter. Useful when '/'
28# is needed in the REGEX part.
29#
30# VARREF is a reference to a scalar or an array. If VARREF is an array
31# reference, then multiple command line options are allowed an append. Example:
32#
33# Command line: -day mon -day fri
34#
35# parse(\@ARGV, "day/(mon|tue|wed|thu|fri)", \@days)
36#
37# days => ('mon', 'fri')
38#
39# Returns 0 if there was an error, nonzero otherwise.
40#
41sub parse
42{
43 my $arglist = shift;
44 my ($spec, $var);
45 my %option;
46
47 while (($spec, $var) = splice(@_, 0, 2))
48 {
49 die "Variable for $spec is not a valid type."
50 unless ref($var) eq 'SCALAR' || ref($var) eq 'ARRAY';
51
52 my $delimiter;
53 if ($spec !~ /^\w/)
54 {
55 $delimiter = substr($spec, 0, 1);
56 $spec = substr($spec, 1);
57 }
58 else
59 {
60 $delimiter = '/';
61 }
62 my ($name, $regex, $default) = split(/$delimiter/, $spec, 3);
63
64 if ($name)
65 {
66 if ($default && $default !~ /$regex/)
67 {
68 die "Default value for $name doesn't match regex ($spec).";
69 }
70 $option{$name} = {'name' => $name,
71 'regex' => $regex,
72 'default' => $default,
73 'varref' => $var,
74 'set' => 0};
75 }
76 else
77 {
78 die "Invalid argument ($spec) for parsargv.";
79 }
80 }
81
82 my @argv;
83 my $arg;
84 my $parse_options = 1;
85 my $errors = 0;
86
87 while ($arg = shift(@$arglist))
88 {
89 if ($parse_options && $arg eq '--')
90 {
91 $parse_options = 0;
92 next;
93 }
94
95 if ($parse_options && $arg =~ /^-+\w/)
96 {
97 $arg =~ s/^-+//;
98
99 if (defined $option{$arg})
100 {
101 &process_arg($option{$arg}, $arglist, \$errors);
102 }
103 else
104 {
105 print STDERR "$arg is not a valid option.\n";
106 $errors++;
107 }
108 }
109 else
110 {
111 push(@argv, $arg);
112 }
113 }
114 @$arglist = @argv;
115
116 foreach $arg (keys %option)
117 {
118 if ($option{$arg}->{'set'} == 0)
119 {
120 if (defined $option{$arg}->{'default'})
121 {
122 &set_var($option{$arg}, $option{$arg}->{'default'});
123 }
124 elsif (!$option{$arg}->{'regex'})
125 {
126 &set_var($option{$arg}, 0)
127 }
128 elsif (ref($option{$arg}->{'varref'}) ne 'ARRAY')
129 {
130 print STDERR "Missing command line argument -$arg.\n";
131 $errors++;
132 }
133 }
134 }
135 return $errors == 0;
136}
137
138sub process_arg
139{
140 my ($option, $arglist, $errors) = @_;
141
142 if ($option->{'regex'} && @$arglist > 0 && $arglist->[0] !~ /^-+\w/)
143 {
144 if ($arglist->[0] =~ /$option->{'regex'}/)
145 {
146 &set_var($option, shift(@$arglist));
147 }
148 else
149 {
150 print STDERR "Bad value for -$option->{'name'} argument.\n";
151 $$errors++;
152 }
153 }
154 elsif (!$option->{'regex'})
155 {
156 &set_var($option, 1);
157 }
158 else
159 {
160 print STDERR "No value given for -$option->{'name'}.\n";
161 $$errors++;
162 }
163}
164
165sub set_var
166{
167 my ($option, $value) = @_;
168 my $type = ref($option->{'varref'});
169
170 if ($type eq 'SCALAR')
171 {
172 ${$option->{'varref'}} = $value;
173 }
174 elsif ($type eq 'ARRAY')
175 {
176 push(@{$option->{'varref'}}, $value);
177 }
178 $option->{'set'} = 1;
179}
180
1811;
Note: See TracBrowser for help on using the repository browser.