#!/usr/bin/env perl #use strict; #use warnings; # do a clean up if we get a CTRL-C $SIG{INT} = sub { unlink "lesspipe.sh.tmp"; print "\n"; exit 1 }; use vars qw($opt_help $opt_prefix $opt_yes $opt_default $opt_ask $opt_nomake $opt_shell $ifsyntax %have %rep $recursion); # the above line will use any perl that is in your PATH. You might want to # replace it by #!/usr/bin/perl or similar if this does not work for you. use Getopt::Long; Getopt::Long::Configure("prefix_pattern=--"); my $result = GetOptions qw(help+ prefix=s shell=s yes+ default+ ask+ nomake+); ### still missing: check proper version of tar, cpio, gzip, bzip2 if ( $ARGV[0] or ! $result or $opt_help) { print << 'EOF'; Usage: configure [options] Options: --help print this message --ask ask questions when running make (this is the default for configure but without --ask it is not for make) --default do not ask questions, try to guess correct answer --yes like --default but assume ´yes´ to all questions --shell= specify full path to an alternative shell to use --nomake do not generate a Makefile Directory and file names: --prefix=PREFIX install lesspipe.sh in PREFIX/bin (/usr/local) configure generates by default both lesspipe.sh and Makefile configure tries to find required and optional programs for lesspipe.sh If optional programs are not found, then you can choose between - giving the correct location of the program if installed - including the code in lesspipe.sh without having the program - or skipping the code for the missing program. EOF exit !$opt_help ? 1 : 0; } $opt_prefix ||= '/usr/local'; # remove trailing slash and trailing bin directory print "removed trailing /bin dir from prefix\n" if $opt_prefix =~ m|/bin/?$|; $opt_prefix =~ s|(/bin)?/?$||; if ( $opt_shell and -f $opt_shell and $opt_shell =~ /^\// ) { print "trying alternate shell: $opt_shell\n"; } elsif ( $opt_shell) { print "unuseable shell $opt_shell: not executable or no absolute path\n"; exit 1; } my $mode = $opt_ask ? "" : $opt_yes ? "yes" : "default"; if ( ! $opt_nomake ) { open OUT, ">Makefile"; print OUT << "EOF"; # This is a generated file, do not edit it. Use configure to modify it PREFIX = $opt_prefix MODE = $mode .PHONY: install all: ./configure --prefix=\$(PREFIX) --nomake --\$(MODE) test: ./test.pl install: mkdir -p \$(PREFIX)/bin cp ./code2color ./sxw2txt ./lesspipe.sh \$(PREFIX)/bin test -r \$(PREFIX)/share/man/man1 && cp ./lesspipe.1 \$(PREFIX)/share/man/man1 chmod 0755 \$(PREFIX)/bin/lesspipe.sh chmod 0755 \$(PREFIX)/bin/sxw2txt chmod 0755 \$(PREFIX)/bin/code2color clean: mv Makefile Makefile.old rm -f lesspipe.sh EOF close OUT; } $|=1; # Check version of file command even before trying to create lesspipe.sh check_file_vers(); open IN, "lesspipe.sh.in"; open OUT, ">lesspipe.sh.tmp"; my $in = 1; my $shell = check_shell_vers(); # ask if syntax highlighting should be included $ifsyntax = ''; if ($opt_yes) { $ifsyntax = 'y'; } elsif ($opt_default) { $ifsyntax = 'n'; } else { while ( $ifsyntax !~ /^[yn]/i ) { print "Activate syntax highlighting code [y/N] ? "; $ifsyntax = ; $ifsyntax = "\L$ifsyntax"; chomp $ifsyntax; $ifsyntax ||= 'n'; } } while () { s/^/#/ if /^setopt / and $shell ne 'zsh'; if (/set -A cmd / and $shell ne 'ksh') { s/$/)/; s/set -A cmd /cmd=(/; } # line #ifdef prog1, prog2, ... encountered, store prog1, prog2, ... in @progs if ( /^#ifdef\s+(.*)/ ) { %rep = (); $_ = $1; chomp; my @progs = split /,/; # check if @progs existing and executable ($in == 1) $in = inpath ("Include code anyway", @progs); # line #elif prog1, prog2, ... seen, store prog1, prog2, ... in @progs } elsif (/^#elif\s+(.*)/ ) { $in = 1 - $in; next unless $in; %rep = (); $_ = $1; chomp; my @progs = split /,/; # check if @progs existing and executable ($in == 1) $in = inpath ("Include code anyway", @progs); # line #endif encountered, clear list of replacement strings %rep } elsif (/^#else\b/ ) { $in = 1 - $in; next unless $in; %rep = (); } elsif (/^#endif\s/ ) { %rep = (); # unconditionally accept all statements after #endif $in = 1; } elsif ( $in ) { # make replacements in lines if neccessary ($in == 1) for my $p (keys %rep) { s/\b$p\b/$rep{$p}/ unless /^#/; } # and write out the line print OUT; } } close OUT; chmod 0755, "lesspipe.sh.tmp"; rename "lesspipe.sh.tmp", "lesspipe.sh"; print "lesspipe.sh with", $ifsyntax eq "n" ? 'out' : '', " syntax highlighting created\n"; print "Please make sure to copy lesspipe.sh ", $ifsyntax ne 'n' ? "and code2color " : "", "to $opt_prefix/bin\n"; sub inpath { my $string = shift; my %optstr = ( cabextract => '-v', bzip2 => '-h' ); for my $prog ( @_ ) { $rep{$prog} = $have{$prog} if $have{$prog} and $have{$prog} =~ /^\//; $rep{file} = $have{file} if $prog eq 'file'; $rep{file} = $have{gfile} if $prog eq 'gfile'; # conditionally activate syntax highlighting code return $ifsyntax ne 'n' if $prog eq 'perl'; return 1 if $have{$prog} and $have{$prog} ne 'N'; return 0 if $have{$prog} and $have{$prog} eq 'N'; my $ok = 0; my $which_one = ""; print "checking $prog..."; for ( split /:/, $ENV{PATH} ) { next unless m|^/|; # consider only absolute PATH elements # skip bzip2 and cabextract if version not at least 1.0 if (exists $optstr{$prog} and -x "$_/$prog") { my $vs = `$_/$prog $optstr{$prog} 2>&1`; $vs = $1 if $vs =~ /\b(\d+\.\d+)\b/; if ($vs < 1.0) { print "$prog version $vs unuseable, need at least 1.0\n"; $which_one = "$_/"; next; } else { # only if we had already a wrong version $which_one = "$_/" if $which_one; } } $have{$prog} = "$which_one$prog", last if -x "$_/$prog"; } if ( $have{$prog} ) { print "using $have{$prog}\n"; $rep{$prog} = $have{$prog}; } else { print "not found\n"; my $yesno = get_answer($string, $prog); $have{$prog} = $yesno if ! $have{$prog} and $yesno =~ /^[yn]$/i; if (exists $optstr{$prog} and $have{$prog} =~ /^\//) { my $vs = `$have{$prog} $optstr{$prog}` if -x $have{$prog}; $vs = $1 if $vs =~ /\b(\d+\.\d+)\b/; if ($vs < 1.0) { $have{$prog} = ""; print "$prog version $vs unuseable, need at least 1.0\n"; } } $rep{$prog} = $have{$prog} if $have{$prog} and $have{$prog} =~ /^\//; return 0 if $yesno !~ /^y/i; } } return 1; } sub get_answer { return 'y' if $opt_yes; return 'N' if $opt_default; my ($string, $prog) = @_; my $yesno; while ( ! $yesno or $yesno !~ /^[yn]/i ) { print "$string [y/N or ] ? "; $yesno = ; chomp $yesno; $yesno = 'N' if ! $yesno or $yesno =~ /^n/i; if ( $yesno =~ m|^/| ) { if ( -x $yesno ) { $have{$prog} = $yesno; $yesno = 'y'; } else { print "Program $prog not found (or at least not executable)\n"; $yesno = ''; } } } return $yesno; } sub check_file_vers { $recursion++; # special treatment for file program inpath("Look for GNU gfile", 'file'); my $rc = system "$have{file} -L ./configure >/dev/null 2>&1"; if ( $rc ) { print " found system version of file, looking for GNU file\n"; $have{file} = $have{gfile} if $have{gfile}; } $rc = system "$have{file} -L ./configure >/dev/null 2>&1"; if ( $rc ) { print " found system version of file only, consider using GNU file\n"; return if $recursion > 1; if ($rep{file} =~ m|^/|) { $have{file} = $rep{file}; check_file_vers(); } } else { my $vers = `$have{file} -v`; $vers = $1 if $vers =~ /(\d+\.\d+)/; if ( $vers < 3.27 ) { $have{file} .= ' -L'; print < 1; my $yesno = 'y' if $opt_default; $yesno = get_answer("Continue anyway", 'file') unless $opt_default; if ($rep{file} =~ m|^/|) { $have{file} = $rep{file}; check_file_vers(); } exit 1 if $yesno =~ /^n/i; } else { $have{file} .= ' -L -s'; print " found GNU file $vers (ok)\n"; } } } sub check_shell_vers { # define useable shells, the order is important ! my @shells = qw( /bin/sh /bin/bash /bin/zsh /bin/ksh ); @shells = ( $opt_shell ) if $opt_shell; my @bad = (); # reorder list of shells depending on OS if ( $^O ne 'linux' ) { my @tmp = reverse @shells; @shells = @tmp; } elsif ( defined $shells[1] ) { ($shells[0], $shells[1]) = ($shells[1], $shells[0]); } my $selected_shell = ''; my $shellcmd = ''; for my $shell ( @shells ) { # get the basename of the shell and shell options my ($path, $name, $opt); if ( $shell =~ /(.*)\/([^\/]+)(\s.*)$/ ) { ($path, $name, $opt) = ($1, $2, $3); } else { ($path, $name, $opt) = ($1, $2, "") if $shell =~ /(.*)\/([^\/]+)\s*$/; } # do we have the shell in the PATH my $versstr = uc $name.'_VERSION'; $versstr = 'BASH_VERSION' if $name eq 'sh'; my @where = grep { -x $_."/$name" } split ':', $ENV{PATH}; $where[0] = $path if -x $path.'/'.$name; my $file = $where[0].'/'.$name if $where[0]; if ( ! $where[0] or ! -x $file ) { print "$name not found in the PATH\n"; push @bad, $shell; next; } # get the shell version my $v = `$file -c \'echo \$$versstr\'`; chomp $v; ### print "$file $v found in the PATH\n"; if ( $name eq 'bash' or $name eq 'sh' ) { my $tst = `$file -c \'if [[ \"a\" = \"a\" ]];then true;fi 2>&1\'`; if ( $tst ) { print "skipping $shell $v, need at least 2.03\n" if $v < 2.03; print "skipping $shell $v, need at least 2.04\n" if $v == 2.03; push @bad, $shell; next; } # pdksh seems to work properly now #} elsif ( $v =~ /PD KSH/ ) { # print "only $shell $v available, reduced functionality!\n" # if $#bad == 1; } $selected_shell = $name if ! $selected_shell; $shellcmd = "$file$opt" if ! $shellcmd; } if ( !$selected_shell ) { print "Sorry, no useable shell found, cannot create lesspipe.sh\n", @bad; print "You could run configure --shell= to retry\n"; exit 1; } else { print OUT "#!$shellcmd\n"; print "Using $shellcmd from the list of available shells:\n @shells\n" if ! $opt_shell; print "The following shells are unuseable: @bad\n" if @bad; } return $selected_shell; }