⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comnd.c

📁 语法分析 编译原理 词法分析 语法分析 C++原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	comnd.c		COMND module; Main module.

	Copyright (C) 1985 Mark E. Mallett

	Permission is hereby granted to distribute this file indiscriminately.

	COMND.C, along with its associated files, contains routines which
	provide command parsing facilities of the TOPS-20 style, with
	command recognition, incremental help, and indirection.

Edit history

When	Who	What
------	---	--------------------------------
84xxxx	MEM	Create file.


	Routines included:

		COMND		The "user" call to parsing.
		COMNDr		General support COMND call
		CMDcab		Collect atom buffer
		CMDspc		Skip leading spaces
		CMDgcc		Get nth unparsed character
		CMDcpt		Checkpoint parsed area
		CMDcpl		Perform command completion
		CMDhlp		Perform common help
		CMDfill		Fill the command line.

*/


#include "stdio.h"			/* Standard system defs */
#include "comnd.h"			/* COMND interface definitions */
#include "comndi.h"			/* COMND internal definitions */


/* External routines */

extern		CMDptc();

/* External data */


/* Internal (public) routines */



/* Internal (public) data */

	int	CMDbel = {0};		/* Beep count */
	int	CMDgvh = {0};		/* Gave-help count */
	int	(*Cocrtc)() = {CMDptc};	/* Output char routine to call */


/* Local (static) data */


static	int	Echofl = {TRUE};	/* Echo on or off */
/*

*//* COMND (CSBptr, CFBptr)

	The general command call

This routine processess a request to parse an element of a command.

Accepts :

	CSBptr		Address of Command State Block
	CFBptr		Address of Command Function Block


Returns :

	<value>		One of result codes _CRxxx as defined in
			  the comnd.h include file

*/

int COMND (CSBptr, CFBptr)

CSB		*CSBptr;		/* Addr of command state block */
CFB		*CFBptr;		/* Addr of command function block */

{
return (COMNDr (CSBptr, CFBptr, 0));	/* Call comnd in non-support mode */
}
/*

*//* COMNDr (CSBptr, CFBptr, sflg)

	General COMND support call

This routine is the general COMND call, for use by extern or internal
(support) routines.

Accepts :

	CSBptr		Address of Command State Block
	CFBptr		Address of Command Function Block
	sflg		0 if general call
			1 if first through n-1st support call
			2 if final support call


Returns :

	<value>		One of result codes _CRxxx as defined in
			  the comnd.h include file



Notes:

	sflg may be set in order to make multiple calls to COMNDr appear
function the same way as a single call to COMND with chained CFBs.  That
is, each successive call to COMNDr in support mode passes a new CFB list
which is a logical extention of the current list.

	Please note that routines setting sflg will be returned internal
parse result codes (_CPxxx) rather than the usual external result codes
(_CRxxx), in order to allow full handling of all conditions.

*/

int COMNDr (CSBptr, CFBptr, sflg)

CSB		*CSBptr;		/* Addr of command state block */
CFB		*CFBptr;		/* Addr of command function block */
int		sflg;			/* Support-mode flag */

{
IND	int	agn;			/* Try-again flag */
IND	int	parse;			/* Parse result */
IND	int	i;			/* Scratch */
	CFB	*CFBcur;		/* Current CFB */
IND	int	c,c1;			/* Char */
IND	char	*sptr;			/* String pointer */
	int	cix;			/* Char index */

CSBptr -> CSB_RFL &= (~_CFPFE);		/* Clear prev-was-escape-completed */
if (CSBptr -> CSB_RFL & _CFESC)		/* If last WAS esc completed */
    CSBptr -> CSB_RFL |= _CFPFE;	/*  then set it */

while (TRUE)				/* Loop until we have something
					   to return to our gentle caller */
    {
    if (!sflg)				/* Reset things if not support mode */
	{
	CMDbel = 0;			/* Set beep counter to 0 */
	CMDgvh = 0;			/* Set gave-help to 0 */
	agn = FALSE;			/* Try-again to FALSE */
	}
    Echofl = !(CSBptr -> CSB_PFL & _CFNEC);
					/* Set echo on or off as desired */
    CFBcur = CFBptr;			/* Start at beginning */
    if (CSBptr -> CSB_FLN == -1)	/* If initial */
	{
	CMDfill (CSBptr, CFBptr);	/* Collect input */
	continue;			/*  and skip to end of while loop */
	}

    if (!sflg)				/* If not support mode */
	{
	if (CFBcur -> CFB_FLG & _CFDPP)	/* Check out default if any */
	    if (sptr = CFBcur -> CFB_DEF) /* (must be non-null ptr) */
		{
		cix = CMDspc (CSBptr);	/* Get inx after spaces */
		c = CMDgcc(CSBptr, cix);
					/* Get first non-space non-tab */
		cix = cix + CSBptr -> CSB_PRS; /* Get real index */
		c1 = CSBptr -> CSB_BUF[cix]; /* Get real character there */
		if ((c == _CCCMP) || (c == _CCEND))
		    {			/* If ok to default */
		    if (c == _CCEND)	/* If it was return */
			if ((cix) && (CSBptr->CSB_BUF[cix-1] != ' '))
			    CSBptr->CSB_BUF[cix++] = ' ';
					/* make sure space separation. */
		    strcpy (&CSBptr -> CSB_BUF[cix], sptr);
		    CSBptr -> CSB_FLN = cix = cix+strlen(sptr);
		    if (c == _CCCMP)	/* If completion */
			{
			CMDpzs (sptr);	/* Show it */
			CMDfob();
			}
		    CSBptr -> CSB_BUF[cix] = c1;
		    }
		}
	}


    CSBptr -> CSB_RFL &= (~_CFESC);	/* Clear completed-with-escape */
    while (CFBcur)			/* Go through... */
	{
	CSBptr -> CSB_CFB = CFBcur;	/* Remember which CFB we're at */
	parse = CMDpf(CSBptr, CFBcur);
					/* Try parse on this function */
	switch (parse)			/* Process the completion code */
	    {
	    case _CPCPE:		/* Completed with escape */
		CSBptr -> CSB_RFL = _CFESC; /* Indicate to caller */
		if (sflg)		/* If support... */
		    return (_CPCPE);	/*  return appropriate code */
		return (_CROK);		/* Return OK */


	    case _CPSUCC:		/* Successfull */
		if (sflg)		/* If support mode */
		    return (_CPSUCC);	/*  return success indication */
		return (_CROK);		/*  Return OK */

	    case _CPABT:		/* Abort */
		if (sflg)		/* If supportmode */
		    return (_CPABT);	/*  return the abort flag */
		return (CSBptr -> CSB_RCD); /* Pass back the return code */

	    case _CPGVH:		/* Gave help */
		CMDgvh++;		/* Count it and act like _CPAGN */

	    case _CPAGN:		/* Try again... */
		agn = TRUE;		/*  set to try again */
	    }

	CFBcur = CFBcur -> CFB_CFB;	/* Get next one */
	}

/* Gone through all the function blocks.. take appropriate result action */

    if (CSBptr -> CSB_PRS == 0)		/* If nothing parsed */
	{
	cix = CMDspc (CSBptr);		/* Skip spaces */
	if (CMDgcc (CSBptr, cix) == _CCEND) /* See if no input */
	    {
	    CSBptr -> CSB_FLN = -1;	/* Indicate reprompt */
	    continue;			/* Go to end of the while loop */
	    }
	}

    if (!agn)				/* If not to try again */
	{
	if (sflg)			/* If support mode */
	    return (_CPNOP);		/*  return internal code */
	return (_CRNOP);		/* Return no-parse */
	}

    if (sflg)				/* If supportmode */
	return (_CPAGN);		/*  return that we ought try agn */

    if (CMDgvh)				/* If gave help... */
	{
	CMDpoc ('\n');			/* give CR */
	CMDpzs (CSBptr -> CSB_PMT);	/* Output prompt */
	for (i = 0; i < CSBptr -> CSB_FLN; i++)
	    CMDpoc (CSBptr -> CSB_BUF[i]); /* Output text typed */
	CMDfob();
	CMDbel = 0;			/* Don't beep */
	}

    if (CMDbel)				/* If wanted to beep */
	{
	CMDpoc ('\007');			/* Make a beep */
	CMDfob();
	}

    CMDfill (CSBptr, CFBptr);		/* do user editing */
    if (CSBptr -> CSB_RFL & _CFRPT)	/* If reparse indicated */
	{
	CSBptr -> CSB_PRS = 0;		/* Reset the parse pointer */
	if (CSBptr -> CSB_RSB)		/* If any setjmp buffer */
	    longjmp (CSBptr -> CSB_RSB, 1); /* Execute the longjump */
	else				/* Otherwise */
	    return (_CRRPT);		/* Return re-parse */
	}
    }
}
/*

*//* CMDcab (CSBptr, buf, buflen, cctbl, ecptr, icix)

	Collect Atom Buffer

This routine collects characters from the input buffer into an atom
buffer as specified by the caller.  It makes use of a character
characteristic table, as described elsewhere.


Accepts :

	CSBptr		Address of command state block
	buf		Address of buffer to store data into
	buflen		Length of buffer
	cctbl		Address of character/characteristic table
	ecptr		Where to store the ending character value
	icix		Initial relative parse index

Returns :

	<value>		New character index relative to parse pointer, for
			use in checkpointing if the parse is successful
			at this point.
	*ecptr		Value of character which caused the end of atom
			collection.

*/

CMDcab (CSBptr, buf, buflen, cctbl, ecptr, icix)

CSB		*CSBptr;		/* Addr of command state block */
char		*buf;			/* Addr of buffer */
int		buflen;			/* Length of buffer */
WORD		*cctbl;			/* CC table */
int		*ecptr;			/* Where to put ending char */
int		icix;			/* Initial cix */

{
IND	int	c;			/* Character */
IND	int	cc;			/* CharChar value */
IND	int	cix;			/* Relative parse index */
IND	int	binx;			/* Buffer index */

cix = icix;				/* Init relative index */
binx = 0;				/* Init buffer index */
while (TRUE)				/* Get characters */
    {
    c = CMDgcc (CSBptr, cix);		/* Get char */
    if ((c & 0xff00) != 0)		/* If special */
	break;				/*  then we done. */

    cc = (cctbl[c/8]>>((7-(c%8))*2))&0x3;	/* Get cc value */
    if ((cc == 0)			/* Invalid char */
     || ((cc == 1) && (binx == 0)))	/*  or invalid first char */
	{
	c = _CCINV;			/* Return invalid char */
	break;				/* Go return */
	}

    if (cc == 3)			/* Break character */
	break;				/*  then break. */

    buf[binx++] = c;			/* Store the char */
    cix++;				/* Bump the parse index */
    }

buf[binx] = NUL;			/* NUL-terminate the buffer */
*ecptr = c;				/* Pass the ending char up */
return (cix);				/* Return the index. */
}
/*

*//* CMDspc (CSBptr)

	Parse past spaces

This routine skips past spaces which are after the current parse point,
and returns the relative parse index of the first non-space non-tab
character.


Accepts :

	CSBptr		Address of command state block


Returns :

	<value>		Relative parse index of first non-space non-tab char.

*/

CMDspc (CSBptr)

CSB		*CSBptr;		/* Addr of command state block */

{
IND	int	c;			/* Character */
IND	int	cix;			/* Command index */

cix = 0;				/* Set command index */
while (TRUE)				/* Skip spaces/tabs */
    {
    c = CMDgcc (CSBptr, cix);		/* Get char */
    if ((c != ' ') && (c != '\011'))
	break;				/* Quit when got something other */
    cix++;				/*  skip em */
    }

return (cix);				/* Return the value */
}
/*

*//* CMDgcc (CSBptr, cix)

	Return unparsed character.

This routine returns the "cix"th unparsed character from the command
line indicated by the command state block at CSBptr.


Accepts :

	CSBptr		Address of command state block
	cix		character index


Returns

	<value>		character @ cix, or special code _CCxxx, as
			 defined in "comndi.h"

*/

int CMDgcc (CSBptr, cix)

CSB		*CSBptr;		/* Command state block addr */
int		cix;			/* Character index */

{
IND	int	i;			/* Scratch */
IND	int	c;			/* character */

i = CSBptr -> CSB_PRS + cix;		/* Get buffer index */
if (i > CSBptr -> CSB_FLN)		/* If beyond filled space */
    return (_CCEND);			/*  return END indicator */
c = CSBptr -> CSB_BUF[i];		/* Get character there */
if (i < CSBptr -> CSB_FLN)		/* If within filled area */
    return (c);				/*  return it. */
switch (c)				/* Dispatch on char found at end */
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -