Sunday, March 22, 2009

How the code comes out, when you're ready to pass out

# message for commit 041a7343eb452b827dbd97a0c82c8538597f86f6:
#   read built-in command implemented

sub read_bin {

    my ($prmpt, $time);
    my $line = "";
    my @argv = @_;
    my %opts = ( 'p=s' => \$prmpt,
                 't=s' => \$time,
                 'e'   => sub { "no-op" },

    do_getopt(\@argv, %opts);
    unless (@argv) {
        warn "I can't read into thin air!";
        return 0;

    if ($prmpt and -t *STDIN) {
        print $prmpt;

    eval {
        # remove custom die for ease of error check/report
        local %SIG;
        $SIG{__DIE__} = sub { die @_ };
        $SIG{ALRM}    = sub { die "timed-out\n" };
        if ($time) {
            # an s, m, or h suffix causes sleep for sec, min, or hour
            if ($time =~ /^(\d*)([smh])/) {
                if ($2 eq 's') {
                    $time = $1;
                } elsif ($2 eq 'm') {
                    $time = $1 * 60;
                } elsif ($2 eq 'h') {
                    $time = $1 * 3600;
                } else {
                    warn "internal error on ", __LINE__;
                    # NOTREACHED
            alarm $time;
        chomp($line = );
        alarm 0 if $time;
    if ($@) {
        warn $@ unless $@ eq "timed-out\n";
        # on time out, init the vars to empty strings
        @ENV{@argv} = ('') x scalar @argv;
        return 0;
    } else {
        # set each var to the words
        # XXX because ifsplit has no notion of a &split 'LIMIT'
        #     if we used ifsplit here instead of a manual split,
        #       read x y
        #       foo bar ham
        #     would set $y to 'bar' instead of 'bar ham'
        my $ifs = defined $ENV{IFS} ? qr/[$ENV{IFS}]/ : qr/\s/;
        @ENV{@argv} = grep !/^$/, split $ifs, $line, scalar(@argv);
        return 1;

from the manual page updated in commit b1317d7e6e7f91b6c3a2650f44cd4f425e381d42 with message:

read built-in command documented

and blockquoted here using the pod2html output

read [-p prompt] [-t timeout] variable ...]

Read a line from standard input, split by fields, and assign each field to the indicated variables. If the number of variables is less then the number of fields, the remaining fields will be stored 'as is' in the last variable. If there are more variables then fields, the excess variables will be undefined. A prompt may be printed before reading input, by using the -p option. The -t option may be used to specify a timeout in which to abort the operation, should the user take their sweet time about pressing CR. The timeout value can take an optional s, m, or h suffix to denote seconds, minutes, or hours. If no suffix is given, s will be assumed.

It's not the greatest... but hey, I ain't had any sleep since this mornings roll out... lol. It'll do fine for an initial implementation, until I've actually got a functioning brain to deal with it :-P

No comments:

Post a Comment