#!/usr/pkg/bin/perl

=begin metadata

Name: awk
Description: pattern-directed scanning and processing language
Author: Tom Christiansen, tchrist@perl.com
Author: Larry Wall, larry@wall.org
License: perl

=end metadata

=cut


# awk - front end for a2p

use strict;

use File::Temp qw();

my(
    $program,		# the code to eval
    @nargs,		# new args for a2p
    @vargs		# temporary holder of variables
);

END {
    close STDOUT 	    || die "$0: can't close stdout: $!\n";
    $? = 1 if $? == 255;    # from die
}

sub usage {
    warn "$0: @_\n" if @_;
    die "usage: $0 [ -F fs ] [ [-v] var=value ] [ 'prog' | -f progfile ] [ file ...  ]\n";
}

usage() unless @ARGV;

# the following dance is needed to avoid explicit
# pipes or even redirections for process control
# on broken soi-disant operating systems.

open(SAVE_OUT, '>&', STDOUT) || die "can't save stdout: $!";
die unless defined fileno SAVE_OUT;

my $tmpin_fh = File::Temp->new();
my $tmpin = $tmpin_fh->filename();
my $tmpout_fh = File::Temp->new();
my $tmpout = $tmpout_fh->filename();

# And some people think getopts does everything. Sheesh.
while (@ARGV) {
    $_ = $ARGV[0];
    if (s/^-//) {
	if (s/^F//) {
	    unless (length) { shift; $_ = $ARGV[0]; }
	    push(@nargs, "-F$_");
	    shift;
	    next;
	}
	elsif (s/^v// || /^\w+=/) {
	    unless (length) { shift; $_ = $ARGV[0]; }
	    push(@vargs, $_);
	    shift;
	    next;
	}
	elsif (s/^f//) {
	    unless (length) { shift; $_ = shift; }
	    push(@nargs, $_);
	    last;
	}
	else {
	    usage("unknown flag: -$_");
	}
    } else {
	# XXX: is it a program or an expression?
        if (/^\w+=/) {
	    push(@vargs, $_);
	    shift;
	    next;
	}
	else {
	    print {$tmpin_fh} "$_\n";
	    shift;
	    push @nargs, $tmpin;
	    last;
	}
    }
}

unshift @ARGV, @vargs;  # put back var=val statements

close($tmpin_fh) or die "can't close $tmpin: $!";

open(STDOUT, '>&', $tmpout_fh) or die "can't dup to $tmpout: $!";
$| = 1;

system 'a2p', @nargs;

if ($?) {
    die <<"HERE";
Couldn't run a2p (wait status == $?)

a2p used to come with perl, but is now distributed separately in
the App::a2p module.

HERE
}

die "empty program" unless -s $tmpout_fh;
die "empty program" unless -s $tmpout;

seek($tmpout_fh, 0, 0) or die "can't rewind $tmpout: $!";
$program = do { local $/;  <$tmpout_fh> };
close($tmpout_fh) or die "can't close $tmpout: $!";
open(STDOUT, '>&', SAVE_OUT) or die "can't restore stdout: $!";

eval qq{
    no strict;
    local \$^W = 0;
    $program;
};

if ($@) {
    die "Couldn't compile and execute awk-to-perl program: $@\n";
}

exit 0;

__END__

=head1 NAME

awk - pattern-directed scanning and processing language

=head1 SYNOPSIS

B<awk>
[ B<-F> I<fs> ]
[ [B<-v>] I<var>=I<value> ]
[ I<'prog'>
|
B<-f>~ I<progfile> ]
[ I<file> ...  ]

=head1 DESCRIPTION

This version of the standard I<awk> utility is nothing more than a
wrapper that massages its arguments and calls the I<a2p> translator to
do the real conversion into Perl, which is then compiled and executed.

=head1 SEE ALSO

a2p(1)

A. V. Aho, B. W. Kernighan, P. J. Weinberger, I<The AWK Programming
Language>, Addison-Wesley, 1988. ISBN 0-201-07981-X

The One True Awk can be found at Brian Kernighan's
http://cm.bell-labs.com/cm/cs/awkbook/index.html page.

=head1 RESTRICTIONS

I<a2p> does not attempt to translate the myriad splinter
versions of I<awk>, nor follow the arguments there to.

=head1 BUGS

This manpage should probably include the entire
I<awk> manpage, and perhaps that of I<a2p> as well.

It is not clear that I<a2p> has tracked Brian's work
in the last few years.

=head1 AUTHOR

This front-end written by Tom Christiansen, I<tchrist@perl.com>.
The I<a2p> translator was written by Larry Wall, I<larry@wall.org>,
author of Perl.

=head1 COPYRIGHT and LICENSE

This program is copyright (c) Tom Christiansen 1999.

This program is free and open software. You may use, modify, distribute,
and sell this program (and any modified variants) in any way you wish,
provided you do not restrict others from doing the same.
