Changeset 173
- Timestamp:
- 07/07/04 01:50:51 (4 years ago)
- Files:
-
- manage/trunk/CLI/Context.pm (modified) (2 diffs)
- manage/trunk/CLI.pm (modified) (8 diffs)
- manage/trunk/manage (modified) (11 diffs)
- manage/trunk/plugins/nodelist2.pm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
manage/trunk/CLI/Context.pm
r171 r173 13 13 $self->{$key} = $args{$key}; 14 14 } 15 my @tmp = @{$self->{tokens}}; 16 $self->{all_tokens} = \@tmp; 15 17 push(@{$self->{grammar_history}}, $self->{grammar}); 16 18 return $self; 19 } 20 21 sub all_tokens() { 22 my $self = shift; 23 24 return $self->{all_tokens}; 17 25 } 18 26 … … 25 33 } 26 34 27 sub current_grammar($) { 35 sub grammar_history() { 36 my $self = shift; 37 38 return $self->{grammar_history}; 39 } 40 41 sub token_history() { 42 my $self = shift; 43 44 return $self->{token_history}; 45 } 46 47 sub current_grammar() { 28 48 my $self = shift; 29 49 manage/trunk/CLI.pm
r172 r173 64 64 } else { 65 65 $| = 1; 66 print( "\e[1m\e[31mCLI plugin '$file' error:\e[22m\n" . $format->format($@) . "\e[0m");66 print(STDERR "\e[1m\e[31mCLI plugin '$file' error:\e[22m\n" . $format->format($@) . "\e[0m"); 67 67 $| = 0; 68 68 } … … 126 126 127 127 # Trailing tokens after help 128 return ('ERROR', 'Trailing tokens after ?' ) if $ctx->more_tokens();128 return ('ERROR', 'Trailing tokens after ?', $ctx) if $ctx->more_tokens(); 129 129 130 130 # Construct help string … … 190 190 $help .= "\n" if $cmd->{HELPFOOTER} or $cmd->{HELPHEADER}; 191 191 $help .= $cmd->{HELPFOOTER} . "\n" if $cmd->{HELPFOOTER}; 192 return ('ERROR', 'No help available.' ) unless defined($help) and $help ne '';193 return ('HELP', $help );192 return ('ERROR', 'No help available.', $ctx) unless defined($help) and $help ne ''; 193 return ('HELP', $help, $ctx); 194 194 } 195 195 … … 211 211 if ($ac =~ /^[A-Z]+$/) { 212 212 if ($rhs) { 213 +1;213 -1; 214 214 } else { 215 215 $ac cmp $bc; … … 217 217 } elsif ($bc =~ /^[A-Z]+$/) { 218 218 if ($lhs) { 219 -1;219 +1; 220 220 } else { 221 221 $ac cmp $bc; … … 268 268 269 269 if ($type eq 'HASH') { 270 # Do validation 271 if ($cmd->{$key}->{VALIDATE}) { 272 return ('ERROR', "Invalid input '$token'.", $ctx) 273 unless $cmd->{$key}->{VALIDATE}->($ctx, $token, @{$ctx->args()}); 274 } 275 270 276 $ctx->inject_token($token) if $rx eq 'ACTION'; 271 277 return $self->parse_node($ctx->next_grammar($cmd->{$key})); … … 275 281 return ('HELP', "\e[32m\e[1mOK Command is complete.\e[0m\n") 276 282 if $ctx->peek_token() eq '?'; 277 return ('ERROR', "Trailing tokens: '" . join(" ", $ctx->more_tokens()) . "' (possibly missing help?)." )283 return ('ERROR', "Trailing tokens: '" . join(" ", $ctx->more_tokens()) . "' (possibly missing help?).", $ctx) 278 284 } 279 285 return ('ACTION', $cmd->{$key}, $ctx); 280 286 } else { 281 return ('ERROR', 'Invalid terminal node, should be CODE or HASH.' );282 } 283 } 284 } 285 } 286 return ('ERROR', 'More input expected.' ) unless defined($token);287 return ('ERROR', 'Invalid terminal node, should be CODE or HASH.', $ctx); 288 } 289 } 290 } 291 } 292 return ('ERROR', 'More input expected.', $ctx) unless defined($token); 287 293 if ($cmd->{ERROR}) { 288 294 my $error = $cmd->{ERROR}; 289 295 290 296 $error =~ s/\${ARG}/$token/g; 291 return ('ERROR', $error );297 return ('ERROR', $error, $ctx); 292 298 } else { 293 299 if (defined($token)) { … … 303 309 push(@candidates, $cp); 304 310 } 305 return ('ERROR', "No unique candidates for '$token', candidates are '@candidates'" )306 } 307 } 308 return ('ERROR', "Unrecognized command '$token'." );311 return ('ERROR', "No unique candidates for '$token', candidates are '@candidates'", $ctx) 312 } 313 } 314 return ('ERROR', "Unrecognized command '$token'.", $ctx); 309 315 } 310 316 } manage/trunk/manage
r172 r173 17 17 use Text::Table; 18 18 use POSIX qw(ctermid); 19 20 use constant CMD_ARG => 1; 21 use constant CMD_STDIN => 2; 22 use constant CMD_INTERACTIVE => 3; 19 23 20 24 … … 39 43 white => "\e[37m", 40 44 ); 41 %C = ( bold => "", underline => "", reset => "", normal => "", black => "",45 %C = ( bold => "", nounderline => "", underline => "", reset => "", normal => "", black => "", 42 46 red => "", green => "", brown => "", blue => "", magenta => "", cyan => "", 43 47 white => "" ) unless (-t STDOUT); … … 49 53 # Plugin path 50 54 my $PLUGINS = "/usr/local/libexec/$SELF"; 51 #$PLUGINS = "./plugins";55 $PLUGINS = "./plugins"; 52 56 our %CONF = ( 53 57 prompt => { … … 116 120 sub fatal { 117 121 my $str = "$C{red}$C{bold}FTL @_$C{reset}\n"; 118 print( $str);122 print(STDERR $str); 119 123 logger($str); 120 124 exit 1; … … 124 128 my $str = "$C{red}$C{bold}ERR @_$C{reset}\n"; 125 129 126 print( $str);130 print(STDERR $str); 127 131 logger($str); 128 132 return undef; … … 132 136 my $str = "$C{brown}$C{bold}WRN @_$C{reset}\n"; 133 137 134 print( $str);138 print(STDERR $str); 135 139 logger($str); 136 140 return undef; … … 207 211 208 212 sub exec_line { 213 my $mode = shift; 209 214 my ($type, $action, $ctx) = $CLI->parse("@_"); 210 215 … … 214 219 $action->($ctx, @{$ctx->args()}); 215 220 } elsif ($type eq 'ERROR') { 221 my @gh = @{$ctx->grammar_history()}; 222 my @th = @{$ctx->token_history()}; 223 my @ath = @{$ctx->all_tokens()}; 224 my $grammar = $gh[$#gh]; 225 my @candidates; 226 push(@th, "") if $action =~ /More input expected/; 227 my $prefix = ' ' x length("@th[0 .. $#th - 1]") . (@th < @ath ? ' ' : ''); 228 229 $action = "$C{underline}@ath$C{nounderline}\n $prefix^ $action"; 230 for my $key (keys(%{$gh[$#gh]})) { 231 my $cmd = $key; 232 my $type = ref($grammar->{$key}); 233 234 next if $cmd =~ /^[A-Z]+$/; 235 $cmd =~ s/^(\d+\))?(\$(\*)?)?//; 236 if ($type eq 'HASH' and $grammar->{$key}->{HELP}) { 237 $type = ref($grammar->{$key}->{HELP}); 238 if ($type eq 'ARRAY') { 239 $cmd = $grammar->{$key}->{HELP}->[0]; 240 } elsif ($type eq 'CODE') { 241 my %s = $grammar->{$key}->{HELP}->($ctx, $ctx->args()); 242 push(@candidates, keys(%s)); 243 $cmd = undef; 244 } 245 } 246 if (defined($cmd)) { 247 push(@candidates, $cmd); 248 } 249 } 250 if (@candidates and $grammar->{ACTION}) { 251 push(@candidates, "<eol>"); 252 } 253 @candidates = sort(@candidates); 254 if (@candidates > 1) { 255 $action .= "\n ${prefix}Candidates are " . join(", ", @candidates[0 .. $#candidates - 1]) . " and " . $candidates[-1] . "."; 256 } elsif (@candidates == 1) { 257 $action .= "\n ${prefix}Expecting @candidates."; 258 } else { 259 if ($grammar->{ACTION}) { 260 $action .= "\n ${prefix}Expected end of command."; 261 } else { 262 $action .= "\n ${prefix}Can't find any candidates, probably a grammar error." 263 } 264 } 216 265 error($action); 217 266 } … … 417 466 } 418 467 } 419 exec_line( @ARGV);468 exec_line(CMD_ARG, @ARGV); 420 469 exit; 421 470 } … … 432 481 while (defined($line = $term->readline($PROMPT))) { 433 482 next if $line =~ /^\s*$/; 434 exec_line( $line);483 exec_line(CMD_INTERACTIVE, $line); 435 484 $BREAK = 0; 436 485 } … … 441 490 next if $line =~ /^\s*$/; 442 491 next if $line =~ /^\s*#.*$/; 443 exec_line( $line);492 exec_line(CMD_STDIN, $line); 444 493 } 445 494 } else { manage/trunk/plugins/nodelist2.pm
r171 r173 39 39 HELP => 'List users.' 40 40 }, 41 '3)$[\w -]+' => {41 '3)$[\w -]+' => { 42 42 HELP => [ '<username>', 'User to manage.' ], 43 43 remove => { … … 75 75 }, 76 76 }, 77 '$\d+' => { 78 HELP => sub { 79 return ( 80 '<digit>' => 'Fooobbrr' 81 ); 82 }, 83 }, 77 84 }, 78 85 },
