#! /usr/bin/perl # This script extracts option strings, longopt arrays and # manpage fragments for xcftools # # This file was written by Henning Makholm # It is hereby in the public domain. # # In jurisdictions that do not recognise grants of copyright to the # public domain: I, the author and (presumably, in those jurisdictions) # copyright holder, hereby permit anyone to distribute and use this code, # in source code or binary form, with or without modifications. This # permission is world-wide and irrevocable. # # Of course, I will not be liable for any errors or shortcomings in the # code, since I give it away without asking any compenstations. # # If you use or distribute this code, I would appreciate receiving # credit for writing it, in whichever way you find proper and customary. use strict ; use warnings ; my $mastersource = "options.i" ; my $target = shift ; my @defines = ( "\U$target", "OPTI_TARGET \"$target\"" ) ; push @defines, "\U$1foo" if $target =~ /^(xcf(2|to))/ ; push @defines, "XCF2FOO" if $target eq "xcfview" ; open INFILE, "-|", join(" ","cpp -imacros config.h", (map {(my $a = "-D$_")=~s/ /=/; $a} @defines), $mastersource) or die "Cannot preprocess options." ; open OUTFILE, ">", "$target.oi" or die "Cannot write $target.oi" ; print OUTFILE "/* Autogenerated by $0 $target */\n" ; print OUTFILE "#define $_\n" for @defines ; print OUTFILE "#define OPTIONGROUP(a,b)\n" ; my %manstrings ; my $mansection = '1i' ; my @desc ; my $optstring = "" ; print OUTFILE "#ifdef HAVE_GETOPT_LONG\n" ; print OUTFILE "static const struct option longopts[] = {\n" ; my $manref = undef ; my $parskip ; while( ) { next if /^#/ ; if( /^OPTION\(([^,]+),([^,]+),(.*),\s*/ ) { my ($short,$long,$desc) = ($1,$2,$3) ; my $hasarg = '' ; if( $desc =~ s/^\s*\(([^()]+)\)\s*// ) { $hasarg = $1 ; } my @long = split / /,$long ; my $longfordesc = $long[0] ; for my $l ( @long ) { my $long = $l ; $long =~ s/^--// or print STDERR "Long option $long should have dashes\n" ; print OUTFILE "\t{ \"$long\", ",$hasarg ? 1 : 0,", 0, $short},\n" ; } if( $short =~ s/^\s*'(.)'\s*$/-$1/ ) { unshift @long, $short ; $optstring .= $1 . ($hasarg && ':') ; } else { undef $short ; } if( @long ) { (my $descarg = $hasarg ) =~ s/\"//g ; $manref = \$manstrings{$mansection}{$long[0]} ; $long[0] =~ s/^(-[^-])/\\$1/ ; $$manref = "" ; my $next = ".TP 8\n" ; $hasarg =~ s/"([^\"]*)"/\\fB$1\\fP/g ; $hasarg = " \\fI$hasarg\\fR" if $hasarg ; for my $long ( @long ) { $$manref .= $next . "\\fB$long\\fR$hasarg" ; $next = ", " ; } $$manref .= "\n" ; $parskip = 1 ; push @desc, [$short || $long[0], $descarg, $desc, $short && $long[1] ] ; } } elsif( /^\s*\)\);/ ) { $manref = undef ; } elsif( defined $manref ) { s/^\s*// ; s/''/\'/g ; s/^\(\s*// if $parskip ; $$manref .= $_ ; $parskip = 0 ; } elsif( /^OPTIONGROUP\(([^(,)]+),([^(,)]*)\)/ ) { push @desc,$2 unless $mansection eq $1 ; $mansection = $1 ; } } print OUTFILE "{0}};\n" ; print OUTFILE "#define LONGALT(s) \" (\" s \")\"\n" ; print OUTFILE "#else\n" ; print OUTFILE "#define LONGALT(s) \"\"\n" ; print OUTFILE "#endif\n" ; close INFILE ; print OUTFILE "static void\nopt_usage(FILE *f)\n{\n" ; my %d15plus ; my $longest = 2 ; for my $desc ( @desc ) { next unless ref $desc ; my $l = length $$desc[0] ; my $x = $$desc[1] ; if( $x ) { next if exists($d15plus{$x}) && $d15plus{$x} >= $l+1 ; $d15plus{$x} = $l+1 ; } else { $longest = $l if $longest < length $l ; } } print OUTFILE " int i = $longest;\n int j;\n" ; for my $d15 ( sort keys %d15plus ) { print OUTFILE " j=strlen(_(\"$d15\"))+$d15plus{$d15}; if( j>i ) i=j;\n" ; } for my $desc ( @desc ) { unless( ref $desc ) { print OUTFILE " fprintf(f,\"%s:\\n\",_(\"$desc\"));\n" if $desc ; next ; } my ($optname,$d15,$helptext,$alternative) = @$desc ; my $d1l = length($optname) ; print OUTFILE (" fprintf(f,\" ",$optname); my $f2a = "i-$d1l,\"\"" ; if( $d15 ) { print OUTFILE " " ; $f2a = "i-".($d1l+1).",_(\"$d15\")" ; } print OUTFILE "%-*s %s" ; if( $alternative ) { print OUTFILE "\" LONGALT(\"$alternative\") \""; } print OUTFILE "\\n\",$f2a,\n _(\"$helptext\"));\n" ; } print OUTFILE "}\n" ; print OUTFILE "#undef LONGALT\n" ; print OUTFILE "#define OPTSTRING \"$optstring\"\n" ; close OUTFILE or die "Problems closing $target.oi" ; for $mansection ( keys %manstrings ) { my $hash = $manstrings{$mansection} ; open OUTFILE,">","$target.$mansection" or die "Cannot write $target.$mansection" ; print OUTFILE @$hash{sort { "\U$a" cmp "\U$b" or $b cmp $a } keys %$hash} ; close OUTFILE or die "Problems closing $target.$mansection" ; }