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