1 ########################################################################
3 ########################################################################
6 groff_lilypond - integrate `lilypond' into `groff' files
8 Source file position: `<groff-source>/contrib/glilypond/args.pl'
9 Installed position: `<prefix>/lib/groff/glilypond'
11 Copyright (C) 2013-2014 Free Software Foundation, Inc.
12 Written by Bernd Warken <groff-bernd.warken-72@web.de>
14 This file is part of `GNU groff'.
16 `GNU groff' is free software: you can redistribute it and/or modify it
17 under the terms of the `GNU General Public License' as published by the
18 `Free Software Foundation', either version 3 of the License, or (at your
19 option) any later version.
21 `GNU groff' is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the `GNU
24 General Public License' for more details.
26 You should have received a copy of the 'GNU General Public License`
27 along with `groff', see the files `COPYING' and `LICENSE' in the top
28 directory of the `groff' source package. If not, see
29 <http://www.gnu.org/licenses/>.
41 our ( $Globals, $Args, $stderr, $v, $out );
44 # subs for second run, for remaining long options after splitting and
52 $Args->{'eps_dir'} = shift;
56 $Args->{'output'} = shift;
60 $Args->{'prefix'} = shift;
64 $Args->{'temp_dir'} = shift;
67 ); # end of %opts_with_arg
79 $Args->{'keep_all'} = TRUE;
88 $Args->{'eps_func'} = 'ly';
92 $Args->{'eps_func'} = 'pdf';
96 $Args->{'verbose'} = TRUE;
104 ); # end of %opts_noarg
107 # used variables in both runs
109 my @files = EMPTYARRAY;
113 # first run for command line arguments
116 # global variables for first run
119 my $double_minus = FALSE;
120 my $arg = EMPTYSTRING;
124 # Split short option collections and transfer these to suitable long
125 # options from above. Note that `-v' now means `--verbose' in version
126 # `v1.1', earlier versions had `--version' for `-v'.
143 # transfer long option abbreviations to the long options from above
148 { # option abbreviations of 3 characters
149 '--e' => '--eps_dir',
150 '--f' => '--prefix', # --f for --file_prefix
152 '--k' => '--keep_all', # and --keep_files
154 '--p' => '--prefix', # and --file_prefix
155 '--t' => '--temp_dir',
156 '--u' => '--help', # '--usage' is mapped to `--help'
160 { # option abbreviations of 4 characters
161 '--li' => '--license',
162 '--ly' => '--ly2eps',
163 '--pd' => '--pdf2eps',
164 '--pr' => '--prefix',
168 { # option abbreviations of 6 characters
169 '--verb' => '--verbose',
170 '--vers' => '--version',
174 # subs for short splitting and replacing long abbreviations
176 my $split_short = sub {
178 my @chars = split //, $1; # omit leading dash
180 # if result is TRUE: run `next SPLIT' afterwards
182 CHARS: while ( @chars ) {
183 my $c = shift @chars;
185 unless ( exists $short_opts{$c} ) {
186 $stderr->print( "Unknown short option `-$c'." );
190 # short option exists
192 # map or transfer to special long option from above
193 my $transopt = $short_opts{$c};
195 if ( exists $opts_noarg{$transopt} ) {
196 push @splitted_args, $transopt;
197 $Args->{'verbose'} = TRUE if ( $transopt eq '--verbose' );
201 if ( exists $opts_with_arg{$transopt} ) {
202 push @splitted_args, $transopt;
205 # if @chars is not empty, option $transopt has argument
206 # in this arg, the rest of characters in @chars
207 push @splitted_args, join "", @chars;
209 return TRUE; # use `next SPLIT' afterwards
212 # optarg is the next argument
213 $has_arg = $transopt;
214 return TRUE; # use `next SPLIT' afterwards
215 } # end of if %opts_with_arg
216 } # end of while CHARS
217 return FALSE; # do not do anything
218 }; # end of sub for short_opt_collection
221 my $split_long = sub {
222 my $from_arg = shift;
223 $from_arg =~ /^([^=]+)/;
224 my $opt_part = lc($1);
226 if ( $from_arg =~ /=(.*)$/ ) {
230 N: for my $n ( qw/6 4 3/ ) {
231 $opt_part =~ / # match $n characters
237 my $argn = $1; # get the first $n characters
239 # no match, so luck for fewer number of chars
240 next N unless ( $argn );
242 next N unless ( exists $long_opts[$n]->{$argn} );
243 # not in $n hash, so go on to next loop for $n
245 # now $n-hash has arg
247 # map or transfer to special long opt from above
248 my $transopt = $long_opts[$n]->{$argn};
250 # test on option without arg
251 if ( exists $opts_noarg{$transopt} ) { # opt has no arg
252 $stderr->print( 'Option ' . $transopt . 'has no argument: ' .
253 $from_arg . '.' ) if ( defined($optarg) );
254 push @splitted_args, $transopt;
255 $Args->{'verbose'} = TRUE if ( $transopt eq '--verbose' );
256 return TRUE; # use `next SPLIT' afterwards
257 } # end of if %opts_noarg
259 # test on option with arg
260 if ( exists $opts_with_arg{$transopt} ) { # opt has arg
261 push @splitted_args, $transopt;
263 # test on optarg in arg
264 if ( defined($optarg) ) {
265 push @splitted_args, $1;
266 return TRUE; # use `next SPLIT' afterwards
267 } # end of if optarg in arg
269 # has optarg in next arg
270 $has_arg = $transopt;
271 return TRUE; # use `next SPLIT' afterwards
272 } # end of if %opts_with_arg
274 # not with and without option, so is not permitted
275 $stderr->print( "`" . $transopt .
276 "' is unknown long option from `" . $from_arg . "'" );
277 return TRUE; # use `next SPLIT' afterwards
279 return FALSE; # do nothing
280 }; # end of split_long()
284 # do split and transfer arguments
288 SPLIT: foreach (@ARGV) {
289 # Transform long and short options into some given long options.
290 # Split long opts with arg into 2 args (no `=').
291 # Transform short option collections into given long options.
295 push @splitted_args, $_;
296 $has_arg = EMPTYSTRING;
300 if ( $double_minus ) {
305 if ( $_ eq '-' ) { # file arg `-'
310 if ( $_ eq '--' ) { # POSIX arg `--'
311 push @splitted_args, $_;
312 $double_minus = TRUE;
316 if ( / # short option or collection of short options
327 } # end of short option
329 if ( /^--/ ) { # starts with 2 dashes, a long option
332 } # end of long option
334 # unknown option without leading dash is a file name
337 } # end of foreach SPLIT
339 # all args are considered
340 $stderr->print( "Option `$has_arg' needs an argument." )
344 push @files, '-' unless ( @files );
345 @ARGV = @splitted_args;
347 }; # end of first run, splitting with map or transfer
351 # open or ignore verbose output
353 sub install_verbose {
354 if ( $Args->{'verbose'} ) { # `--verbose' was used
355 # make verbose output into $v
356 my $s = $v->get(); # get content of string so far as array ref, close
358 $v = new FH_STDERR(); # make verbose output into STDERR
361 # print the file content into new verbose output
365 # verbose output is now active (into STDERR)
366 $v->print( "Option `-v' means `--verbose'." );
367 $v->print( "Version information is printed by option `--version'." );
368 $v->print( "#" x 72 );
370 } else { # `--verbose' was not used
371 # do not be verbose, make verbose invisible
373 $v->close(); # close and ignore the string content
376 # this is either into /dev/null or in an ignored string
378 } # end if-else about verbose
379 # `$v->print' works now in any case
381 $v->print( "Verbose output was chosen." );
383 my $s = $Globals->{'prog_is_installed'} ? '' : ' not';
384 $v->print( $Globals->{'prog'} . " is" . $s .
387 $v->print( 'The command line options are:' );
390 $s .= " `" . $_ . "'" for ( @ARGV );
394 $s .= " `" . $_ . "'\n" for ( @files );
396 } # end install_verbose()
400 # second run of command line arguments
403 # Second run of args with new @ARGV from the former splitting.
404 # Arguments are now splitted and transformed into special long options.
406 my $double_minus = FALSE;
409 ARGS: for my $arg ( @ARGV ) {
411 # ignore `--', file names are handled later on
412 last ARGS if ( $arg eq '--' );
415 unless ( exists $opts_with_arg{$has_arg} ) {
416 $stderr->print( "`\%opts_with_args' does not have key `" .
421 $opts_with_arg{$has_arg}->($arg);
426 if ( exists $opts_with_arg{$arg} ) {
431 if ( exists $opts_noarg{$arg} ) {
432 $opts_noarg{$arg}->();
436 # not a suitable option
437 $stderr->print( "Wrong option `" . $arg . "'." );
443 if ( $has_arg ) { # after last argument
444 die "Option `$has_arg' needs an argument.";
447 }; # end of second run
451 # handling the output of args
453 if ( $Args->{'output'} ) { # `--output' was set in the arguments
454 my $out_path = &path2abs($Args->{'output'});
455 die "Output file name $Args->{'output'} cannot be used."
456 unless ( $out_path );
459 ( $file, $dir ) = File::Basename::fileparse($out_path)
460 or die "Could not handle output file path `" . $out_path . "': " .
461 "directory name `" . $dir . "' and file name `" . $file . "'.";
463 die "Could not find output directory for `" . $Args->{'output'} . "'"
465 die "Could not find output file: `" . $Args->{'output'} .
466 "'" unless ( $file );
469 die "Could not write to output directory `" . $dir . "'."
472 $dir = &make_dir($dir);
473 die "Could not create output directory in: `" . $out_path . "'."
477 # now $dir is a writable directory
479 if ( -e $out_path ) {
480 die "Could not write to output file `" . $out_path . "'."
481 unless ( -w $out_path );
484 $out = new FH_FILE( $out_path );
485 $v->print( "Output goes to file `" . $out_path . "'." );
486 } else { # `--output' was not set
487 $out = new FH_STDOUT();
489 # no $out is the right behavior for standard output
491 # $Args->{'prefix'} .= '_' . $Args->{'eps_func'} . '2eps';
498 ########################################################################