allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (06/22/89)
Posting-number: Volume 7, Issue 45 Submitted-by: fox@marlow.UUCP (Paul Fox) Archive-name: crisp1.9/part25 #!/bin/sh # this is part 4 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file ./cm.c continued # CurArch=4 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 ./cm.c" sed 's/^X//' << 'SHAR_EOF' >> ./cm.c X if (l_flag) { X printf("Entering macro '%s'\n", name); X list_macro(0, lp); X } X macro_tbl[macro_cnt].m_list = lp; X macro_cnt++; X} Xvoid Xpatom(first_atom, mptr, str) XLIST *first_atom; XLIST *mptr; Xchar *str; X{ X char buf[10]; X int atom_no = mptr - first_atom; X X switch (*mptr) { X case F_HALT: nhalt++; break; X case F_INT: nint++; break; X case F_LIT: X case F_STR: nstr++; break; X case F_ID: nid++; break; X case F_LIST: nlist++; break; X case F_NULL: nnull++; break; X default: ndontknow++; break; X } X X if (l_flag == 0 || mptr == NULL) X return; X if (*mptr == F_STR && strcmp(str, "macro") == 0) X printf("\n"); X sprintf(buf, "0x%02x", *mptr); X printf("Atom %02x: ", atom_no); X if (L_flag) { X if (*mptr == F_HALT || *mptr == F_END) X printf("[%02x/........] ", *mptr); X else if (*mptr == F_LIST || *mptr == F_ID) X printf("[%02x/....%04x] ", *mptr, LGET16(mptr)); X else X printf("[%02x/%08lx] ", *mptr, LGET32(mptr)); X } X printf("%s ", X *mptr == F_HALT ? "HALT" : X *mptr == F_INT ? "int" : X *mptr == F_STR ? "str" : X *mptr == F_LIT ? "lit" : X *mptr == F_LIST ? "list" : X *mptr == F_END ? "***END***" : X *mptr == F_ID ? "ID" : buf); X if (*mptr == F_STR) X printf("%s\n", str); X else if (*mptr == F_LIT) X printf("\"%s\"\n", str); X else if (*mptr == F_HALT || *mptr == F_END) X printf("\n"); X else if (*mptr == F_ID) X printf("%s\n", builtin[LGET16(mptr)].name); X else if (*mptr == F_LIST) { X int i = LGET16(mptr); X if (i == 0) X printf("======\n"); X else X printf("--> %x\n", atom_no + i); X } X else X printf("%08lx\n", LGET32(mptr)); X X} Xvoid Xewprintf(s, a, b, c, d, e, f, g, h, i, j, k) Xchar *s; X{ X fprintf(stderr, s, a, b, c, d, e, f, g, h, i, j, k); X fprintf(stderr, "\n"); X} Xvoid Xerrorf(s, a, b, c, d, e, f, g, h, i, j, k) Xchar *s; X{ X fprintf(stderr, s, a, b, c, d, e, f, g, h, i, j, k); X fprintf(stderr, "\n"); X} SHAR_EOF echo "File ./cm.c is complete" chmod 0444 ./cm.c || echo "restore of ./cm.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./config.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./config.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 * This file contains machine independent configuration variables. X * X * Machine dependent ones appear in unix.c or vms.c X * X **************************************************************/ X# include "list.h" X# include "alt.h" X XSCCSID("@(#) config.c 1.7, (C) 1989, P. Fox"); X Xchar *bfile = "BFILE=newfile"; Xchar *bflags = "BFLAGS=-i60"; Xchar *bterm = "vt100\0 Spare string space"; Xchar *bpackages = "BPACKAGES=c,h:t"; X Xint strip_cr_flag = TRUE; /* Set to FALSE if dont want <CR> stripped */ X /* by default. */ XCOLOR col_table = { X 0, /* Background. */ X 2, /* Normal text. */ X 11, /* Selected window title*/ X 14, /* Normal messages. */ X 12, /* Error messages. */ X 4, /* Hi-lite background. */ X 10, /* Hi-lite foreground. */ X }; X Xstruct k_tbl k_tbl[] = { X ALT_A, "mark 4", X ALT_B, "_case", X ALT_C, "mark 2", X ALT_D, "delete_line", X ALT_E, "edit_file", X ALT_G, "goto_line", X ALT_I, "insert_mode", X ALT_J, "goto_bookmark", X ALT_K, "delete_to_eol", X ALT_L, "mark 3", X ALT_M, "mark", X ALT_O, "output_file", X ALT_P, "_print", X ALT_R, "read_file", X ALT_S, "search_fwd", X ALT_T, "translate", X ALT_U, "undo", X ALT_W, "write_buffer", X ALT_V, "version", X ALT_X, "exit", X CTRL_X, "exit", X ALT_Z, "dos", X F1, "change_window", X F2, "move_edge", X F3, "create_edge", X F4, "delete_edge", X F5, "search_fwd", X F6, "translate", X F7, "remember", X F8, "playback", X F9, "load_macro", X F10, "execute_macro", X SHIFT_F1+6, "pause", X KEY_0, "paste", X KEY_0+1, "end_of_line", X KEY_0+2, "down", X KEY_0+3, "page_down", X KEY_0+4, "left", X KEY_0+6, "right", X KEY_0+7, "beginning_of_line", X KEY_0+8, "up", X KEY_0+9, "page_up", X KEY_0+13, "undo", X 213, "copy", X 214, "cut", X 212, "delete_block", X 223, "top_of_window", X CTRL_0+1, "end_of_window", X 225, "top_of_buffer", X 219, "end_of_buffer", X 0, NULL X }; SHAR_EOF chmod 0444 ./config.c || echo "restore of ./config.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./debug.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./debug.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("@(#) debug.c 1.7, (C) 1989, P. Fox"); Xchar *crisp_log = "crisp.log"; Xint dflag = 0; Xextern int pflag; Xstatic FILE *debug_fp = NULL; Xextern BUILTIN builtin[]; Xvoid list_macro(); X X# ifdef PROTO X void trace_log(char *, DOT); X void trace_ilog(char *, DOT); X# else X void trace_log(); X void trace_ilog(); X# endif X Xdo_debug() X{ X X if (argv[1].l_flags != F_NULL) X dflag = argv[1].l_int & 0xffff; X else X dflag = !dflag; X ewprintf("[Debug %s (0x%04x)%s%s]", dflag ? "ON" : "OFF", dflag, X dflag & DB_REGEXP ? " REGEXP" : "", X dflag & DB_UNDO ? " UNDO" : "", X dflag & DB_PROMPT ? " PROMPT" : "" X ); X if (!dflag) { X fclose(debug_fp); X debug_fp = NULL; X } X return 0; X} Xdo_profile() X{ X X if (argv[1].l_flags != F_NULL) X pflag = argv[1].l_int & 0xffff; X else X pflag = !pflag; X ewprintf("[Profiling %s]", pflag ? "ON" : "OFF"); X return 0; X} Xtrace_bit(lp, level) XLIST *lp; X{ LIST *lp1 = lp + level; X trace_log("First bit of list:\n"); X if (lp == NULL) { X trace_log(" nil\n"); X return; X } X while (lp < lp1) { X if (*lp == F_HALT) trace_log("F_HALT\n"); X else if (*lp == F_INT) trace_log(" F_INT: %ld\n", LGET32(lp)); X else if (*lp == F_STR) trace_log(" F_STR: '%s'\n", LGET32(lp)); X else if (*lp == F_ID) trace_log(" F_ID: %s\n", X builtin[LGET16(lp)].name); X else if (*lp == F_LIST) trace_log("F_LIST: %d\n", LGET16(lp)); X else { X trace_log("<Dont know>\n"); X break; X } X lp += sizeof_atoms[*lp]; X } X} Xvoid Xtrace_list(lp) XLIST *lp; X{ extern int dflag; X if (dflag == 0) X return; X if (lp == NULL) { X trace_ilog("nil\n"); X return; X } X trace_ilog("(", (char *) NULL); X while (*lp != F_HALT) { X r_str *rp; X if (*lp == F_INT) X trace_log("%ld ", LGET32(lp)); X else if (*lp == F_STR) { X trace_log("%s ", (char *) LGET32(lp)); X } X else if (*lp == F_RSTR) { X rp = (r_str *) LGET32(lp); X trace_log("%s ", rp->r_str); X } X else if (*lp == F_LIT) { X trace_log("\"%s\" ", (char *) LGET32(lp)); X } X else if (*lp == F_ID) X trace_log("%s ", builtin[LGET16(lp)].name); X else if (*lp == F_LIST) { X u_int16 i = LGET16(lp); X trace_log("(..) ", (char *) NULL); X if (i == 0) X break; X lp += i; X continue; X } X lp += sizeof_atoms[*lp]; X } X X trace_log(")\n", (char *) NULL); X} X/* VARARGS1 */ Xvoid Xtrace_ilog(str, ptr) Xchar *str; Xchar *ptr; X{ int i = nest_level; X char buf[1024]; X static int old_level = -1; X X if (dflag == 0) X return; X if (old_level == nest_level) X strcpy(buf, "\t"); X else X sprintf(buf, "%02d:.....", nest_level); X X while (i-- > 0) X strcat(buf, old_level == nest_level ? " " : "."); X trace_log(buf); X trace_log(str, ptr); X old_level = nest_level; X} X/* VARARGS1 */ Xvoid Xtrace_log(str, ptr) Xchar *str; Xchar *ptr; X X{ X extern int dflag; X extern int flush_flag; X X if (dflag == 0) X return; X X if (debug_fp == NULL) X debug_fp = fopen(crisp_log, "w"); X X if (debug_fp) { X (void) fprintf(debug_fp, str, ptr); X if (flush_flag) X fflush(debug_fp); X } X} Xvoid Xlist_macro(level, lp) XLIST *lp; X{ int tokcnt = 0; X X for (; *lp != F_END; lp += sizeof_atoms[*lp]) { X if (tokcnt++) X trace_log(" "); X if (*lp == F_INT) X trace_log("%ld", LGET32(lp)); X else if (*lp == F_ID) X trace_log("%s", builtin[LGET32(lp)].name); X else if (*lp == F_STR) { X char *cp; X char *str = (char *) LGET32(lp); X for (cp = str; *cp; cp++) X if (*cp == '"' && cp != str) X trace_log("\\\""); X else if (*cp == '\r') X trace_log("\\r"); X else if (*cp == '\n') X trace_log("\\n"); X else if (*cp == '\t') X trace_log("\\t"); X else X trace_log("%c", *cp); X if (str[0] == '"') X trace_log("\""); X } X else if (*lp == F_LIST) { X int i; X trace_log("\n "); X for (i = level; i-- > 0; ) X trace_log(" "); X trace_log("("); X list_macro(level+1, lp + sizeof_atoms[F_LIST]); X trace_log(")"); X } X } X if (level == 0) X trace_log("\n"); X} Xvoid Xdump_all_lines() X{ X# if 0 X BUFFER *bp; X LINE *lp; X int line_no; X char buf[132]; X X trace_log("Dump all Lines\n"); X for (bp = bheadp; bp; bp = bp->b_bufp) { X trace_log("Buffer %s:\n", bp->b_fname); X line_no = 0; X for (lp = lforw(bp->b_linep); lp != bp->b_linep; X lp = lforw(lp)) { X (void) sprintf(buf, "\tLine %3d: used=%2d size=%2d fl=%d\n", X ++line_no, lp->l_used, lp->l_size, X lp->l_flags); X trace_log(buf); X } X trace_log("\n"); X } X# endif X} Xvoid Xdmp_lines(bp) XBUFFER *bp; X{ LINE *lp; X# if 0 X int i = 0; X X trace_log("DMP_LINES\n"); X trace_log("WP=%08lx ", curwp); X trace_log("WP->w_bufp=%08lx ", curwp->w_bufp); X trace_log("hooked=%s ", hooked ? "TRUE" : "FALSE"); X trace_log("*cur_line=%d \n", *cur_line); X trace_log("BP=%08lx ", bp); X trace_log("b_line=%d ", bp->b_line); X trace_log("b_linep=%08lx\n\t", bp->b_linep); X lp = lforw(bp->b_linep); X while (1) { X if (++i > 6) { X i = 0; X trace_log("\n\t"); X } X trace_log("%08lx ", lp); X lp = lforw(lp); X if (lp == lforw(bp->b_linep)) X break; X } X trace_log("\n"); X# endif X} Xvoid Xphex(str, n) Xchar *str; X{ X char buf[256]; X int i = 0; X if (dflag == 0) X return; X X buf[0] = NULL; X while (n-- > 0) { X (void) sprintf(buf+strlen(buf), "%02x ", *str++); X if (++i >= 16 || n <= 0) { X strcat(buf, "\n"); X trace_log("%s", buf); X i = 0; X buf[0] = NULL; X } X } X} Xvoid Xdmp_win(winp, lp) XWINDOW *winp; XLINE *lp; X{ X WINDOW *wp = wheadp; X X trace_log("DMP_WIN\n"); X trace_log("wp=%08lx ", winp); X trace_log("lp=%08lx ", lp); X trace_log("curwp=%08lx ", curwp); X trace_log("curbp=%08lx\n", curbp); X trace_log("wheadp="); X for (; wp; wp = wp->w_wndp) X trace_log("%08lx ", wp); X trace_log("\n"); X dmp_lines(curbp); X} Xvoid Xdmp_coord() X{ X WINDOW *wp; X trace_log("dmp_coord:\n"); X for (wp = wheadp; wp; wp = wp->w_wndp) { X trace_log("%08lx: ", wp); X trace_log("(%d, ", wp->w_x); X trace_log("%d) ", wp->w_y); X trace_log("w=%d ", wp->w_w); X trace_log("h=%d ", wp->w_h); X trace_log("%s", wp->w_tiled ? X "tiled" : "not tiled"); X } X trace_log("curwp=%08lx\n", curwp); X} Xvoid Xprint_line(lp) XLINE *lp; X{ char buf[128]; X sprintf(buf, "%08lx: used=%d size=%d tell=%ld fl=%d ", X lp, lp->l_used, lp->l_size, lp->l_tell, lp->l_flags); X if (lp->l_flags & L_INCORE) X strcat(buf, "INCORE "); X if (lp->l_flags & L_LOCKED) X strcat(buf, "LOCKED"); X strcat(buf, "\n"); X trace_log(buf); X} Xvoid Xtrace_sym(sp) XSYMBOL *sp; X{ X if (dflag == 0) X return; X X trace_ilog(" %s := ", sp->s_name); X if (sp->s_type == F_INT) X trace_log("%ld\n", sp->s_int); X else if (sp->s_type == F_STR || sp->s_type == F_RSTR) X trace_log("'%s'\n", c_string(sp->s_str->r_str)); X else { X if (sp->s_list == NULL) X trace_log("NIL\n"); X else X trace_list(sp->s_list); X } X} Xvoid Xkey_list(k) Xchar *k[]; X{ int i; X char buf[128]; X u_char *cp; X X for (i = 0; i < NFKEYS; i++) { X sprintf(buf, "K[%d] := '", i); X cp = (u_char*) k[i]; X if (cp == NULL) X strcat(buf, "<null>"); X else X while (*cp) { X unsigned char ch = *cp++; X if (ch & 0x80) { X sprintf(buf+strlen(buf), "[0x%02x]", ch); X continue; X } X if (ch < ' ') { X strcat(buf, "^"); X ch += '@'; X } X sprintf(buf + strlen(buf), "%c", ch); X } X trace_log("%s'\n", buf); X } X} Xtrace_trigger(type) X{ X static char *triggers[] = { X "REG_TYPED", X "REG_EDIT", X "REG_ALT_H", X "REG_UNASSIGNED", X "REG_IDLE", X "REG_EXIT", X "REG_NEW", X "REG_CTRLC", X "REG_INVALID" X }; X trace_log("*** TRIGGER=%s ***\n", triggers[type]); X} Xtrace_refs() X{ X BUILTIN *bp; X char buf[128]; X X if (dflag == 0) X return; X for (bp = builtin; bp < &builtin[sizeof_builtin]; bp++) { X sprintf(buf, "%5ld %s\n", bp->reference, bp->name); X trace_log(buf); X } X} Xchar * Xc_string(str) Xregister char *str; X{ X static char buf[256]; X register char *bp = buf; X if (dflag == 0) X return str; X while (*str) { X if (*str == '\n') *bp++ = '\\', *bp++ = 'n'; X else if (*str == '\r') *bp++ = '\\', *bp++ = 'r'; X else if (*str == '\t') *bp++ = '\\', *bp++ = 't'; X else if (*str == '\\') *bp++ = '\\', *bp++ = '\\'; X else X *bp++ = *str; X str++; X if (bp > &buf[sizeof buf - 10]) { X *bp++ = '.'; X *bp++ = '.'; X *bp++ = '.'; X break; X } X } X *bp = NULL; X return buf; X} Xtrace_acc() X{ static long old_acc = -1234567; X if (dflag == 0) X return; X if (acc_type == F_INT) { X if (old_acc != accumulator) X trace_ilog(" ACC = %ld\n", accumulator); X old_acc = accumulator; X } X else if (acc_type == F_STR) { X old_acc = -1234567; X trace_ilog(" SACC = '%s'\n", c_string(saccumulator)); X } X else { X if (saccumulator == NULL) X trace_ilog (" LACC = NIL\n"); X else { X trace_ilog (" LACC = "); X trace_list((LIST *) saccumulator); X } X } X} SHAR_EOF chmod 0444 ./debug.c || echo "restore of ./debug.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./display.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./display.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 1989 [PDF] Improved performance when updating X * screen. X * X **************************************************************/ X X#include "list.h" X X# define trace_log(a,b) /* Turn off debugging here. */ XSCCSID("@(#) display.c 1.16, (C) P. Fox"); X# define V_CHANGE 0x01 X X/*---------------------------------------- X/* Following #define's are expressions X/* which return 1 or 0 depending on X/* whether certain of the 4 window X/* borders are on or not. X/*----------------------------------------*/ X# define LBORDERS(wp) (wp->w_tiled == W_POPUP || \ X border_flag || \ X wp->w_x > 1) X# define RBORDERS(wp) (wp->w_tiled == W_POPUP || \ X border_flag || \ X wp->w_x + wp->w_w < ncol-3) X# define TBORDERS(wp) (1) X# define BBORDERS(wp) (wp->w_tiled == W_POPUP || \ X (wp->w_y + wp->w_h != nrow -1) || \ X border_flag) X Xint updating = 0; Xextern int border_flag; Xextern int imode; Xextern int start_line, start_col; Xextern int end_line, end_col; Xextern int mark_type; Xstatic int tl; Xstatic int mark_areas; /* TRUE if should mark current window. */ Xint pchar_buf[10]; /* Printable character buffer. */ Xextern unsigned char _chars_[256]; Xstatic char hex_digits[] = "0123456789ABCDEF"; Xextern int base_flag; XWINDOW *wp; Xstatic WINDOW *current_window; X Xstatic BYTE vt_color; X Xextern char *echo_line; Xint sgarbf = TRUE; /* TRUE if screen is garbage. */ Xu_int16 vtrow = 0; /* Virtual cursor row. */ Xu_int16 vtcol = 0; /* Virtual cursor column. */ Xu_int16 ttrow = HUGE; /* Physical cursor row. */ Xu_int16 ttcol = HUGE; /* Physical cursor column. */ Xu_int16 tttop = HUGE; /* Top of scroll region. */ Xu_int16 ttbot = HUGE; /* Bottom of scroll region. */ X XBYTE **vscreen; XBYTE **pscreen; XBYTE *video; /* Actual screen data. */ XBYTE *blanks; /* Blank line image. */ Xint *vflags; /* Array of flags. */ XBYTE *vp; X Xvoid vtputs(); Xvoid vtupdate(); Xvoid vtputl(); Xvoid ucopy(); Xvoid draw_title(); Xvoid uline(); Xstatic int window_indent; /* Indent from start of line for sideways scrolling. */ Xstatic int indent; /* Indent from start of line for sideways scrolling. */ X/* X * Initialize the data structures used X * by the display code. The edge vectors used X * to access the screens are set up. The operating X * system's terminal I/O channel is set up. Fill the X * "blanks" array with ASCII blanks. The rest is done X * at compile time. The original window is marked X * as needing full update, and the physical screen X * is marked as garbage, so all the right stuff happens X * on the first call to redisplay. X */ Xvoid Xvtinit() X{ X X vt_color = FG(col_table.c_normal); X char_width_init(); X X ttinit(); X ttopen(); X vtinit1(); X} Xvtinit1() X{ X register int i; X X if (video) { X chk_free(video); X chk_free(vscreen); X chk_free(pscreen); X chk_free(vflags); X chk_free(blanks); X chk_free(echo_line); X } X video = (BYTE *) chk_alloc(sizeof (BYTE) * 2 * nrow * ncol); X vscreen = (BYTE **) chk_alloc(sizeof (BYTE *) * nrow); X pscreen = (BYTE **) chk_alloc(sizeof (BYTE *) * nrow); X vflags = (int *) chk_alloc(sizeof (int) * nrow); X blanks = (BYTE *) chk_alloc(sizeof (BYTE) * ncol); X echo_line = chk_alloc(ncol + 1); X X if (video == NULL || vscreen == NULL || pscreen == NULL || X echo_line == NULL || blanks == NULL || vflags == NULL) X panic("Cannot allocate screen buffer."); X X vtblanks(); X for (i = 0; i < nrow; ++i) { X vflags[i] = 0; X vscreen[i] = video + (2 * i * ncol); X pscreen[i] = vscreen[i] + ncol; X } X vp = vscreen[0]; X} Xvtblanks() X{ register int i; X BYTE normal_space = (BYTE) (FG(col_table.c_normal) | ' '); X for (i = 0; i < ncol; ) X blanks[i++] = normal_space; X X} X X/* X * Tidy up the virtual display system X * in anticipation of a return back to the host X * operating system. Right now all we do is position X * the cursor to the last line, erase the line, and X * close the terminal channel. X */ Xvoid Xvttidy() X{ X ttmove(nrow-1, (u_int16) 0); X ttputc(FG(col_table.c_normal)); X tteeol(); X tttidy(); X ttflush(); X ttclose(); X} X X/* X * Move the virtual cursor to an origin X * 0 spot on the virtual display screen. X */ Xvoid Xvtmove(row, col) X{ X if (row > nrow) X row = nrow; X if (col >= ncol - 1) X col = ncol - 1; X vtrow = (u_int16) row; X vtcol = (u_int16) col; X vp = vscreen[vtrow]; X} X X/* X * Write a character to the virtual display. X */ X# define vtputc(c) { if (vtcol < ncol) VTPUTC(c); } Xvoid XVTPUTC(c) Xregister int c; X{ int attr; X X# define ADDC(ch) indent ? indent-- : (vp[vtcol++] = ch) X X if (_chars_[c & 0xff] & 0x08) { X ADDC(c); X return; X } X X attr = c & COLOR_MASK; X c &= 0xff; X if (c != '\t') { X int right_edge; X int *cp; X int i; X if ((i = printable_char(c | attr)) == 1) { X ADDC(pchar_buf[0]); X return; X } X right_edge = wp->w_x + wp->w_w; X for (cp = pchar_buf; i-- > 0 && vtcol < right_edge; ) X ADDC(*cp++ | attr); X return; X } X {int i = vtcol + window_indent - indent; X int w_x = wp->w_x - !LBORDERS(wp); X int ch_width; X int ch; X int right; X X ch_width = next_tab_stop(i - w_x + 1) + w_x - i; X ch = (BYTE) (' ' | attr); X right = w_x + wp->w_w; X X if (ch_width + vtcol >= right) X ch_width = right - vtcol; X while (ch_width-- > 0) X ADDC(ch); X return; X } X X} Xprintable_char(c1) X{ register int c = c1 & 0xff; X X pchar_buf[0] = c1; X if (_chars_[c] & 0x08) X return 1; X X if (base_flag == 0 && pt.pt_character[0]) { X if (c < ' ') X pchar_buf[0] = (BYTE) (c1 | 0x80); X return 1; X } X if (base_flag == 0 && c < ' ') { X BYTE attr = c1 & 0xff00; X extern char *ctrl_chars[]; X extern char char_width_tbl[]; X char *cp = ctrl_chars[c]; X int i; X int w = char_width_tbl[c]; X for (i = 0; i < w; ) X pchar_buf[i++] = attr | *cp++; X return w; X } X pchar_buf[0] = '\\'; X if (base_flag < 2) { X pchar_buf[1] = 'x'; X pchar_buf[2] = hex_digits[(c >> 4) & 0x0f]; X pchar_buf[3] = hex_digits[c & 0x0f]; X } X else { X pchar_buf[1] = hex_digits[(c >> 6) & 3]; X pchar_buf[2] = hex_digits[(c >> 3) & 7]; X pchar_buf[3] = hex_digits[c & 7]; X } X return 4; X} X X/* X * Erase from the end of the X * software cursor to the end of the X * line on which the software cursor is X * located. The display routines will decide X * if a hardware erase to end of line command X * should be used to display this. X */ Xvoid Xvteeol() X{ X register BYTE *bp; X register u_int16 col = ncol; X int color = FG(col_table.c_normal); X BYTE normal_space = color | ' '; X X col = wp->w_x + wp->w_w; X bp = &vp[vtcol]; X while (vtcol < col) X vtcol++, *bp++ = normal_space; X if (RBORDERS(wp)) { X vtputc(CH_VERTICAL | color); X } X X} X X/* X * Make sure that the display is X * right. This is a three part process. First, X * scan through all of the windows looking for dirty X * ones. Check the framing, and refresh the screen. X * Second, make sure that "currow" and "curcol" are X * correct for the current window. Third, make the X * virtual and physical screens the same. X */ Xupdate() X{ X register BYTE *vp1; X register BYTE *vp2; X register int i; X extern int display_enabled; X X if (updating || !display_enabled) X return; X updating++; X if (typeahead()) { X updating--; X return; X } X X current_window = curwp; X X if (sgarbf) /* must update everything */ X for (wp = wheadp; wp; wp = wp->w_wndp) X wp->w_flag |= WFHARD; X else if (curbp->b_anchor && curbp->b_anchor->a_type == MK_COLUMN) X curwp->w_flag |= WFHARD; X for (wp = wheadp; wp; wp = wp->w_wndp) { X WINDOW *wp1; X if (wp->w_flag) { X upd_update(wp); X /*---------------------------------------- X /* Dirty all windows after this, cos this X /* could be a process window and we may X /* obscure the current window. X /*----------------------------------------*/ X for (wp1 = wp->w_wndp; wp1; wp1 = wp1->w_wndp) X wp1->w_flag |= WFHARD; X } X wp->w_old_line = wp->w_line; X wp->w_mined = wp->w_maxed = 0; X wp->w_flag = 0; X } X X if (sgarbf) { /* Screen is garbage. */ X epresf = FALSE; /* the message area. */ X tttop = HUGE; /* Forget where you set */ X ttbot = HUGE; /* scroll region. */ X ttclear(); X echo_line[0] = NULL; X for (i=0; i<nrow-1; ++i) { X vflags[i] = 0; X uline(i, vscreen[i], &blanks); X ucopy(vscreen[i], pscreen[i]); X } X } X else { X for (i=0; i<nrow-1; ++i) { X if (vflags[i] & V_CHANGE) { X vp1 = vscreen[i]; X vp2 = pscreen[i]; X uline(i, vp1, vp2); X ucopy(vp1, vp2); X } X vflags[i] = 0; X } X } X line_col(sgarbf); X set_cursor(); X sgarbf = FALSE; /* Erase-page clears */ X updating--; X} Xupd_update(wp) Xregister WINDOW *wp; X{ int old_line = wp->w_old_line; X register int line = wp->w_line; X register int top = wp->w_top_line; X int height = wp->w_h; X int half_height; X int bborder = BBORDERS(wp); X int bottom = wp->w_y + wp->w_h + !bborder; X int flag; X int scrolled = FALSE; X X trace_log("nrow=%d ", nrow); X trace_log("w_flag=0x%02x ", wp->w_flag); X trace_log("w_y=%d ", wp->w_y); X trace_log("w_h=%d ", wp->w_h); X trace_log("w_top_line=%d ", top); X trace_log("w_line=%d ", line); X trace_log("bottom=%d\n", bottom); X if (!bborder) X height--; X half_height = height / 2; X /*--------------------------------------- X * Sideways scrolling check. X *---------------------------------------*/ X window_indent = wp->w_indent; X if (wp->w_col - wp->w_indent > wp->w_w) { X if ((wp->w_indent = wp->w_col - wp->w_w) < 0) X wp->w_indent = 0; X } X else if (wp->w_col <= wp->w_indent) { X if ((wp->w_indent = wp->w_col - 1) < 0) X wp->w_indent = 0; X } X if (window_indent != wp->w_indent) { X wp->w_flag |= WFHARD; X window_indent = wp->w_indent; X } X indent = window_indent; X X if (top < 1) X top = wp->w_top_line = 1; X X flag = wp->w_flag; X# if 1 X# define WORTHIT (wp->w_w == ncol - 2) X# else X /************************************************************************ X * This definition means that window must be at least half * X * screen wide in order to do scrolling. However, it can cause * X * display bugs in that another window maybe destroyed in doing * X * that. I cant work out an easy fix, so we'll use the above * X * definition that only allows us to do scrolling if window is * X * full width. * X ************************************************************************/ X# define WORTHIT (wp->w_w > ncol / 2 + 1) X# endif X if (line < top && line > top - half_height && X old_line == top && WORTHIT && X ttinsl(wp->w_y+1, bottom - !bborder, top - line)) { X int diff = top - line; X int j; X scrolled = TRUE; X wp->w_top_line = line; X for (j = 0; j++ < diff; ) { X upd_scroll_down(wp->w_y+2, pscreen, bottom); X upd_scroll_down(wp->w_y+2, vscreen, bottom); X } X if ((flag & (WFHARD|WFEDIT)) == 0) { X int i = wp->w_y + TBORDERS(wp); X vtupdate(i, wp->w_line, i + diff, FALSE); X return TRUE; X } X } X else if (line >= top + height && X line - old_line < half_height && X line < top + height + half_height && WORTHIT && X ttdell(wp->w_y+1, bottom - !bborder, line - top - height + 1)) { X int diff = line - top - height; X int j; X wp->w_top_line += diff + 1; X scrolled = TRUE; X for (j = 0; j++ <= diff; ) { X upd_scroll_up(wp->w_y+1, pscreen, bottom); X upd_scroll_up(wp->w_y+1, vscreen, bottom); X } X if ((flag & (WFHARD|WFEDIT)) == 0) { X int i = wp->w_y + TBORDERS(wp) + X wp->w_line - wp->w_top_line; X vtupdate(i - diff, wp->w_line - diff, i, FALSE); X return TRUE; X } X } X else if (!(line >= top && line < top + height)) { X int rel_line = old_line - top; X if (rel_line < 0) X wp->w_top_line = wp->w_line; X else if ((wp->w_top_line = line - rel_line) < 1) X wp->w_top_line = 1; X if (line >= wp->w_top_line + height) X wp->w_top_line = line - height + bborder; X flag |= WFHARD; X } X else if (flag & WFDELL) { X if (flag == WFDELL && WORTHIT) { X int rel_line = line - top + 1; X int diff, j, i; X ttdell(wp->w_y + rel_line, bottom, 1); X diff = bottom - rel_line; X scrolled = TRUE; X upd_scroll_up(wp->w_y+rel_line, pscreen, bottom); X upd_scroll_up(wp->w_y+rel_line, vscreen, bottom); X i = bottom + TBORDERS(wp) - 1 - !bborder; X# define XX top + bottom - wp->w_y - 1 - !bborder X for (j = 0; j < nrow; j++) X vflags[j] = TRUE; X vtupdate(i, XX, i, FALSE); X return TRUE; X } X flag |= WFHARD; X } X X if (flag & WFHARD) { X trace_log("upd_update: WFHARD\n", (char *) NULL); X vtupdate(wp->w_y + 1, wp->w_top_line, X wp->w_y+height, TRUE); X } X else if (flag & WFEDIT) { X int i = wp->w_y + 1 - wp->w_top_line; X int mined = wp->w_mined; X int maxed = wp->w_maxed; X X trace_log("upd_update: WFEDIT\n", (char *) NULL); X if (mined < wp->w_top_line) X mined = wp->w_top_line; X if (maxed >= wp->w_top_line + wp->w_h) X maxed = wp->w_top_line + wp->w_h - 1; X vtupdate(i + mined, mined, i + maxed, FALSE); X } X return scrolled; X} Xupd_scroll_down(end, screen, bottom) XBYTE **screen; X{ register BYTE **bp = &screen[bottom]; X register BYTE *bp1 = *bp; X register int i; X for (i = bottom; i >= end; i--) { X bp[0] = bp[-1]; X bp--; X } X *bp = bp1; X ucopy(blanks, bp1); X} Xupd_scroll_up(end, screen, bottom) XBYTE **screen; X{ register BYTE **bp = &screen[end]; X register BYTE *bp1 = *bp; X register int i; X X for (i = end; i < bottom; i++) { X bp[0] = bp[1]; X bp++; X } X if (screen == vscreen) { X int *ip = &vflags[end]; X for (i = end+1; i < bottom; i++) { X ip[0] = ip[1]; X ip++; X } X *ip = 0; X } X *bp = bp1; X ucopy(blanks, bp1); X} Xset_cursor() X{ X register u_int16 currow; X register u_int16 curcol; X u_int16 c; X print_cursor(imode); X currow = curwp->w_y + (curwp->w_line - curwp->w_top_line) + 1; X curcol = curwp->w_col - 1 - curwp->w_indent; X X if (curcol >= ncol) X curcol = ncol-1; X X c = curcol + curwp->w_x; X if (curwp->w_indent == 0) X c -= !LBORDERS(curwp); X ttmove(currow, c > curwp->w_x + curwp->w_w ? X (u_int16) curwp->w_x + curwp->w_w : c); X ttflush(); X} Xvoid Xucopy(vvp, pvp) Xregister BYTE *vvp; Xregister BYTE *pvp; X{ X register struct s80 {BYTE b[80];} *sp1, *sp2; X int n = ncol; X X sp1 = (struct s80 *) vvp; X sp2 = (struct s80 *) pvp; X X while (n >= 80) { X *sp2++ = *sp1++; X n -= 80; X } X if (n) X memcpy((char *) sp2, (char *) sp1, sizeof (BYTE) * n); X} X/*---------------------------------------- X/* Following two routines try to avoid X/* moving cursor until absolutely necessary. X/*----------------------------------------*/ Xstatic int ucol = -1; Xstatic int urow = -1; X Xvoid Xuputc(x) XBYTE x; X{ X if (ucol >= 0) { X ttmove((u_int16) urow, (u_int16) ucol); X ucol = -1; X } X if (x) X ttputc(x); X} Xvoid Xumove(row, col) Xu_int16 row, col; X{ X ucol = col; X urow = row; X} X Xvoid Xuline(row, vvp, pvp) XBYTE *vvp; XBYTE *pvp; X{ X register int i; X register int right, left; X register BYTE *leftv = vvp; X register BYTE *bp = pvp; X register BYTE *rightv; X register BYTE *cp5; X BYTE normal_space; X register int nbflag; X BYTE space; X int cleared_line = FALSE; X X for (i = ncol; --i > 0 && *leftv == *bp; ) X leftv++, bp++; X if (i == 0) /* All equal. */ X return; X rightv = &vvp[ncol]; X X bp = &pvp[ncol]; /* Compute right match. */ X nbflag = FALSE; X while (rightv[-1] == bp[-1]) { X --bp; X if (*--rightv != ' ') /* Note non-blanks in */ X nbflag = TRUE; /* the right match. */ X } X X cp5 = rightv; /* Is erase good? */ X if (nbflag == FALSE) { X while (cp5 != leftv && cp5[-1] == ' ') X --cp5; X if ((int)(rightv-cp5) <= tceeol) X cp5 = rightv; X } X X umove((u_int16) row, (u_int16)(leftv - vvp)); X normal_space = (BYTE) ((col_table.c_normal << FG_SHIFT) | ' '); X X left = leftv - vvp; X right = cp5 - vvp; X while (left < right) { X register BYTE *vp = &vvp[left]; X register BYTE *pp = &pvp[left]; X register int n = 0; X register int bytes = right - left; X while (bytes-- > 0) { X if (*vp++ != *pp++) X break; X n++; X } X if (n > 8) { X left += n; X umove((u_int16) row, left); X continue; X } X if ((vvp[left] & 0xff) != ' ') { X uputc(vvp[left++]); X continue; X } X space = vvp[left]; X for (i = 0; vvp[left] == space && left != right; ) X left++, i++; X if (i > 2 && (cleared_line || (sgarbf && space == normal_space))) { X umove((u_int16) row, (u_int16)left); X } X else if (!pt.pt_color && space == normal_space && i > 10 && i > ncol - right) { X /*---------------------------------------- X /* Can only delete to end of line if X /* we aren't a color screen cos otherwise X /* we may clear to end of line with the X /* background color set. X /*----------------------------------------*/ X register BYTE *pp1, *ppend; X right = ncol; X uputc((BYTE) 0); X tteeol(); X for (pp1 = &pvp[left], ppend = &pvp[right]; pp1 < ppend; ) X *pp1++ = space; X umove((u_int16) row, (u_int16)left); X cleared_line = TRUE; X } X else { X uputc((BYTE) 0); X ttspace(i, space, FALSE); X } X } X uputc((BYTE) 0); X ucol = -1; X} X X Xvoid Xvtputs(s, col) Xregister unsigned char *s; X{ X X for (; *s != NULL; s++) X vtputc(*s | col); X} Xvoid Xvtleft(i, x) X{ X vtmove(i, x); X if (x != 0 || LBORDERS(wp)) { X vtputc(CH_VERTICAL | FG(col_table.c_normal)); X } X} Xvoid Xvtupdate(i, line, n, redraw) X{ register int x = wp->w_x - 1; X WINDOW *saved_wp = curwp; X BUFFER *saved_bp = curbp; X X mark_areas = curwp == wp; X curwp = wp; X curbp = wp->w_bufp; X if (curbp && mark_areas && (mark_areas = get_marked_areas(wp))) X start_col--, end_col--; X tl = line; X X X if (redraw && wp->w_ttitle) X draw_title(TRUE, wp->w_y, wp); X for (; i <= n; i++) { X vflags[i] = V_CHANGE; X indent = 0; X vtleft(i, x); X indent = window_indent; X if (curbp && line <= wp->w_bufp->b_numlines) { X LINE *lp = vm_lock_line(line); X vtputl(lp); X tl++; X vm_unlock(line); X line++; X } X vteeol(); X } X curwp = saved_wp; X curbp = saved_bp; X if (redraw && wp->w_btitle && BBORDERS(wp)) { X line = wp->w_y + wp->w_h + BBORDERS(wp); X if (line == nrow-2 || wp->w_popup) X draw_title(FALSE, line, wp); X } X} Xvoid Xdraw_title(top, line, wp) XWINDOW *wp; X{ register unsigned char *cp = (unsigned char *) X (top ? wp->w_ttitle : wp->w_btitle); X int denom = 0, i, j; X int l = cp ? strlen(cp) : 0; X unsigned char buf[128]; X extern int b_level; X int digits; X int ch; X int col = FG(col_table.c_normal); X X indent = 0; X if (l == 0) X i = wp->w_w; X else { X if ((denom = wp->w_w - l - 2) < 0) { X strcpy(buf, cp); X cp = buf; X buf[wp->w_w-2] = NULL; X i = 0; X } X else X i = denom / 2; X } X X vtmove(line, wp->w_x-1); X digits = (b_level > 1 && vtrow == nrow - 2) X ? (b_level > 9 ? 2 : 1) : 0; X vflags[line] = V_CHANGE; X X ch = col | (top ? CH_TOP_LEFT : CH_BOT_LEFT); X vtputc(ch); X if (digits) X j = i - digits + 1; X else X j = i; X X ch = CH_HORIZONTAL | col; X while (j-- > 0) X vtputc(ch); X X if (l) { X ch = col | ' '; X vtputc(ch); X vtputs(cp, wp == current_window ? FG(col_table.c_select) : col); X vtputc(ch); X } X else X i = 0; X X ch = CH_HORIZONTAL | col; X for (j = i + (denom & 1); j-- > 0; ) X vtputc(ch); X if (digits) { X char buf[4]; X sprintf(buf, "%d", b_level); X vtputs(buf, col); X } X else { X ch = col | (top ? CH_TOP_RIGHT : CH_BOT_RIGHT); X vtputc(ch); X } X} Xvoid Xvtputl(lp) Xregister LINE *lp; X{ int attr = FG(col_table.c_normal); X u_int16 ch; X register u_int16 col = ncol; X register u_char *cp = lp->l_text; X register u_char *cpend = cp + llength(lp); X int mc; X int dc; X int column; X int fg = col_table.c_fg << FG_SHIFT; X int bg = col_table.c_bg << BG_SHIFT; X X fg |= bg; X X indent = window_indent; X col = wp->w_x + wp->w_w; X if (!RBORDERS(wp)) X col += 1; X X if (!mark_areas || tl < start_line || tl > end_line) { Xno_change: X column = ncol < col ? ncol : col; X for (; vtcol < column; cp++) { X if (cp >= cpend) { X vtputc(' ' | attr); X continue; X } X ch = *cp; X# if 1 X if (ch == 0x1b && curbp->b_flag & BFANSI) { X int inc = vtgetcolor(cp+1, cpend, attr); X if (inc) { X cp += inc; X if (mark_areas && !(tl < start_line || tl > end_line)) { X bg = (vt_color & BG_COLOR) >> BG_SHIFT; X fg = (vt_color & FG_COLOR) >> FG_SHIFT; X attr = (bg << FG_SHIFT) | (fg << BG_SHIFT); X } X else X attr = vt_color; X continue; X } X } X# endif X vtputc(ch | attr); X } X return; X } X X X if (mark_type == MK_LINE || X (tl > start_line && tl < end_line && mark_type != MK_COLUMN)) { X attr = fg; X goto no_change; X } X X mc = start_col + wp->w_x - window_indent; X dc = end_col + wp->w_x - window_indent; X column = ncol < col ? ncol : col; X cp = lp->l_text; X X for (; vtcol < column; cp++) { X int ch_width = 1; X int mask; X X ch = cp < cpend ? *cp : ' '; X if (ch == 0x1b) { X int inc = vtgetcolor(cp+1, cpend, attr); X if (inc) { X cp += inc; X attr = vt_color; X continue; X } X } X if (ch == '\t') { X int i = vtcol + window_indent - indent; X ch_width = next_tab_stop(i - wp->w_x + 1) + wp->w_x - i; X if (ch_width + vtcol >= col) X ch_width = col - vtcol; X ch = ' '; X } X while (ch_width-- > 0) { X if ((tl == start_line && tl == end_line) || mark_type == MK_COLUMN) X mask = (vtcol < mc) ? attr : X (vtcol <= dc) ? fg : attr; X else if (tl == start_line) /* This line is start of mark. */ X mask = (vtcol < mc) ? attr : fg; X else /* This line is end of mark. */ X mask = (vtcol <= dc) ? fg : attr; X vtputc(ch | mask); X } X } X} X/*---------------------------------------- X/* Following array maps ANSI colors to BRIEFs. X/*----------------------------------------*/ Xint ab_color_map[8] = {0, 4, 2, 6, 1, 5, 3, 7}; Xint ba_color_map[8] = {0, 4, 2, 6, 1, 5, 3, 7}; X Xvtgetcolor(cp, cpend, attr) Xregister u_char *cp, *cpend; X{ u_char *start = cp; X DISPLAY dp; X int ch; X int bold = vt_color & FG(8); X int fg = (vt_color & FG_COLOR) >> FG_SHIFT; X int bg = (vt_color & BG_COLOR) >> BG_SHIFT; X X dp.d_escptr = dp.d_escape; X dp.d_attr = bold ? 1 : 0; X fg = ba_color_map[fg]; X bg = ba_color_map[bg]; X dp.d_color = attr; X for ( ; cp < cpend; cp++) { X ch = *cp; X *dp.d_escptr++ = ch; X if (isalpha(ch)) { X if (ch != 'm') X return 0; X *dp.d_escptr = NULL; X p_escape(&dp, FALSE); X vt_color = dp.d_color; X if (dp.d_attr & 1) X bold = FG(8); X else X bold = 0; X vt_color |= bold; X return cp - start + 1; X } X } X return 0; X X} Xscreen_dump() X{ char *filename = get_str(1); X FILE *fp; X register int line, col; X BYTE *lineptr; X X if (filename == NULL || *filename == NULL) X filename = "/tmp/crisp.screen"; X X if ((fp = fopen(filename, "w")) == NULL) { X accumulator = -1; X return; X } X for (line = 0; line < nrow-1; line++) { X lineptr = vscreen[line]; X for (col = 0; col < ncol; col++) { X int c = lineptr[col] & 0xff; X switch (c) { X case CH_HORIZONTAL: c = '-'; break; X case CH_VERTICAL: c = '|'; break; X case CH_TOP_LEFT: X case CH_TOP_RIGHT: X case CH_BOT_LEFT: X case CH_BOT_RIGHT: X case CH_TOP_JOIN: X case CH_BOT_JOIN: X case CH_LEFT_JOIN: X case CH_RIGHT_JOIN: X case CH_CROSS: X c = '+'; X break; X } X fputc(c, fp); X } X fputc('\n', fp); X } X X accumulator = 0; X fclose(fp); X} SHAR_EOF chmod 0444 ./display.c || echo "restore of ./display.c fails" mkdir . >/dev/null 2>&1 echo "x - extracting ./echo.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ./echo.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# include "alt.h" X# include <time.h> X X XSCCSID("@(#) echo.c 1.13, (C) P. Fox"); X# define EBUFSIZ 512 X X# define E_LINE 0x01 /* Line: .. */ X# define E_COL 0x02 /* Col: .. */ X# define E_PERCENT 0x04 /* nn% */ X# define E_TIME 0x08 /* hh:mm a/pm */ X# define E_REMEMBER 0x10 /* RE / PA String. */ X# define E_CURSOR 0x20 /* IN / OV cursor type. */ Xint echo_flags = E_CURSOR | E_LINE | E_COL | E_REMEMBER | E_TIME; X X# define ARG_LIST x1, x2, x3, x4, x5, x6, x7, x8, x9, x10 X# define LSIZE ncol /* Echo line size. */ X# define LCOL (LSIZE - 31) X /* Position of 'Line: ..' */ Xint epresf = FALSE; /* Stuff in echo line flag. */ Xstatic u_int16 ecol = 0; /* Current echo line column. */ Xchar *echo_line; Xint prompting = FALSE; Xint prompt_len = 0; /* Length of prompt - so we can skip */ X /* prompt in (inq_cmd_line). */ Xint pcolor = CMESSAGE; /* Used by (error) */ X Xextern int imode; X Xvoid ewputs(); Xvoid eputc(); Xvoid eerase(); Xvoid ewprintf(); Xvoid eclear(); X/* X * Ask "yes" or "no" question. X * Return ABORT if the user answers the question X * with the abort ("^G") character. Return FALSE X * for "no" and TRUE for "yes". No formatting X * services are available. No newline required. X */ Xeyorn(sp) Xchar *sp; X{ X register KEY s; X X ewprintf("%s? (y or n) ", sp); X for (;;) { X s = getkey(); X if (s == 'y' || s == 'Y') return (TRUE); X if (s == 'n' || s == 'N') return (FALSE); X if (s == '\033') X return ABORT; X ewprintf("Please answer y or n. %s? (y or n) ", sp); X } X} X X/* X * Like eyorn, but for more important question. User must type either all of X * "yes" or "no", and the trainling newline. X */ Xeyesno(sp) Xchar *sp; X{ X register int s; X char buf[64]; X X s = ereply("%s? (yes or no) ", buf, sizeof(buf), sp); X for (;;) { X if (s == ABORT) return ABORT; X if (s != FALSE) { X if ((buf[0] == 'y' || buf[0] == 'Y') X && (buf[1] == 'e' || buf[1] == 'E') X && (buf[2] == 's' || buf[2] == 'S')) return TRUE; X if ((buf[0] == 'n' || buf[0] == 'N') X && (buf[1] == 'o' || buf[0] == 'O')) return FALSE; X } X s = ereply("Please answer yes or no. %s? (yes or no) ", X buf, sizeof(buf), sp); X } X} Xvoid Xprint_cursor(insert_mode) X{ extern int virtual_space; X static int old_mode = -2; X static int old_space = -2; X X if (pt.pt_icursor[0] == NULL) X return; X set_hooked(); X current_offset(curwp->w_col, FALSE); X if (old_space == virtual_space && insert_mode == old_mode) X return; X X if (insert_mode) X putpad(virtual_space ? pt.pt_vicursor : pt.pt_icursor); X else X putpad(virtual_space ? pt.pt_vocursor : pt.pt_ocursor); X old_mode = insert_mode; X old_space = virtual_space; X} X/* X * Write out a prompt, and read back a X * reply. The prompt is now written out with full "ewprintf" X * formatting, although the arguments are in a rather strange X * place. This is always a new message, there is no auto X * completion, and the return is echoed as such. X */ Xereply(fp, buf, nbuf, ARG_LIST) Xchar *fp; Xchar *buf; X{ char prompt[EBUFSIZ]; X X sprintf(prompt, fp, ARG_LIST); X return ereply1(prompt, (char *) NULL, buf, nbuf); X} Xedefreply(fp, defstr, buf, nbuf, ARG_LIST) Xchar *fp; Xchar *defstr; Xchar *buf; X{ char prompt[EBUFSIZ]; X X sprintf(prompt, fp, ARG_LIST); X return ereply1(prompt, defstr, buf, nbuf); X} Xereply1(fp, defstr, buf, nbuf) Xchar *fp; Xchar *defstr; Xchar *buf; X{ int ret; X char pbuf[EBUFSIZ + 20]; X extern int dflag; X int saved_dflag = dflag; X int dflag1 = dflag; X X X if (dflag && (dflag & DB_PROMPT) == 0) X dflag1 = 0; X X prompt_len = estrlen(fp); X ewputs(fp, defstr); X sprintf(pbuf, "_prompt_begin \"%s\"", fp); X X dflag = dflag1; X str_exec(pbuf); X dflag = saved_dflag; X X ret = ereply2(fp, defstr, buf, nbuf); X dflag = dflag1; X str_exec("_prompt_end"); X X set_hooked(); X X dflag = saved_dflag; X return ret; X X} Xereply2(prompt, defstr, buf, nbuf) Xchar *prompt; Xchar *defstr; Xchar *buf; X{ register int cpos, bpos; X register KEY c; X char *def = NULL; X u_int16 startcol = estrlen(prompt); X int insert_mode = TRUE; X u_int16 n; X char *cp; X int first_key = TRUE; X int left = 0; X X prompting = TRUE; X print_cursor(insert_mode); X bpos = 0; X buf[0] = NULL; X if (defstr == NULL) X defstr = ""; X strcpy(buf, defstr); X for (;;) { X c = getkey(); X if (first_key && X (c == 0x7f || c == CTRL_H || X c == KEY_WLEFT || c == KEY_WRIGHT || X c == KEY_HOME || c == KEY_END || X c == KEY_LEFT || c == KEY_RIGHT)) { X if (nbuf == 1) { X buf[0] = (char) c; X buf[1] = NULL; X prompting = FALSE; X return TRUE; X } X strcpy(buf, defstr); X bpos = strlen(buf); X cpos = estrlen(defstr); X ewputs(prompt, (char *) NULL); X for (cp = buf; *cp; cp++) X eputc1(*cp); X ttflush(); X } X else X if (first_key && c != 0x0D) { X ttmove(nrow-1, ecol = startcol); X while (ecol < LCOL - 1) X eputc1(' '); X buf[bpos = 0] = NULL; X cpos = position_prompt(buf, startcol, bpos, &left); X } X defstr = ""; X first_key = FALSE; X if (nbuf == 1 && c != 0x1b) { X buf[0] = (char) c; X buf[1] = NULL; X goto done; X } X switch (c) { X case 0x0D: /* Return, done. */ X goto done; X X case ALT_H: X trigger(REG_ALT_H); /* Fall into.... */ X case '\033': Xcancel: X print_cursor(imode); X ewprintf("Command cancelled."); X prompting = FALSE; X return (ABORT); X X case '\t': X case ALT_L: X case KEY_DOWN: X case KEY_UP: X push_back1(c); X trigger(REG_INVALID); X str_exec("_bad_key"); X if (acc_type != F_STR) X goto cancel; X defstr = saccumulator; X ewputs(prompt, saccumulator); X strncpy(buf, saccumulator, nbuf); X first_key = TRUE; X continue; X X case KEY_WLEFT: X while (isspace(buf[bpos]) && bpos > 0) X bpos--; X while (!isspace(buf[bpos]) && bpos > 0) X bpos--; X cpos = position_prompt(buf, startcol, bpos, &left); X break; X case KEY_WRIGHT: X while (isspace(buf[bpos]) && buf[bpos]) X bpos++; X while (!isspace(buf[bpos]) && buf[bpos]) X bpos++; X cpos = position_prompt(buf, startcol, bpos, &left); X break; X case KEY_RIGHT: X if (buf[bpos]) { X ++bpos; X cpos = position_prompt(buf, startcol, bpos, &left); X } X break; X case KEY_LEFT: X if (bpos > 0) { X --bpos; X cpos = position_prompt(buf, startcol, bpos, &left); X } X break; X case KEY_HOME: X cpos = position_prompt(buf, startcol, bpos = 0, &left); X break; X case KEY_END: X cpos = position_prompt(buf, startcol, bpos = strlen(buf), &left); X break; X case ALT_I: X insert_mode = !insert_mode; X print_cursor(insert_mode); X ttflush(); X break; X X case CCHR('H'): X case 0x7F: /* Rubout, erase. */ X#ifdef APW X if (bpos == 0) X#else X if ((c == CCHR('H') && bpos == 0) || X (c == 0x7f && buf[bpos] == NULL)) X#endif X break; X if (insert_mode) { X#ifndef APW X if (c == CCHR('H')) X#endif X ecol -= printable_char(buf[--bpos]); X if (ecol < startcol) X ecol = startcol; X cp = buf + bpos; X strcpy(cp, cp + 1); X ttmove(nrow-1, ecol); X while (*cp && ecol < LCOL - 1) X eputc1(*cp++); X eclear(); X cpos = position_prompt(buf, startcol, bpos, &left); X ttflush(); X } X else X cpos = position_prompt(buf, startcol, --bpos, &left); X break; X X case ALT_D: X case CCHR('X'): /* C-X */ X case CCHR('U'): /* C-U, kill line. */ X { X ttmove(nrow-1, ecol = startcol); X while (ecol < LCOL - 1) X eputc1(' '); X buf[bpos = 0] = NULL; X cpos = position_prompt(buf, startcol, bpos, &left); X } X break; X X#ifdef APW X case CCHR('Q'): /* C-Q */ X#endif X case ALT_Q: X c = getkey(); X#ifdef APW /* translate c/r to newline */ X if (c == '\r') X c = '\n'; X#endif X default: /* All the rest. */ X if (estrlen(buf) >= nbuf-1) { X ttbeep(); X continue; X } X if (insert_mode) { X char buf1[EBUFSIZ]; X strcpy(buf1, buf+bpos); X strcpy(buf+bpos+1, buf1); X } X else if (buf[bpos] == NULL) X buf[bpos+1] = NULL; X cp = buf + bpos++; X *cp = (char) c; X /*-------------------------------- X * Echo shifted characters. X *--------------------------------*/ X for (; *cp && ecol < LCOL-1; eputc1(*cp++)) X ; X if (!insert_mode) X eclear(); X echo_line[ecol] = NULL; X /*-------------------------------- X * Put cursor back where it was. X *--------------------------------*/ X cpos = position_prompt(buf, startcol, bpos, &left); X } X } Xdone: X prompting = FALSE; X print_cursor(imode); X return TRUE; X} X X Xposition_prompt(buf, startcol, bpos, left) Xchar *buf; Xint *left; X{ X int n, i; X int pos = 0; X X for (i = 0; i < bpos; i++) SHAR_EOF echo "End of part 4" echo "File ./echo.c is continued in part 5" echo "5" > 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