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-2018 Free Software Foundation, Inc.
12 Written by Bernd Warken <groff-bernd.warken-72@web.de>
14 Last update: 10 Sep 2015
16 This file is part of 'GNU groff'.
18 'GNU groff' is free software: you can redistribute it and/or modify it
19 under the terms of the 'GNU General Public License' as published by the
20 'Free Software Foundation', either version 3 of the License, or (at your
21 option) any later version.
23 'GNU groff' is distributed in the hope that it will be useful, but
24 WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 'GNU
26 General Public License' for more details.
28 You should have received a copy of the 'GNU General Public License'
29 along with 'groff', see the files 'COPYING' and 'LICENSE' in the top
30 directory of the 'groff' source package. If not, see
31 <http://www.gnu.org/licenses/>.
43 our ( $Globals, $Args, $stderr, $v, $out );
46 # subs for second run, for remaining long options after splitting and
54 $Args->{'eps_dir'} = shift;
58 $Args->{'output'} = shift;
62 $Args->{'prefix'} = shift;
66 $Args->{'temp_dir'} = shift;
69 ); # end of %opts_with_arg
81 $Args->{'keep_all'} = TRUE;
90 $Args->{'eps_func'} = 'ly';
94 $Args->{'eps_func'} = 'pdf';
98 $Args->{'verbose'} = TRUE;
106 ); # end of %opts_noarg
109 # used variables in both runs
111 my @files = EMPTYARRAY;
115 # first run for command-line arguments
118 # global variables for first run
121 my $double_minus = FALSE;
122 my $arg = EMPTYSTRING;
126 # Split short option collections and transfer these to suitable long
127 # options from above. Note that '-v' now means '--verbose' in version
128 # 'v1.1', earlier versions had '--version' for '-v'.
145 # transfer long option abbreviations to the long options from above
150 { # option abbreviations of 3 characters
151 '--e' => '--eps_dir',
152 '--f' => '--prefix', # --f for --file_prefix
154 '--k' => '--keep_all', # and --keep_files
156 '--p' => '--prefix', # and --file_prefix
157 '--t' => '--temp_dir',
158 '--u' => '--help', # '--usage' is mapped to '--help'
162 { # option abbreviations of 4 characters
163 '--li' => '--license',
164 '--ly' => '--ly2eps',
165 '--pd' => '--pdf2eps',
166 '--pr' => '--prefix',
170 { # option abbreviations of 6 characters
171 '--verb' => '--verbose',
172 '--vers' => '--version',
176 # subs for short splitting and replacing long abbreviations
178 my $split_short = sub {
180 my @chars = split //, $1; # omit leading dash
182 # if result is TRUE: run 'next SPLIT' afterwards
184 CHARS: while ( @chars ) {
185 my $c = shift @chars;
187 unless ( exists $short_opts{$c} ) {
188 $stderr->print( "Unknown short option '-$c'." );
192 # short option exists
194 # map or transfer to special long option from above
195 my $transopt = $short_opts{$c};
197 if ( exists $opts_noarg{$transopt} ) {
198 push @splitted_args, $transopt;
199 $Args->{'verbose'} = TRUE if ( $transopt eq '--verbose' );
203 if ( exists $opts_with_arg{$transopt} ) {
204 push @splitted_args, $transopt;
207 # if @chars is not empty, option $transopt has argument
208 # in this arg, the rest of characters in @chars
209 push @splitted_args, join "", @chars;
211 return TRUE; # use 'next SPLIT' afterwards
214 # optarg is the next argument
215 $has_arg = $transopt;
216 return TRUE; # use 'next SPLIT' afterwards
217 } # end of if %opts_with_arg
218 } # end of while CHARS
219 return FALSE; # do not do anything
220 }; # end of sub for short_opt_collection
223 my $split_long = sub {
224 my $from_arg = shift;
225 $from_arg =~ /^([^=]+)/;
226 my $opt_part = lc($1);
228 if ( $from_arg =~ /=(.*)$/ ) {
232 N: for my $n ( qw/6 4 3/ ) {
233 $opt_part =~ / # match $n characters
239 my $argn = $1; # get the first $n characters
241 # no match, so luck for fewer number of chars
242 next N unless ( $argn );
244 next N unless ( exists $long_opts[$n]->{$argn} );
245 # not in $n hash, so go on to next loop for $n
247 # now $n-hash has arg
249 # map or transfer to special long opt from above
250 my $transopt = $long_opts[$n]->{$argn};
252 # test on option without arg
253 if ( exists $opts_noarg{$transopt} ) { # opt has no arg
254 $stderr->print( 'Option ' . $transopt . 'has no argument: ' .
255 $from_arg . '.' ) if ( defined($optarg) );
256 push @splitted_args, $transopt;
257 $Args->{'verbose'} = TRUE if ( $transopt eq '--verbose' );
258 return TRUE; # use 'next SPLIT' afterwards
259 } # end of if %opts_noarg
261 # test on option with arg
262 if ( exists $opts_with_arg{$transopt} ) { # opt has arg
263 push @splitted_args, $transopt;
265 # test on optarg in arg
266 if ( defined($optarg) ) {
267 push @splitted_args, $1;
268 return TRUE; # use 'next SPLIT' afterwards
269 } # end of if optarg in arg
271 # has optarg in next arg
272 $has_arg = $transopt;
273 return TRUE; # use 'next SPLIT' afterwards
274 } # end of if %opts_with_arg
276 # not with and without option, so is not permitted
277 $stderr->print( "'" . $transopt .
278 "' is unknown long option from '" . $from_arg . "'" );
279 return TRUE; # use 'next SPLIT' afterwards
281 return FALSE; # do nothing
282 }; # end of split_long()
286 # do split and transfer arguments
290 SPLIT: foreach (@ARGV) {
291 # Transform long and short options into some given long options.
292 # Split long opts with arg into 2 args (no '=').
293 # Transform short option collections into given long options.
297 push @splitted_args, $_;
298 $has_arg = EMPTYSTRING;
302 if ( $double_minus ) {
307 if ( $_ eq '-' ) { # file arg '-'
312 if ( $_ eq '--' ) { # POSIX arg '--'
313 push @splitted_args, $_;
314 $double_minus = TRUE;
318 if ( / # short option or collection of short options
329 } # end of short option
331 if ( /^--/ ) { # starts with 2 dashes, a long option
334 } # end of long option
336 # unknown option without leading dash is a file name
339 } # end of foreach SPLIT
341 # all args are considered
342 $stderr->print( "Option '$has_arg' needs an argument." )
346 push @files, '-' unless ( @files );
347 @ARGV = @splitted_args;
349 }; # end of first run, splitting with map or transfer
353 # open or ignore verbose output
355 sub install_verbose {
356 if ( $Args->{'verbose'} ) { # '--verbose' was used
357 # make verbose output into $v
358 my $s = $v->get(); # get content of string so far as array ref, close
360 $v = new FH_STDERR(); # make verbose output into STDERR
363 # print the file content into new verbose output
367 # verbose output is now active (into STDERR)
368 $v->print( "Option '-v' means '--verbose'." );
369 $v->print( "Version information is printed by option '--version'." );
370 $v->print( "#" x 72 );
372 } else { # '--verbose' was not used
373 # do not be verbose, make verbose invisible
375 $v->close(); # close and ignore the string content
378 # this is either into /dev/null or in an ignored string
380 } # end if-else about verbose
381 # '$v->print' works now in any case
383 $v->print( "Verbose output was chosen." );
385 my $s = $Globals->{'prog_is_installed'} ? '' : ' not';
386 $v->print( $Globals->{'prog'} . " is" . $s .
389 $v->print( 'The command-line options are:' );
392 $s .= " '" . $_ . "'" for ( @ARGV );
396 $s .= " '" . $_ . "'\n" for ( @files );
398 } # end install_verbose()
402 # second run of command-line arguments
405 # Second run of args with new @ARGV from the former splitting.
406 # Arguments are now splitted and transformed into special long options.
408 my $double_minus = FALSE;
411 ARGS: for my $arg ( @ARGV ) {
413 # ignore '--', file names are handled later on
414 last ARGS if ( $arg eq '--' );
417 unless ( exists $opts_with_arg{$has_arg} ) {
418 $stderr->print( "'\%opts_with_args' does not have key '" .
423 $opts_with_arg{$has_arg}->($arg);
428 if ( exists $opts_with_arg{$arg} ) {
433 if ( exists $opts_noarg{$arg} ) {
434 $opts_noarg{$arg}->();
438 # not a suitable option
439 $stderr->print( "Wrong option '" . $arg . "'." );
445 if ( $has_arg ) { # after last argument
446 die "Option '$has_arg' needs an argument.";
449 }; # end of second run
453 # handling the output of args
455 if ( $Args->{'output'} ) { # '--output' was set in the arguments
456 my $out_path = &path2abs($Args->{'output'});
457 die "Output file name $Args->{'output'} cannot be used."
458 unless ( $out_path );
461 ( $file, $dir ) = File::Basename::fileparse($out_path)
462 or die "Could not handle output file path '" . $out_path . "': " .
463 "directory name '" . $dir . "' and file name '" . $file . "'.";
465 die "Could not find output directory for '" . $Args->{'output'} . "'"
467 die "Could not find output file: '" . $Args->{'output'} .
468 "'" unless ( $file );
471 die "Could not write to output directory '" . $dir . "'."
474 $dir = &make_dir($dir);
475 die "Could not create output directory in: '" . $out_path . "'."
479 # now $dir is a writable directory
481 if ( -e $out_path ) {
482 die "Could not write to output file '" . $out_path . "'."
483 unless ( -w $out_path );
486 $out = new FH_FILE( $out_path );
487 $v->print( "Output goes to file '" . $out_path . "'." );
488 } else { # '--output' was not set
489 $out = new FH_STDOUT();
491 # no $out is the right behavior for standard output
493 # $Args->{'prefix'} .= '_' . $Args->{'eps_func'} . '2eps';
500 ########################################################################