📄 textsw_again.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)textsw_again.c 1.1 92/07/30 Copyright 1988 Sun Micro";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * AGAIN action recorder and interpreter for text subwindows. */#include <suntool/primal.h>#include <varargs.h>#include <suntool/textsw_impl.h>#include "sunwindow/sv_malloc.h"extern char *strncpy();pkg_private Es_index textsw_do_input();pkg_private Es_index textsw_do_pending_delete();string_t null_string = {0, 0, 0};#define TEXT_DELIMITER "\\"char *text_delimiter = TEXT_DELIMITER;typedef enum { CARET_TOKEN, DELETE_TOKEN, EDIT_TOKEN, EXTRAS_TOKEN, FIELD_TOKEN, FILTER_TOKEN, FIND_TOKEN, INSERT_TOKEN, MENU_TOKEN, NULL_TOKEN} Token;char *cmd_tokens[] = { "CARET", "DELETE", "EDIT", "EXTRAS", "FIELD", "FILTER", "FIND", "INSERT", "MENU", NULL};typedef enum { FORWARD_DIR, BACKWARD_DIR, NO_DIR, EMPTY_DIR} Direction;char *direction_tokens[] = { "FORWARD", "BACKWARD", TEXT_DELIMITER, "", NULL};char *edit_tokens[] = { "CHAR", "WORD", "LINE", NULL};#define CHAR_TOKEN 0#define WORD_TOKEN 1#define LINE_TOKEN 2char *text_tokens[] = { "PIECES", "TRASHBIN", TEXT_DELIMITER, NULL};#define PIECES_TOKEN 0#define TRASH_TOKEN 1#define DELIMITER_TOKEN 2pkg_private intmatch_in_table(to_match, table) /* Modified from ucb/lpr/lpc.c */ register char *to_match; register char **table;{ register char *p, *q; int found, index, nmatches, longest; longest = nmatches = 0; found = index = -1; for (p = *table; p; p = *(++table)) { index++; for (q = to_match; *q == *p++; q++) if (*q == 0) /* exact match? */ return(index); if (!*q) { /* the to_match was a prefix */ if (q - to_match > longest) { longest = q - to_match; nmatches = 1; found = index; } else if (q - to_match == longest) nmatches++; } } if (nmatches > 1) return(-1); return(found);}statictextsw_string_append(ptr_to_string, buffer, buffer_length) string_t *ptr_to_string; char *buffer; int buffer_length;/* Returns FALSE iff it needed to malloc and the malloc failed */{ if (textsw_string_min_free(ptr_to_string, buffer_length) != TRUE) return(FALSE); bcopy(buffer, ptr_to_string->free, buffer_length); ptr_to_string->free += buffer_length; *(ptr_to_string->free) = '\0'; return(TRUE);}int textsw_again_debug; /* = 0 for -A-R */static inttextsw_string_min_free(ptr_to_string, min_free_desired) register string_t *ptr_to_string; int min_free_desired;/* Returns FALSE iff it needed to malloc and the malloc failed */{ int used = TXTSW_STRING_LENGTH(ptr_to_string); register int desired_max = used + min_free_desired; /* BEAR TRAP */ if (ptr_to_string->max_length < (ptr_to_string->free - ptr_to_string->base)) { while (!textsw_again_debug) {} } if (ptr_to_string->max_length < desired_max) { char *old_string = ptr_to_string->base; ptr_to_string->base = malloc( (unsigned)(desired_max+1) * sizeof(char)); if (ptr_to_string->base == NULL) { ptr_to_string->base = old_string; return(FALSE); } ptr_to_string->max_length = desired_max; if (old_string == NULL) { ptr_to_string->free = ptr_to_string->base; *(ptr_to_string->free) = '\0'; } else { (void) strcpy(ptr_to_string->base, old_string); ptr_to_string->free = ptr_to_string->base + used; free(old_string); } } return(TRUE);}/* * Recording routines *//* * Following is stolen from 3.2ALPHA sprintf(str, fmt, va_alist) * SIDE_EFFECT: TXTSW_STRING_FREE(ptr_to_string) is modified by this routine. *//* VARARGS2 */#ifdef lintpkg_private int /* LINT BUG: complains about VARARGS on static */#elsestatic int#endiftextsw_printf(ptr_to_string, fmt, va_alist) register string_t *ptr_to_string; register char *fmt; va_dcl{ FILE _strbuf; int result; va_list args; _strbuf._flag = _IOWRT|_IOSTRG; _strbuf._base = (unsigned char *)TXTSW_STRING_FREE(ptr_to_string); _strbuf._ptr = _strbuf._base; _strbuf._cnt = ptr_to_string->max_length - TXTSW_STRING_LENGTH(ptr_to_string); va_start(args); result = _doprnt(fmt, args, &_strbuf); va_end(args); TXTSW_STRING_FREE(ptr_to_string) = (char *)_strbuf._ptr;#ifndef lint if (result >= 0) putc('\0', &_strbuf);#endif return(result);}statictextsw_record_buf(again, buffer, buffer_length) register string_t *again; char *buffer; int buffer_length;{ (void) textsw_printf(again, "%s %6d %s\n", text_delimiter, buffer_length, text_delimiter); (void) textsw_string_append(again, buffer, buffer_length); (void) textsw_printf(again, "\n%s\n", text_delimiter);}voidtextsw_record_caret_motion(textsw, direction, loc_x) Textsw_folio textsw; unsigned direction; int loc_x;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; textsw->again_insert_length = 0; if (textsw_string_min_free(again, 15) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s %x %d\n", cmd_tokens[ord(CARET_TOKEN)], direction, loc_x); }textsw_record_delete(textsw) Textsw_folio textsw;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; textsw->again_insert_length = 0; if (textsw_string_min_free(again, 10) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s\n", cmd_tokens[ord(DELETE_TOKEN)]);}textsw_record_edit(textsw, unit, direction) Textsw_folio textsw; unsigned unit, direction;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; textsw->again_insert_length = 0; if (textsw_string_min_free(again, 25) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s %s %s\n", cmd_tokens[ord(EDIT_TOKEN)], edit_tokens[(unit == EV_EDIT_CHAR) ? CHAR_TOKEN : (unit == EV_EDIT_WORD) ? WORD_TOKEN : LINE_TOKEN], direction_tokens[(direction == 0) ? ord(FORWARD_DIR) : ord(BACKWARD_DIR)]);}textsw_record_extras(folio, cmd_line) Textsw_folio folio; char *cmd_line;{ register string_t *again = &folio->again[0]; int cmd_len = (cmd_line ? strlen(cmd_line) : 0); if (folio->func_state & TXTSW_FUNC_AGAIN) return; folio->again_insert_length = 0; if (textsw_string_min_free(again, cmd_len+30) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s ", cmd_tokens[ord(EXTRAS_TOKEN)]); textsw_record_buf(again, cmd_line, cmd_len);}textsw_record_find(textsw, pattern, pattern_length, direction) Textsw_folio textsw; char *pattern; int pattern_length, direction;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; if (textsw->state & (TXTSW_AGAIN_HAS_FIND|TXTSW_AGAIN_HAS_MATCH)) { (void) textsw_checkpoint_again( VIEW_REP_TO_ABS(textsw->first_view)); } else { textsw->again_insert_length = 0; } if (textsw_string_min_free(again, pattern_length+30) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s %s ", cmd_tokens[ord(FIND_TOKEN)], direction_tokens[(direction == 0) ? ord(FORWARD_DIR) : ord(BACKWARD_DIR)]); textsw_record_buf(again, pattern, pattern_length); textsw->state |= TXTSW_AGAIN_HAS_FIND;}textsw_record_filter(textsw, event) Textsw_folio textsw; Event *event;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; textsw->again_insert_length = 0; if (textsw_string_min_free(again, 50) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s %x %x %x ", cmd_tokens[ord(FILTER_TOKEN)], event_action(event), event->ie_flags, event->ie_shiftmask); textsw_record_buf(again, textsw->to_insert, textsw->to_insert_next_free - textsw->to_insert);}textsw_record_input(textsw, buffer, buffer_length) Textsw_folio textsw; char *buffer; long int buffer_length;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; if (textsw_string_min_free(again, buffer_length+25) != TRUE) return; /* Cannot guarantee enough space */ /* Above guarantees enough space */ if (textsw->again_insert_length == 0) { (void) textsw_printf(again, "%s ", cmd_tokens[ord(INSERT_TOKEN)]); textsw->again_insert_length = TXTSW_STRING_LENGTH(again)+strlen(text_delimiter)+1; textsw_record_buf(again, buffer, buffer_length); } else { /* * Following is a disgusting efficiency hack to compress a * sequence of INSERTs. */ char *insert_length, new_length_buf[7]; int i, old_length; insert_length = TXTSW_STRING_BASE(again)+ textsw->again_insert_length; old_length = atoi(insert_length); ASSUME(old_length > 0); (void) sprintf(new_length_buf, "%6d", old_length+buffer_length); for (i = 0; i < 6; i++) { insert_length[i] = new_length_buf[i]; } TXTSW_STRING_FREE(again) -= strlen(text_delimiter)+2; (void) textsw_string_append(again, buffer, buffer_length); (void) textsw_printf(again, "\n%s\n", text_delimiter); }}textsw_record_match(textsw, flag, start_marker) Textsw_folio textsw; unsigned flag; char *start_marker;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; if (textsw->state & TXTSW_AGAIN_HAS_MATCH) { (void) textsw_checkpoint_again( VIEW_REP_TO_ABS(textsw->first_view)); } else { textsw->again_insert_length = 0; } if (textsw_string_min_free(again, 15) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s %x %s\n", cmd_tokens[ord(FIELD_TOKEN)], flag, start_marker); textsw->state |= TXTSW_AGAIN_HAS_MATCH;}textsw_record_piece_insert(textsw, pieces) Textsw_folio textsw; Es_handle pieces;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; textsw->again_insert_length = 0; if (textsw_string_min_free(again, 25) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s %s %d\n", cmd_tokens[ord(INSERT_TOKEN)], text_tokens[PIECES_TOKEN], pieces);}textsw_record_trash_insert(textsw) Textsw_folio textsw;{ register string_t *again = &textsw->again[0]; if (textsw->func_state & TXTSW_FUNC_AGAIN) return; textsw->again_insert_length = 0; if (textsw_string_min_free(again, 20) != TRUE) return; /* Cannot guarantee enough space */ (void) textsw_printf(again, "%s %s\n", cmd_tokens[ord(INSERT_TOKEN)], text_tokens[TRASH_TOKEN]);}/* * Replaying routines *//* * Following is stolen from sscanf(str, fmt, args) * SIDE_EFFECT: TXTSW_STRING_BASE(ptr_to_string) is modified by this routine. *//* VARARGS2 */static inttextsw_scanf(ptr_to_string, fmt, va_alist) register string_t *ptr_to_string; register char *fmt; va_dcl{ FILE _strbuf; int result; va_list args; _strbuf._flag = _IOREAD|_IOSTRG; _strbuf._base = (unsigned char *)TXTSW_STRING_BASE(ptr_to_string); _strbuf._ptr = _strbuf._base; _strbuf._bufsiz = _strbuf._cnt = TXTSW_STRING_LENGTH(ptr_to_string); va_start(args); result = _doscan(&_strbuf, fmt, args); va_end(args); TXTSW_STRING_BASE(ptr_to_string) = (char *)_strbuf._ptr; return(result);}static inttextsw_next_is_delimiter(again) string_t *again;{ char token[2]; int count; count = textsw_scanf(again, "%1s", token); if AN_ERROR(count != 1 || token[0] != text_delimiter[0]) { return(FALSE); } else return(TRUE);}static Es_handletextsw_pieces_for_replay(again) register string_t *again;{#define CHECK_ERROR(test) if AN_ERROR(test) goto Again_Error; int count; Es_handle pieces = (Es_handle)NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -