]> git.lyx.org Git - lyx.git/blob - development/tools/GetOptions.pm
ctests: ignore Japanese dvi3 systemF tests
[lyx.git] / development / tools / GetOptions.pm
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3
4 # file GetOptions.pm
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING
7 # or at http://www.lyx.org/about/licence.php
8 #
9 # author Kornel Benko
10 # Full author contact details are available in the file CREDITS
11 # or at https://www.lyx.org/Credits
12 #
13 # Used as wrapper for Getopt::Mixed
14 # as
15 #    use GetOptions;
16 #    ...
17 #    my %optionsDef = (
18 #    ...
19 #    );
20 #    my %options = %{&handleOptions(\%optionsDef)};
21
22 package GetOptions;
23
24 use strict;
25 our(@EXPORT, @ISA);
26
27 sub handleOptions($);
28
29 BEGIN {
30   use Exporter   ();
31   @ISA        = qw(Exporter);
32   @EXPORT     = qw(handleOptions);
33 }
34
35 use warnings;
36 use Getopt::Mixed;
37
38 sub makeOpts();            # Create option spec for Getopt::Mixed::init()
39 sub makeHelp();            # Create help-string to describe options
40
41 # Following fields for a parameter can be defined:
42 # fieldname:         Name of entry in %options
43 # type:              [:=][sif], ':' = optional, '=' = required, 's' = string, 'i' = integer, 'f' = float
44 # alias:             reference to a list of aliases e.g. ["alias1", "alias2", ... ]
45 # listsep:           Separator for multiple data
46 # comment:           Parameter description
47
48 my %optionsDef = ();
49 #option|param|type|aliases|comment
50 my $helpFormat = "  %-8.8s|%-9.9s|%-7.7s|%-17.17s|%s\n";
51
52 sub handleOptions($)
53 {
54   if (ref($_[0]) eq "ARRAY") {
55     for (my $i = 0; defined($_[0]->[$i]); $i++) {
56       my $rO = $_[0]->[$i];
57       $optionsDef{$rO->[0]} = $rO->[1];
58       $optionsDef{$rO->[0]}->{Sort} = $i+2;
59     }
60   }
61   else {
62     %optionsDef = %{$_[0]};
63   }
64   $optionsDef{h}->{fieldname} = "help";
65   $optionsDef{h}->{alias} = ["help"];
66   $optionsDef{h}->{Sort} = 0;
67   $optionsDef{v}->{fieldname} = "verbose";
68   $optionsDef{v}->{alias} = ["verbose"];
69   $optionsDef{v}->{comment} = "Display recognized params";
70   $optionsDef{v}->{Sort} = 1;
71
72   my %options = ("help" => 0);
73   my $opts = &makeOpts();
74
75   Getopt::Mixed::init($opts);
76   while( my( $option, $value, $pretty ) = Getopt::Mixed::nextOption()) {
77     if (defined($optionsDef{$option})) {
78       my $fieldname = $optionsDef{$option}->{fieldname};
79       if (exists($options{$fieldname}) && ($option ne "h")) {
80         print "Option $option already set\n";
81         if (defined($options{$fieldname})) {
82           print "Value \"$value\" would overwrite ";
83           if (ref($options{$fieldname}) eq "ARRAY") {
84             print "\"" . join(',', @{$options{$fieldname}}) . "\"\n";
85           }
86           else {
87             print "\"$options{$fieldname}\"\n";
88           }
89         }
90         $option = "h";
91         $fieldname = "help";
92       }
93       if ($option eq "h") {
94         print "Syntax: $0 options xxxx ...\n";
95         print "Available options:\n";
96         printf($helpFormat, "option", "param", "type", "aliases", "comment");
97         print "  " . "-" x 90 . "\n";
98         my $optx = &makeHelp();
99         print "$optx";
100         $options{$fieldname} = 1;
101       }
102       else {
103         if (defined($optionsDef{$option}->{listsep})) {
104           my @list = split(/(?<!\\)$optionsDef{$option}->{listsep}/, $value);
105           $options{$fieldname} = \@list;
106         }
107         else {
108           $options{$fieldname} = $value;
109         }
110       }
111     }
112   }
113
114   Getopt::Mixed::cleanup();
115   if (exists($options{verbose})) {
116     printf("Found following options:\n    %-16soptvalue\n", "option");
117     print "    " . "-" x 32 . "\n";
118     for my $k (sort keys %options) {
119       if (defined($options{$k})) {
120         my $val;
121         if (ref($options{$k}) eq "ARRAY") {
122           $val = join(',', @{$options{$k}});
123         }
124         else {
125           $val = $options{$k};
126         }
127         printf("    %-16s%s\n", $k, $val);
128       }
129       else {
130         print "    $k\n";
131       }
132     }
133   }
134   if ($options{help}) {
135     exit 0;
136   }
137   return \%options;
138 }
139
140 #############################################################
141
142 # Create option spec for Getopt::Mixed::init()
143 sub makeOpts()
144 {
145   my $first = 1;
146   my $opts = "";
147   for my $ex (sort keys %optionsDef) {
148     my $e = $optionsDef{$ex};
149     if (! $first) {
150       $opts .= " ";
151     }
152     $first = 0;
153     $opts .= $ex;
154     if (defined($e->{type})) {
155       my $tp = $e->{type};
156       $opts .= $tp;
157     }
158     if (defined($e->{alias})) {
159       for my $a (@{$e->{alias}}) {
160         $opts .= " $a>$ex";
161       }
162     }
163   }
164   return($opts);
165 }
166
167 sub sortHelp
168 {
169   if (defined($optionsDef{$a}->{Sort})) {
170     if (defined($optionsDef{$b}->{Sort})) {
171       return $optionsDef{$a}->{Sort} <=> $optionsDef{$b}->{Sort};
172     }
173     return -1;
174   }
175   if (defined($optionsDef{$b}->{Sort})) {
176     return 1;
177   }
178   else {
179     return $a cmp $b;
180   }
181 }
182
183 # Create help-string to describe options
184 sub makeHelp()
185 {
186   my $opts = "";
187   my %modifier = (
188     ":" => "optional",
189     "=" => "required",
190     "s" => "string",
191     "i" => "integer",
192     "f" => "float",
193       );
194   for my $ex (sort sortHelp keys %optionsDef) {
195     my $e = $optionsDef{$ex};
196     my $type = "";
197     my $needed = "";
198     my $partype = "";
199     my $aliases = "";
200     my $comment = "";
201     if (defined($e->{type})) {
202       my $tp = $e->{type};
203       if ($tp =~ /^([:=])([sif])$/) {
204         $needed = $modifier{$1};
205         $partype = $modifier{$2};
206       }
207       else {
208         print "wrong option type: $tp\n";
209         exit(1);
210       }
211     }
212     if (defined($e->{alias})) {
213       $aliases = join(',', @{$e->{alias}});
214     }
215     if (defined($e->{comment})) {
216       $comment = $e->{comment};
217     }
218     $opts .= sprintf($helpFormat, $ex, $needed, $partype, $aliases, $comment);
219     if (defined($e->{comment2})) {
220       my $fill = "_" x 20;
221       $opts .= sprintf($helpFormat, $fill, $fill, $fill, $fill, $e->{comment2});
222     }
223   }
224   return($opts);
225 }
226
227 #############################################################
228 1;
229