[comp.lang.perl] Anyone running a perl command line interpreter?

jew@rt.uucp (/87336) (04/30/91)

Every page I turn in "The Book" convinces me more that perl is just
what I've always wanted!  Now, I have to pick your brains to see
what's been done, can be done, will be done?

Has anybody written, or are they writing a perl command line
interpreter?  Doesn't that sound like fun?  :-)


jew@sunquest.com

Confucious say...
Writing free verse is like playing tennis with the net down.

pochmara@ogicse.ogi.edu (John Pochmara) (05/09/91)

In article <18459@sunquest.UUCP> jew@rt.uucp (/87336) writes:
>Has anybody written, or are they writing a perl command line
>interpreter?  Doesn't that sound like fun?  :-)

	Here is something I whipped up one day.  This CLI does
	command compeletion( space-bar ) and show which commands
	match the current line ( '?' ).  Just fill in the %CommandTable.

	I know this works on Sun's, the CLearLine() and
	cbreak routines may need to be changed for other machines.

		--John
		  pochmara@cse.ogi.edu

P.S.  To all you JAPH's, I have only been using Perl for about a 2 weeks
      know....

------------ CUT HERE --------------------- CUT HERE --------------------------
#!/usr/local/bin/perl
#
#
#

$Prompt = "command> ";

#
# Command Table
#
%CommandTable = ();
@CmdList;

$CommandTable{"quit"} = "QuitCmd";
$CommandTable{"exit"} = "QuitCmd";
$CommandTable{"help"} = "HelpCmd";
$CommandTable{"create-user"} = "CreateUser";
$CommandTable{"create-host"} = "CreateHost";
$CommandTable{"create-group"} = "CreateGroup";
$CommandTable{"add-account"} = "AddAccount";
$CommandTable{"add-to-group"} = "AddToGroup";
$CommandTable{"load-account"} = "LoadAccount";
$CommandTable{"delete-account"} = "DeleteAccount";
$CommandTable{"delete-user"} = "DeleteUser";
$CommandTable{"show-user"} = "ShowUser";
$CommandTable{"show-group"} = "ShowGroup";

sub Init {
	local( $i, $key );

	$i = 0;
	foreach $key ( keys %CommandTable ) {
		$CmdList[$i++] = $key;
	}
}

sub cbreak {
	system( "/bin/stty", "cbreak", "-echo" );
	$| = 1;
}

sub nocbreak {
	system( "/bin/stty", "-cbreak", "echo" );
	$| = 0;
}

sub ClearLine {
	local( $num ) = @_;
	local( $str );

	$str = "\010" x $num;
	$str .= " " x $num;
	$str .= "\010" x $num;

	print "$str";
}

sub MatchCmd {
	local( $pat ) = @_;
	local( $ret, $i, $c, $k, $mc, @ml );

	$k = 0;

	for( $i = 0; $i <= $#CmdList; $i++ ) {
		
		if( $CmdList[$i] =~ /^$pat/ ) {
			$ml[$k++] = $CmdList[$i];
		}
	}

	if( $#ml == 0 ) {
		$ret = $ml[0];
		return( $ret );
	}

	$c = $ml[0];

	while( 1 ) {

		$mc = 0;

		for( $i = 0; $i <= $#ml; $i++ ) {

			if( $ml[$i] =~ /^$c/ ) {
				$mc++;
			}
		}

		if( $mc == ( $#ml + 1 ) ) {
			last;
		} else {
			chop( $c );
		}
	}

	$ret = $c;

	$ret;
}

sub ShowMatchCmdList {
	local( $pat ) = @_;
	local( $i );

	for( $i = 0; $i <= $#CmdList; $i++ ) {

		if( $CmdList[$i] =~ /^$pat/ ) {
			print "$CmdList[$i]\n";
		}
	}

}

#
# Main 
#

do Init();

open( TTY, "/dev/tty" ) || die "Could not open tty!?!?";

while( 1 ) {
	local( $c, $cmd, $buf, $num, $cmdsub );


	$num = 0;
	$buf = "";

	&cbreak();
	print $Prompt;

	while( 1 ) {
	
		$c = getc( TTY );

		if( $c eq "\n" ) {
			print "\n";
			last;
		} elsif( $c eq "\010" ) {

			if( $num > 0 ) {
				print "\010 \010";
				chop( $buf );
				$num--;
			}

		} elsif( ( $c eq " " ) || ( $c eq "\011" ) ) {
			&ClearLine( $num );
			$buf = &MatchCmd( $buf );
			print "$buf";
			$num = length( $buf );
		} elsif( $c eq "?" ) {

			print "\n\n";
			&ShowMatchCmdList( $buf );
			print "\n$Prompt$buf";

		} else {
			$buf .= $c;
			$num++;
			print "$c";
		}
	}

	&nocbreak();

	
	$cmdsub = $CommandTable{$buf};

	if( $cmdsub eq "" ) {
		print STDERR "$cmd: invalid command.\n";
		next;
	}

	print "\n";

	do $cmdsub();

	print "\n";
}