This patch fixes a number of problems with TECO 4.69 It is unofficial and unsupported. Bugs: 1. } accesses freed memory 2. :FS, :FR, :FD, :FK don't return values 3. occasional buff_delete failures 4. reads from files in root directory sometimes fail 5. EX cannot be undone 6. resume_execute_ct not initialised to NULL after each $$ Mark Henderson 24 Oct 1994 *** old/tecbuf.c Mon Oct 24 22:18:39 1994 --- tecbuf.c Mon Oct 24 22:18:48 1994 *************** *** 1998,2009 **** --- 1998,2018 ---- * Insure that there are that many character in the buffer after the specified * position. */ + + #if 0 if((position + count) > hbp->zee){ char tmp_message[LINE_BUFFER_SIZE]; sprintf(tmp_message,"buff_delete: illegal range %d-%d %s Z = %d\n", position,position+count,hbp->name,hbp->zee); panic(tmp_message); }/* End IF */ + #endif + + /* blatant hack alert -- I'm having trouble tracking down a problem + that hits me about once every two weeks - this is a workaround - mch */ + + if((position + count) > hbp->zee) + count = hbp->zee - position; /* * For now we are cheap and just repeatedly call the single character delete * routine, because this is simple. It is also very expensive and will have to *************** *** 2094,2100 **** * make the character go away... */ if(*cp != '\n'){ ! movc3(cp+1,cp,lbp->byte_count-i); lbp->byte_count -= 1; return(SUCCESS); }/* End IF */ --- 2103,2109 ---- * make the character go away... */ if(*cp != '\n'){ ! movc3(cp+1,cp,lbp->byte_count-i-1); lbp->byte_count -= 1; return(SUCCESS); }/* End IF */ *** old/tecexec.c Mon Oct 24 22:18:40 1994 --- tecexec.c Mon Oct 24 22:18:49 1994 *************** *** 733,738 **** --- 733,742 ---- {/* Local Block */ register struct buff_header *hbp; + ut = allocate_undo_token(uct); + if(ut == NULL) return(FAIL); + ut->opcode = UNDO_C_SET_EXIT_FLAG; + if(ct->ctx.iarg1_flag == NO || ct->ctx.iarg1 != -1){ for(hbp = buffer_headers; hbp != NULL; hbp = hbp->next_header){ if(hbp->buffer_number <= 0) continue; *************** *** 1475,1481 **** }/* End IF */ if(ct->ctx.flags & CTOK_M_COLON_SEEN){ ! ct->ctx.tmpval = SUCCESS; }/* End IF */ return(SUCCESS); --- 1479,1485 ---- }/* End IF */ if(ct->ctx.flags & CTOK_M_COLON_SEEN){ ! ct->ctx.tmpval = last_search_status; }/* End IF */ return(SUCCESS); *************** *** 2519,2525 **** */ parser_replace_command_line(qbp); ! return(SUCCESS); }/* End Local Block */ /* --- 2523,2529 ---- */ parser_replace_command_line(qbp); ! return(INVALIDATE); }/* End Local Block */ /* *** old/teco.c Mon Oct 24 22:18:40 1994 --- teco.c Mon Oct 24 22:18:43 1994 *************** *** 1365,1370 **** --- 1365,1371 ---- char *cp; PREAMBLE(); + directory_path[0] = '\0'; /* * Find the next slash, and if there isn't one, then we have reached *** old/teco.h Mon Oct 24 22:18:40 1994 --- teco.h Mon Oct 24 22:18:45 1994 *************** *** 32,37 **** --- 32,38 ---- #define NULL 0 #define BLOCKED 2 + #define INVALIDATE 3 #define VMAJOR 4 #define VMINOR 64 *** old/tecparse.c Mon Oct 24 22:18:40 1994 --- tecparse.c Mon Oct 24 22:18:47 1994 *************** *** 102,107 **** --- 102,108 ---- * 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; *************** *** 384,390 **** if(status == BLOCKED){ resume_execute_ct = ct; } ! if(trace_mode_flag == YES){ trace_mode(TRACE_C_EXEC,&trace_ct,ct); }/* End IF */ --- 385,398 ---- 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 */ *** old/tecparse.h Mon Oct 24 22:18:40 1994 --- tecparse.h Mon Oct 24 22:18:44 1994 *************** *** 292,294 **** --- 292,295 ---- #define UNDO_C_SET_SEARCH_GLOBALS 23 #define UNDO_C_LOAD_TAGS 24 #define UNDO_C_SELECT_TAGS 25 + #define UNDO_C_SET_EXIT_FLAG 26 *** old/tecstate.c Mon Oct 24 22:18:40 1994 --- tecstate.c Mon Oct 24 22:18:49 1994 *************** *** 1084,1089 **** --- 1084,1094 ---- }/* End IF */ ct->execute_state = EXEC_C_FRREPLACE; ct->ctx.state = STATE_C_INITIALSTATE; + if(ct->ctx.flags & CTOK_M_STATUS_PASSED){ /* mch */ + ct = allocate_cmd_token(ct); + ct->ctx.iarg1_flag = YES; ct->ctx.iarg2_flag = NO; + ct->execute_state = EXEC_C_STORE1; + }/* End IF */ return; /* * Here when we have an 'F' command with an unknown second character. This *************** *** 1138,1143 **** --- 1143,1153 ---- if(ct->input_byte == ESCAPE){ ct->ctx.state = STATE_C_ESCAPESEEN; ct->execute_state = EXEC_C_FSREPLACE3; + if(ct->ctx.flags & CTOK_M_STATUS_PASSED){ /* mch */ + ct = allocate_cmd_token(ct); + ct->ctx.iarg1_flag = YES; ct->ctx.iarg2_flag = NO; + ct->execute_state = EXEC_C_STORE1; + }/* End IF */ return; } *************** *** 1228,1233 **** --- 1238,1248 ---- }/* End IF */ ct->ctx.carg = NULL; ct->execute_state = EXEC_C_FDCOMMAND; + if(ct->ctx.flags & CTOK_M_STATUS_PASSED){ /* mch */ + ct = allocate_cmd_token(ct); + ct->ctx.iarg1_flag = YES; ct->ctx.iarg2_flag = NO; + ct->execute_state = EXEC_C_STORE1; + }/* End IF */ return; /* * The following state is the return-state from STRING when the search part *************** *** 1252,1257 **** --- 1267,1277 ---- }/* End IF */ ct->ctx.carg = NULL; ct->execute_state = EXEC_C_FKCOMMAND; + if(ct->ctx.flags & CTOK_M_STATUS_PASSED){ /* mch */ + ct = allocate_cmd_token(ct); + ct->ctx.iarg1_flag = YES; ct->ctx.iarg2_flag = NO; + ct->execute_state = EXEC_C_STORE1; + }/* End IF */ return; /* * The following state is a return-state from STRING when we have seen an *** old/tecundo.c Mon Oct 24 22:18:40 1994 --- tecundo.c Mon Oct 24 22:18:44 1994 *************** *** 30,35 **** --- 30,36 ---- extern struct search_buff search_string; extern char user_message[]; + extern char exit_flag; extern char immediate_execute_flag; extern int last_search_pos1,last_search_pos2; extern int last_search_status; *************** *** 330,335 **** --- 331,340 ---- current_tags->current_entry = (struct tagent *)ut->carg1; break; + case UNDO_C_SET_EXIT_FLAG: + exit_flag = 0; + break; + /* * Here when we get an undo code we don't know about. This is an internal * error to teco! *************** *** 495,500 **** --- 500,508 ---- break; case UNDO_C_LOAD_TAGS: tag_free_struct(ut->carg1); + break; + case UNDO_C_SET_EXIT_FLAG: + free_undo_token(ut); break; default: free_undo_token(ut);