allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (06/22/89)
Posting-number: Volume 7, Issue 49 Submitted-by: fox@marlow.UUCP (Paul Fox) Archive-name: crisp1.9/part29 #!/bin/sh # this is part 8 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file ./map.c continued # CurArch=8 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 echo "x - Continuing file ./map.c" sed 's/^X//' << 'SHAR_EOF' >> ./map.c X Xcurrent_col(offset) Xint offset; X{ int col = 1; X LINE *lp; X unsigned char *cp; X X lp = vm_lock_line(*cur_line); X cp = ltext(lp); X while (offset > 0) { X col += char_width(col, &offset, &cp); X } X vm_unlock(*cur_line); X return col; X} X X X/************************************************************************ X * * X * current_offset * X * -------------- * X * * X * Purpose: * X * * X * Convert current column position into an offset from the start * X * of the line. If the fill is set and cursor is not on a valid * X * character, fill the line with tabs/spaces so that it becomes * X * valid. * X *----------------------------------------------------------------------* X * Input Parameters: * X *----------------------------------------------------------------------* X * Output: * X *----------------------------------------------------------------------* X * Global variables modified: * X ************************************************************************/ X Xcurrent_offset(col, fill) Xregister int col; X{ register int pos = 1; X int last_pos = 1; X int i; X int width = 0; X u_char *cp; X int len; X X global_lp = vm_lock_line(*cur_line); X cp = ltext(global_lp); X i = len = llength(global_lp); X X while (pos <= col && len > 0) { X/* if (pos == col && *cp == '\t')*/ X if (pos == col && *cp != 0x1b) X break; X width = char_width(pos, &len, &cp); X pos += width; X } X last_pos = pos - width; X i -= len; X X virtual_space = pos != col; X if (!virtual_space || fill == FALSE) { X i = cp - ltext(global_lp); X if (fill == FALSE && pos > col) X i--; X vm_unlock(*cur_line); X return i; X } X /*------------------------------------- X * The following condition is true if cursor X * is past the end of the line. We can then X * tab and space fill. X *-------------------------------------*/ X if (pos < col) X i = space_fill(global_lp, col - pos, i, pos); X else /*if (width == 1)*/ { X /*------------------------------------- X * The following condition is true if cursor X * is NOT past the end of the line. In X * this case we can only space fill. X *-------------------------------------*/ X if (len) X i = space_fill(global_lp, col - last_pos, i - 1, last_pos); X else X i = space_fill(global_lp, pos - col, i-1, col); X } X vm_unlock(*cur_line); X return i; X} Xtab_replace() X{ int offset = current_offset(*cur_col, FALSE); X LINE *lp = vm_lock_line(*cur_line); X int result = FALSE; X if (lp->l_flags & L_FILE) X lnormal(lp, 0); X if (lp->l_text[offset] == '\t') { X int col = *cur_col; X int ntab = next_tab_stop(*cur_col); X current_offset(ntab - 1, TRUE); X *cur_col = ntab - 1; X ldelete((RSIZE) 1); X l_insert(' '); X *cur_col = col; X result = TRUE; X } X vm_unlock(*cur_line); X return result; X} Xnext_tab_stop(col) Xint col; X{ X register u_int16 *tp = curbp->b_tabs; X u_int16 tabstop; X u_int16 c; X X while (*tp && *tp < col) X tp++; X if (*tp) X return *tp; X X if (tp > &curbp->b_tabs[1]) X c = tp[-1], tabstop = tp[-1] - tp[-2]; X else if (tp == &curbp->b_tabs[1]) X c = tp[-1], tabstop = tp[-1]; X else X c = 0, tabstop = 8; X while (c < col) X c += tabstop; X return c; X} SHAR_EOF echo "File ./map.c is complete" chmod 0444 ./map.c || echo "restore of ./map.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./math.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./math.c && X/************************************************************** X * X * CRISP - Custom Reduced Instruction Set Programmers Editor X * X * (C) Paul Fox, 1989 X * 43, Jerome Close Tel: +44 6284 4222 X * Marlow X * Bucks. X * England SL7 1TX X * X * X * Please See COPYRIGHT notice. X * X **************************************************************/ X# include "list.h" X XSCCSID("@(#) math.c 1.10, (C) 1989 P. Fox"); X XOPCODE acc_type; Xlong accumulator; X X Xcom_equ(op) X{ X com_equ1(op, (SYMBOL *) argv[1].l_sym); X} Xcom_equ1(op, sp) Xregister SYMBOL *sp; X{ long rvalue; X LIST *lp; X OPCODE type = argv[2].l_flags; X X if (sp->s_type != F_LIST && type == F_NULL && (sp->s_flag & SF_POLY) == 0) { X ewprintf("Missing assignment value."); X return; X } X if (sp->s_type != type) { X if (sp->s_type == F_STR && type == F_RSTR) X goto ok_check; X if (type == F_NULL) X ; X else if (op == NOOP && sp->s_flag & SF_POLY) { X if (sp->s_type == F_STR || sp->s_type == F_LIST) X r_dec(sp->s_str); X sp->s_str = NULL; X sp->s_type = type; X if (type == F_STR || type == F_LIST) X sp->s_str = r_init(""); X } X else { X ewprintf("Mixed types in assignment: %s", sp->s_name); X return; X } X } Xok_check: X if (type == F_INT) X rvalue = argv[2].l_int; X else if (type == F_LIST) X lp = (LIST *) get_str(2); X switch (op) { X case NOOP: X if (type == F_INT) X sp->s_int = rvalue; X else if (type == F_RSTR) { X str_rassign(sp, argv[2].l_rstr); X str_acc_assign(argv[2].l_rstr->r_str, argv[2].l_rstr->r_used); X sp->s_type = F_STR; X } X else if (type == F_STR) { X char *cp = get_str(2); X str_assign(sp, cp); X strl_acc_assign(cp); X } X else if (type == F_NULL) { X if (sp->s_list) { X chk_free(sp->s_list); X sp->s_list = NULL; X } X } X else X list_assign(sp, lp); X break; X case PLUS: X if (type == F_STR) { X sp->s_str = r_cat(sp->s_str, get_str(2)); X str_acc_assign(sp->s_str->r_str, sp->s_str->r_used); X } X else if (type == F_RSTR) { X sp->s_str = r_cat(sp->s_str, argv[2].l_rstr->r_str); X str_acc_assign(sp->s_str->r_str, sp->s_str->r_used); X } X else X sp->s_int += rvalue; X break; X case MINUS: sp->s_int -= rvalue; break; X case MULTIPLY: sp->s_int *= rvalue; break; X case DIVIDE: X if (rvalue == 0) X rvalue = 1; X sp->s_int /= rvalue; X break; X case MODULO: X if (rvalue == 0) X rvalue = 1; X sp->s_int %= rvalue; X break; X case BAND: sp->s_int &= rvalue; break; X case BOR: sp->s_int |= rvalue; break; X case BXOR: sp->s_int ^= rvalue; break; X } X accumulator = sp->s_int; X trace_sym(sp); X return; X} X Xminusminus() X{ X accumulator = --argv[1].l_sym->s_int; X return 0; X} Xplusplus() X{ X accumulator = ++argv[1].l_sym->s_int; X return 0; X} Xlnot() X{ X accumulator = !argv[1].l_int; X return 0; X} Xcom_op(op) X{ long op1 = argv[1].l_int, X op2 = argv[2].l_int; X OPCODE type; X extern char *command_name; X X if (argv[1].l_flags == F_INT && argv[2].l_flags == F_INT) X type = F_INT; X else if ((argv[1].l_flags == F_STR || argv[1].l_flags == F_RSTR) X && (argv[2].l_flags == F_STR || argv[2].l_flags == F_RSTR)) X type = F_STR; X else if (op != BNOT) { X ewprintf("%s: invalid parameters.", command_name); X return -1; X } X X switch (op) { X case PLUS: X if (type == F_INT) X accumulator = op1 + op2; X else { X char *str1 = get_str(1); X char *str2 = get_str(2); X int len_1 = get_len(1); X int len_2 = get_len(2); X str_acc_assign(str1, len_1 + len_2); X memcpy(saccumulator+len_1, str2, len_2); X } X break; X case MINUS: X accumulator = op1 - op2; X break; X case MULTIPLY: X accumulator = op1 * op2; X break; X case DIVIDE: X accumulator = op1 / (op2 ? op2 : 1); X break; X case MODULO: X accumulator = op1 % (op2 ? op2 : 1); X break; X case EQ: X if (type == F_INT) X accumulator = op1 == op2; X else X accumulator = strcmp(get_str(1), get_str(2)) == 0; X break; X case NE: X if (type == F_INT) X accumulator = op1 != op2; X else X accumulator = strcmp(get_str(1), get_str(2)) != 0; X break; X case LT: X if (type == F_INT) X accumulator = op1 < op2; X else X accumulator = strcmp(get_str(1), get_str(2)) < 0; X break; X case LE: X if (type == F_INT) X accumulator = op1 <= op2; X else X accumulator = strcmp(get_str(1), get_str(2)) <= 0; X break; X case GT: X if (type == F_INT) X accumulator = op1 > op2; X else X accumulator = strcmp(get_str(1), get_str(2)) > 0; X break; X case GE: X if (type == F_INT) X accumulator = op1 >= op2; X else X accumulator = strcmp(get_str(1), get_str(2)) >= 0; X break; X case ABOVE: X if (type == F_INT) X accumulator = (unsigned long) op1 > X (unsigned long) op2; X else X accumulator = strcmp(get_str(1), get_str(2)) > 0; X break; X case ABOVE_EQ: X if (type == F_INT) X accumulator = (unsigned long) op1 >= X (unsigned long) op2; X else X accumulator = strcmp(get_str(1), get_str(2)) >= 0; X break; X case BELOW: X if (type == F_INT) X accumulator = (unsigned long) op1 < X (unsigned long) op2; X else X accumulator = strcmp(get_str(1), get_str(2)) < 0; X break; X case BELOW_EQ: X if (type == F_INT) X accumulator = (unsigned long) op1 <= X (unsigned long) op2; X else X accumulator = strcmp(get_str(1), get_str(2)) <= 0; X break; X case BAND: X accumulator = argv[1].l_int & argv[2].l_int; X break; X case BOR: X accumulator = argv[1].l_int | argv[2].l_int; X break; X case BXOR: X accumulator = argv[1].l_int ^ argv[2].l_int; X break; X case BNOT: X accumulator = ~argv[1].l_int; X break; X X X } X return 0; X} Xdo_strlen() X{ X accumulator = get_len(1); X return 0; X} Xdo_atoi() X{ char *cp = get_str(1); X if (argv[2].l_flags == F_NULL || argv[2].l_int) X accumulator = (int) atoi(cp); X else X accumulator = *cp; X return 0; X} Xstring_count() X{ register char *str1 = get_str(1); X register char *str2 = get_str(2); X char *strchr(); X X accumulator = 0; X while (*str1) { X if (strchr(str2, *str1++)) X accumulator++; X } X} Xvoid Xdo_index() X{ X extern char *instr(); X char *cp; X char *cp2 = get_str(2); X char *str1 = get_str(1); X X accumulator = 0; X if (*cp2 == NULL) X accumulator = strlen(str1) + 1; X else if (cp = instr(str1, cp2)) X accumulator = cp - str1 + 1; X} Xdo_rindex() X{ X extern char *instr(); X char *cp; X char *str1 = get_str(1); X char *str2 = get_str(2); X int len = get_len(2); X X accumulator = 0; X for (cp = str1+strlen(str1)-1; cp >= str1; cp--) X if (strncmp(cp, str2, len) == 0) { X accumulator = cp - str1 + 1; X break; X } X return 0; X} Xsubstr() X{ char *str1 = get_str(1); X int len1 = get_len(1); X int offset = argv[2].l_flags == F_INT ? argv[2].l_int - 1 : 0; X char *cp; X X if (offset < 0) X offset = 0; X else if (offset > len1) X offset = len1; X cp = str1 + offset; X len1 = argv[3].l_flags == F_NULL ? strlen(cp) : (int) argv[3].l_int; X str_acc_assign(cp, argv[2].l_int ? len1 : 0); X return 0; X} Xcompress() X{ register char *cp; X register char *cp1; X strl_acc_assign(get_str(1)); X cp = saccumulator; X while (*cp) { X for (cp1 = cp; isspace(*cp1) || *cp1 == '\n'; ) X cp1++; X if (*cp1 != *cp) { X strcpy(cp+1, cp1); X *cp = ' '; X } X cp++; X } X return 0; X} Xtrim() X{ register char *cp; X int len = get_len(1); X X str_acc_assign(get_str(1), len); X cp = saccumulator + len - 1; X while (cp >= saccumulator && (*cp == ' ' || *cp == '\t' || *cp == '\n')) X *cp-- = NULL; X return 0; X} Xltrim() X{ register char *cp = get_str(1); X X while (*cp == ' ' || *cp == '\t' || *cp == '\n') X cp++; X strl_acc_assign(cp); X return 0; X} Xandand() X{ LISTV result; X X accumulator = 0; X if (argv[1].l_int == 0) X return 0; X if (eval(argv[2].l_list, &result) != F_INT) X return -1; X accumulator = result.l_int; X return 0; X} Xoror() X{ LISTV result; X X accumulator = 1; X if (argv[1].l_int) X return 0; X if (eval(argv[2].l_list, &result) != F_INT) X return -1; X accumulator = result.l_int; X return 0; X} SHAR_EOF chmod 0444 ./math.c || echo "restore of ./math.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./phys_term.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./phys_term.c && X/************************************************************** X * X * CRISP - Custom Reduced Instruction Set Programmers Editor X * X * (C) Paul Fox, 1989 X * 43, Jerome Close Tel: +44 6284 4222 X * Marlow X * Bucks. X * England SL7 1TX X * X * X * Please See COPYRIGHT notice. X * X * 24 Jan 89 [PDF] Added support for ESC [ n C X **************************************************************/ X X# include "list.h" X# include <ctype.h> X# include "alt.h" X XSCCSID("@(#) phys_term.c 1.12, (C) P. Fox"); X Xextern char *K[NFKEYS]; XPHYS_TERM pt; Xextern LIST *next_atom(); Xstatic st_key(); X Xstruct pt_map { X int isbool; X char *ptr; X }; X Xstruct pt_map pt_chars[] = { X FALSE, pt.pt_top_left, X FALSE, pt.pt_top_right, X FALSE, pt.pt_bot_left, X FALSE, pt.pt_bot_right, X FALSE, pt.pt_vertical, X FALSE, pt.pt_horizontal, X FALSE, pt.pt_top_join, X FALSE, pt.pt_bot_join, X FALSE, pt.pt_cross, X FALSE, pt.pt_left_join, X FALSE, pt.pt_right_join, X NULL, NULL X }; Xstruct pt_map pt_features[] = { X FALSE, pt.pt_space, X FALSE, pt.pt_character, X FALSE, pt.pt_icursor, X FALSE, pt.pt_ocursor, X FALSE, pt.pt_vicursor, X FALSE, pt.pt_vocursor, X FALSE, pt.pt_escape, X FALSE, pt.pt_repeat, X TRUE, &pt.pt_0m, X TRUE, &pt.pt_color, X FALSE, pt.pt_escC, X NULL, NULL X }; Xset_display_chars() X{ LISTV result; X register LIST *lp = argv[1].l_list; X int type; X int i = 0; X extern char *ctrl_chars[]; X char *strdup(); X X for ( ; lp && *lp != F_HALT; lp = next_atom(lp)) { X type = eval(lp, &result); X if (type != F_STR && type != F_LIT) X continue; X if (i > 31) X break; X ctrl_chars[i++] = strdup(result.l_str); X } X char_width_init(); X} Xst_characters() X{ X return st_common(pt_chars); X} Xst_features() X{ X return st_common(pt_features); X} Xst_common(p) Xregister struct pt_map *p; X{ LISTV result; X register LIST *lp = argv[1].l_list; X int type; X X for ( ; lp && *lp != F_HALT && p->ptr; p++, lp = next_atom(lp)) { X char *cp = ""; X type = eval(lp, &result); X if (p->isbool) { X *p->ptr = (char) result.l_int; X continue; X } X if (type == F_INT) { X p->ptr[0] = (char) result.l_int; X p->ptr[1] = NULL; X continue; X } X if (type == F_NULL) X continue; X if (type == F_STR || type == F_LIT) X cp = result.l_str; X else if (type == F_RSTR) X cp = result.l_rstr->r_str; X tcopy_string(p->ptr, cp, NULL); X } X X} Xst_keyboard() X{ LISTV result; X int key_no; X LIST *lp = argv[1].l_list; X LIST *lp1; X int type; X X for (; lp && *lp != F_HALT; lp = next_atom(lp)) { X type = eval(lp, &result); X if (type != F_INT) X break; X key_no = result.l_int; X lp += sizeof_atoms[*lp]; X type = eval(lp, &result); X if (type != F_LIST) { X st_key(key_no, &result); X continue; X } X lp1 = result.l_list; X while (lp1 && *lp1 != F_HALT) { X char *cp; X long l; X r_str *rp; X X result.l_flags = (OPCODE) *lp1; X switch (*lp1) { X case F_INT: X cp = chk_alloc(2); X l = LGET32(lp1); X cp[0] = l; X cp[1] = NULL; X K[key_no - KFIRST] = cp; X break; X case F_STR: case F_LIT: X K[key_no - KFIRST] = strdup((char *) LGET32(lp1)); X break; X case F_RSTR: X rp = (r_str *) LGET32(lp1); X K[key_no - KFIRST] = strdup(rp->r_str); X break; X } X lp1 = next_atom(lp1); X key_no++; X } X } X} Xstatic Xst_key(key_no, result) XLISTV *result; X{ char *cp; X X switch (result->l_flags) { X case F_INT: X cp = chk_alloc(2); X cp[0] = result->l_int; X cp[1] = NULL; X K[key_no - KFIRST] = cp; X break; X case F_STR: case F_LIT: X K[key_no - KFIRST] = strdup(result->l_str); X break; X case F_RSTR: X K[key_no - KFIRST] = strdup(result->l_rstr->r_str); X break; X } X} Xgt_characters() X{ X gt_common(pt_chars); X} Xgt_common(pt) Xregister struct pt_map *pt; X{ register int i; X for (i = 0; pt[i].ptr; i++) X if (argv[i+1].l_flags != F_NULL) { X if (pt[i].isbool) X int_assign(argv[i+1].l_sym, pt_chars[i].ptr); X else X str_assign(argv[i+1].l_sym, pt_chars[i].ptr); X } X} Xgt_keyboard() X{ X} Xgt_features() X{ X gt_common(pt_features); X} SHAR_EOF chmod 0444 ./phys_term.c || echo "restore of ./phys_term.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./playback.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./playback.c && X/************************************************************** X * X * CRISP - Custom Reduced Instruction Set Programmers Editor X * X * (C) Paul Fox, 1989 X * 43, Jerome Close Tel: +44 6284 4222 X * Marlow X * Bucks. X * England SL7 1TX X * X * X * Please See COPYRIGHT notice. X * X **************************************************************/ X# include "list.h" X XSCCSID("@(#) playback.c 1.7, (C) 1989, P. Fox"); X# define MAX_STORAGE 512 X# define MAX_KMACROS 20 X Xstatic struct playback { X int buffer_id; X r_str *macro; X unsigned char *ip; X unsigned char *op; X } kmacs[MAX_KMACROS]; Xstatic struct playback *ptr_info = NULL; Xint last_rem_index = 0; Xint defining_macro = FALSE; Xint playing_back = FALSE; Xint rem_nest_level = -1; Xint rem_doing_self_insert; Xchar *rem_string = " "; Xint rem_size = MAX_STORAGE; X Xvoid Xdo_pause() X{ X if (defining_macro) X rem_string = *rem_string == 'P' ? "RE" : "PA"; X else if (playing_back) X rem_string = *rem_string == 'P' ? " " : "PA"; X else X return; X line_col(TRUE); X} Xvoid Xremember() X{ X char ch = argv[1].l_flags == F_NULL ? 0 : get_str(1)[0]; X int mac_no = argv[2].l_int; X r_str *r_alloc(); X X if (playing_back) X return; X if (!defining_macro && argv[2].l_flags == F_NULL) { X if (last_rem_index >= MAX_KMACROS) X last_rem_index = 0; X mac_no = last_rem_index++; X } X X if (mac_no < 0 || mac_no >= MAX_KMACROS) X return; X ptr_info = &kmacs[mac_no]; X X if (ptr_info->buffer_id == 0) { X char buf[20]; X BUFFER *bp; X char *filename(); X sprintf(buf, "KBD-MACRO-%d", mac_no); X bp = bfind(filename(buf), TRUE); X bp->b_flag |= BFREAD; X ptr_info->buffer_id = bp->b_bufnum; X } X X if (!defining_macro) { X if (ptr_info->macro == NULL) { X ptr_info->macro = r_alloc(rem_size); X if (ch == 'n' || ch == 'N') X return; X ewprintf("Defining keystroke macro."); X rem_string = "RE"; X } X else { X if (ch == 'y' || ch == 'Y' || X eyorn("Overwrite existing keystroke macro")) { X ewprintf("Defining keystroke macro."); X rem_string = "RE"; X } X else X return; X } X defining_macro = TRUE; X ptr_info->macro->r_used = 0; X bclear(numberb(ptr_info->buffer_id)); X rem_nest_level = -1; X rem_doing_self_insert = FALSE; X } X else { X defining_macro = FALSE; X ewprintf("Keystroke macro defined."); X rem_string = " "; X } X X ptr_info->ip = (unsigned char *) ptr_info->macro->r_str; X line_col(TRUE); X} Xvoid Xplayback() X{ int mac_no = argv[1].l_int; X X if (argv[1].l_flags == F_NULL) X mac_no = last_rem_index - 1; X if (playing_back || mac_no < 0 || mac_no >= MAX_KMACROS || X kmacs[mac_no].buffer_id == 0) X return; X if (defining_macro) { X infof("Can't play back while remembering."); X accumulator = -1; X return; X } X infof("Playing back keystroke macro."); X playing_back = TRUE; X ptr_info = &kmacs[mac_no]; X ptr_info->op = (unsigned char *) ptr_info->macro->r_str; X} Xvoid Xremember_macro(cp, list_flag) Xchar *cp; X{ X BUFFER *saved_bp = curbp; X X if (!defining_macro || rem_string[0] == 'P') X return; X if (rem_nest_level == -1) X rem_nest_level = nest_level; X else if (rem_nest_level != nest_level) X return; X X curbp = numberb(ptr_info->buffer_id); X set_hooked(); X curbp->b_system = 1; X if (list_flag) { X char *msg = "/* LIST -- not implemented feature */"; X llinsert(msg, strlen(msg), TRUE); X } X else { X if (*cp == 's' && strcmp(cp, "self_insert") == 0) { X char buf[5]; X char *bp = buf; X extern char character; X if (rem_doing_self_insert) { X switch (character) { X case '\\': X case '"': X *bp++ = '\\'; X break; X } X *bp++ = character; X llinsert(buf, bp - buf, FALSE); X } X else { X llinsert("(insert", 7, FALSE); X *bp++ = ' '; X *bp++ = '"'; X switch (character) { X case '\\': X case '"': X *bp++ = '\\'; X break; X } X *bp++ = character; X llinsert(buf, bp - buf, FALSE); X rem_doing_self_insert = TRUE; X } X } X else { X if (rem_doing_self_insert) X llinsert("\")", 2, TRUE); X if (*cp == 'r' && strcmp(cp, "remember") == 0) { X char *msg = "/* End of macro */"; X llinsert(msg, strlen(msg), TRUE); X } X else { X llinsert("(", 1, FALSE); X llinsert(cp, strlen(cp), FALSE); X llinsert(")", 1, TRUE); X } X rem_doing_self_insert = FALSE; X } X } X X curbp->b_system = 0; X curbp = saved_bp; X set_hooked(); X} Xvoid Xstore_char(ch) X{ X if (defining_macro && rem_string[0] != 'P') { X if (ptr_info->ip < (unsigned char *) X &ptr_info->macro->r_str[rem_size]) { X ptr_info->macro->r_used++; X *ptr_info->ip++ = ch; X } X else { X ewprintf("Maximum keystroke length reached."); X defining_macro = FALSE; X ptr_info->ip = NULL; X } X } X} Xgrab_char() X{ X if (playing_back) { X if (*rem_string == 'P') X return 0; X if (ptr_info->op >= (unsigned char *) X &ptr_info->macro->r_str[ptr_info->macro->r_used]) { X playing_back = FALSE; X u_chain(); X infof("Playback successful."); X return 0; X } X return *ptr_info->op++; X } X return 0; X} X X SHAR_EOF chmod 0444 ./playback.c || echo "restore of ./playback.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./pty.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./pty.c && X/************************************************************** X * X * CRISP - Custom Reduced Instruction Set Programmers Editor X * X * (C) Paul Fox, 1989 X * 43, Jerome Close Tel: +44 6284 4222 X * Marlow X * Bucks. X * England SL7 1TX X * X * X * Please See COPYRIGHT notice. X * X **************************************************************/ X# include "list.h" X# include "alt.h" X# include <signal.h> X# if !defined(VMS) X# include <termio.h> X# endif X# include "clk.h" XSCCSID("@(#) pty.c 1.15, (C) P. Fox"); Xextern BYTE *blanks; X X# define BOLD 0x01 X# define REVERSE 0x02 X X# define POLL_TIME 1 /* Seconds between polls. */ X# define BIT(x) (1 << (x)) X Xstatic int entry = 0; Xextern long sel_bits; Xstatic char *flush_pty_buf(); Xstatic void p_update(); Xvoid p_clear_screen(); Xvoid p_escape(); Xvoid p_newline(); Xvoid p_scroll(); Xvoid p_tab(); Xvoid p_poll(); Xstatic dup2(); Xint pty = TRUE; Xint num_pty = 0; Xint mapped = FALSE; X Xinq_process_position() X{ X if (curbp->b_display == NULL) { X accumulator = -1; X return; X } X accumulator = 0; X if (argv[1].l_flags != F_NULL) X int_assign(argv[1].l_sym, curbp->b_display->d_line_marker); X if (argv[2].l_flags != F_NULL) X int_assign(argv[2].l_sym, curbp->b_display->d_col_marker); X} Xset_process_position() X{ int line = argv[1].l_int > curbp->b_numlines X ? curbp->b_numlines X : argv[1].l_int; X X if (curbp->b_display == NULL) { X accumulator = -1; X return; X } X accumulator = 0; X if (argv[1].l_flags != F_NULL) { X curbp->b_display->d_line_marker = line; X curbp->b_display->d_col_marker = 1; X } X if (argv[2].l_flags != F_NULL) X curbp->b_display->d_col_marker = argv[2].l_int; X} XDISPLAY * Xp_create(x, y) X{ X DISPLAY *dp = (DISPLAY *) chk_alloc(sizeof (DISPLAY)); X int i; X X if (dp == NULL) X return (DISPLAY *) NULL; X dp->d_display = (BYTE *) chk_alloc(sizeof (BYTE) * nrow * ncol); X if (dp->d_display == NULL) { X chk_free((char *) dp); X return (DISPLAY *) NULL; X } X dp->d_line = (BYTE **) chk_alloc(sizeof (BYTE *) * nrow); X if (dp->d_line == NULL) { X chk_free((char *) dp->d_display); X chk_free((char *) dp); X return (DISPLAY *) NULL; X } X dp->d_escptr = NULL; X dp->d_flags = 0; X dp->d_x = dp->d_y = 0; X dp->d_rows = (short) y; X dp->d_cols = (short) x; X dp->d_color = FG(WHITE); X dp->d_attr = 0; X dp->d_wlen = 0; X dp->d_waitfor = (char *) NULL; X dp->d_line_marker = 1; X dp->d_col_marker = 1; X X dp->d_line[0] = dp->d_display; X for (i = 1; i < nrow; i++) X dp->d_line[i] = dp->d_line[i-1] + ncol; X X p_clear_screen(dp); X X return dp; X} Xp_enter() X{ X if (entry == 0) { X entry++; X return TRUE; X } X return FALSE; X X} Xp_leave() X{ X entry--; X X} Xvoid Xp_destroy(bp) XBUFFER *bp; X{ X if (bp->b_display) { X chk_free((char *) bp->b_display->d_line); X chk_free((char *) bp->b_display->d_display); X chk_free((char *) bp->b_display); X if (bp->b_display->d_waitfor) X chk_free(bp->b_display->d_waitfor); X bp->b_display = NULL; X } X} Xstatic int tmo_wait_for; Xp_wait_for_tmo() X{ X tmo_wait_for = TRUE; X} Xp_wait() X{ X p_wait_common(0L, F_LIT, "", TRUE); X if (argv[1].l_flags != F_NULL) X int_assign(argv[1].l_sym, curbp->b_wstat); X X} Xp_wait_for() X{ X p_wait_common(argv[1].l_flags == F_NULL ? 0l : argv[1].l_int, X argv[2].l_flags, X (LIST *) get_str(2), FALSE); X} Xp_wait_common(tmo, type, lp, waiting) Xlong tmo; XLIST *lp; X{ X# if defined(VMS) X return; X# else X char buf[2]; X extern long accumulator; X# define QUEUE_SIZE 32 X char queue[QUEUE_SIZE+1]; X int i; X int len; X char *str_arg = NULL; X int fd = curbp->b_display->d_pipe_in; X int flags = fcntl(fd, F_GETFL, 0); X extern int case_flag; X extern int magic; X extern REGEXP *prog; X extern int child_sig; X char *qp; X X accumulator = -1; X if (curbp->b_display == NULL) { X if (!waiting) X ewprintf("cannot wait on a normal buffer."); X return; X } X X if (type != F_LIST) X str_arg = (char *) lp; X tmo_wait_for = FALSE; X curbp->b_display->d_flags |= P_WAIT; X buf[1] = NULL; X queue[QUEUE_SIZE] = NULL; X qp = &queue[QUEUE_SIZE]; X if (tmo) X clk_timeout(p_wait_for_tmo, 0, tmo SECONDS); X len = QUEUE_SIZE; X if (str_arg && (prog = regcomp(str_arg)) == NULL) X goto end_of_function; X X while (clock_check()) { X int n; X LIST *lp1; X X if (tmo_wait_for || curbp->b_display == NULL) { X accumulator = -1; X break; X } X if (typeahead()) { X break; X } X /*---------------------------------------- X /* There is a race condition in the code X /* below and I dont know how to solve it X /* portably. Hopefully the window is too X /* small to cause a problem. X /*----------------------------------------*/ X if (child_sig) X i = -1; X else { X fcntl(fd, F_SETFL, flags & ~O_NDELAY); X if (child_sig) X i = -1; X i = read(fd, buf, 1); X fcntl(fd, F_SETFL, flags); X } X if (i != 1) { X update(); X if (check_if_died(curbp)) { X break; X } X i = read(fd, buf, 1); X } X if (i != 1) X continue; X p_update(curbp, buf); X if (waiting) X continue; X X memcpy(queue, queue+1, QUEUE_SIZE - 1); X queue[QUEUE_SIZE - 1] = buf[0]; X if (qp > queue) X qp--; X if (len > 0) X len--; X if (str_arg) { X if (regexec(prog, qp, strlen(qp)) == TRUE) { X accumulator = 1; X break; X } X continue; X } X for (n = 0, lp1 = lp; *lp1 != F_HALT; n++, lp1 += sizeof_atoms[*lp1]) { X char *str; X if (*lp1 == F_STR || *lp1 == F_LIT) X str = (char *) LGET32(lp1); X else if (*lp1 == F_RSTR) X str = ((r_str *) LGET32(lp1))->r_str; X else X continue; X if ((prog = regcomp(str)) == NULL) X goto end_of_function; X X qp = queue + QUEUE_SIZE - strlen(str); X if (regexec(prog, qp, strlen(qp)) == TRUE) { X accumulator = n; X goto end_of_function; X } X } X } Xend_of_function: X update(); X if (curbp->b_display) X curbp->b_display->d_flags &= ~P_WAIT; X clk_remove(p_wait_for_tmo); X# endif X} Xstatic void Xp_update(bp, buf) XBUFFER *bp; Xchar *buf; X{ WINDOW *wp; X X p_addstr(bp, buf); X for (wp = wheadp; wp; wp = wp->w_wndp) X if (wp->w_bufp == bp) { X wp->w_flag |= WFHARD; X wp->w_line = bp->b_display->d_line_marker; X } X} Xvoid Xp_addstr(bp, str) XBUFFER *bp; Xchar *str; X{ register DISPLAY *dp = bp->b_display; X BUFFER *saved_bp = curbp; X int pos; X int cursor_moved = FALSE; X int orig_line; X int saved_system = bp->b_system; X char *start_ptr = NULL; X X curbp = bp; X curbp->b_system = TRUE; X X set_hooked(); X pos = current_col(llength(linep(*cur_line))) - *cur_col; X orig_line = *cur_line; X *cur_line = dp->d_line_marker; X if (*cur_line > curbp->b_numlines) X *cur_line = curbp->b_numlines; X *cur_col = dp->d_col_marker; X X for ( ; *str; str++) { X if (dp->d_escptr) { X *dp->d_escptr++ = *str; X if (isalpha(*str) || dp->d_escape[0] != '[') { X *dp->d_escptr = NULL; X cursor_moved = TRUE; X p_escape(dp, TRUE); X } X continue; X } X switch (*str) { X case ESC: X start_ptr = flush_pty_buf(start_ptr, str); X dp->d_escptr = dp->d_escape; X break; X case 0x07: X start_ptr = flush_pty_buf(start_ptr, str); X ttbeep(); X break; X case '\r': X start_ptr = flush_pty_buf(start_ptr, str); X break; X case '\n': X start_ptr = flush_pty_buf(start_ptr, str); X if (*cur_line < curbp->b_numlines) { X (*cur_line)++; X *cur_col = 1; X break; X } X linsert(str, 1); X break; X case '\b': X start_ptr = flush_pty_buf(start_ptr, str); X if (*cur_col > 1) X (*cur_col)--; X break; X case '\f': X start_ptr = flush_pty_buf(start_ptr, str); X p_clear_screen(dp); X break; X default: X if (start_ptr == NULL) X start_ptr = str; X break; X } X } X start_ptr = flush_pty_buf(start_ptr, str); X dp->d_line_marker = *cur_line; X dp->d_col_marker = *cur_col; X if (!cursor_moved) { X if (*cur_line != orig_line) X pos = 0; X *cur_col = current_col(llength(linep(*cur_line))) - pos; X if (hooked) X set_buffer_parms(curwp, bp); X } X curbp->b_system = saved_system; X curbp = saved_bp; X set_hooked(); X} Xstatic char * Xflush_pty_buf(start, end) Xchar *start; Xchar *end; X{ LINE *lp = linep(*cur_line); X int coff; X RSIZE diff; X int len; X X if (start == NULL) X return NULL; X X coff = current_offset(*cur_col); X len = end - start; X diff = lp->l_used - coff; X if (diff > len) X diff = len; X if (diff) X ldelete(diff); X llinsert(start, len, FALSE); X return NULL; X} Xvoid Xp_newline(dp) Xregister DISPLAY *dp; X{ X if (++dp->d_y >= dp->d_rows) { X p_scroll(dp); X dp->d_y = dp->d_rows - 1; X } X} Xvoid Xp_scroll(dp) Xregister DISPLAY *dp; X{ register int i; X BYTE *vp = dp->d_line[0]; X X for (i = 0; i < dp->d_rows; i++) X dp->d_line[i] = dp->d_line[i+1]; X dp->d_line[i] = vp; X for (i = 0; i < ncol; i++) X vp[i] = ' '; X X} Xvoid Xp_clear_screen(dp) Xregister DISPLAY *dp; X{ X register int i, j; X BYTE *bp; X X for (i = 0; i < nrow; i++) { X bp = dp->d_line[i]; X for (j = 0; j < ncol; ) X bp[j++] = ' '; X } X} Xvoid Xp_tab(dp) Xregister DISPLAY *dp; X{ X dp->d_x = (dp->d_x | 7) + 1; X} Xvoid Xp_escape(dp, modify) Xregister DISPLAY *dp; X{ X register char *cp = dp->d_escape; X u_int16 args[MAX_ESCAPE]; X u_int16 arg_no = 0; X u_int16 one_base; X u_int16 two_base; X u_int16 i; X LISTV local_argv[MAX_ARGC]; X X argv = local_argv; X for(arg_no = 0; arg_no < MAX_ESCAPE; ) X args[arg_no++] = 0; X arg_no = 0; X X dp->d_escptr = NULL; X if (*cp++ != '[') X return; X while (*cp) { X if (isalpha(*cp)) X break; X if (*cp == ';') { X cp++; X args[arg_no++] = 0; X continue; X } X if (!isdigit(*cp)) X return; X args[arg_no++] = (u_int16) atoi(cp); X while (isdigit(*cp)) X cp++; X if (*cp == ';') X cp++; X } X X one_base = (u_int16) (args[0] == 0 ? 1 : args[0]); X two_base = (u_int16) (args[1] == 0 ? 1 : args[1]); X switch (*cp) { X case '@': X case 'A': X dp->d_y -= one_base; X break; X case 'B': X dp->d_y += one_base; X break; X case 'C': X *cur_col += one_base; X break; X case 'D': X *cur_col -= one_base; X break; X case 'f': X case 'H': { X int lines_to_insert = one_base - curbp->b_numlines; X *cur_line = one_base; X *cur_col = two_base; X dp->d_y = curwp->w_top_line + one_base; X dp->d_x = two_base; X while (lines_to_insert-- > 0) { X *cur_line = curbp->b_numlines; X lnewline(TRUE); X } X *cur_line = one_base; X break; X } X case 'J': { X if (args[0] == 2) X *cur_line = curwp->w_top_line; X argv[1].l_int = MK_LINE; X argv[1].l_flags = F_INT; X while (*cur_line < curbp->b_numlines) X lfree(curbp, *cur_line); X break; X } X case 'K': X del_to_eol(); X break; X case 'M': X case 'X': X break; X case 'm': X for (i = 0; i < arg_no; i++) { X int j = args[i]; X extern int ab_color_map[]; X switch (j) { X case 0: X dp->d_attr &= ~(BOLD | REVERSE); X break; X case 1: X dp->d_attr |= BOLD; X break; X case 7: X dp->d_attr |= REVERSE; X break; X case 30: case 31: case 32: case 33: case 34: X case 35: case 36: case 37: X j = ab_color_map[j - 30]; X dp->d_color = (dp->d_color & ~FG_COLOR) | X FG(j); X j += 30; X break; X case 40: case 41: case 42: case 43: case 44: X case 45: case 46: case 47: X j = ab_color_map[j - 40]; X dp->d_color = (dp->d_color & ~BG_COLOR) | X BG(j); X j += 40; X break; X } X if (modify) { X sprintf(dp->d_escape, "\033[%dm", args[i]); X linsert(dp->d_escape, strlen(dp->d_escape)); X dp->d_x = *cur_col; X dp->d_y = *cur_line; X } X } X break; X } X X if (*cur_col < 1) X *cur_col = 1; X if (dp->d_x < 0) X dp->d_x = 0; X else if (dp->d_x >= dp->d_cols) X dp->d_x = dp->d_cols - 1; X if (dp->d_y < 0) X dp->d_y = 0; X else if (dp->d_y >= dp->d_rows) X dp->d_y = dp->d_rows - 1; X X} Xcreate_ipc(send, recv) Xint *send; Xint *recv; X{ int pid; X X# if !defined(HAVE_PTY) X int pipe1[2], pipe2[2]; X X if (pipe(pipe1) < 0) X return -1; X if (pipe(pipe2) < 0) { X close(pipe1[0]); X close(pipe1[1]); X return -1; X } X if ((pid = fork()) < 0) { X close(pipe1[0]); X close(pipe1[1]); X close(pipe2[0]); X close(pipe2[1]); X return -1; X } X if (pid == 0) { X dup2(pipe1[0], 0); X dup2(pipe2[1], 1); X dup2(pipe2[1], 2); X close(pipe1[0]); X close(pipe1[1]); X close(pipe2[0]); X close(pipe2[1]); X } X else { X close(pipe2[1]); X close(pipe1[0]); X *send = pipe1[1]; X *recv = pipe2[0]; X } X# else X# define PTY_NAME "/dev/ptyXX" X# define TTY_NAME "/dev/ttyXX" X# define TTY_MODE 0622 X char pty_name[20]; X char tty_name[20]; X int xx; X int c1, c2; X strcpy(pty_name, PTY_NAME); X strcpy(tty_name, TTY_NAME); X for (xx = 0; pty_name[xx] != 'X'; ) X xx++; X for (c1 = 'q'; c1 != 'z'; c1++) { X for (c2 = 0; c2 < 0x10; c2++) { X tty_name[xx] = pty_name[xx] = c1; X tty_name[xx+1] = pty_name[xx+1] = X c2 >= 0x0a ? (c2 + 'a' - 0x0a) X : (c2 + '0'); X if ((*send = open(pty_name, O_RDWR)) >= 0) { X if ((*recv = open(tty_name, O_RDWR)) >= 0) { X chown(tty_name, getuid(), getgid()); X chmod(tty_name, TTY_MODE); X goto ipc_created; X } X close(*send); X } X } X } X if (c1 >= 'z') X return -1; X Xipc_created: X if ((pid = fork()) < 0) { X close(*send); X close(*recv); X return -1; X } X if (pid == 0) { X int mypid = getpid(); X dup2(*recv, 0); X dup2(*recv, 1); X dup2(*recv, 2); X close(*recv); X close(*send); X signal(SIGTTIN, SIG_DFL); X signal(SIGTTOU, SIG_DFL); X setpgrp(0, mypid); X ioctl(0, TIOCSPGRP, &mypid); X } X else { X *recv = *send; X signal(SIGTTIN, SIG_IGN); X signal(SIGTTOU, SIG_IGN); X } X# endif X X /*---------------------------------------- X /* At this point we have created the X /* IPC mechanism, and we are running X /* in both the parent and child, via fork(). X /*----------------------------------------*/ X# if defined(SIGTTIN) X if (pid == 0) { X signal(SIGTTIN, SIG_DFL); X signal(SIGTTOU, SIG_DFL); X } X# endif X return pid; X} Xdo_connect() X{ register DISPLAY *dp; X int flags = argv[1].l_flags == F_NULL ? P_ECHO : argv[1].l_int; X char *sh = get_str(2); X X if (curbp->b_display) { X accumulator = 0; X curbp->b_display->d_flags = (u_int16) flags; X return 0; X } X accumulator = 1; X dp = p_create(ncol, nrow-2); X if (dp == NULL) { X ewprintf("Couldn't allocate memory for connection."); X return 0; X } X dp->d_flags = (u_int16) flags; X X /*---------------------------------------- X /* Create the IPC mechanism (pipe or pty) X /* and fork a child. X /*----------------------------------------*/ X if ((dp->d_pid = create_ipc(&dp->d_pipe_out, &dp->d_pipe_in)) < 0) { X chk_free((char *) dp); X ewprintf("Couldn't create IPC."); X return 0; X } X proc_add(dp->d_pid, (char *) NULL); X /*---------------------------------------- X /* Child gets to exec a shell. X /*----------------------------------------*/ X if (dp->d_pid == 0) { X extern char *get_shell(); X char *shell = (sh && sh[0]) ? sh : get_shell(); X# if defined(SIGCLD) X signal(SIGCLD, SIG_DFL); X# endif X execl(shell, shell, "-i", (char *) NULL); X trace_log("exec failed"); X _exit(1); X } X X /*---------------------------------------- X /* Parent gets to tidy up. X /*----------------------------------------*/ X# if defined(F_GETFL) X flags = fcntl(dp->d_pipe_in, F_GETFL, 0); X if (fcntl(dp->d_pipe_in, F_SETFL, flags | O_NDELAY) < 0) X errorf("connect: fcntl error."); X flags = fcntl(dp->d_pipe_out, F_GETFL, 0); X if (fcntl(dp->d_pipe_out, F_SETFL, flags | O_NDELAY) < 0) X errorf("connect: fcntl error."); X# endif X accumulator = 0; X curbp->b_display = dp; X infof("Buffer connected."); X num_pty++; X sel_bits |= BIT(dp->d_pipe_in); X p_poll(); X return 0; X} Xvoid Xp_cleanup(bp) XBUFFER *bp; X{ X DISPLAY *dp = bp->b_display; X if (dp == NULL) X return; X sel_bits &= ~BIT(dp->d_pipe_in); X close(dp->d_pipe_in); X close(dp->d_pipe_out); X if (dp->d_pid) { X kill(dp->d_pid, SIGTERM); X kill(dp->d_pid, SIGKILL); X } X p_destroy(bp); X infof("%s disconnected.", bp->b_fname); X num_pty--; X} Xdo_disconnect() X{ register DISPLAY *dp = curbp->b_display; X X accumulator = 0; X if (dp == NULL) X return 0; X p_cleanup(curbp); X p_poll(); X return 0; X} Xvoid Xp_poll() X{ register BUFFER *bp; X char buf[256]; X BUFFER *saved_curbp = curbp; X int updated; X extern int dflag; X X if (entry || num_pty <= 0) { X num_pty = 0; X return; X } X X entry++; Xstart_again: X do { X updated = FALSE; X for (bp = bheadp; bp; bp = bp->b_bufp) { X int i; X while (1) { X if (bp->b_display == NULL || bp->b_display->d_flags & P_WAIT) X break; X if ((i = read(bp->b_display->d_pipe_in, buf, sizeof buf - 1)) <= 0) { X if (i <= 0) { X if (check_if_died(bp)) X goto start_again; X } X break; X } X buf[i] = NULL; Xtrace_log("p_update(buf=%s)", buf); X p_update(bp, buf); X updated = TRUE; X } X } X curbp = saved_curbp; X set_hooked(); X if (updated) X update(); X } X while (updated && !typeahead()); X entry--; X# if !defined(SELECT) X clk_timeout(p_poll, 0, (long) (dflag ? 5 : POLL_TIME) SECONDS); X# endif X} Xcheck_if_died(bp) Xregister BUFFER *bp; X{ extern int child_sig; X X if (child_sig) X proc_wait(-1); X if (kill(bp->b_display->d_pid, 0) < 0) { X p_cleanup(bp); X return TRUE; X } X return FALSE; X} Xp_write(buf, len) Xchar *buf; Xu_int16 len; X{ X if (curbp->b_display == NULL) X return; X write(curbp->b_display->d_pipe_out, buf, (int) len); X/* return curbp->b_display->d_flags & P_ECHO;*/ X} Xstatic Xdup2(old, new) X{ X close(new); X dup(old); X} X SHAR_EOF chmod 0444 ./pty.c || echo "restore of ./pty.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./ref_string.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./ref_string.c && X/************************************************************** X * X * CRISP - Custom Reduced Instruction Set Programmers Editor X * X * (C) Paul Fox, 1989 X * 43, Jerome Close Tel: +44 6284 4222 X * Marlow X * Bucks. X * England SL7 1TX X * X * X * Please See COPYRIGHT notice. X * X **************************************************************/ X X# include "list.h" X XSCCSID("@(#) ref_string.c 1.4, (C) 1989, P. Fox"); X Xr_str * Xnew_rp() X{ X return (r_str *) chk_alloc(sizeof (r_str)); X} Xr_str * Xr_alloc(size) X{ register r_str *rp = new_rp(); X X rp->r_ref = 1; X rp->r_size = size; X rp->r_str = chk_alloc(size); X return rp; X} Xr_str * Xr_init(new_string) Xchar *new_string; X{ int len = strlen(new_string) + 1; X r_str *rp = r_alloc(len); X X memcpy(rp->r_str, new_string, rp->r_size); X rp->r_used = len - 1; X return rp; X} Xr_str * Xr_linit(new_string, len) Xchar *new_string; X{ r_str *rp = r_alloc(len); X X memcpy(rp->r_str, new_string, len); X rp->r_used = len; X return rp; X} Xr_rinit(rp, new_string) Xr_str *rp; Xchar *new_string; X{ int len = strlen(new_string) + 1; X rp->r_ref = 1; X rp->r_size = len; X rp->r_str = new_string; X rp->r_used = len - 1; X X} Xr_str * Xr_cat(rp, str) Xregister r_str *rp; Xchar *str; X{ int len = strlen(str); X char *cp; X int new_used = rp->r_used + len; X r_str *rp1; X X if (rp->r_ref == 1) { X if (rp->r_size <= rp->r_used + len) { X cp = rp->r_str; X rp->r_str = chk_alloc(new_used+1); X rp->r_size = new_used + 1; X memcpy(rp->r_str, cp, rp->r_used); X chk_free(cp); X } X memcpy(rp->r_str + rp->r_used, str, len+1); X rp->r_used += len; X return rp; X } X rp1 = r_alloc(new_used+1); X rp1->r_used = new_used; X memcpy(rp1->r_str, rp->r_str, rp->r_used); X memcpy(rp1->r_str + rp->r_used, str, len+1); X return rp1; X} Xr_str * Xr_inc(rp) Xr_str *rp; X{ X rp->r_ref++; X return rp; X} Xr_dec(rp) Xr_str *rp; X{ X if (rp && --rp->r_ref <= 0) { X chk_free(rp->r_str); X chk_free(rp); X } X} SHAR_EOF chmod 0444 ./ref_string.c || echo "restore of ./ref_string.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./regexp.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./regexp.c && X/************************************************************** X * X * CRISP - Custom Reduced Instruction Set Programmers Editor X * X * (C) Paul Fox, 1989 X * 43, Jerome Close Tel: +44 6284 4222 X * Marlow X * Bucks. X * England SL7 1TX X * X * X * Please See COPYRIGHT notice. X * X **************************************************************/ X# include "list.h" X XSCCSID("@(#) regexp.c 1.14, (C) 1989, P. Fox"); X X# define DEBUG_REGEXP X# undef DEBUG_REGEXP X X# define ERROR(x) { ewprintf(x); return -1; } X# define REGEXP_SIZE 512 X# define REGEXP_INCR 128 X X# define BITMAP_SIZE (256 / 8) X# define FINISH 1 /* End of compiled r.e. */ X# define ZERO_OR_MORE 2 /* ..@ */ X# define ONE_OR_MORE 3 /* ..+ */ X# define STAR 4 /* * */ X# define QUESTION 5 /* ? */ X# define CLASS 6 /* [xyz] or [~xyz] */ X# define STRING 7 /* xyz... */ X# define END 8 /* End of branch list. */ X# define OR 9 /* '|' alternatives. */ X# define SETPOS 10 /* \c */ X# define BOL 11 /* < or ^ */ X# define EOL 12 /* > or $ */ X# define LOOP 13 /* Used as end of block terminator*/ X /* for @ and +. */ X# define OPEN 20 /* '{' */ X# define CLOSE 30 /* '}' */ Xint bittab[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; Xstatic int match_level; Xstatic char *reg_print_bitmap(); Xenum re_syntax { X BRIEF_SYNTAX = 0, X UNIX_SYNTAX = 1 X }; Xenum re_syntax re_syntax = BRIEF_SYNTAX; X# define MAGIC_BRIEF "@+*?[|{}\\$>" X# define MAGIC_UNIX "+*.[|{}\\$>" Xchar *re_opcodes[] = { X "<0>", X "FINISH", X "ZERO_OR_MORE", X "ONE_OR_MORE", X "STAR", X "QUESTION", X "CLASS", X "STRING", X "END", X "OR", X "SETPOS", X "BOL", X "EOL", X "LOOP", "14", "15", "16", "17", "18", "19", X "OPEN-0", "OPEN-1", "OPEN-2", "OPEN-3", "OPEN-4", "OPEN-5", X "OPEN-6", "OPEN-7", "OPEN-8", "OPEN-9", X "CLOSE-0", "CLOSE-1", "CLOSE-2", "CLOSE-3", "CLOSE-4", "CLOSE-5", X "CLOSE-6", "CLOSE-7", "CLOSE-8", "CLOSE-9" X }; Xint bstack[10]; Xint re_level; Xint re_group; /* Used for {..} in translate patterns. */ Xchar *re_code = NULL; Xint re_code_size = 0; Xint end_of_code; Xint last_end; Xchar *pat_ptr; Xint allow_modifier; Xint or_just_done = FALSE; Xextern int dflag; Xextern int case_flag; Xextern int magic; X Xvoid Xre_syntax_fn() X{ X accumulator = (int) re_syntax; X if (argv[1].l_flags == F_INT && (argv[1].l_int == 0 || argv[1].l_int == 1)) X re_syntax = (enum re_syntax) argv[1].l_int; X} XREGEXP * Xregcomp(pattern) Xchar *pattern; X{ X static REGEXP regexp; X register char *re; X char *next_block(); X X if (re_code == NULL) { X re_code = chk_alloc(REGEXP_SIZE); X re_code_size = REGEXP_SIZE; X } X end_of_code = 0; X re_group = re_level = 0; X pat_ptr = pattern; X last_end = -1; X allow_modifier = FALSE; X X if (re_comp() < 0) X return NULL; X if (re_level) { X ewprintf("Missing close brace"); X return NULL; X } X X re_code[end_of_code] = FINISH; X regexp.program = re_code; X if (dflag & DB_REGEXP) { X trace_log("Pass 1:\n"); X re_print(re_code); X } X /*---------------------------------------- X /* Following piece of code walks down the X /* regular expression and sets up the X /* link fields needed by the '|'-OR X /* pattern matching code. X /*----------------------------------------*/ X for (re = re_code; *re != FINISH; ) { X register char *re1; X register char *re2; X X if (*re == ZERO_OR_MORE || *re == ONE_OR_MORE) { X re += 3; X continue; X } X if (*re != OR) { X re += *re == END ? 3 : LGET16(re); X continue; X } X re1 = re + 3; X re1 = next_block(re1); X if (*re1 != END) { X ewprintf("Internal inconsistency."); X return NULL; X } X /*-------------------------------- X * Update link field for OR. X *--------------------------------*/ X LPUT16(re, re1 - re + 3); X /*-------------------------------- X * Update END field. X *--------------------------------*/ X if ((re2 = next_block(re1)) == NULL) { X ewprintf("Internal inconsistency (1)."); X return NULL; X } X while (1) { X if (*re2 != OR) { X if ((re2 = next_block(re2)) == NULL) { X ewprintf("Internal inconsistency (1)."); X return NULL; X } X break; X } X re2 += 3; X while (*re2 != END && *re2 != FINISH) X if ((re2 = next_block(re2)) == NULL) { X ewprintf("Internal inconsistency (1)."); X return NULL; X } X if (*re2 == END) X re2 += 3; X } X LPUT16(re1, re2 - re1); X re += 3; X } X if (dflag & DB_REGEXP) { X trace_log("Pass 2:\n"); X re_print(re_code); X } X return ®exp; X} Xchar * Xnext_block(re) Xregister char *re; X{ register int i; X X if (*re >= OPEN && *re <= OPEN + 9) { X int close = *re + 10; X while (*re != close) { X i = (*re == OR || *re == END) ? 3 : LGET16(re); X if (i == 0) X return NULL; X re += i; X } X } X if (*re == OR || *re == END) X return re+3; X return re + LGET16(re); X} Xre_comp() X{ int allow_or = FALSE; X int last_end_on_entry = last_end; X# define MAX_OR 32 X X or_just_done = FALSE; X while (*pat_ptr) { X if (!magic) { X pat_ptr++; X goto DEFAULT; X } X switch (*pat_ptr++) { X case '*': X if (re_syntax == BRIEF_SYNTAX) X goto DEFAULT; X /* Fall thru.. */ X case '@': X if (pat_ptr[-1] == '@' && re_syntax == UNIX_SYNTAX) X goto DEFAULT; X /* Fall thru.. */ X case '+': X if (allow_modifier == FALSE) X goto DEFAULT; X shift_up(last_end); X re_code[last_end] = pat_ptr[-1] == '+' ? ONE_OR_MORE X : ZERO_OR_MORE; X re_code[end_of_code] = LOOP; /* NEW */ X LPUT16(&re_code[end_of_code], 3); /* NEW */ X end_of_code += 3; /* NEW */ X LPUT16(&re_code[last_end], end_of_code - last_end); X allow_modifier = FALSE; X break; X case '|': X if (allow_or == FALSE) X ERROR("Null expression before |"); X shift_up(last_end); X re_code[last_end] = OR; X allow_or = FALSE; X re_code[end_of_code] = END; X LPUT16(&re_code[end_of_code], 0); X end_of_code += 3; X or_just_done = TRUE; X continue; X case '{': X if (re_syntax == UNIX_SYNTAX) X goto DEFAULT; Xopen_bracket: X if (re_level > NSUBEXP) X ERROR("Too many '{'"); X last_end = end_of_code; X re_code[end_of_code] = OPEN + re_group; X bstack[re_level++] = re_group; X if (re_group < 9) X re_group++; X LPUT16(&re_code[end_of_code], 3); X end_of_code += 3; X if (re_comp() < 0) X return -1; X re_level--; X allow_or = TRUE; X break; X case '}': X if (re_syntax == UNIX_SYNTAX) X goto DEFAULT; Xclose_bracket: X re_code[end_of_code] = CLOSE + bstack[re_level-1]; X LPUT16(&re_code[end_of_code], 3); X end_of_code += 3; X allow_modifier = TRUE; X last_end = last_end_on_entry; X return 0; X case '\\': X if (re_syntax == UNIX_SYNTAX && *pat_ptr == '(') { X pat_ptr++; X goto open_bracket; X } X if (re_syntax == UNIX_SYNTAX && *pat_ptr == ')') { X pat_ptr++; X goto close_bracket; X } X /* Fall thru .. */ X DEFAULT: X default: X pat_ptr--; X last_end = end_of_code; X allow_or = TRUE; X allow_modifier = TRUE; X if (gen_atom() == FALSE) X return -1; X LPUT16(&re_code[last_end], end_of_code - last_end); X break; X } X or_just_done = FALSE; X } X return 0; X} Xgen_atom() X{ int len; X int size = 3; X int incr = 1; X char *magic_str = re_syntax == BRIEF_SYNTAX ? MAGIC_BRIEF : MAGIC_UNIX; X X if (!magic) X goto DEFAULT; X switch (*pat_ptr) { SHAR_EOF echo "End of part 8" echo "File ./regexp.c is continued in part 9" echo "9" > s2_seq_.tmp exit 0 -- ===================== Reuters Ltd PLC, Tel: +44 628 891313 x. 212 Westthorpe House, UUCP: fox%marlow.uucp@idec.stc.co.uk Little Marlow, Bucks, England SL7 3RQ