v07i049: CRISP release 1.9 part 28/32
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Thu Jun 22 13:56:44 AEST 1989
Posting-number: Volume 7, Issue 49
Submitted-by: fox at 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 at idec.stc.co.uk Little Marlow,
Bucks, England SL7 3RQ
More information about the Comp.sources.misc
mailing list