home *** CD-ROM | disk | FTP | other *** search
- From: tchrist@convex.com (Tom Christiansen)
- Newsgroups: comp.lang.perl,alt.sources
- Subject: preambulate: stick NIH header on perl programs
- Message-ID: <1991Jul11.010856.12783@convex.com>
- Date: 11 Jul 91 01:08:56 GMT
-
- The following script can be used to help a perl program execute even if
- the path and version of the perl executable are unknown by sticking a
- system-independent preamble in front of your script.
-
- A nice thing about this is that it tries to find a good patchlevel of
- perl. Failing that, even if you've used something that's syntactically
- too advanced for the current version (such as 'require' at 3.018), you
- will get a semi-decent error message instead of a syntax error.
-
- The way it works is to first put a header that it still tries very hard to
- to call the first perl in your path. This should work even if #! doesn't
- work on your system or the program is called by any Bourne- or csh-compatible
- shell (or of course perl). Once it's done this, it makes sure that the
- version of perl it's running under is at least as high as the one it was
- wrapped with. If not, it looks around to try to find a perl with a high
- enough version number and execs one if it can find it. Finally, it evals
- the real script, which allows it to catch any version-dependent syntax errors.
-
- Usage:
-
- preambulate < old-script > new-script
- or
- preambulate script1 script2 script3 ...
-
-
- The second form puts the old scripts in script1.bak etc, and the wrapped
- version back into script1. Make sure you preambulate with a version of
- perl that works on your script, like
-
- perl4.003 script && perl4.003 preambulate script && script
-
- --tom
-
- #!/usr/local/bin/perl
- #
- # preambulate -- wrap a perl program with a system-independent preamble.
- #
- # Tom Christiansen tchrist@convex.com
-
- $mypath = '/usr/local/bin/perl';
- ($myversion, $mypatchlevel) = $] =~ /(\d+\.\d+).*\nPatch level: (\d+)/;
-
-
- unless (@ARGV) {
- unshift(@ARGV, '-');
- $was_stdin++;
- }
-
- while ($file = shift) {
- open file || die "can't open $file: $!";
- $mode = (stat(file))[2] & 0777;
- if ($file ne '-') {
- $TMP = "$file.tmp";
- open (TMP, ">$TMP") || die "can't create $TMP: $!";
- } else {
- open (TMP, ">&STDOUT");
- }
- print TMP <<'EOF';
- #!/bin/sh -- need to mention perl here to avoid recursion
-
- 'true' || eval 'exec perl -S $0 $argv:q';
- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- if 0;
-
- VERSION_SANITY: {
- package VERSION_SANITY;
- local($_);
- EOF
- print TMP <<"EOF";
- \$PERL_PATH = '$mypath';
- local(\$version, \$patchlevel) = ($myversion, $mypatchlevel);
- EOF
-
- print TMP <<'EOF';
-
- local($want_vp) = sprintf("%d.%03d", $version, $patchlevel);
- local($need_perl) = $PERL_PATH . $want_vp;
-
- die "can't get version"
- unless $] =~ /(\d+\.\d+).*\nPatch level: (\d+)/;
-
- sub try_version {
- warn "current perl version ($got_vp) too low, execing $need_perl\n";
- exec $need_perl, $0, @ARGV;
- warn "exec of $need_perl failed: $!";
- }
-
- if ($1 < $version || $2 < $patchlevel) {
- local($got_vp) = sprintf("%d.%03d", $1, $2);
- &try_version if -x $need_perl;
- for $need_perl (reverse sort </usr/local/bin/perl* /usr/bin/perl*>) {
- next unless $need_perl =~ /perl(\d+)\.(\d+)$/;
- &try_version if $1 >= $version && $2 >= $patchlevel;
- }
- warn "WARNING: perl version too low: $got_vp < $want_vp; good luck...\n";
- }
- }
-
- eval <<'___VERSION_SANITY___';
-
- # BEGIN REAL PROGRAM
-
- EOF
-
- while (<file>) {
- print TMP;
- }
-
- print TMP <<'EOF';
-
-
- # END REAL PROGRAM
-
- ___VERSION_SANITY___
-
- die "$0: OOPS, YOU LOSE: $@" if $@;
-
- exit 0;
-
- EOF
-
- unless ($file eq '-') {
- close TMP;
- chmod $mode, $TMP;
- rename ($file, "$file.bak") || die "can't rename $file to $file.bak: $!";
- rename ($TMP, $file) || die "can't rename $TMP to $file: $!";
- }
- }
-
- --
- "GUIs normally make it simple to accomplish simple actions and impossible
- to accomplish complex actions." --Doug Gwyn (22/Jun/91 in comp.unix.wizards)
-
- Tom Christiansen tchrist@convex.com convex!tchrist
-