Trailing-Edge
-
PDP-10 Archives
-
tops20-v7-ft-dist1-clock
-
7-sources/prparcom.bli
There are 10 other files named prparcom.bli in the archive. Click here to see a list.
%TITLE 'PRPARCOM - parse a command'
MODULE PRPARCOM ( ! Parse a command
IDENT = '3-016' ! File: PRPARCOM.BLI Edit:GB3016
) =
BEGIN
!COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1981, 1988. ALL RIGHTS RESERVED.
!
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ONLY
!IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE INCLUSION OF
!THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES THEREOF MAY
!NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE
!TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
!
!THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
!SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
!
!DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
!SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
!
!
!++
! FACILITY: EDT -- The DEC Standard Editor
!
! ABSTRACT:
!
! Parse a command.
!
! ENVIRONMENT: Runs on TOPS-20 only
!
! AUTHOR: Chris Gill, CREATION DATE: March 1, 1983
!
! MODIFIED BY:
!
! 3-001 - Created. CJG 1-Mar-1983
! 3-002 - Change the way that filespecs are handled. CJG 28-Jun-1983
! 3-003 - Add code for PUSH command and tidy up. CJG 25-Sep-1983
! 3-004 - Add PROMPT_LENGTH so that we can get error pointer in right place. CJG 7-Oct-1983
! 3-005 - Add TRACE and XDDT commands. CJG 10-Oct-1983
! 3-006 - Add SET SEARCH IGNORE parsing. CJG 2-Nov-1983
! 3-007 - Apply some modifications required by fixes in PRFILE. CJG 12-Dec-1983
! 3-008 - Fix problem when <ESC> and Control-R interact. CJG 20-Dec-1983
! 3-009 - Make Control-H work remove some old code. CJG 20-Dec-1983
! 3-010 - Check for control-C being typed. CJG 5-Jan-1984
! 3-011 - Allow SUBSTITUTE string to be terminated by <CR>. GB 2-May-1984
! 3-012 - Allow control chars as SUBSTITUTE string delimiters. GB 2-May-1984
! 3-013 - Fix TAB ADJUST to parse a range specification. GB 20-Jul-1984
! 3-014 - Allow <LF> as a null command. GB 24-Jul-1984
! 3-015 - Fix problems with numeric zero argument on some SET commands. GB 7-Sep-1984
! 3-016 - Fix bug in comment handling which causes command buffer size to be
! reduced by 2 for each comment parsed. GB 15-Oct-1984
!--
%SBTTL 'DECLARATIONS'
!
! TABLE OF CONTENTS:
!
REQUIRE 'EDTSRC:TRAROUNAM';
REQUIRE 'EDTSRC:PARLITS';
FORWARD ROUTINE
EDT$$PA_CMD,
PA_PARSE;
!
! INCLUDE FILES:
!
REQUIRE 'EDTSRC:EDTREQ';
REQUIRE 'SYS:JSYS';
REQUIRE 'EDTSRC:PARDATA';
!
! EXTERNAL REFERENCES:
!
EXTERNAL
! CMD_BUF, ! Command line buffer.
CMD_PTR, ! Pointer into command buffer.
CMD_END, ! Pointer to end of current command.
CMD_LEN, ! Length of command.
VFY, ! verify switch
INP_SRC, ! Source of input
DEFKEY, ! Flag for DEFINE KEY
TAB_SIZ, ! Size of a tab
TI_WID, ! Terminal width
PA_CURCMD : REF NODE_BLOCK, ! Current command node
PA_CURTOK, ! start of the current token
PA_CURTOKLEN, ! Length of current token
PA_CURRNG, ! Current range node
PA_MORE, ! More on command line
PA_ERRNO, ! Error number of parsing error.
PA_SP, ! Parse stack pointer
PROMPT_LENGTH, ! Length of prompt
WRT_NAM : BLOCK, ! Descriptor for WRITE command
OUT_NAM : BLOCK, ! Descriptor for EXIT command
INC_NAM : BLOCK, ! Descriptor for INCLUDE command
TEMP_BUFFER, ! Temp string buffer
HELP_DFLT, ! Help defaults for PA_FILE
CMD_DFLT, ! Command defaults for PA_FILE
CC_WAIT, ! ^C may be typed and should be handled
CC; ! Control-C flag
EXTERNAL ROUTINE
EDT$$FMT_CRLF, ! Terminate an output line
EDT$$FMT_CH,
EDT$$FMT_LIT,
EDT$$MSG_TOSTR,
EDT$$PA_TSTMACCAL, ! Test atom for being a macro name
EDT$$PA_NEW_NOD, ! Create a new node
EDT$$PA_SCANTOK : NOVALUE, ! Find length of current atom
EDT$$PA_SWITCH, ! Parse a switch
EDT$$PA_GET_KEY, ! Parse a key name
EDT$$PA_GET_CHAR, ! Get a single character
EDT$$PA_FILE, ! Parse a filespec
EDT$$PA_BUFFER, ! Parse a buffer name
EDT$$PA_NUMBER, ! Parse a decimal number
EDT$$PA_COLON, ! Parse a colon
EDT$$PA_RANGE; ! Parse a range specifier
!
! MACROS:
!
! NONE
!
!
! OWN STORAGE
!
! NONE
!
%SBTTL 'EDT$$PA_CMD - parse a command'
GLOBAL ROUTINE EDT$$PA_CMD(
PROMPT,
PRLEN) = ! Parse a command
BEGIN
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine is called to parse a single command on the current command
! line. The command will be read from the relevent file or the terminal
! which allows for full recognition. In this case, a copy of the command
! is returned in the command buffer. If the parse is successful, a 1 is
! is returned and the parsing stack contains a description of the command.
! CMD_PTR is left pointing at the '\' or <CR> which are are the only
! valid terminators of commands. If an error occurs, a 0 is returned,
! and PA_MORE is left as zero to indicate that no more data exists on the
! command line.
!
! FORMAL PARAMETERS:
!
! NONE
!
! IMPLICIT INPUTS:
!
! CMD_BUF
! CMD_PTR
! CMD_END
! CMD_LEN
! VFY
! INP_SRC
!
! IMPLICIT OUTPUTS:
!
! PA_CURCMD
! PA_SP
! PA_CURTOK
! PA_ERRNO
!
! ROUTINE VALUE:
!
! 1 = parse was successful
! 0 = parse failed, PA_ERRNO set
!
! SIDE EFFECTS:
!
! MANY
!
!--
BEGIN
LOCAL
C_FLAG, ! COMND flags
C_DATA, ! COMND data pointer
C_FDB, ! COMND actual FDB used
STS : INITIAL (0);
MESSAGES ((UNXCHRAFT, UNRCOM));
!+
! Indicate that if a control-C is typed it should be handled by aborting
! the COMND JSYS.
!-
CC_WAIT = -1;
!+
! Initialise the COMND JSYS ready for a command. This is only done if
! there is no more data in the rescan buffer.
!-
IF (.PA_MORE EQL 0) THEN
BEGIN
IF (.PRLEN NEQ 0) THEN PROMPT_LENGTH = .PRLEN;
CH$WCHAR (0, CH$MOVE (.PRLEN, .PROMPT, CH$PTR (TEMP_BUFFER,, BYTE_SIZE)));
CSB [$CMRTY] = CH$PTR (TEMP_BUFFER,, BYTE_SIZE);
IF (NOT COMMAND (FD_INI))
THEN
BEGIN
CC_WAIT = 0;
RETURN (0);
END;
IF (.CC NEQ 0) THEN STS = -1;
END;
!+
! Loop around the parser as long as a reparse is required. When an error
! occurs or the command is accepted, then continue.
!-
PA_MORE = 0;
WHILE (.STS EQL 0) DO
BEGIN
!+
! Initialize the command node pointer and the parsing stack pointer.
!-
PA_CURCMD = 0;
PA_SP = -1;
PA_ERRNO = 0;
STS = PA_PARSE (); ! Parse a command
IF (.STS EQL 1) THEN
BEGIN
!+
! The command has been parsed - make sure that it ends correctly.
!-
IF (NOT COMMAND (FD_END))
THEN
BEGIN
CC_WAIT = 0;
RETURN (0);
END;
IF (.CC NEQ 0)
THEN
STS = -1
ELSE
BEGIN
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN STS = 0;
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN
BEGIN
PA_ERRNO = EDT$_UNXCHRAFT;
STS = -1;
END;
END;
END;
END;
!+
! If the command ended with '\', then indicate more to come
!-
IF (.STS EQL 1) THEN
BEGIN
IF (.C_FDB<0,18> EQL FD_END) THEN
BEGIN
PA_CURTOK = .CSB [$CMPTR];
PA_CURTOKLEN = .CSB [$CMINC];
PA_MORE = 1;
END;
CMD_LEN = 256 - .CSB [$CMCNT];
CC_WAIT = 0;
RETURN (1);
END;
!+
! There was an error - if it occured because of control-C then tidy up,
! go to a new line for the message, and exit now. (Assume no other errors)
!-
IF (.CC NEQ 0) THEN
BEGIN
PA_MORE = 0;
PA_ERRNO = 0;
CC_WAIT = 0;
EDT$$FMT_CRLF ();
RETURN (0);
END;
!+
! The command failed to parse correctly - indicate the error
!-
IF (.PA_ERRNO EQL 0) THEN PA_ERRNO = EDT$_UNRCOM;
!+
! Print the command with an indication of where the error is. If the
! user ended the bad field with an escape, then send <CR><LF> first.
! Also take account of the prompt length so we get the pointer in the
! right place.
!-
IF ((.INP_SRC NEQ INP_TERM) AND (.VFY EQL 0)) THEN
BEGIN
EDT$$FMT_CH (%C' ');
EDT$$FMT_LIT (CH$PTR (CMD_BUF,, BYTE_SIZE), .CMD_LEN);
EDT$$FMT_CRLF ();
END;
IF ((.CSB [$CMFLG] AND CM_ESC) NEQ 0) THEN EDT$$FMT_CRLF ();
DECR I FROM (CH$DIFF (.CSB [$CMPTR], CH$PTR (CMD_BUF,, BYTE_SIZE)) +
.PROMPT_LENGTH) TO 0 DO EDT$$FMT_CH (%C' ');
EDT$$FMT_CH (%C'^');
EDT$$FMT_CRLF ();
PROMPT_LENGTH = 0;
!+
! Print the corresponding error message and ensure that other commands
! on this line are not parsed.
!-
EDT$$MSG_TOSTR (.PA_ERRNO);
EDT$$FMT_CRLF ();
PA_MORE = 0;
CC_WAIT = 0;
RETURN (0);
END;
END;
%SBTTL 'PA_PARSE - Parse the individual commands'
ROUTINE PA_PARSE = ! Start parsing a command
BEGIN
!+
! This routine parses the command keyword and dispatches to the relevent
! subroutine to parse the rest of the command. If a reparse is required,
! the value of the routine is set to 0, if an error occurs, it is set to
! -1, else it is set to 1.
!-
OWN
PARSED_FILE : BLOCK [DSC$K_SIZE]; ! Space for parsed files
LOCAL
C_FLAG, ! COMND flags
C_DATA, ! COMND data pointer
C_FDB, ! COMND actual FDB used
CMDTYP, ! Command type or subtype
STS;
LITERAL ! Filespec parsing flags
F_REQD = 1, ! Filespec required
F_EXIT = 2, ! EXIT command
F_OUTPUT = 4, ! Parse an output filespec
F_RELEAS = 8; ! Release the JFN when done
MESSAGES ((ASREQ, QUOSTRREQ, MACKEYREQ, INVPARFOR, NUMVALREQ, NUMVALILL,
UNXCHRAFT, UNRCOM, INVVALSET, ENTMUSTBE, NONALPNUM,
SUBSTRNUL, INVSTR));
BEGIN
!+
! Parse the command keyword
!-
STS = 0;
IF (NOT COMMAND (FD_CMD)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
!+
! If the atom ended in an escape, then don't try to match it with a buffer
! name (we can't do recognition on these). If the atom parsed OK and it is
! not a buffer name, then treat it as a good command. Otherwise, try to
! make a range node out of it. If the command is just a carriage return,
! then default to NULL, ignore the command if it is a comment.
!-
SELECTONE .C_FDB<0,18> OF
SET
[ FD_CMD ] :
BEGIN
!+
! Found a valid command keyword. If recognition was not used, then see
! if it is a macro name. Otherwise, see to it.
!-
IF ((.C_FLAG AND CM_ESC) EQL 0)
THEN
BEGIN
EDT$$PA_SCANTOK (0,1);
IF (EDT$$PA_TSTMACCAL ()) THEN RETURN (1);
END;
CMDTYP = .(.C_DATA)<0,18>;
END;
[ FD_CMM ] :
BEGIN
!+
! Found an alphanumeric field. If it is not a macro name then fail, if
! it was empty, then try to parse a range.
!-
STS = 1;
EDT$$PA_SCANTOK (0,1);
IF (.PA_CURTOKLEN NEQ 0) THEN
BEGIN
IF (EDT$$PA_TSTMACCAL ()) THEN RETURN (1);
CMDTYP = CH$RCHAR (.PA_CURTOK);
IF (.CMDTYP GEQ %C'@') THEN RETURN (-1);
CSB [$CMINC] = .CSB [$CMINC] + .PA_CURTOKLEN; ! Backup
CSB [$CMPTR] = .PA_CURTOK;
CSB [$CMCNT] = .CSB [$CMCNT] + .PA_CURTOKLEN;
END;
CMDTYP = COM_NULL;
END;
[ FD_CMT ] :
BEGIN
!+
! Set the command type appropriately, and backup to the <CR><LF> so that
! the end of line parsing will work.
!-
LOCAL
PTR,
LEN;
LEN = CH$DIFF (.CSB [$CMPTR], CH$PTR (CMD_BUF,, BYTE_SIZE));
IF (.LEN LEQ 2) THEN
CMDTYP = COM_NULL
ELSE
CMDTYP = -1;
PTR = CH$PLUS (.CSB [$CMPTR], -1);
WHILE (CH$RCHAR (.PTR) EQL %O'15') OR (CH$RCHAR (.PTR) EQL %O'12') DO
BEGIN
CSB [$CMINC] = .CSB [$CMINC] + 1;
CSB [$CMPTR] = .PTR;
CSB [$CMCNT] = .CSB [$CMCNT] + 1;
PTR = CH$PLUS (.PTR, -1);
END;
END;
TES;
!+
! Get a new parse node for this command
!-
IF (.PA_CURCMD NEQ 0) THEN PA_CURCMD [ NEXT_COM ] = .PA_SP;
IF ((PA_CURCMD = EDT$$PA_NEW_NOD (COM_NODE, .CMDTYP)) EQL 0) THEN RETURN (0);
IF (.CMDTYP EQL -1) THEN RETURN (1);
CASE .CMDTYP FROM COM_NULL TO LAST_COM OF
SET
[ COM_NULL ] :
BEGIN
IF .STS
THEN
RETURN (EDT$$PA_RANGE (1)) ! Just parse a range
ELSE
CSB [$CMCNT] = .CSB [$CMCNT] + 2; ! Fix the counter
END;
[ COM_CHANGE, COM_FILL, COM_FIND, COM_INSERT, COM_REPLACE ] :
BEGIN
RETURN (EDT$$PA_RANGE (1)); ! Just parse a range
END;
[ COM_COPY, COM_MOVE ] :
BEGIN
STS = EDT$$PA_RANGE (2); ! Parse a range subcommand
IF (.STS LEQ 0) THEN RETURN (.STS);
IF (NOT COMMAND (FD_RTO)) THEN RETURN (-1); ! Parse 'TO'
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
IF (.C_FDB<0,18> EQL FD_RTO) THEN
BEGIN
!+
! If a '%' was found then try to parse 'TO'
!-
IF (NOT COMMAND (FD_RT1)) THEN RETURN (-1); ! Parse 'TO'
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
END;
STS = EDT$$PA_RANGE (1); ! Parse second range
IF (.STS LEQ 0) THEN RETURN (.STS);
RETURN (EDT$$PA_SWITCH (
IF (.CMDTYP EQL COM_COPY) THEN
FD_COP
ELSE
FD_DEL
));
END;
[ COM_DEFINE, COM_DEF_MAC ] :
BEGIN
PA_ERRNO = EDT$_MACKEYREQ;
IF (NOT COMMAND (FD_DEF)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
CMDTYP = .(.C_DATA)<0,18>;
PA_CURCMD [COM_NUM] = .CMDTYP;
SELECTONE .CMDTYP OF
SET
[ COM_DEFINE ] :
BEGIN
!+
! Get the key number from the command
!-
STS = EDT$$PA_GET_KEY ();
IF (.STS LEQ 0) THEN RETURN (.STS);
PA_ERRNO = EDT$_ASREQ;
DEFKEY = 0;
!+
! Parse 'AS "string" '
!-
IF (NOT COMMAND (FD_AS)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
PA_ERRNO = EDT$_QUOSTRREQ;
IF (NOT COMMAND (FD_QST)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
!+
! Store the length and pointer to the string
!-
EDT$$PA_SCANTOK (1,0);
PA_CURCMD [AS_STR] = .PA_CURTOK;
PA_CURCMD [AS_LEN] = .PA_CURTOKLEN;
END;
[ COM_DEF_MAC ] :
BEGIN
!+
! Parse a buffer name (same format as macro name)
!-
STS = EDT$$PA_BUFFER ();
IF (.STS LEQ 0) THEN RETURN (.STS);
PA_CURCMD [RANGE1] = .PA_CURRNG;
END;
TES;
END;
[ COM_CLEAR ] :
BEGIN
STS = EDT$$PA_BUFFER (); ! Parse a buffer name
IF (.STS LEQ 0) THEN RETURN (.STS);
PA_CURCMD [RANGE1] = .PA_CURRNG;
END;
[ COM_DELETE ] :
BEGIN
STS = EDT$$PA_RANGE (1); ! Parse a range
IF (.STS LEQ 0) THEN RETURN (.STS);
RETURN (EDT$$PA_SWITCH (FD_DEL)); ! Parse /QUERY
END;
[ COM_EXIT ] :
BEGIN
STS = EDT$$PA_FILE (OUT_NAM, F_EXIT + F_OUTPUT, 0);
IF (.STS LEQ 0) THEN RETURN (.STS);
RETURN (EDT$$PA_SWITCH (FD_EXI)); ! Parse /SAVE or /SEQUENCE
END;
[ COM_INCLUDE, COM_PRINT, COM_WRITE ] :
BEGIN
STS = (IF (.CMDTYP EQL COM_INCLUDE)
THEN EDT$$PA_FILE (INC_NAM, F_REQD, 0)
ELSE EDT$$PA_FILE (WRT_NAM, F_REQD + F_OUTPUT, 0));
IF (.STS LEQ 0) THEN RETURN (.STS);
STS = EDT$$PA_RANGE (1);
IF ((.STS LEQ 0) OR (.CMDTYP NEQ COM_WRITE)) THEN RETURN (.STS);
RETURN (EDT$$PA_SWITCH (FD_RES));
END;
[ COM_QUIT ] :
BEGIN
RETURN (EDT$$PA_SWITCH (FD_QIT)); ! Only look for /SAVE
END;
[ COM_RESEQ ] :
BEGIN
STS = EDT$$PA_RANGE (1);
IF (.STS LEQ 0) THEN RETURN (.STS);
RETURN (EDT$$PA_SWITCH (FD_RES)); ! Parse /SEQUENCE
END;
[ COM_SET ] :
BEGIN
PA_ERRNO = EDT$_INVPARFOR;
!+
! Clear out PARSED_FILE in case this is SET HELP or SET COMMAND.
!-
PARSED_FILE [DSC$A_DEVICE] = 0;
PARSED_FILE [DSC$A_DIRECT] = 0;
PARSED_FILE [DSC$A_FNAME] = 0;
PARSED_FILE [DSC$A_FEXTN] = 0;
!+
! Parse the SET option
!-
IF (NOT COMMAND (FD_SET)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
!+
! Save the option number
!-
CMDTYP = .(.C_DATA)<0,18>;
PA_CURCMD [SET_TYPE] = .CMDTYP;
!+
! Perform any extra argument parsing that may be required
!-
CASE .CMDTYP FROM 1 TO MAX_SET OF
SET
[ SET_WRAP, SET_SCRN, SET_LINES, SET_TAB ] :
BEGIN
PA_ERRNO = EDT$_NUMVALREQ;
!+
! A decimal number is required
!-
STS = EDT$$PA_NUMBER ();
IF (.STS LSS 0) THEN RETURN (.STS);
PA_ERRNO = EDT$_NUMVALILL;
IF (.STS GEQ 256) THEN RETURN (-1);
PA_CURCMD [SET_VAL] = .STS;
END;
[ SET_CASE, SET_SRCH, SET_TERM, SET_MODE, SET_NTITY,
SET_TEXT, SET_WORD, SET_PARA, SET_PROMPT ] :
BEGIN
PA_ERRNO = EDT$_INVVALSET;
IF (NOT COMMAND (
SELECTONE .CMDTYP OF
SET
[ SET_CASE ] : FD_CAS;
[ SET_SRCH ] : FD_SCH;
[ SET_TERM ] : FD_TRM;
[ SET_MODE ] : FD_MOD;
[ SET_NTITY] : FD_ENT;
[ SET_TEXT ] : FD_TEX;
[ SET_WORD ] : FD_WRD;
[ SET_PARA ] : FD_PAR;
[SET_PROMPT] : FD_PRO;
TES)
) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
PA_CURCMD [SET_VAL] = .(.C_DATA)<0,18>;
IF ((.CMDTYP EQL SET_NTITY) OR
(.CMDTYP EQL SET_TEXT) OR
(.CMDTYP EQL SET_PROMPT) OR
((.CMDTYP EQL SET_SRCH) AND (.(.C_DATA)<0,18> EQL SET_SIGN))) THEN
!+
! SET ENTITY, TEXT, or PROMPT also take a string
!-
BEGIN
PA_ERRNO = EDT$_QUOSTRREQ;
IF (NOT COMMAND (FD_QST)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
EDT$$PA_SCANTOK (1,0);
PA_CURCMD [AS_STR] = .PA_CURTOK;
PA_CURCMD [AS_LEN] = .PA_CURTOKLEN;
END;
END;
[ SET_HELP ] :
BEGIN
STS = EDT$$PA_FILE (PARSED_FILE, F_REQD + F_RELEAS, HELP_DFLT);
IF (.STS LEQ 0) THEN RETURN (.STS);
END;
[ SET_COMND ] :
BEGIN
STS = EDT$$PA_FILE (PARSED_FILE, F_REQD + F_RELEAS, CMD_DFLT);
IF (.STS LEQ 0) THEN RETURN (.STS);
END;
[ SET_CURSR ] :
BEGIN
PA_ERRNO = EDT$_NUMVALREQ;
STS = EDT$$PA_NUMBER ();
IF (.STS LSS 0) THEN RETURN (.STS);
PA_ERRNO = EDT$_NUMVALILL;
IF (.STS GEQ 32768) THEN RETURN (-1);
PA_CURCMD [SET_VAL1] = .STS;
STS = EDT$$PA_COLON (1);
IF (.STS LEQ 0) THEN RETURN (.STS);
PA_ERRNO = EDT$_NUMVALREQ;
STS = EDT$$PA_NUMBER ();
IF (.STS LSS 0) THEN RETURN (-1);
PA_ERRNO = EDT$_NUMVALILL;
IF (.STS GEQ 32768) THEN RETURN (-1);
PA_CURCMD [SET_VAL] = .STS;
END;
[ INRANGE ] :
;
TES;
RETURN (1);
END;
[ COM_SHOW ] :
BEGIN
PA_ERRNO = EDT$_INVPARFOR;
IF (NOT COMMAND (FD_SHO)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
CMDTYP = .(.C_DATA)<0,18>;
PA_CURCMD [SET_TYPE] = .CMDTYP;
SELECTONE .CMDTYP OF
SET
[ SHO_NTITY, SHO_PROMPT, SHO_TEXT ] :
BEGIN
PA_ERRNO = EDT$_ENTMUSTBE;
IF (NOT COMMAND (
SELECTONE .CMDTYP OF
SET
[ SHO_NTITY ] : FD_ENT;
[ SHO_PROMPT] : FD_PRO;
[ SHO_TEXT ] : FD_TEX;
TES)
) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
PA_CURCMD [SET_VAL] = .(.C_DATA)<0,18>;
END;
[ SHO_KEY ] :
BEGIN
RETURN (EDT$$PA_GET_KEY ());
END;
[ OTHERWISE ] :
;
TES;
RETURN (1);
END;
[ COM_SUBS, COM_SUBS_NEXT ] :
BEGIN
LOCAL
STRNODE : REF NODE_BLOCK, ! Node pointer
QCHAR; ! Quote character
!+
! If the command was SUBSTITUTE NEXT, then set CMDTYP and make sure the
! command node is correctly set.
!-
IF (.CMDTYP EQL COM_SUBS) THEN
BEGIN
IF (NOT COMMAND (FD_SNX)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) EQL 0) THEN CMDTYP = COM_SUBS_NEXT;
PA_CURCMD [COM_NUM] = .CMDTYP;
END;
!+
! If the command was [SUBSTITUTE] NEXT, then it can be terminated by <CR>
!-
IF (.CMDTYP EQL COM_SUBS_NEXT) THEN
IF ((.C_FLAG AND CM_EOC) NEQ 0) THEN RETURN (1);
!+
! Create a new node
!-
IF ((STRNODE = EDT$$PA_NEW_NOD (STR_NODE, 0)) EQL 0) THEN
RETURN (-1);
PA_CURCMD [STR_PNT] = .STRNODE;
!+
! Use the next character as the quote character - unless its alphanumeric
!-
QCHAR = EDT$$PA_GET_CHAR ();
IF (.QCHAR LEQ 0) THEN RETURN (.QCHAR);
PA_ERRNO = EDT$_NONALPNUM;
IF (((.QCHAR GEQ %C'0') AND (.QCHAR LEQ %C'9')) OR
((.QCHAR GEQ %C'A') AND (.QCHAR LEQ %C'Z')) OR
((.QCHAR GEQ %C'a') AND (.QCHAR LEQ %C'z'))) THEN RETURN (-1);
!+
! Now set the break mask for the new break character
!-
BREAK_MASK [0] = %O'20000000';
BREAK_MASK [1] = 0;
BREAK_MASK [2] = 0;
BREAK_MASK [3] = 0;
BREAK_MASK [.QCHAR/32] = 1 ^ (35 - (.QCHAR MOD 32)) OR
.BREAK_MASK [.QCHAR/32];
!+
! Parse an unquoted string - up to the break or <CR>
!-
STRNODE [SRCHADDR] = .CSB [$CMPTR];
IF (NOT COMMAND (FD_UQS)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
!+
! Save the length. Die if <CR> was the terminator
!-
STRNODE [SRCHLEN] = CH$DIFF (.CSB [$CMPTR], .STRNODE [SRCHADDR]);
CSB [$CMINC] = .CSB [$CMINC] - 1;
PA_ERRNO = EDT$_INVSTR;
IF (CH$RCHAR_A (CSB [$CMPTR]) EQL ASC_K_CR) THEN RETURN (-1);
!+
! Parse another unquoted string
!-
STRNODE [REPADDR] = .CSB [$CMPTR];
IF (NOT COMMAND (FD_UQS)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (-1);
!+
! Save the length of the replacement and make sure the aren't null
!-
STRNODE [REPLEN] = CH$DIFF (.CSB [$CMPTR], .STRNODE [REPADDR]);
PA_ERRNO = EDT$_SUBSTRNUL;
IF ((.STRNODE [REPLEN] EQL 0) AND (.STRNODE [SRCHLEN] EQL 0))
THEN RETURN (-1);
CSB [$CMINC] = .CSB [$CMINC] - 1;
CSB [$CMCNT] = .CSB [$CMCNT] - 1;
CSB [$CMPTR] = CH$PLUS (.CSB [$CMPTR], 1);
!+
! For a SUBSTITUTE command, then next atoms can be a range and switches.
!-
IF (.CMDTYP EQL COM_SUBS) THEN
BEGIN
QCHAR = EDT$$PA_RANGE (1);
IF (.QCHAR LEQ 0) THEN RETURN (.QCHAR);
RETURN (EDT$$PA_SWITCH (FD_SUB));
END;
END;
[ COM_TYPE ] :
BEGIN
STS = EDT$$PA_RANGE (1);
IF (.STS LEQ 0) THEN RETURN (.STS);
RETURN (EDT$$PA_SWITCH (FD_TYP));
END;
[ COM_HELP ] :
BEGIN
IF (NOT COMMAND (FD_TXT)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN
PA_CURCMD [FSPCLEN] = 0
ELSE
BEGIN
EDT$$PA_SCANTOK (0,0);
PA_CURCMD [FILSPEC] = .PA_CURTOK;
PA_CURCMD [FSPCLEN] = .PA_CURTOKLEN;
END;
END;
[ COM_TADJ ] :
BEGIN
PA_ERRNO = EDT$_NUMVALREQ;
IF (NOT COMMAND (FD_ADJ)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
IF (.C_FDB<0,18> EQL FD_ADJ) THEN
BEGIN
IF (NOT COMMAND (FD_VAL)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
END;
PA_ERRNO = EDT$_NUMVALILL;
STS = 1;
IF (.C_DATA LSS 0) THEN
BEGIN
STS = -1;
C_DATA = - .C_DATA;
END;
IF ((.C_DATA GEQ 32768) OR (.C_DATA * .TAB_SIZ GEQ 256)) THEN
RETURN (-1);
PA_CURCMD [TAB_COUNT] = .STS * .C_DATA;
STS = EDT$$PA_RANGE (1);
IF (.STS LEQ 0) THEN RETURN (.STS);
END;
[ COM_TRACE ] :
BEGIN
PA_ERRNO = EDT$_INVPARFOR;
IF ( NOT COMMAND (FD_TRC)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
CMDTYP = .(.C_DATA)<0,18>;
PA_CURCMD [SET_TYPE] = .CMDTYP;
PA_CURCMD [AS_STR] = 0; ! Preset
IF (((.CMDTYP EQL TRC_ON) OR (.CMDTYP EQL TRC_OFF)) AND
((.C_FLAG AND CM_EOC) EQL 0))
THEN
BEGIN
IF ( NOT COMMAND (FD_TRR)) THEN RETURN (-1);
IF (.CC NEQ 0) THEN RETURN (-1);
IF ((.C_FLAG AND CM_RPT) NEQ 0) THEN RETURN (0);
IF ((.C_FLAG AND CM_NOP) NEQ 0) THEN RETURN (-1);
EDT$$PA_SCANTOK (1, 0);
PA_CURCMD [AS_LEN] = .PA_CURTOKLEN;
PA_CURCMD [AS_STR] = .PA_CURTOK;
IF (.CMDTYP EQL TRC_ON) THEN EDT$$PA_SWITCH (FD_TRS);
END;
END;
[ COM_XDDT , COM_MAC_CALL , COM_PUSH ] :
;
TES;
RETURN (1);
END;
END;
END
ELUDOM