aboutsummaryrefslogtreecommitdiff
path: root/tecparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'tecparse.c')
-rw-r--r--tecparse.c2178
1 files changed, 2178 insertions, 0 deletions
diff --git a/tecparse.c b/tecparse.c
new file mode 100644
index 0000000..9682bf0
--- /dev/null
+++ b/tecparse.c
@@ -0,0 +1,2178 @@
+char *tecparse_c_version = "tecparse.c: $Revision: 1.1 $";
+
+/*
+ * $Date: 2007/12/10 21:59:20 $
+ * $Source: /cvsroot/videoteco/videoteco/tecparse.c,v $
+ * $Revision: 1.1 $
+ * $Locker: $
+ */
+
+/* tecparse.c
+ * Subroutines to implement the finite state parser
+ *
+ * COPYRIGHT (c) 1985-2003 BY
+ * PAUL CANTRELL & J. M. NISHINAGA
+ * SUDBURY, MA 01776
+ * ALL RIGHTS RESERVED
+ *
+ * This software is furnished in it's current state free of charge.
+ * The authors reserve all rights to the software. Further
+ * distribution of the software is not authorized. Modifications to
+ * the software may be made locally, but shall not be distributed
+ * without the consent of the authors. This software or any other
+ * copies thereof, may not be provided or otherwise made available
+ * to anyone without express permission of the authors. Title to and
+ * ownership of this software remains with the authors.
+ *
+ */
+
+#include "teco.h"
+#include "tecparse.h"
+
+ struct cmd_token *cmd_list = NULL;
+ struct cmd_token *last_cmd_list = NULL;
+ struct cmd_token *jump_to_token;
+ struct cmd_token *resume_execute_ct;
+ struct cmd_token *last_token_executed;
+ struct search_buff search_string;
+ char user_message[PARSER_STRING_MAX];
+ int remembered_dot;
+ char immediate_execute_flag = YES;
+ char trace_mode_flag = NO;
+
+ extern int tty_input_chan;
+ extern int errno;
+ extern char exit_flag;
+ extern char intr_flag;
+ extern char susp_flag;
+ extern char input_pending_flag;
+ extern char alternate_escape_character;
+ extern char main_delete_character;
+ extern char alternate_delete_character;
+ extern char checkpoint_flag;
+ extern char checkpoint_enabled;
+ extern char waiting_for_input_flag;
+ extern char resize_flag;
+ extern char ring_audible_bell;
+ extern char suspend_is_okay_flag;
+ extern struct buff_header *curbuf,*buffer_headers;
+ extern int term_speed;
+
+/*
+ * Forward declarations
+ */
+ struct cmd_token *parse_rubout_character(struct cmd_token *,int);
+ struct cmd_token *parse_rubout_cmd_token(struct cmd_token *);
+ void preserve_rubout_char(char);
+ void parser_clean_preserve_list(void);
+ int parser_getc(void);
+ int unpreserve_rubout_char(struct cmd_token *);
+
+
+
+/* TECPARSE - Main entry point of the parser
+ *
+ * Function:
+ *
+ * This routine reads input characters and builds the token
+ * list. It also calls the execute states as long as the go
+ * flag is set. When it hits the final parse state, it then
+ * executes any states which were not immediately executed.
+ */
+void
+tecparse()
+{
+register struct cmd_token *ct;
+int status;
+int c;
+static char no_mem = 0;
+
+ PREAMBLE();
+
+/*
+ * We start our command token list with a special token that simply means that
+ * this is the begining of the list. We also set the current state to be the
+ * initial state of the parser.
+ */
+ resume_execute_ct = NULL;
+ ct = allocate_cmd_token((struct cmd_token *)NULL);
+ if(ct != NULL){
+ no_mem = 0;
+ ct->opcode = TOK_C_FIRSTTOKEN;
+ ct->ctx.state = STATE_C_INITIALSTATE;
+ ct->ctx.go_flag = YES;
+ if(immediate_execute_flag == NO) ct->ctx.go_flag = NO;
+ cmd_list = ct;
+ screen_reset_echo(cmd_list);
+/*
+ * Now we loop until we reach a final state, or something horrible happens.
+ */
+ while(1){
+ c = parser_getc();
+ status = tecparse_syntax(c);
+ if(status == FAIL) break;
+ }/* End While */
+
+ screen_format_windows();
+
+ }/* End IF */
+
+ else {
+ if(no_mem){
+ tec_panic("no memory available");
+ }/* End IF */
+ no_mem = 1;
+ error_message("<no memory>");
+ }/* End Else */
+
+ screen_refresh();
+
+/*
+ * Here to clean up old parse lists. Note that we always clean up the list
+ * on last_cmd_list, and then move the current command list over there. This
+ * is so that we always remember one command string back incase the user uses
+ * the '*' command to save it all to a q-register. Besides unchaining command
+ * blocks, the cleanup routine follows down undo lists and macro lists to
+ * reclaim all the memory they are using.
+ */
+ parser_cleanup_ctlist(last_cmd_list);
+ last_cmd_list = cmd_list;
+ cmd_list = NULL;
+
+/*
+ * Also clean up the rubout Q-register.
+ */
+ parser_clean_preserve_list();
+
+/*
+ * Also, clean up any lookaside lists
+ */
+ tec_gc_lists();
+
+}/* End Routine */
+
+
+
+/* TECPARSE_SYNTAX - Here to manipulate the tree according to new input
+ *
+ * Function:
+ *
+ * This routine is called with an input byte to manipulate the
+ * parser tree and execute any associated code.
+ */
+int
+tecparse_syntax(c)
+int c;
+{
+register struct cmd_token *ct;
+struct cmd_token trace_ct;
+register struct cmd_token *final_token,*last_token;
+int status;
+char token_used,token_marked;
+char old_modified_state;
+struct buff_header *old_curbuf;
+struct undo_token *ut;
+
+ PREAMBLE();
+
+/*
+ * Find the end of the current command list.
+ */
+ ct = cmd_list;
+ while(ct->next_token){
+ ct = ct->next_token;
+ }/* End While */
+/*
+ * parse_special_character tests whether this character is an immediate
+ * typing control character which should not be sent to the state machine but
+ * handled locally. This is how we handle things like rubout, rubout word,
+ * and Control-U.
+ */
+ if(parse_special_character(ct,c)){
+ return(1);
+ }/* End IF */
+/*
+ * We only echo the character if is is not a special character
+ */
+ screen_echo(c);
+ if(input_pending_flag == NO){
+ screen_format_windows();
+ screen_refresh();
+ }/* End IF */
+/*
+ * We set the token_used flag to indicate that we have not used the input
+ * byte yet.
+ */
+ token_used = token_marked = NO;
+/*
+ * Now we loop until we use the input byte, or reach a terminating state
+ */
+ while(1){
+/*
+ * If the last state transition used the input byte, we return to our
+ * caller.
+ */
+ if(token_used == YES){
+ return(1);
+ }/* End IF */
+/*
+ * Allocate a command token to hold the next state transition in. The routine
+ * will automatically link it onto the end of the list.
+ */
+ ct = allocate_cmd_token(ct);
+ if(ct == NULL){
+ error_message("<out of memory>");
+ return(1);
+ }/* End IF */
+/*
+ * Here we check for the special RETURN state. Although all this could be done
+ * in the state machine itself, this was a good place to consolidate things.
+ * We pop the state machine stack a level so as to return to the calling state.
+ * Note that iarg1 and iarg2 are copied from the calling state, so that they
+ * are preserved. This means that the substate must return it's value through
+ * tmpval which is not preserved.
+ */
+ if(ct->ctx.state == STATE_C_RETURN){
+ ct->ctx.state = ct->ctx.return_state;
+ ct->ctx.return_state = ct->ctx.caller_token->ctx.return_state;
+ ct->ctx.iarg1_flag = ct->ctx.caller_token->ctx.iarg1_flag;
+ ct->ctx.iarg2_flag = ct->ctx.caller_token->ctx.iarg2_flag;
+ ct->ctx.iarg1 = ct->ctx.caller_token->ctx.iarg1;
+ ct->ctx.iarg2 = ct->ctx.caller_token->ctx.iarg2;
+ ct->ctx.caller_token = ct->ctx.caller_token->ctx.caller_token;
+ }/* End IF */
+/*
+ * Set up the initial state of the command token. The COPYTOKEN opcode doesn't
+ * really mean anything except that the opcode hasn't really been set, so it's
+ * more for debugging purposes than anything else. Notice that since we are
+ * actually placing an input byte in input_byte, we set the default that the
+ * state will indeed eat the byte. If this is not the case, it is up to the
+ * state to clear the flag.
+ */
+ ct->opcode = TOK_C_COPYTOKEN;
+ ct->flags |= TOK_M_EAT_TOKEN;
+ ct->input_byte = c;
+/*
+ * If this is the first time through here for this input character,
+ * mark this is the input character token so that rubout works correctly.
+ */
+ if(token_marked == NO){
+ ct->opcode = TOK_C_INPUTCHAR;
+ token_marked = YES;
+ }/* End IF */
+/*
+ * Call the state machine to process this character. Although more command
+ * tokens may be added onto the list by the state machine, we leave ct where
+ * it is for the moment so that we can work forward through all the generated
+ * states.
+ */
+ parse_input_character(ct,ct);
+/*
+ * If the state machine indicates that the input character was eaten, remember
+ * this fact.
+ */
+ if(ct->flags & TOK_M_EAT_TOKEN) token_used = YES;
+/*
+ * If this character would cause us to transition into an error state, we
+ * simply don't allow it. We generate a rubout sequence to remove the offending
+ * character and allow the user to make a decision about what to do next.
+ */
+ if(ct->ctx.state == STATE_C_ERRORSTATE){
+ token_used = YES;
+ while(ct->next_token) ct = ct->next_token;
+ ct = parse_rubout_character(ct,0);
+ screen_reset_echo(cmd_list);
+ return(1);
+ }/* End IF*/
+
+/*
+ * If ? debug mode is on, record new syntax tokens in the ? buffer
+ */
+ if(trace_mode_flag == YES){
+ last_token = ct;
+ while(last_token){
+ trace_mode(TRACE_C_PARSE,last_token,0);
+ last_token = last_token->next_token;
+ }/* End While */
+ }/* End IF */
+
+/*
+ * Ok, the state transition seems to have gone smoothly, if the go flag is set
+ * we are in immediate execute mode and can perform the execution phase of the
+ * state transition.
+ */
+ if(resume_execute_ct != NULL){
+ ct = resume_execute_ct;
+ ct->ctx.go_flag = YES;
+ resume_execute_ct = NULL;
+ }
+
+/*
+ * We need a place to chain off undo tokens. If we use the current token,
+ * loops will distribute undo tokens all over the parse tree, with no way
+ * to tell which order they were created in. So we find the last token, and
+ * chain everything off of that. That way, if a rubout is hit, all the undo
+ * tokens will be undone in order back to the last keystroke token. As the
+ * user types more keystrokes, we keep finding the new end of the command
+ * chain, and chaining undo tokens off of that. Thus order will be preserved.
+ */
+ final_token = ct;
+ while (final_token->next_token) final_token = final_token->next_token;
+ last_token = ct->prev_token;
+
+ while(ct){
+/*
+ * We still want to copy tmpvals forward from state to state unless the
+ * parse stage is attempting a store.
+ */
+ if(last_token){
+/*
+ * Carry the argument values forward to this state. If the last state was a
+ * RETURN state, then only copy out the tmpval, and fetch the callers iargs.
+ */
+ if((ct->flags & TOK_M_PARSELOAD_IARG1) == 0){
+ ct->ctx.iarg1 = last_token->ctx.iarg1;
+ }/* End IF */
+ if((ct->flags & TOK_M_PARSELOAD_IARG2) == 0){
+ ct->ctx.iarg2 = last_token->ctx.iarg2;
+ }/* End IF */
+
+ if(ct->ctx.state == STATE_C_RETURN){
+ if((ct->flags & TOK_M_PARSELOAD_IARG1) == 0){
+ ct->ctx.iarg1 = ct->ctx.caller_token->ctx.iarg1;
+ }/* End IF */
+ if((ct->flags & TOK_M_PARSELOAD_IARG2) == 0){
+ ct->ctx.iarg2 = ct->ctx.caller_token->ctx.iarg2;
+ }/* End IF */
+ }/* End IF */
+/*
+ * If the next state is STOREVAL, the syntax stage is setting storeval. The
+ * typical example of this is when the syntax stage sees a constant like '1'.
+ * It uses this state to set the temporary value to 1.
+ */
+ if(
+ ct->execute_state != EXEC_C_STOREVAL &&
+ ((ct->flags & TOK_M_PARSELOAD_TMPVAL) == 0)
+ ){
+ ct->ctx.tmpval = last_token->ctx.tmpval;
+ }/* End IF */
+
+ }/* End IF */
+
+ if(ct->execute_state){
+/*
+ * This is sort of a kludge, but it's an easy place to see if this
+ * state transition causes the buffer to become modified. If so, we
+ * link on an undo token to that if this gets undone, the modified
+ * status gets put back. If we didn't do it here, we would have to
+ * either do it in every command, and that would get tedious.
+ */
+ old_modified_state = curbuf->ismodified;
+ old_curbuf = curbuf;
+
+ if(trace_mode_flag == YES){
+ trace_ct = *ct;
+ }/* End IF */
+
+ status = execute_a_state(ct,final_token);
+ if(status == BLOCKED){
+ resume_execute_ct = ct;
+ }
+/*
+ * An INVALIDATE status occurs when the execute engine changes the
+ * command token list in such a way that we may no longer be pointing
+ * at something valid. So we back out, and re-enter..
+ */
+ if(status == INVALIDATE){
+ return(SUCCESS);
+ }
+
+ if(trace_mode_flag == YES){
+ trace_mode(TRACE_C_EXEC,&trace_ct,ct);
+ }/* End IF */
+/*
+ * If the modified state went from unmodified to modified, link on an
+ * undo token incase this gets undone - then the modified status will
+ * get put back to its original state.
+ */
+ if(old_modified_state == NO && old_curbuf->ismodified == YES){
+ if(ct->undo_list){
+ ut = ct->undo_list;
+ while(ut->next_token) ut = ut->next_token;
+ ut->next_token = allocate_undo_token(NULL);
+ ut = ut->next_token;
+ }/* End IF */
+
+ else ct->undo_list = ut = allocate_undo_token(NULL);
+ if(ut != NULL){
+ ut->opcode = UNDO_C_MODIFIED;
+ ut->carg1 = (char *)old_curbuf;
+ }/* End IF */
+ }/* End IF */
+
+ if(susp_flag) cmd_pause();
+/*
+ * Since we are in immediate execute mode, if we get an error during the
+ * execution phase, we know it was generated by the most recently input
+ * character. Therefore, we can handle it the same way we do during the syntax
+ * parsing, by pretending a rubout character was input.
+ */
+ if(status == BLOCKED) break;
+ if(intr_flag) break;
+
+ if(status != SUCCESS){
+ token_used = YES;
+ while(ct->next_token) ct = ct->next_token;
+ ct = parse_rubout_character(ct,0);
+ screen_reset_echo(cmd_list);
+ break;
+ }/* End IF */
+ }/* End IF */
+
+ last_token = ct;
+
+ if(jump_to_token){
+ ct = jump_to_token;
+ jump_to_token = NULL;
+ continue;
+ }
+
+ if(ct->next_token) ct = ct->next_token;
+ else break;
+ }/* End While */
+/*
+ * Now regardless of whether go_flag is set, chain ct forward to the end of
+ * the token list.
+ */
+ while(ct->next_token) ct = ct->next_token;
+/*
+ * If we hit FINALSTATE, this is the way the state machine has of telling us
+ * to reset to the begining parser state. We remember the final token address
+ * so that all additional undo tokens can be chained off of it.
+ */
+ if(ct->ctx.state == STATE_C_FINALSTATE){
+ return(0);
+ }/* End IF */
+
+ }/* End While */
+
+}/* End Routine */
+
+
+
+/* TECMACRO - Here to execute a Q register as a macro
+ *
+ * Function:
+ *
+ * This routine executes the specified q register as a macro. It returns
+ * SUCCESS or FAILURE depending on what happens within the macro. Note
+ * that it is very similar to the main parse routine. There are two major
+ * differences: First, the characters are gotton from the q-register
+ * rather than the input stream, and second, the entire parse is done
+ * to completion before any execution takes place. This means that the
+ * macro can modify the contents of the q-register without changing the
+ * way the macro will execute.
+ */
+int
+tecmacro(qbp,input_ct,macro_cmd_list)
+register struct buff_header *qbp;
+struct cmd_token *input_ct;
+struct cmd_token **macro_cmd_list;
+{
+register struct cmd_token *ct;
+struct cmd_token trace_ct;
+register struct cmd_token *last_token;
+int c = 0;
+int status;
+char token_used;
+int i;
+char old_modified_state;
+struct buff_header *old_curbuf;
+struct undo_token *ut;
+
+ PREAMBLE();
+
+/*
+ * We start our command token list with a special token that simply means that
+ * this is the begining of the list. We also set the current state to be the
+ * initial state of the parser.
+ */
+ ct = allocate_cmd_token((struct cmd_token *)NULL);
+ if(ct == NULL) return(FAIL);
+
+ ct->opcode = TOK_C_FIRSTTOKEN;
+ ct->ctx.state = STATE_C_INITIALSTATE;
+ ct->ctx.go_flag = NO;
+/*
+ * By setting STATUS_PASSED, we insure that the first command in the macro will
+ * get any arguments we have been passed.
+ */
+ ct->ctx.flags |= CTOK_M_STATUS_PASSED;
+ ct->ctx.iarg1_flag = input_ct->ctx.iarg1_flag;
+ ct->ctx.iarg2_flag = input_ct->ctx.iarg2_flag;
+ ct->ctx.iarg1 = input_ct->ctx.iarg1;
+ ct->ctx.iarg2 = input_ct->ctx.iarg2;
+ *macro_cmd_list = ct;
+/*
+ * We set the token_used flag so that we will call the getc routine. This flag
+ * in general lets us remember whether or not a state transistion ate an input
+ * character or not.
+ */
+ token_used = YES;
+/*
+ * Now we loop until we reach a final state, or something horrible happens.
+ */
+ i = 0;
+
+ while(i <= qbp->zee){
+/*
+ * Allocate a command token to hold the next state transition in. The routine
+ * will automatically link it onto the end of the list.
+ */
+ ct = allocate_cmd_token(ct);
+ if(ct == NULL) return(FAIL);
+/*
+ * Here we check for the special RETURN state. Although all this could be done
+ * in the state machine itself, this was a good place to consolidate things.
+ * We pop the state machine stack a level so as to return to the calling state.
+ * Note that iarg1 and iarg2 are copied from the calling state, so that they
+ * are preserved. This means that the substate must return it's value through
+ * tmpval which is not preserved.
+ */
+ if(ct->ctx.state == STATE_C_RETURN){
+ ct->ctx.state = ct->ctx.return_state;
+ ct->ctx.return_state = ct->ctx.caller_token->ctx.return_state;
+ ct->ctx.iarg1_flag = ct->ctx.caller_token->ctx.iarg1_flag;
+ ct->ctx.iarg2_flag = ct->ctx.caller_token->ctx.iarg2_flag;
+ ct->ctx.iarg1 = ct->ctx.caller_token->ctx.iarg1;
+ ct->ctx.iarg2 = ct->ctx.caller_token->ctx.iarg2;
+ ct->ctx.caller_token = ct->ctx.caller_token->ctx.caller_token;
+ }/* End IF */
+/*
+ * Set up the comand token a little
+ */
+ ct->opcode = TOK_C_COPYTOKEN;
+ ct->flags |= TOK_M_EAT_TOKEN;
+ ct->input_byte = c;
+/*
+ * If the last state ate the input character, we need to fetch another from the
+ * command source.
+ */
+ if(token_used == YES){
+ if(i == qbp->zee) c = ESCAPE;
+ else c = buff_contents(qbp,i++);
+#ifdef NEEDED_WHICH_I_DONT_THINK_IT_IS
+ if(parse_special_character(ct,c)){
+ ct = *macro_cmd_list;
+ while(ct->next_token) ct = ct->next_token;
+ continue;
+ }/* End IF */
+#endif
+ ct->opcode = TOK_C_INPUTCHAR;
+ ct->input_byte = c;
+ }/* End IF */
+
+ token_used = NO;
+/*
+ * Call the state machine to process this character. Although more command
+ * tokens may be added onto the list by the state machine, we leave ct where
+ * it is for the moment so that we can work forward through all the generated
+ * states.
+ */
+ parse_input_character(ct,*macro_cmd_list);
+/*
+ * If the state machine indicates that the input character was eaten, remember
+ * this fact.
+ */
+ if(ct->flags & TOK_M_EAT_TOKEN) token_used = YES;
+/*
+ * If this character would cause us to transition into an error state, we
+ * terminate the macro and indicate where the error was.
+ */
+ if(ct->ctx.state == STATE_C_ERRORSTATE){
+ token_used = YES;
+ while(ct->next_token) ct = ct->next_token;
+ while(ct->opcode != TOK_C_FIRSTTOKEN){
+ ct = parse_rubout_character(ct,0);
+ }/* End While */
+ return(FAIL);
+ }/* End IF*/
+/*
+ * Always chain ct forward over any generated tokens
+ */
+ while(ct->next_token) ct = ct->next_token;
+/*
+ * If we hit FINALSTATE, this is the way the state machine has of telling us
+ * to reset to the begining parser state.
+ */
+ if(ct->ctx.state == STATE_C_FINALSTATE) break;
+
+ }/* End While */
+
+/*
+ * Now that the syntax parsing has been completed, we start execution of the
+ * macro.
+ */
+ ct = last_token = *macro_cmd_list;
+
+ while(ct){
+
+/*
+ * If we hit the final state, we don't need to go any further.
+ */
+ if(ct->ctx.state == STATE_C_FINALSTATE) break;
+
+/*
+ * Carry the argument values forward to this state. If the last state was a
+ * RETURN state, then only copy out the tmpval, and fetch the callers iargs.
+ */
+ if((ct->flags & TOK_M_PARSELOAD_IARG1) == 0){
+ ct->ctx.iarg1 = last_token->ctx.iarg1;
+ }/* End IF */
+ if((ct->flags & TOK_M_PARSELOAD_IARG2) == 0){
+ ct->ctx.iarg2 = last_token->ctx.iarg2;
+ }/* End IF */
+
+ if(ct->ctx.state == STATE_C_RETURN){
+ if((ct->flags & TOK_M_PARSELOAD_IARG1) == 0){
+ ct->ctx.iarg1 = ct->ctx.caller_token->ctx.iarg1;
+ }/* End IF */
+ if((ct->flags & TOK_M_PARSELOAD_IARG2) == 0){
+ ct->ctx.iarg2 = ct->ctx.caller_token->ctx.iarg2;
+ }/* End IF */
+ }/* End IF */
+/*
+ * If the next state is STOREVAL, the syntax stage is setting storeval. The
+ * typical example of this is when the syntax stage sees a constant like '1'.
+ * It uses this state to set the temporary value to 1.
+ */
+ if(
+ ct->execute_state != EXEC_C_STOREVAL &&
+ ((ct->flags & TOK_M_PARSELOAD_TMPVAL) == 0)
+ ){
+ ct->ctx.tmpval = last_token->ctx.tmpval;
+ }/* End IF */
+
+/*
+ * If this token has an execute state, call the execute phase to implement it.
+ */
+ if(trace_mode_flag == YES){
+ trace_mode(TRACE_C_MACRO,ct,0);
+ }/* End IF */
+
+ if(ct->execute_state){
+
+ old_modified_state = curbuf->ismodified;
+ old_curbuf = curbuf;
+
+ if(trace_mode_flag == YES){
+ trace_ct = *ct;
+ }/* End IF */
+
+ status = execute_a_state(ct,*macro_cmd_list);
+
+ if(trace_mode_flag == YES){
+ trace_mode(TRACE_C_EXEC,&trace_ct,ct);
+ }/* End IF */
+
+ if(old_modified_state == NO && old_curbuf->ismodified == YES){
+ if(ct->undo_list){
+ ut = ct->undo_list;
+ while(ut->next_token) ut = ut->next_token;
+ ut->next_token = allocate_undo_token(NULL);
+ ut = ut->next_token;
+ }/* End IF */
+
+ else ct->undo_list = ut = allocate_undo_token(NULL);
+ if(ut != NULL){
+ ut->opcode = UNDO_C_MODIFIED;
+ ut->carg1 = (char *)old_curbuf;
+ }/* End IF */
+ }/* End IF */
+
+ if(status != SUCCESS) goto cleanup;
+ if(exit_flag == YES) goto cleanup;
+ if(intr_flag) goto cleanup;
+ if(susp_flag) cmd_pause();
+ }/* End IF */
+/*
+ * Ok, now chain to the next token, or quit if done
+ */
+ last_token = ct;
+ ct = ct->next_token;
+ if(jump_to_token){
+ ct = jump_to_token;
+ last_token = ct;
+ jump_to_token = NULL;
+ }/* End IF */
+ }/* End While */
+
+cleanup:
+
+ if(input_ct->ctx.flags & CTOK_M_STATUS_PASSED){
+ input_ct->ctx.iarg1_flag = last_token->ctx.iarg1_flag;
+ input_ct->ctx.iarg1 = last_token->ctx.iarg1;
+ }/* End IF */
+
+ return(SUCCESS);
+
+}/* End Routine */
+
+
+
+/* PARSE_SPECIAL_CHARACTER - Test for and handle special characters
+ *
+ * Function:
+ *
+ * This routine is called on each input character to determine whether
+ * it requires special handling. It catches characters such as rubout,
+ * ^W, ^U.
+ */
+int
+parse_special_character(ct,c)
+register struct cmd_token *ct;
+register int c;
+{
+char state_seen;
+int tmp;
+
+ PREAMBLE();
+
+ switch(c){
+ case RUBOUT:
+ ct = parse_rubout_character(ct,1);
+ break;
+ case CNTRL_U:
+/*
+ * Get rid of any <CR> right at the deletion point
+ */
+ if(ct->opcode == TOK_C_INPUTCHAR){
+ ct = parse_rubout_character(ct,1);
+ }/* End IF */
+
+ while(ct != cmd_list){
+ if(ct->opcode == TOK_C_INPUTCHAR && ct->input_byte == '\n'){
+ break;
+ }/* End IF */
+ ct = parse_rubout_character(ct,1);
+ }/* End While */
+ break;
+ case CNTRL_W:
+ state_seen = 0;
+ tmp = 0;
+
+ while(ct != cmd_list){
+ if(ct->flags & TOK_M_WORDBOUNDARY){
+ state_seen = 1;
+ break;
+ }/* End IF */
+
+ if(ct->opcode == TOK_C_INPUTCHAR){
+ tmp += 1;
+ if(tmp == 1 && ct->input_byte == '\n'){
+ preserve_rubout_char(ct->input_byte);
+ ct = parse_rubout_cmd_token(ct);
+ break;
+ }/* End IF */
+
+ if(ct->input_byte != ' ' && ct->input_byte != '\t') break;
+ preserve_rubout_char(ct->input_byte);
+
+ }/* End IF */
+
+ ct = parse_rubout_cmd_token(ct);
+
+ }/* End While */
+
+ while(ct != cmd_list){
+ if(ct->flags & TOK_M_WORDBOUNDARY) state_seen = 1;
+
+ if(ct->opcode == TOK_C_INPUTCHAR){
+ if(state_seen){
+ preserve_rubout_char(ct->input_byte);
+ ct = parse_rubout_cmd_token(ct);
+ break;
+ }/* End IF */
+
+ if(isspace((int)ct->input_byte)) break;
+ preserve_rubout_char(ct->input_byte);
+
+ }/* End IF */
+
+ ct = parse_rubout_cmd_token(ct);
+
+ }/* End While */
+
+ break;
+
+ case CNTRL_R:
+ if(!unpreserve_rubout_char(ct)){
+ error_message("^R no input tokens available");
+ }/* End IF */
+ return(1);
+
+ default:
+ return(0);
+ }/* End Switch */
+
+ screen_reset_echo(cmd_list);
+ return(1);
+
+}/* End Routine */
+
+
+
+/* PARSE_RUBOUT_CHARACTER - Rubout the most recent character
+ *
+ * Function:
+ *
+ * This routine is called when a rubout character is typed. We have to
+ * back the parser up to the state it was in before the original char
+ * was typed, as well as performing any undo functions to make sure
+ * that the edit buffer also gets backed up.
+ */
+struct cmd_token *
+parse_rubout_character(ct,preserve_flag)
+register struct cmd_token *ct;
+int preserve_flag;
+{
+register struct cmd_token *oct;
+struct undo_token *ut;
+char saved_opcode;
+
+ PREAMBLE();
+
+ while(1){
+
+/*
+ * If the preserve flag is on, we want to save any deleted bytes in the
+ * q-register that is used for this purpose. That way, the user can
+ * correct for mistakenly typing the wrong rubout code.
+ */
+ if(preserve_flag && ct->opcode == TOK_C_INPUTCHAR){
+ preserve_rubout_char(ct->input_byte);
+ }/* End IF */
+
+/*
+ * For each of the command tokens, we need to undo all the chained undo
+ * tokens.
+ */
+ while( (ut = ct->undo_list) != NULL ){
+/*
+ * Take the top undo token off of the list and change the listhead to point
+ * to it's child.
+ */
+ ct->undo_list = ut->next_token;
+ ut->next_token = NULL;
+/*
+ * Now call the undo routine to back out the changes to the edit buffer that
+ * this token calls for. Then place the token back on the free list.
+ */
+ parser_undo(ut);
+ free_undo_token(ut);
+
+ }/* End While */
+/*
+ * If this is TOK_C_FIRSTTOKEN, it means he is trying to rubout the head of the
+ * list. This is probably not such a hot idea...
+ */
+ if(ct->opcode == TOK_C_FIRSTTOKEN) break;
+/*
+ * We save the opcode so that after cleaning up the token, we will know whether
+ * it was an input character or not.
+ */
+ saved_opcode = ct->opcode;
+
+ oct = ct->prev_token;
+ if(oct == NULL) break;
+ oct->next_token = NULL;
+ ct->prev_token = NULL;
+ free_cmd_token(ct);
+ ct = oct;
+/*
+ * If this was an input character, then we have backed up enough.
+ */
+ if(saved_opcode == TOK_C_INPUTCHAR) break;
+
+ }/* End While */
+
+ return(ct);
+
+}/* End Routine */
+
+
+
+/* PARSE_RUBOUT_CMD_TOKEN - Rubout the most recent command token
+ *
+ * Function:
+ *
+ * This routine is called to remove the last token on the command
+ * list. It gets used in rubout / ^U / ^W processing.
+ */
+struct cmd_token *
+parse_rubout_cmd_token(ct)
+register struct cmd_token *ct;
+{
+register struct cmd_token *oct;
+struct undo_token *ut;
+
+ PREAMBLE();
+
+/*
+ * We need to undo all the undo tokens chained off of this command token.
+ */
+ while( (ut = ct->undo_list) != NULL ){
+/*
+ * Take the top undo token off of the list and change the listhead to point
+ * to it's child.
+ */
+ ct->undo_list = ut->next_token;
+ ut->next_token = NULL;
+/*
+ * Now call the undo routine to back out the changes to the edit buffer that
+ * this token calls for. Then place the token back on the free list.
+ */
+ parser_undo(ut);
+ free_undo_token(ut);
+
+ }/* End While */
+
+ oct = ct->prev_token;
+ if(oct) oct->next_token = NULL;
+ ct->prev_token = NULL;
+ free_cmd_token(ct);
+ return(oct);
+
+}/* End Routine */
+
+
+
+/* PARSER_GETC - Return next input character
+ *
+ * Function:
+ *
+ * This routine is called by the parser when another input byte is needed.
+ */
+int
+parser_getc()
+{
+register int i;
+char inbuf[4];
+
+#ifdef VMS
+ short qio_iosb[4];
+#endif /* VMS */
+
+ PREAMBLE();
+
+/*
+ * If there are no unclaimed bytes in the buffer, we need to read one
+ * from the command channel.
+ */
+ input_pending_flag = tty_input_pending();
+
+ if(input_pending_flag == NO){
+ if(ring_audible_bell){
+ term_putc(BELL);
+ ring_audible_bell = 0;
+ }/* End IF */
+ screen_echo('\0');
+ screen_format_windows();
+ screen_refresh();
+ }/* End IF */
+
+#ifdef CHECKPOINT
+ if(checkpoint_enabled == YES && checkpoint_flag == YES){
+ cmd_checkpoint();
+ checkpoint_flag = NO;
+ }/* End IF */
+#endif /* CHECKPOINT */
+
+ while(1){
+
+#ifdef UNIX
+
+ if(susp_flag){
+ pause_while_in_input_wait();
+ continue;
+ }/* End IF */
+
+ if(resize_flag){
+ screen_resize();
+ }/* End IF */
+
+ waiting_for_input_flag = YES;
+ i = read(tty_input_chan,inbuf,1);
+ waiting_for_input_flag = NO;
+
+ intr_flag = 0;
+
+ if(i >= 0) break;
+
+ if(errno == EINTR) continue;
+#endif
+#ifdef VMS
+ waiting_for_input_flag = YES;
+ i = sys$qiow(0,tty_input_chan,IO$_READVBLK|IO$M_NOECHO|IO$M_NOFILTR,
+ qio_iosb,0,0,inbuf,1,0,0,0,0);
+ waiting_for_input_flag = NO;
+ if(!(i & STS$M_SUCCESS)) exit(i);
+if(qio_iosb[0] != 1)
+printf("!!! iosb[0] is %d\n",qio_iosb[0]);
+ if(inbuf[0] == '\r') inbuf[0] = '\n';
+ else if(inbuf[0] == '\n') inbuf[0] = '\r';
+ if(inbuf[0] == '`') inbuf[0] = ESCAPE;
+ if(inbuf[0] == CNTRL_Z && suspend_is_okay_flag == YES){
+ pause_while_in_input_wait();
+ continue;
+ }/* End IF */
+
+ break;
+#endif
+ perror("error reading command input");
+ punt(errno);
+ }/* End While */
+
+ screen_reset_message();
+
+ input_pending_flag = tty_input_pending();
+
+ if(inbuf[0] == alternate_escape_character){
+ return(ESCAPE);
+ }/* End IF */
+
+ if(inbuf[0] == main_delete_character){
+ return(RUBOUT);
+ }/* End IF */
+
+ if(inbuf[0] == alternate_delete_character){
+ return(RUBOUT);
+ }/* End IF */
+
+ return(inbuf[0]);
+
+}/* End Routine */
+
+
+
+/* PRESERVE_RUBOUT_CHARCTER - Save rubbed out characters
+ *
+ * Function:
+ *
+ * This routine is called in response to the user rubbing out input
+ * characters with rubout, ^U, or ^W. Sometimes he does this by
+ * mistake, and can delete large amounts of typing unintentially.
+ * This routine saves these characters in a special Q-register so
+ * that he can get them back if he wants.
+ */
+void
+preserve_rubout_char(the_byte)
+char the_byte;
+{
+register struct buff_header *qbp;
+
+ PREAMBLE();
+
+/*
+ * Get a pointer to the special Q-register which holds the characters which
+ * have been rubbed out.
+ */
+ qbp = buff_qfind('@',1);
+ if(qbp == NULL){
+ return;
+ }/* End IF */
+
+/*
+ * Put the deleted byte into the Q-register where it can be retrieved by
+ * the user if so desired.
+ */
+ buff_insert_char(qbp,0,the_byte);
+
+}/* End Routine */
+
+
+
+/* UNPRESERVE_RUBOUT_CHAR - Poke a rubbed out char back into the parse
+ *
+ * Function:
+ *
+ * This routine is called on behalf of a ^R command which causes the
+ * most recent rubbed out character to be restored to the parse tree.
+ * The return code determines whether this was done okay or not.
+ */
+int
+unpreserve_rubout_char(ct)
+struct cmd_token *ct;
+{
+register struct buff_header *qbp;
+int c;
+
+ PREAMBLE();
+
+/*
+ * Get a pointer to the special Q-register which holds the characters which
+ * have been rubbed out.
+ */
+ qbp = buff_qfind('@',1);
+ if(qbp == NULL){
+ return(FAIL);
+ }/* End IF */
+
+/*
+ * Make sure thre are some bytes in it
+ */
+ if(qbp->zee <= 0) return(FAIL);
+
+/*
+ * Get the first byte saved in the Q-register
+ */
+ c = buff_contents(qbp,0);
+ buff_delete(qbp,0,1);
+
+ tecparse_syntax(c);
+
+ return(SUCCESS);
+
+}/* End Routine */
+
+
+
+/* PARSER_CLEAN_PRESERVE_LIST - Zero the rubout preserve Q-register
+ *
+ * Function:
+ *
+ * This routine is called at double-escape time to clean up the
+ * special Q-register so that it doesn't grow without bounds.
+ */
+void
+parser_clean_preserve_list()
+{
+register struct buff_header *qbp;
+
+ PREAMBLE();
+
+/*
+ * Get a pointer to the special Q-register which holds the characters which
+ * have been rubbed out.
+ */
+ qbp = buff_qfind('@',1);
+ if(qbp == NULL){
+ return;
+ }/* End IF */
+
+/*
+ * Delete all the bytes in the Q-register
+ */
+ buff_delete(qbp,0,qbp->zee);
+
+}/* End Routine */
+
+
+
+/* PARSER_DUMP_COMMAND_LINE - Copy the current parse tree into a Q-register
+ *
+ * Function:
+ *
+ * This routine copies the input bytes from the current command string
+ * into the specified Q-register.
+ */
+void
+parser_dump_command_line(qbp)
+register struct buff_header *qbp;
+{
+register struct cmd_token *ct;
+
+ PREAMBLE();
+
+ ct = cmd_list;
+
+ while(ct){
+ if(ct->opcode == TOK_C_INPUTCHAR){
+ buff_insert_char(qbp,qbp->zee,ct->input_byte);
+ }/* End IF */
+ ct = ct->next_token;
+ }/* End While */
+
+}/* End Routine */
+
+
+
+/* PARSER_REPLACE_COMMAND_LINE - Replace current parse tree
+ *
+ * Function:
+ *
+ * This routine replaces the current command string with the contents
+ * the specified Q-register.
+ */
+int
+parser_replace_command_line(qbp)
+register struct buff_header *qbp;
+{
+register struct cmd_token *ct;
+register struct cmd_token *first_different_ct;
+register int c;
+char temp;
+register char *command_buffer;
+register int cb_zee;
+
+ PREAMBLE();
+
+ cb_zee = 0;
+ command_buffer = tec_alloc(TYPE_C_CBUFF,qbp->zee);
+ if(command_buffer == NULL) return(FAIL);
+/*
+ * Walk the parse list to find the first place there is a difference
+ * between the current parse list, and the one to be installed. When
+ * we find the first difference, remember it, and then start copying
+ * the changed bytes into our temporary Q-register.
+ */
+ first_different_ct = NULL;
+ ct = cmd_list;
+ for(c = 0; c < qbp->zee - 1; c++){
+ temp = buff_contents(qbp,c);
+ if(first_different_ct == NULL){
+ while(ct && ct->opcode != TOK_C_INPUTCHAR){
+ ct = ct->next_token;
+ }/* End While */
+ if(ct && ct->input_byte != temp) first_different_ct = ct;
+ if(ct && ct->next_token) ct = ct->next_token;
+ }/* End IF */
+ if(first_different_ct){
+ command_buffer[cb_zee++] = temp;
+ }/* End IF */
+ }/* End FOR */
+
+ if(ct != NULL && first_different_ct == NULL){
+ while(ct->next_token){
+ if(ct->opcode == TOK_C_INPUTCHAR) break;
+ ct = ct->next_token;
+ }
+ first_different_ct = ct;
+ }
+/*
+ * We only have to do the following if there were any changed bytes at
+ * all. If he changed his mind and didn't modify the command list at all,
+ * nothing really has to happen at all.
+ */
+ if(first_different_ct){
+ while(first_different_ct->next_token != NULL &&
+ first_different_ct->next_token->opcode != TOK_C_INPUTCHAR){
+ first_different_ct = first_different_ct->next_token;
+ }
+ ct = cmd_list;
+ while(ct->next_token) ct = ct->next_token;
+/*
+ * Remove from the tail of the parse list all the bytes up to and including
+ * the first different character. This leaves us with a parse list which is
+ * just the part that has not changed.
+ */
+ temp = 1;
+ while(ct != cmd_list && temp != 0){
+ if(ct == first_different_ct) temp = 0;
+ ct = parse_rubout_character(ct,0);
+ }/* End While */
+
+/*
+ * Now we walk through the Q-register, adding these bytes to the end of the
+ * parse list. These are the bytes which are different from the original
+ * parse list.
+ */
+ qbp->pos_cache.lbp = NULL;
+ input_pending_flag = YES;
+ for(c = 0; c < cb_zee; c++){
+ temp = command_buffer[c];
+ tecparse_syntax(temp);
+ }/* End While */
+ }/* End IF */
+ tec_release(TYPE_C_CBUFF,command_buffer);
+ parser_reset_echo();
+
+ return(SUCCESS);
+
+}/* End Routine */
+
+
+
+/* ALLOCATE_CMD_TOKEN - Allocate a command token structure
+ *
+ * Function:
+ *
+ * This routine is called to allocate a command token structure. If there
+ * is one on the free list, it is used, otherwise we allocate one. If
+ * an old_token was specified, the context area is copied into the new
+ * token, which has the effect of rippling the context forward through
+ * the parse.
+ */
+struct cmd_token *
+allocate_cmd_token(old_token)
+register struct cmd_token *old_token;
+{
+register struct cmd_token *ct;
+
+ PREAMBLE();
+
+/*
+ * Call the memory allocator for a command token block
+ */
+ ct = (struct cmd_token *)tec_alloc(TYPE_C_CMD,sizeof(struct cmd_token));
+ if(ct == NULL) return(NULL);
+
+/*
+ * We set up the initial state to be that of an empty token, with fields
+ * which are not set up yet set to their proper defaults.
+ */
+ ct->opcode = TOK_C_UNUSED;
+ ct->ctx.iarg1_flag = ct->ctx.iarg2_flag = NO;
+ ct->ctx.iarg1 = ct->ctx.iarg2 = 0;
+ ct->ctx.carg = NULL;
+ ct->next_token = NULL;
+ ct->undo_list = NULL;
+ ct->execute_state = 0;
+ ct->flags = 0;
+
+ ct->prev_token = NULL;
+ ct->ctx.state = 0;
+ ct->ctx.go_flag = NO;
+ ct->ctx.return_state = 0;
+ ct->ctx.caller_token = NULL;
+ ct->ctx.pnest = ct->ctx.inest = ct->ctx.cnest = 0;
+/*
+ * If there was an old token specified, two things must happen. First, we
+ * have to link the new token onto the old token list. Second, we have to
+ * copy the context area from the old token into the new one.
+ */
+ if(old_token){
+ old_token->next_token = ct;
+ ct->prev_token = old_token;
+ ct->ctx = old_token->ctx;
+ }/* End IF */
+
+ return(ct);
+
+}/* End Routine */
+
+
+
+/* FREE_CMD_TOKEN - Routine to place a cmd token on the free list
+ *
+ * Function:
+ *
+ * This routine is called with the address of the command token
+ * to be placed on the free list.
+ */
+void
+free_cmd_token(ct)
+register struct cmd_token *ct;
+{
+
+ PREAMBLE();
+
+ tec_release(TYPE_C_CMD,(char *)ct);
+
+}/* End Routine */
+
+/* PAUSE_WHILE_IN_INPUT_WAIT - Pauses with the terminal in a good state
+ *
+ * Function:
+ *
+ * This routine is called to pause the editor while we have been in
+ * an input wait state. The big deal here is that we want to remove
+ * the reverse video box that may be on the echo line before we pause
+ * back to the system command processor.
+ */
+void
+pause_while_in_input_wait()
+{
+
+ PREAMBLE();
+
+ screen_reset_echo(cmd_list);
+ screen_refresh();
+ cmd_pause();
+ screen_echo('\0');
+ screen_refresh();
+
+}/* End Routine */
+
+
+
+/* PARSER_CLEANUP_CTLIST - Routine to deallocate all the blocks on a ct list
+ *
+ * Function:
+ *
+ * This function deallocates all the blocks on a command token list,
+ * including cmd_tokens and undo_tokens.
+ */
+void
+parser_cleanup_ctlist(ct)
+register struct cmd_token *ct;
+{
+register struct cmd_token *oct;
+
+ PREAMBLE();
+
+/*
+ * For each command token, if it has a list of undo tokens connected we
+ * call the routine which knows how to clean them up.
+ */
+ while(ct){
+ if(ct->undo_list){
+ tecundo_cleanup(ct->undo_list);
+ }/* End IF */
+
+ ct->undo_list = NULL;
+/*
+ * Now we remember what the next token in the list is, and then call the
+ * routine to free the current one.
+ */
+ oct = ct;
+ ct = ct->next_token;
+ free_cmd_token(oct);
+
+ }/* End While */
+
+}/* End Routine */
+
+
+
+/* PARSE_ANY_ARGUMENTS - Called by routines that don't want any arguments
+ *
+ * Function:
+ *
+ * This function is called by states which don't want to accept any
+ * arguments. If there are any present, it will generate an error message
+ * and set the error state.
+ */
+int
+parse_any_arguments(ct,cmd_name)
+register struct cmd_token *ct;
+char *cmd_name;
+{
+char tmp_message[LINE_BUFFER_SIZE];
+
+ PREAMBLE();
+
+/*
+ * If either of the iarg flags is set, that means we received an argument.
+ */
+ if(ct->ctx.iarg1_flag == YES || ct->ctx.iarg2_flag == YES){
+ (void) strcpy(tmp_message,"?The ");
+ (void) strcat(tmp_message,cmd_name);
+ (void) strcat(tmp_message," command accepts no arguments");
+ error_message(tmp_message);
+ ct->ctx.state = STATE_C_ERRORSTATE;
+ return(1);
+ }/* End IF */
+
+ return(0);
+
+}/* End Routine */
+
+/* PARSE_MORE_THAN_ONE_ARG - Called by routines that only want one arg
+ *
+ * Function:
+ *
+ * This function is called by states which only want to accept one
+ * argument. If there are two present, it will generate an error message
+ * and set the error state.
+ */
+int
+parse_more_than_one_arg(ct,cmd_name)
+register struct cmd_token *ct;
+char *cmd_name;
+{
+char tmp_message[LINE_BUFFER_SIZE];
+
+ PREAMBLE();
+
+/*
+ * If the iarg2 flag is set, that means that we received two arguments when
+ * we really only want one.
+ */
+ if(ct->ctx.iarg2_flag == YES){
+ (void) strcpy(tmp_message,"?Two Arguments to ");
+ (void) strcat(tmp_message,cmd_name);
+ (void) strcat(tmp_message," not allowed");
+ error_message(tmp_message);
+ ct->ctx.state = STATE_C_ERRORSTATE;
+ return(1);
+ }/* End IF */
+
+ return(0);
+
+}/* End Routine */
+
+
+
+/* PARSE_ILLEGAL_BUFFER_POSITION - Check for illegal buffer positions
+ *
+ * Function:
+ *
+ * This routine is called to verify that buffer positions specified are
+ * legal. If they are not, it generates an error message.
+ */
+int
+parse_illegal_buffer_position(pos1,pos2,cmd_name)
+register int pos1;
+register int pos2;
+char *cmd_name;
+{
+char illegal_position;
+char tmp_message[LINE_BUFFER_SIZE];
+
+ PREAMBLE();
+
+ illegal_position = 0;
+ if(pos1 < 0) illegal_position = 1;
+ if(pos2 < 0) illegal_position = 1;
+ if(pos1 > curbuf->zee) illegal_position = 1;
+ if(pos2 > curbuf->zee) illegal_position = 1;
+
+ if(illegal_position == 0) return(0);
+
+ (void) strcpy(tmp_message,"?Attempt to Move Pointer Off Page with ");
+ (void) strcat(tmp_message,cmd_name);
+ error_message(tmp_message);
+ return(1);
+
+}/* End Routine */
+
+
+
+/* PARSER_RESET_ECHO - Re-echo the input line
+ *
+ * Function:
+ *
+ * This is just an entry point to restore the echo line from a module
+ * that doesn't want to know about the cmd_list structure.
+ */
+void
+parser_reset_echo()
+{
+ PREAMBLE();
+
+ screen_reset_echo(cmd_list);
+
+}/* End Routine */
+
+
+
+/* TRACE_MODE - Trace execution of commands
+ *
+ * Function:
+ *
+ * This routine is called at parse and execute time if tracing has been
+ * enabled by the ? command. It causes q-register ? to be filled with
+ * execution trace information.
+ */
+void
+trace_mode(phase,ct0,ct1)
+register int phase;
+struct cmd_token *ct0;
+struct cmd_token *ct1;
+{
+register struct buff_header *qbp;
+char tmp_message[LINE_BUFFER_SIZE];
+register char *cp;
+register char *state_name;
+char *trace_convert_state_to_name();
+char *trace_convert_opcode_to_name();
+char *trace_convert_exec_state_to_name();
+
+ PREAMBLE();
+
+ qbp = buff_qfind('?',1);
+ if(qbp == NULL) return;
+
+ switch(phase){
+ case TRACE_C_PARSE:
+ state_name = trace_convert_opcode_to_name(ct0->opcode);
+ if(state_name == NULL) state_name = "UNKNOWN";
+ sprintf(tmp_message,"PARSE: 0x%08X Opcode %s %c",
+ (unsigned int)ct0,
+ state_name,
+/* ct0->opcode == TOK_C_INPUTCHAR ? ct0->input_byte : ' '); */
+ ct0->flags & TOK_M_EAT_TOKEN ? ct0->input_byte : ' ');
+ if(ct0->flags & TOK_M_EAT_TOKEN){
+ strcat(tmp_message," TOK_M_EAT_TOKEN");
+ }/* End IF */
+ if(ct0->flags & TOK_M_WORDBOUNDARY){
+ strcat(tmp_message," TOK_M_WORDBOUNDARY");
+ }/* End IF */
+ if(ct0->flags & TOK_M_PARSELOAD_IARG1){
+ strcat(tmp_message," TOK_M_PARSELOAD_IARG1");
+ }/* End IF */
+ if(ct0->flags & TOK_M_PARSELOAD_IARG2){
+ strcat(tmp_message," TOK_M_PARSELOAD_IARG2");
+ }/* End IF */
+ if(ct0->flags & TOK_M_PARSELOAD_TMPVAL){
+ strcat(tmp_message," TOK_M_PARSELOAD_TMPVAL");
+ }/* End IF */
+ strcat(tmp_message,"\n");
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+/* int execute_state; */
+ state_name = trace_convert_state_to_name(ct0->ctx.state);
+ if(state_name == NULL) state_name = "UNKNOWN";
+ sprintf(tmp_message," Parser State: %s '%c'",
+ state_name,isprint((int)ct0->q_register) ?
+ ct0->q_register : ' ');
+ if(ct0->ctx.flags & CTOK_M_COLON_SEEN){
+ strcat(tmp_message," CTOK_M_COLON_SEEN");
+ }/* End IF */
+ if(ct0->ctx.flags & CTOK_M_ATSIGN_SEEN){
+ strcat(tmp_message," CTOK_M_ATSIGN_SEEN");
+ }/* End IF */
+ if(ct0->ctx.flags & CTOK_M_STATUS_PASSED){
+ strcat(tmp_message," CTOK_M_STATUS_PASSED");
+ }/* End IF */
+ strcat(tmp_message,"\n");
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ if(ct0->ctx.go_flag == 0){
+ sprintf(tmp_message," Go flag clear\n");
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+ }/* End IF */
+
+ if(ct0->ctx.pnest || ct0->ctx.inest || ct0->ctx.cnest){
+ sprintf(tmp_message," PNEST: %d INEST %d CNEST %d\n",
+ ct0->ctx.pnest,ct0->ctx.inest,ct0->ctx.cnest);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+ }/* End IF */
+
+ sprintf(tmp_message," iarg1_flag %d iarg1 %d (0x%x)\n",
+ ct0->ctx.iarg1_flag,ct0->ctx.iarg1,ct0->ctx.iarg1);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," iarg2_flag %d iarg2 %d (0x%x)\n",
+ ct0->ctx.iarg2_flag,ct0->ctx.iarg2,ct0->ctx.iarg2);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," carg 0x%x\n",(unsigned int)ct0->ctx.carg);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," tmpval %d (0x%x)\n",
+ ct0->ctx.tmpval,ct0->ctx.tmpval);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ if(ct0->ctx.return_state || ct0->ctx.caller_token){
+ state_name = "";
+ if(ct0->ctx.return_state){
+ state_name =
+ trace_convert_state_to_name(ct0->ctx.return_state);
+ if(state_name == NULL) state_name = "UNKNOWN";
+ }/* End IF */
+ sprintf(tmp_message," return_state %s caller_token 0x%x\n",
+ state_name,(unsigned int)ct0->ctx.caller_token);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+ }/* End IF */
+ break;
+
+ case TRACE_C_EXEC:
+ state_name = trace_convert_exec_state_to_name(ct0->execute_state);
+ if(state_name == NULL) state_name = "UNKNOWN";
+ sprintf(tmp_message,"EXEC: 0x%08X Exec State: %s\n",
+ (unsigned int)ct1,state_name);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," iarg1_flag %d iarg1 %d (0x%x)",
+ ct0->ctx.iarg1_flag,ct0->ctx.iarg1,ct0->ctx.iarg1);
+ while(strlen(tmp_message) < 39) strcat(tmp_message," ");
+ strcat(tmp_message," ");
+ cp = &tmp_message[strlen(tmp_message)];
+ sprintf(cp," iarg1_flag %d iarg1 %d (0x%x)\n",
+ ct1->ctx.iarg1_flag,ct1->ctx.iarg1,ct1->ctx.iarg1);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," iarg2_flag %d iarg2 %d (0x%x)",
+ ct0->ctx.iarg2_flag,ct0->ctx.iarg2,ct0->ctx.iarg2);
+ while(strlen(tmp_message) < 39) strcat(tmp_message," ");
+ strcat(tmp_message," ");
+ cp = &tmp_message[strlen(tmp_message)];
+ sprintf(cp," iarg2_flag %d iarg2 %d (0x%x)\n",
+ ct1->ctx.iarg2_flag,ct1->ctx.iarg2,ct1->ctx.iarg2);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," carg 0x%x",(unsigned int)ct0->ctx.carg);
+ while(strlen(tmp_message) < 39) strcat(tmp_message," ");
+ strcat(tmp_message," ");
+ cp = &tmp_message[strlen(tmp_message)];
+ sprintf(cp," carg 0x%x\n",(unsigned int)ct1->ctx.carg);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," tmpval %d (0x%x)",
+ ct0->ctx.tmpval,ct0->ctx.tmpval);
+ while(strlen(tmp_message) < 39) strcat(tmp_message," ");
+ strcat(tmp_message," ");
+ cp = &tmp_message[strlen(tmp_message)];
+ sprintf(cp," tmpval %d (0x%x)\n",
+ ct1->ctx.tmpval,ct1->ctx.tmpval);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+ break;
+
+ case TRACE_C_MACRO:
+ state_name = trace_convert_opcode_to_name(ct0->opcode);
+ if(state_name == NULL) state_name = "UNKNOWN";
+ sprintf(tmp_message,"MACRO PLACEHOLDER: 0x%08X Opcode %s %c",
+ (unsigned int)ct0,
+ state_name,
+/* ct0->opcode == TOK_C_INPUTCHAR ? ct0->input_byte : ' '); */
+ ct0->flags & TOK_M_EAT_TOKEN ? ct0->input_byte : ' ');
+ if(ct0->flags & TOK_M_EAT_TOKEN){
+ strcat(tmp_message," TOK_M_EAT_TOKEN");
+ }/* End IF */
+ if(ct0->flags & TOK_M_WORDBOUNDARY){
+ strcat(tmp_message," TOK_M_WORDBOUNDARY");
+ }/* End IF */
+ if(ct0->flags & TOK_M_PARSELOAD_IARG1){
+ strcat(tmp_message," TOK_M_PARSELOAD_IARG1");
+ }/* End IF */
+ if(ct0->flags & TOK_M_PARSELOAD_IARG2){
+ strcat(tmp_message," TOK_M_PARSELOAD_IARG2");
+ }/* End IF */
+ if(ct0->flags & TOK_M_PARSELOAD_TMPVAL){
+ strcat(tmp_message," TOK_M_PARSELOAD_TMPVAL");
+ }/* End IF */
+ strcat(tmp_message,"\n");
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+/* int execute_state; */
+ state_name = trace_convert_state_to_name(ct0->ctx.state);
+ if(state_name == NULL) state_name = "UNKNOWN";
+ sprintf(tmp_message," Parser State: %s '%c'",
+ state_name,
+ isprint((int)ct0->q_register) ? ct0->q_register : ' ');
+ if(ct0->ctx.flags & CTOK_M_COLON_SEEN){
+ strcat(tmp_message," CTOK_M_COLON_SEEN");
+ }/* End IF */
+ if(ct0->ctx.flags & CTOK_M_ATSIGN_SEEN){
+ strcat(tmp_message," CTOK_M_ATSIGN_SEEN");
+ }/* End IF */
+ if(ct0->ctx.flags & CTOK_M_STATUS_PASSED){
+ strcat(tmp_message," CTOK_M_STATUS_PASSED");
+ }/* End IF */
+ strcat(tmp_message,"\n");
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ if(ct0->ctx.go_flag == 0){
+ sprintf(tmp_message," Go flag clear\n");
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+ }/* End IF */
+
+ if(ct0->ctx.pnest || ct0->ctx.inest || ct0->ctx.cnest){
+ sprintf(tmp_message," PNEST: %d INEST %d CNEST %d\n",
+ ct0->ctx.pnest,ct0->ctx.inest,ct0->ctx.cnest);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+ }/* End IF */
+
+ sprintf(tmp_message," iarg1_flag %d iarg1 %d (0x%x)\n",
+ ct0->ctx.iarg1_flag,ct0->ctx.iarg1,ct0->ctx.iarg1);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," iarg2_flag %d iarg2 %d (0x%x)\n",
+ ct0->ctx.iarg2_flag,ct0->ctx.iarg2,ct0->ctx.iarg2);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," carg 0x%x\n",(unsigned int)ct0->ctx.carg);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ sprintf(tmp_message," tmpval %d (0x%x)\n",
+ ct0->ctx.tmpval,ct0->ctx.tmpval);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+
+ if(ct0->ctx.return_state || ct0->ctx.caller_token){
+ state_name = "";
+ if(ct0->ctx.return_state){
+ state_name =
+ trace_convert_state_to_name(ct0->ctx.return_state);
+ if(state_name == NULL) state_name = "UNKNOWN";
+ }/* End IF */
+ sprintf(tmp_message," return_state %s caller_token 0x%x\n",
+ state_name,(unsigned int)ct0->ctx.caller_token);
+ buff_insert(qbp,qbp->zee,tmp_message,strlen(tmp_message));
+ }/* End IF */
+ break;
+
+ }/* End Switch */
+
+}
+
+char *
+trace_convert_opcode_to_name(opcode)
+int opcode;
+{
+
+ PREAMBLE();
+
+ switch(opcode){
+ case TOK_C_UNUSED:
+ return("TOK_C_UNUSED");
+ case TOK_C_FIRSTTOKEN:
+ return("TOK_C_FIRSTTOKEN");
+ case TOK_C_INPUTCHAR:
+ return("TOK_C_INPUTCHAR");
+ case TOK_C_COPYTOKEN:
+ return("TOK_C_COPYTOKEN");
+ case TOK_C_ITERATION_BEGIN:
+ return("TOK_C_ITERATION_BEGIN");
+ case TOK_C_ITERATION_END:
+ return("TOK_C_ITERATION_END");
+ case TOK_C_CONDITIONAL_END:
+ return("TOK_C_CONDITIONAL_END");
+ case TOK_C_LABEL_BEGIN:
+ return("TOK_C_LABEL_BEGIN");
+ case TOK_C_LABEL_END:
+ return("TOK_C_LABEL_END");
+ case TOK_C_GOTO_BEGIN:
+ return("TOK_C_GOTO_BEGIN");
+ case TOK_C_GOTO_END:
+ return("TOK_C_GOTO_END");
+ case TOK_C_FINALTOKEN:
+ return("TOK_C_FINALTOKEN");
+ case TOK_C_INITIALSTATE:
+ return("TOK_C_INITIALSTATE");
+ case TOK_C_CONDITIONAL_ELSE:
+ return("TOK_C_CONDITIONAL_ELSE");
+ default:
+ return(NULL);
+ }/* End Switch */
+
+}/* End Routine */
+
+char *
+trace_convert_state_to_name(state)
+int state;
+{
+
+ PREAMBLE();
+
+ switch(state){
+ case STATE_C_INITIALSTATE:
+ return("STATE_C_INITIALSTATE");
+ case STATE_C_MAINCOMMANDS:
+ return("STATE_C_MAINCOMMANDS");
+ case STATE_C_ESCAPESEEN:
+ return("STATE_C_ESCAPESEEN");
+ case STATE_C_ECOMMAND:
+ return("STATE_C_ECOMMAND");
+ case STATE_C_ARG1:
+ return("STATE_C_ARG1");
+ case STATE_C_ARG2:
+ return("STATE_C_ARG2");
+ case STATE_C_EXPRESSION:
+ return("STATE_C_EXPRESSION");
+ case STATE_C_OPERATOR:
+ return("STATE_C_OPERATOR");
+ case STATE_C_PLUS:
+ return("STATE_C_PLUS");
+ case STATE_C_MINUS:
+ return("STATE_C_MINUS");
+ case STATE_C_TIMES:
+ return("STATE_C_TIMES");
+ case STATE_C_DIVIDE:
+ return("STATE_C_DIVIDE");
+ case STATE_C_MINUSSEEN:
+ return("STATE_C_MINUSSEEN");
+ case STATE_C_SUBEXPRESSION:
+ return("STATE_C_SUBEXPRESSION");
+ case STATE_C_OPERAND:
+ return("STATE_C_OPERAND");
+ case STATE_C_NUMBER_SUBSTATE:
+ return("STATE_C_NUMBER_SUBSTATE");
+ case STATE_C_QOPERAND:
+ return("STATE_C_QOPERAND");
+ case STATE_C_INSERT:
+ return("STATE_C_INSERT");
+ case STATE_C_QUOTED_INSERT:
+ return("STATE_C_QUOTED_INSERT");
+ case STATE_C_UMINUS:
+ return("STATE_C_UMINUS");
+ case STATE_C_LABEL:
+ return("STATE_C_LABEL");
+ case STATE_C_UQREGISTER:
+ return("STATE_C_UQREGISTER");
+ case STATE_C_WRITEFILE:
+ return("STATE_C_WRITEFILE");
+ case STATE_C_STRING:
+ return("STATE_C_STRING");
+ case STATE_C_SEARCH:
+ return("STATE_C_SEARCH");
+ case STATE_C_FCOMMAND:
+ return("STATE_C_FCOMMAND");
+ case STATE_C_FSPART1:
+ return("STATE_C_FSPART1");
+ case STATE_C_FSPART2:
+ return("STATE_C_FSPART2");
+ case STATE_C_EDITBUF:
+ return("STATE_C_EDITBUF");
+ case STATE_C_READFILE:
+ return("STATE_C_READFILE");
+ case STATE_C_XQREGISTER:
+ return("STATE_C_XQREGISTER");
+ case STATE_C_GQREGISTER:
+ return("STATE_C_GQREGISTER");
+ case STATE_C_MQREGISTER:
+ return("STATE_C_MQREGISTER");
+ case STATE_C_VIEWBUF:
+ return("STATE_C_VIEWBUF");
+ case STATE_C_FDCOMMAND:
+ return("STATE_C_FDCOMMAND");
+ case STATE_C_CONDITIONALS:
+ return("STATE_C_CONDITIONALS");
+ case STATE_C_GOTO:
+ return("STATE_C_GOTO");
+ case STATE_C_FRPART1:
+ return("STATE_C_FRPART1");
+ case STATE_C_FRPART2:
+ return("STATE_C_FRPART2");
+ case STATE_C_MESSAGE:
+ return("STATE_C_MESSAGE");
+ case STATE_C_FKCOMMAND:
+ return("STATE_C_FKCOMMAND");
+ case STATE_C_ECCOMMAND:
+ return("STATE_C_ECCOMMAND");
+ case STATE_C_SAVECOMMAND:
+ return("STATE_C_SAVECOMMAND");
+ case STATE_C_PERCENT_OPERAND:
+ return("STATE_C_PERCENT_OPERAND");
+ case STATE_C_ATINSERT:
+ return("STATE_C_ATINSERT");
+ case STATE_C_ATINSERT_PART2:
+ return("STATE_C_ATINSERT_PART2");
+ case STATE_C_ONE_EQUALS:
+ return("STATE_C_ONE_EQUALS");
+ case STATE_C_TWO_EQUALS:
+ return("STATE_C_TWO_EQUALS");
+ case STATE_C_SKIP_ELSE:
+ return("STATE_C_SKIP_ELSE");
+ case STATE_C_PUSH_QREGISTER:
+ return("STATE_C_PUSH_QREGISTER");
+ case STATE_C_POP_QREGISTER:
+ return("STATE_C_POP_QREGISTER");
+ case STATE_C_NSEARCH:
+ return("STATE_C_NSEARCH");
+ case STATE_C_ACCEPT_ARGS:
+ return("STATE_C_ACCEPT_ARGS");
+ case STATE_C_EQQREGISTER1:
+ return("STATE_C_EQQREGISTER1");
+ case STATE_C_EQQREGISTER2:
+ return("STATE_C_EQQREGISTER2");
+ case STATE_C_RADIX:
+ return("STATE_C_RADIX");
+ case STATE_C_HEX_NUMBER:
+ return("STATE_C_HEX_NUMBER");
+ case STATE_C_OCTAL_NUMBER:
+ return("STATE_C_OCTAL_NUMBER");
+ case STATE_C_HEX_NUMBER_SUBSTATE:
+ return("STATE_C_HEX_NUMBER_SUBSTATE");
+ case STATE_C_OCTAL_NUMBER_SUBSTATE:
+ return("STATE_C_OCTAL_NUMBER_SUBSTATE");
+ case STATE_C_BACKSLASH:
+ return("STATE_C_BACKSLASH");
+ case STATE_C_DELAYED_MINUS:
+ return("STATE_C_DELAYED_MINUS");
+ case STATE_C_DELAYED_PLUS:
+ return("STATE_C_DELAYED_PLUS");
+ case STATE_C_FSPART3:
+ return("STATE_C_FSPART3");
+
+
+ case STATE_C_RETURN:
+ return("STATE_C_RETURN");
+ case STATE_C_FINALSTATE:
+ return("STATE_C_FINALSTATE");
+ case STATE_C_ERRORSTATE:
+ return("STATE_C_ERRORSTATE");
+ default:
+ return(NULL);
+ }/* End Switch */
+
+}/* End Routine */
+
+
+
+char *
+trace_convert_exec_state_to_name(state)
+int state;
+{
+
+ PREAMBLE();
+
+ switch(state){
+ case EXEC_C_NULLSTATE:
+ return("EXEC_C_NULLSTATE");
+ case EXEC_C_DOTARG1:
+ return("EXEC_C_DOTARG1");
+ case EXEC_C_ZEEARG1:
+ return("EXEC_C_ZEEARG1");
+ case EXEC_C_HARGUMENT:
+ return("EXEC_C_HARGUMENT");
+ case EXEC_C_EXITCOMMAND:
+ return("EXEC_C_EXITCOMMAND");
+ case EXEC_C_UQREGISTER:
+ return("EXEC_C_UQREGISTER");
+ case EXEC_C_JUMP:
+ return("EXEC_C_JUMP");
+ case EXEC_C_INSERT:
+ return("EXEC_C_INSERT");
+ case EXEC_C_LINE:
+ return("EXEC_C_LINE");
+ case EXEC_C_CHAR:
+ return("EXEC_C_CHAR");
+ case EXEC_C_RCHAR:
+ return("EXEC_C_RCHAR");
+ case EXEC_C_DELETE:
+ return("EXEC_C_DELETE");
+ case EXEC_C_HVALUE:
+ return("EXEC_C_HVALUE");
+ case EXEC_C_DOTVALUE:
+ return("EXEC_C_DOTVALUE");
+ case EXEC_C_ZEEVALUE:
+ return("EXEC_C_ZEEVALUE");
+ case EXEC_C_QVALUE:
+ return("EXEC_C_QVALUE");
+ case EXEC_C_EQUALS:
+ return("EXEC_C_EQUALS");
+ case EXEC_C_REDRAW_SCREEN:
+ return("EXEC_C_REDRAW_SCREEN");
+ case EXEC_C_STOREVAL:
+ return("EXEC_C_STOREVAL");
+ case EXEC_C_STORE1:
+ return("EXEC_C_STORE1");
+ case EXEC_C_STORE2:
+ return("EXEC_C_STORE2");
+ case EXEC_C_UMINUS:
+ return("EXEC_C_UMINUS");
+ case EXEC_C_PLUS:
+ return("EXEC_C_PLUS");
+ case EXEC_C_MINUS:
+ return("EXEC_C_MINUS");
+ case EXEC_C_TIMES:
+ return("EXEC_C_TIMES");
+ case EXEC_C_DIVIDE:
+ return("EXEC_C_DIVIDE");
+ case EXEC_C_KILL:
+ return("EXEC_C_KILL");
+ case EXEC_C_WRITEFILE:
+ return("EXEC_C_WRITEFILE");
+ case EXEC_C_SEARCH:
+ return("EXEC_C_SEARCH");
+ case EXEC_C_SETSEARCH:
+ return("EXEC_C_SETSEARCH");
+ case EXEC_C_FSREPLACE1:
+ return("EXEC_C_FSREPLACE1");
+ case EXEC_C_ITERATION_BEGIN:
+ return("EXEC_C_ITERATION_BEGIN");
+ case EXEC_C_ITERATION_END:
+ return("EXEC_C_ITERATION_END");
+ case EXEC_C_READFILE:
+ return("EXEC_C_READFILE");
+ case EXEC_C_EDITBUF:
+ return("EXEC_C_EDITBUF");
+ case EXEC_C_XQREGISTER:
+ return("EXEC_C_XQREGISTER");
+ case EXEC_C_GQREGISTER:
+ return("EXEC_C_GQREGISTER");
+ case EXEC_C_SEMICOLON:
+ return("EXEC_C_SEMICOLON");
+ case EXEC_C_MQREGISTER:
+ return("EXEC_C_MQREGISTER");
+ case EXEC_C_CLOSEBUF:
+ return("EXEC_C_CLOSEBUF");
+ case EXEC_C_VIEWBUF:
+ return("EXEC_C_VIEWBUF");
+ case EXEC_C_FDCOMMAND:
+ return("EXEC_C_FDCOMMAND");
+ case EXEC_C_ACOMMAND:
+ return("EXEC_C_ACOMMAND");
+ case EXEC_C_BACKSLASH:
+ return("EXEC_C_BACKSLASH");
+ case EXEC_C_BACKSLASHARG:
+ return("EXEC_C_BACKSLASHARG");
+ case EXEC_C_COND_GT:
+ return("EXEC_C_COND_GT");
+ case EXEC_C_COND_LT:
+ return("EXEC_C_COND_LT");
+ case EXEC_C_COND_EQ:
+ return("EXEC_C_COND_EQ");
+ case EXEC_C_COND_NE:
+ return("EXEC_C_COND_NE");
+ case EXEC_C_COND_DIGIT:
+ return("EXEC_C_COND_DIGIT");
+ case EXEC_C_COND_ALPHA:
+ return("EXEC_C_COND_ALPHA");
+ case EXEC_C_COND_LOWER:
+ return("EXEC_C_COND_LOWER");
+ case EXEC_C_COND_UPPER:
+ return("EXEC_C_COND_UPPER");
+ case EXEC_C_COND_SYMBOL:
+ return("EXEC_C_COND_SYMBOL");
+ case EXEC_C_GOTO:
+ return("EXEC_C_GOTO");
+ case EXEC_C_FRREPLACE:
+ return("EXEC_C_FRREPLACE");
+ case EXEC_C_MESSAGE:
+ return("EXEC_C_MESSAGE");
+ case EXEC_C_RESET_MESSAGE:
+ return("EXEC_C_RESET_MESSAGE");
+ case EXEC_C_OUTPUT_MESSAGE:
+ return("EXEC_C_OUTPUT_MESSAGE");
+ case EXEC_C_FKCOMMAND:
+ return("EXEC_C_FKCOMMAND");
+ case EXEC_C_REMEMBER_DOT:
+ return("EXEC_C_REMEMBER_DOT");
+ case EXEC_C_ECCOMMAND:
+ return("EXEC_C_ECCOMMAND");
+ case EXEC_C_SAVECOMMAND:
+ return("EXEC_C_SAVECOMMAND");
+ case EXEC_C_SCROLL:
+ return("EXEC_C_SCROLL");
+ case EXEC_C_UPDATE_SCREEN:
+ return("EXEC_C_UPDATE_SCREEN");
+ case EXEC_C_SET_IMMEDIATE_MODE:
+ return("EXEC_C_SET_IMMEDIATE_MODE");
+ case EXEC_C_PERCENT_VALUE:
+ return("EXEC_C_PERCENT_VALUE");
+ case EXEC_C_WORD:
+ return("EXEC_C_WORD");
+ case EXEC_C_TWO_EQUALS:
+ return("EXEC_C_TWO_EQUALS");
+ case EXEC_C_THREE_EQUALS:
+ return("EXEC_C_THREE_EQUALS");
+ case EXEC_C_SKIP_ELSE:
+ return("EXEC_C_SKIP_ELSE");
+ case EXEC_C_PUSH_QREGISTER:
+ return("EXEC_C_PUSH_QREGISTER");
+ case EXEC_C_POP_QREGISTER:
+ return("EXEC_C_POP_QREGISTER");
+ case EXEC_C_NSEARCH:
+ return("EXEC_C_NSEARCH");
+ case EXEC_C_EQQREGISTER:
+ return("EXEC_C_EQQREGISTER");
+ case EXEC_C_WINDOW_CONTROL:
+ return("EXEC_C_WINDOW_CONTROL");
+ case EXEC_C_NEXT_WINDOW:
+ return("EXEC_C_NEXT_WINDOW");
+ case EXEC_C_RLINE:
+ return("EXEC_C_RLINE");
+ case EXEC_C_DELWORD:
+ return("EXEC_C_DELWORD");
+ case EXEC_C_RDELWORD:
+ return("EXEC_C_RDELWORD");
+ case EXEC_C_OPENBRACE:
+ return("EXEC_C_OPENBRACE");
+ case EXEC_C_CLOSEBRACE:
+ return("EXEC_C_CLOSEBRACE");
+ case EXEC_C_SKIPLABEL:
+ return("EXEC_C_SKIPLABEL");
+ case EXEC_C_SETOPTIONS:
+ return("EXEC_C_SETOPTIONS");
+ case EXEC_C_FSREPLACE2:
+ return("EXEC_C_FSREPLACE2");
+ case EXEC_C_FSREPLACE3:
+ return("EXEC_C_FSREPLACE3");
+ default:
+ return(NULL);
+ }/* End Switch */
+
+}/* End Routine */