Changeset 171

Show
Ignore:
Timestamp:
07/06/04 02:22:14 (4 years ago)
Author:
svn
Message:

Added context support. This breaks all previous ACTION and HELP subroutines, in
that the first argument is now a CLI::Context object.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • manage/trunk/CLI.pm

    r170 r171  
    1111use Term::ReadKey; 
    1212use POSIX qw(ctermid floor); 
     13use CLI::Context; 
    1314 
    1415$VERSION = 0.1; 
     
    106107# 
    107108# parse_node(\@tokens [, $node, \@args, $trackall]) 
     109# parse_node($ctx [, $trackall]) 
    108110sub parse_node { 
    109111my $self = shift; 
    110 my @tokens = @{$_[0]}; 
    111 my %cmd = (@_ > 1 ? %{$_[1]} : %{$self->{grammar}}); 
    112 my @args = (@_ > 2 ? @{$_[2]} : ()); 
    113 my $trackallparent = (@_ > 3 ? $_[3] : 0); 
    114 my $token = shift(@tokens); 
     112my $ctx = shift; 
     113my $cmd = $ctx->current_grammar(); 
     114my $trackallparent = @_ ? shift() : 0; 
     115my $token = $ctx->next_token(); 
    115116my ($width, $height) = GetTerminalSize(*STDIN); 
    116117 
     
    125126 
    126127                # Trailing tokens after help 
    127                 return ('ERROR', 'Trailing tokens after ?') if @tokens
     128                return ('ERROR', 'Trailing tokens after ?') if $ctx->more_tokens()
    128129 
    129130                # Construct help string 
    130                 $help .= $format->paragraphs(split(/^\s*$/m, $cmd{HELPHEADER})) . "\n" if $cmd{HELPHEADER}; 
     131                $help .= $format->paragraphs(split(/^\s*$/m, $cmd->{HELPHEADER})) . "\n" if $cmd->{HELPHEADER}; 
    131132 
    132133        my $process_help = sub { 
     
    139140                                $commands->{$help->[0]} = $help->[1]; 
    140141                        } elsif ($type eq 'CODE') { 
    141                                 %$commands = (%$commands, $help->(@args)); 
     142                                %$commands = (%$commands, $help->($ctx)); 
    142143                        } elsif (!$type) { 
    143144                                $commands->{$command} = $help; 
     
    145146                }; 
    146147 
    147                 for my $key (keys %cmd) { 
     148                for my $key (keys %$cmd) { 
    148149                my $text = $key; 
    149150 
     
    151152                        $text =~ s/^(\d+\))?(\$(\*)?)?//; 
    152153 
    153                         if (ref($cmd{$key}) eq 'HASH' and $cmd{$key}->{HELP}) { 
    154                                 $process_help->($cmd{$key}->{HELP}, \%commands, $text); 
     154                        if (ref($cmd->{$key}) eq 'HASH' and $cmd->{$key}->{HELP}) { 
     155                                $process_help->($cmd->{$key}->{HELP}, \%commands, $text); 
    155156                        } else { 
    156157                                $commands{$text} = ''; 
     
    161162                # key. If it exists, use this as the help line for <eol>, otherwise try 
    162163                # HELP, then generate a warning. 
    163                 if ($cmd{ACTION}) { 
    164                         if (ref($cmd{ACTION}) eq 'HASH' and $cmd{ACTION}->{HELP}) { 
    165                                 $process_help->($cmd{ACTION}->{HELP}, \%commands, '<eol>'); 
    166                         } elsif ($cmd{ACTIONHELP}) { 
    167                                 $commands{'<eol>'} = $cmd{ACTIONHELP}; 
    168                         } elsif ($cmd{HELP}) { 
    169                                 $process_help->($cmd{HELP}, \%commands, '<eol>'); 
     164                if ($cmd->{ACTION}) { 
     165                        if (ref($cmd->{ACTION}) eq 'HASH' and $cmd->{ACTION}->{HELP}) { 
     166                                $process_help->($cmd->{ACTION}->{HELP}, \%commands, '<eol>'); 
     167                        } elsif ($cmd->{ACTIONHELP}) { 
     168                                $commands{'<eol>'} = $cmd->{ACTIONHELP}; 
     169                        } elsif ($cmd->{HELP}) { 
     170                                $process_help->($cmd->{HELP}, \%commands, '<eol>'); 
    170171                        } else { 
    171172                                $commands{'<eol>'} = "\e[31m\e[1m(need ACTIONHELP, ACTION->HELP or HELP entry)\e[0m"; 
     
    187188                } 
    188189 
    189                 $help .= "\n" if $cmd{HELPFOOTER} or $cmd{HELPHEADER}; 
    190                 $help .= $cmd{HELPFOOTER} . "\n" if $cmd{HELPFOOTER}; 
     190                $help .= "\n" if $cmd->{HELPFOOTER} or $cmd->{HELPHEADER}; 
     191                $help .= $cmd->{HELPFOOTER} . "\n" if $cmd->{HELPFOOTER}; 
    191192                return ('ERROR', 'No help available.') unless defined($help) and $help ne ''; 
    192193                return ('HELP', $help); 
     
    194195 
    195196        # Parse command itself 
    196         if (defined($token) or $cmd{ACTION} or $cmd{ERROR}) { 
     197        if (defined($token) or $cmd->{ACTION} or $cmd->{ERROR}) { 
    197198                for my $rx (sort { 
    198199                my ($lhs, $rhs) = ($a =~ /^\d+\)/, $b =~ /^\d+\)/); 
     
    226227                                } 
    227228                        } 
    228                 } keys %cmd) { 
     229                } keys %$cmd) { 
    229230                my $key = $rx; 
    230231                my $trackvar = 0; 
     
    252253 
    253254                        if (defined($token)) { 
    254                         my @candidates = grep(/^(\d+\))?(\$(\*)?)?\Q$token\E/, keys(%cmd)); 
     255                        my @candidates = grep(/^(\d+\))?(\$(\*)?)?\Q$token\E/, keys(%$cmd)); 
    255256 
    256257                                $unique = 1 if @candidates == 1 and $candidates[0] eq $key; 
     
    258259 
    259260                        if ($unique or (!defined($token) and $rx eq 'ACTION') or (defined($token) and $token =~ /^(?:$rx)$/is)) { 
    260                         my $type = ref($cmd{$key}); 
    261  
    262                                 push(@args, $token) if $trackvar; 
     261                        my $type = ref($cmd->{$key}); 
     262 
     263                                $ctx->next_arg($token) if $trackvar; 
    263264 
    264265                                # Recurse if we are tracking 
    265                                 return $self->parse_node(\@tokens, \%cmd, \@args, $trackall) 
    266                                         if @tokens and $trackall; 
     266                                return $self->parse_node($ctx->next_grammar($cmd), $trackall) 
     267                                        if $ctx->more_tokens() and $trackall; 
    267268 
    268269                                if ($type eq 'HASH') { 
    269                                         push(@tokens, $token) if $rx eq 'ACTION'; 
    270                                         return $self->parse_node(\@tokens, $cmd{$key}, \@args); 
     270                                        $ctx->inject_token($token) if $rx eq 'ACTION'; 
     271                                        return $self->parse_node($ctx->next_grammar($cmd->{$key})); 
    271272                                } elsif ($type eq 'CODE') { 
    272273                                        # Tokens are still remaining 
    273                                         if (@tokens) { 
     274                                        if ($ctx->more_tokens()) { 
    274275                                                return ('HELP', "\e[32m\e[1mOK Command is complete.\e[0m\n") 
    275                                                         if "@tokens" eq '?'; 
    276                                                 return ('ERROR', "Trailing tokens: '@tokens' (possibly missing help?).") 
     276                                                        if $ctx->peek_token() eq '?'; 
     277                                                return ('ERROR', "Trailing tokens: '" . join(" ", $ctx->more_tokens()) . "' (possibly missing help?).") 
    277278                                        } 
    278                                         return ('ACTION', $cmd{$key}, \@args); 
     279                                        return ('ACTION', $cmd->{$key}, $ctx); 
    279280                                } else { 
    280281                                        return ('ERROR', 'Invalid terminal node, should be CODE or HASH.'); 
     
    284285        } 
    285286        return ('ERROR', 'More input expected.') unless defined($token); 
    286         if ($cmd{ERROR}) { 
    287         my $error = $cmd{ERROR}; 
     287        if ($cmd->{ERROR}) { 
     288        my $error = $cmd->{ERROR}; 
    288289 
    289290                $error =~ s/\${ARG}/$token/g; 
     
    291292        } else { 
    292293                if (defined($token)) { 
    293                 my @rawcandidates = grep(/^(\d+\))?(\$(\*)?)?\Q$token\E/, keys(%cmd)); 
     294                my @rawcandidates = grep(/^(\d+\))?(\$(\*)?)?\Q$token\E/, keys(%$cmd)); 
    294295 
    295296                        if (@rawcandidates > 1) { 
     
    330331                } 
    331332        } 
    332         return $self->parse_node(\@tokens); 
     333        return $self->parse_node(new CLI::Context( 
     334                tokens => \@tokens, 
     335                grammar => $self->{grammar}, 
     336                )); 
    333337} 
    334338 
  • manage/trunk/manage

    r170 r171  
    207207 
    208208sub exec_line { 
    209 my ($type, $action, $args) = $CLI->parse("@_"); 
     209my ($type, $action, $ctx) = $CLI->parse("@_"); 
    210210 
    211211        if ($type eq 'HELP') { 
    212212                print($action); 
    213213        } elsif ($type eq 'ACTION') { 
    214                 $action->($CLI, @{$args}); 
     214                $action->($ctx, @{$ctx->args()}); 
    215215        } elsif ($type eq 'ERROR') { 
    216216                error($action); 
     
    248248                        '$.+' => { 
    249249                                ACTION => sub { 
     250                                my $ctx = shift; 
    250251                                my ($key, $value) = @_; 
    251252 
     
    266267                        }, 
    267268                        HELP => sub { 
     269                        my $ctx = shift; 
    268270                        my %help; 
    269271 
     
    275277                        ACTION => { 
    276278                                ACTION => sub { 
     279                                my $ctx = shift; 
    277280                                my $key = shift; 
    278281 
     
    290293                        HELP => 'Display full list of settings.', 
    291294                        ACTION => sub { 
     295                        my $ctx = shift; 
    292296                        my @rows = (); 
    293297 
     
    302306                clear => { 
    303307                        ACTION => sub { 
     308                        my $ctx = shift; 
     309 
     310                                print(join(" ", @{$ctx->{token_history}}) . "\n"); 
    304311                                Term::ReadLine::Gnu->clear_history(); 
    305312                                info("History cleared"); 
     
    308315                }, 
    309316                ACTION => sub { 
     317                my $ctx = shift; 
    310318                        print(join("\n", Term::ReadLine::Gnu->GetHistory) . "\n"); 
    311319                }, 
  • manage/trunk/plugins/nodelist2.pm

    r170 r171  
    22 
    33{ 
    4         HELPHEADER => "Fooo", 
    54        test => { 
    65                '1)lalala' => sub { print "FOO\n"; }, 
     
    1413                        ACTION => { 
    1514                                ACTION => sub { 
    16                                         print("STUFF: @_\n"); 
     15                                my $c = shift; 
     16 
     17                                        print("@_\n"); 
    1718                                }, 
    1819                                HELP => "Do it.",