#

#include "globals.h"
#include <stdio.h>

/*
 *	getcmd.c: do command processing
 */

CONST	char	*_S_getcmd	"@(#)getcmd.c	1.8";

VAR	struct cmdtable 
	{	COMMAND	cmd;
		char	*comm;
	} cmdtab[] {
			NL,	"",
			BACK,	"^",
			PREV,	"-",
			NEXT,	"+",
			EQUAL,	"=",
			DOT,	".",
			HELP,	"?",
			SHELL,	"!",
			QUIT,	"\04",
			QUIT,	"quit",
			HELP,	"help",
			LOOK,	"look",
			TEXT,	"text",
			DISPLAY,"display",
			DATA,	"data",
			LABEL,	"label",
			NAME,	"name",
			STACK,	"stack",
			REG,	"registers",
			MODE,	"mode",
			PPT,	"ppt",
			SIGNAL,	"signal",
			TABLE,	"table",
			NEXT,	"next",
			PREV,	"previous",
			NOCMD,	"",
		   };

	char	line[ MAXLINELENGTH ];
	integer	lindex;

/*
 *	eow: end of word tester
 */

PROCEDURE boolean eow( c )

CONST	char	c;

BEGIN	return( ( c == eoln    ) OR 
		( c == eos     ) OR 
		( c == blank   ) OR 
		( c == tab     ) OR
		( c == comma   ) );
END

/*
 *	getword: get the indicated word in command line
 */

PROCEDURE getword( word )

VAR	char	*word;

BEGIN	VAR	integer	index;
	
	index = 0;

	LOOP	WHEN ( lindex == MAXLINELENGTH ) OR
		     ( line[ lindex ] == eoln )  OR
		       NOT eow( line[ lindex ] ) DO EXIT;
		
		inc( lindex );
	END;

	IF lindex != MAXLINELENGTH
	THEN	LOOP	word[ index ] = line[ lindex ];
			inc( lindex );

			WHEN ( eow( word[ index ] ) OR
			     ( lindex == MAXLINELENGTH ) ) DO EXIT;
			inc( index );
		END;

		IF word[ index ] == eoln
		THEN	lindex = MAXLINELENGTH;
		END;
	END;

	word[ index ] = eos;
END


/*
 *	getnum: get next word as if it were a number
 */

#define	nchar(x,b)	(( '0' <= x ) AND ( x < ( '0'+b )))


PROCEDURE getnum( result )

VAR	long	*result;

BEGIN	/*	handles both base 8 and base 10 	*/

	VAR	integer	index;
		integer	base;
		char	word[ MAXLINELENGTH ];

	*result	= 0L;
	index 	= 0;
	base	= 10;

	getword( word );

	IF word[ 0 ] == eos
	THEN	*result = -1L;
     ELSIF ( word[0] == dot ) AND ( word[1] == eos )
	THEN	*result = addr;
	ELSE	IF word[ 0 ] == '0'
		THEN	base = 8;
		END;

		LOOP	WHEN word[ index ] == eos DO EXIT;

			WHEN NOT nchar( word[ index ], base )
			DO	*result = -1L;
			EXIT;

			*result = *result*(long)base + 
					(long)( word[ index] - '0' );

			inc( index );
		END;
	END;

	/*	printf("Result = %lo\n",*result );	*/
END

/*
 *	getnw: getnum or getword
 */

PROCEDURE boolean getnw( word, num )

VAR	char	*word;
	long	*num;

BEGIN	VAR	integer	sindex;

	sindex = lindex;

	getnum( num );

	IF *num == -1L
	THEN	lindex = sindex;
		getword( word );
		return( true );
	ELSE	return( false );
	END;
END


/*
 *	getadr: get address
 */

PROCEDURE long getadr( result )

VAR	long	*result;

BEGIN	getnum( result );

	IF *result == -1L
	THEN	*result = addr + step;
	END;

	addr = *result;
	/*	printf("addr = %lo\n",*result);		*/
END

/*
 *	getcmd: do command processing
 */

PROCEDURE COMMAND getcmd()

BEGIN	VAR	char	word[ MAXLINELENGTH ];
		integer	index;
	
	lindex = 0;
	index = 0;

	LOOP	line[ index ] = getc( stdin );

		WHEN line[ index ] == '\n' DO EXIT;

		inc( index );

		IF index == MAXLINELENGTH
		THEN	exit( 3 );
		END;
	END;
	
	getword( word );

	index = 0;

	IF word[0] == eos
	THEN	lindex = MAXLINELENGTH;
	ELSE	index = 1;
		
		LOOP	WHEN cmdtab[ index ].cmd == NOCMD DO EXIT;

			WHEN imatch( word, cmdtab[ index ].comm ) DO EXIT;

			inc( index );
		END;
	END;

	return( cmdtab[ index ].cmd );
END
