Mercurial > hg > Members > kono > nitros9-code
changeset 995:48c646212b1c
'microEMACS' for OS-9.
Posted to USENET net.micro.6809, 4-May-86. Picked up from Google groups
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/README Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,30 @@ +From: jimomura@lsuc.UUCP (Jim Omura) +Newsgroups: net.micro.6809 +Subject: MicroEMACS OS-9 Part 1 of 7 +Message-ID: <1197@lsuc.UUCP> +Date: Sun, 4-May-86 12:51:35 EDT +Article-I.D.: lsuc.1197 +Posted: Sun May 4 12:51:35 1986 +Date-Received: Sun, 4-May-86 15:07:58 EDT +Reply-To: jimomura@lsuc.UUCP (Jim Omura) +Organization: Barrister & Solicitor, Toronto +Lines: 414 +Summary: + + + + These files are the best I could do to get 'microEMACS' for OS-9 +'here'. This is the now legendary Bob Santy/Bob Larson port which time +and luck have conspired to keep out of the hands of most OS-9'ers. +As it is, it's being brought to you from Usenet, to my Color Computer, +to BIX, to Bob Santy, to Bob Larson, to me, to BIX again, to my +Spectravideo CP/M machine, to 'lsuc', to the net. That's only part +of the story and doesn't even go into the *days* I wasted just trying +to upload it from my Color Computer to 'lsuc' and other fiascos. + + Please, someone, use it. That's make me feel much better about +the whole mess. + + Cheers! -- Jim Omura + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/ueansi.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,106 @@ +/* + * The routines in this file provide support for ANSI style terminals + * over a serial line. The serial I/O services are provided by routines in + * "termio.c". It compiles into nothing if not an ANSI device. + */ + +#include <stdio.h> +#include "ueed.h" + +#ifdef ANSI + +#define NROW 23 /* Screen size. */ +#define NCOL 77 /* Edit if you want to. */ +#define BEL 0x07 /* BEL character. */ +#define ESC 0x1B /* ESC character. */ + +extern int ttopen(); /* Forward references. */ +extern int ttgetc(); +extern int ttputc(); +extern int ttflush(); +extern int ttclose(); +extern int ansimove(); +extern int ansieeol(); +extern int ansieeop(); +extern int ansibeep(); +extern int ansiopen(); + +/* + * Standard terminal interface dispatch table. Most of the fields point into + * "termio" code. + */ +TERM term = { + NROW-1, + NCOL, + ansiopen, + ttclose, + ttgetc, + ttputc, + ttflush, + ansimove, + ansieeol, + ansieeop, + ansibeep +}; + +ansimove(row, col) +{ + ttputc(ESC); + ttputc('['); + ansiparm(row+1); + ttputc(';'); + ansiparm(col+1); + ttputc('H'); +} + +ansieeol() +{ + ttputc(ESC); + ttputc('['); + ttputc('K'); +} + +ansieeop() +{ + ttputc(ESC); + ttputc('['); + ttputc('J'); +} + +ansibeep() +{ + ttputc(BEL); + ttflush(); +} + +ansiparm(n) +register int n; +{ + register int q; + + q = n/10; + if (q != 0) + ansiparm(q); + ttputc((n%10) + '0'); +} + +#endif + +ansiopen() +{ +#ifdef V7 + register char *cp; + char *getenv(); + + if ((cp = getenv("TERM")) == NULL) { + puts("Shell variable TERM not defined!"); + exit(1); + } + if (strcmp(cp, "vt100") != 0) { + puts("Terminal type not 'vt100'!"); + exit(1); + } +#endif + ttopen(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uebasic.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,283 @@ +/* + * The routines in this file move the cursor around on the screen. They + * compute a new value for the cursor, then adjust ".". The display code + * always updates the cursor location, so only moves between lines, or + * functions that adjust the top line in the window and invalidate the + * framing, are hard. + */ +#include <stdio.h> +#include "ueed.h" + +/* + * Move the cursor to the + * beginning of the current line. + * Trivial. + */ +gotobol(f, n) +{ + curwp->w_doto = 0; + return (TRUE); +} + +/* + * Move the cursor backwards by "n" characters. If "n" is less than zero call + * "forwchar" to actually do the move. Otherwise compute the new cursor + * location. Error if you try and move out of the buffer. Set the flag if the + * line pointer for dot changes. + */ +backchar(f, n) +register int n; +{ + register LINE *lp; + + if (n < 0) + return (forwchar(f, -n)); + while (n--) { + if (curwp->w_doto == 0) { + if ((lp=lback(curwp->w_dotp)) == curbp->b_linep) + return (FALSE); + curwp->w_dotp = lp; + curwp->w_doto = llength(lp); + curwp->w_flag |= WFMOVE; + } else + curwp->w_doto--; + } + return (TRUE); +} + +/* + * Move the cursor to the end of the current line. Trivial. No errors. + */ +gotoeol(f, n) +{ + curwp->w_doto = llength(curwp->w_dotp); + return (TRUE); +} + +/* + * Move the cursor forwwards by "n" characters. If "n" is less than zero call + * "backchar" to actually do the move. Otherwise compute the new cursor + * location, and move ".". Error if you try and move off the end of the + * buffer. Set the flag if the line pointer for dot changes. + */ +forwchar(f, n) +register int n; +{ + if (n < 0) + return (backchar(f, -n)); + while (n--) { + if (curwp->w_doto == llength(curwp->w_dotp)) { + if (curwp->w_dotp == curbp->b_linep) + return (FALSE); + curwp->w_dotp = lforw(curwp->w_dotp); + curwp->w_doto = 0; + curwp->w_flag |= WFMOVE; + } else + curwp->w_doto++; + } + return (TRUE); +} + +/* + * Goto the beginning of the buffer. Massive adjustment of dot. This is + * considered to be hard motion; it really isn't if the original value of dot + * is the same as the new value of dot. Normally bound to "M-<". + */ +gotobob(f, n) +{ + curwp->w_dotp = lforw(curbp->b_linep); + curwp->w_doto = 0; + curwp->w_flag |= WFHARD; + return (TRUE); +} + +/* + * Move to the end of the buffer. Dot is always put at the end of the file + * (ZJ). The standard screen code does most of the hard parts of update. + * Bound to "M->". + */ +gotoeob(f, n) +{ + curwp->w_dotp = curbp->b_linep; + curwp->w_doto = 0; + curwp->w_flag |= WFHARD; + return (TRUE); +} + +/* + * Move forward by full lines. If the number of lines to move is less than + * zero, call the backward line function to actually do it. The last command + * controls how the goal column is set. Bound to "C-N". No errors are + * possible. + */ +forwline(f, n) +{ + register LINE *dlp; + + if (n < 0) + return (backline(f, -n)); + if ((lastflag&CFCPCN) == 0) /* Reset goal if last */ + curgoal = curcol; /* not C-P or C-N */ + thisflag |= CFCPCN; + dlp = curwp->w_dotp; + while (n-- && dlp!=curbp->b_linep) + dlp = lforw(dlp); + curwp->w_dotp = dlp; + curwp->w_doto = getgoal(dlp); + curwp->w_flag |= WFMOVE; + return (TRUE); +} + +/* + * This function is like "forwline", but goes backwards. The scheme is exactly + * the same. Check for arguments that are less than zero and call your + * alternate. Figure out the new line and call "movedot" to perform the + * motion. No errors are possible. Bound to "C-P". + */ +backline(f, n) +{ + register LINE *dlp; + + if (n < 0) + return (forwline(f, -n)); + if ((lastflag&CFCPCN) == 0) /* Reset goal if the */ + curgoal = curcol; /* last isn't C-P, C-N */ + thisflag |= CFCPCN; + dlp = curwp->w_dotp; + while (n-- && lback(dlp)!=curbp->b_linep) + dlp = lback(dlp); + curwp->w_dotp = dlp; + curwp->w_doto = getgoal(dlp); + curwp->w_flag |= WFMOVE; + return (TRUE); +} + +/* + * This routine, given a pointer to a LINE, and the current cursor goal + * column, return the best choice for the offset. The offset is returned. + * Used by "C-N" and "C-P". + */ +getgoal(dlp) +register LINE *dlp; +{ + register int c; + register int col; + register int newcol; + register int dbo; + + col = 0; + dbo = 0; + while (dbo != llength(dlp)) { + c = lgetc(dlp, dbo); + newcol = col; + if (c == '\t') + newcol |= 0x07; + else if (c<0x20 || c==0x7F) + ++newcol; + ++newcol; + if (newcol > curgoal) + break; + col = newcol; + ++dbo; + } + return (dbo); +} + +/* + * Scroll forward by a specified number of lines, or by a full page if no + * argument. Bound to "C-V". The "2" in the arithmetic on the window size is + * the overlap; this value is the default overlap value in ITS EMACS. Because + * this zaps the top line in the display window, we have to do a hard update. + */ +forwpage(f, n) +register int n; +{ + register LINE *lp; + + if (f == FALSE) { + n = curwp->w_ntrows - 2; /* Default scroll. */ + if (n <= 0) /* Forget the overlap */ + n = 1; /* if tiny window. */ + } else if (n < 0) + return (backpage(f, -n)); +#ifdef CVMVAS + else /* Convert from pages */ + n *= curwp->w_ntrows; /* to lines. */ +#endif + lp = curwp->w_linep; + while (n-- && lp!=curbp->b_linep) + lp = lforw(lp); + curwp->w_linep = lp; + curwp->w_dotp = lp; + curwp->w_doto = 0; + curwp->w_flag |= WFHARD; + return (TRUE); +} + +/* + * This command is like "forwpage", but it goes backwards. The "2", like + * above, is the overlap between the two windows. The value is from the ITS + * EMACS manual. Bound to "M-V". We do a hard update for exactly the same + * reason. + */ +backpage(f, n) +register int n; +{ + register LINE *lp; + + if (f == FALSE) { + n = curwp->w_ntrows - 2; /* Default scroll. */ + if (n <= 0) /* Don't blow up if the */ + n = 1; /* window is tiny. */ + } else if (n < 0) + return (forwpage(f, -n)); +#ifdef CVMVAS + else /* Convert from pages */ + n *= curwp->w_ntrows; /* to lines. */ +#endif + lp = curwp->w_linep; + while (n-- && lback(lp)!=curbp->b_linep) + lp = lback(lp); + curwp->w_linep = lp; + curwp->w_dotp = lp; + curwp->w_doto = 0; + curwp->w_flag |= WFHARD; + return (TRUE); +} + +/* + * Set the mark in the current window to the value of "." in the window. No + * errors are possible. Bound to "M-.". + */ +setmark(f, n) +{ + curwp->w_markp = curwp->w_dotp; + curwp->w_marko = curwp->w_doto; + mlwrite("[Mark set]"); + return (TRUE); +} + +/* + * Swap the values of "." and "mark" in the current window. This is pretty + * easy, bacause all of the hard work gets done by the standard routine + * that moves the mark about. The only possible error is "no mark". Bound to + * "C-X C-X". + */ +swapmark(f, n) +{ + register LINE *odotp; + register int odoto; + + if (curwp->w_markp == NULL) { + mlwrite("No mark in this window"); + return (FALSE); + } + odotp = curwp->w_dotp; + odoto = curwp->w_doto; + curwp->w_dotp = curwp->w_markp; + curwp->w_doto = curwp->w_marko; + curwp->w_markp = odotp; + curwp->w_marko = odoto; + curwp->w_flag |= WFMOVE; + return (TRUE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uebuffer1.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,219 @@ +/* + * Buffer management. + * Some of the functions are internal, + * and some are actually attached to user + * keys. Like everyone else, they set hints + * for the display system. + */ +#include <stdio.h> +#include "ueed.h" + +#ifndef OS9 +/* + * Attach a buffer to a window. The + * values of dot and mark come from the buffer + * if the use count is 0. Otherwise, they come + * from some other window. + */ +usebuffer(f, n) +{ + register BUFFER *bp; + register WINDOW *wp; + register int s; + char bufn[NBUFN]; + + if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE) + return (s); + if ((bp=bfind(bufn, TRUE, 0)) == NULL) + return (FALSE); + if (--curbp->b_nwnd == 0) { /* Last use. */ + curbp->b_dotp = curwp->w_dotp; + curbp->b_doto = curwp->w_doto; + curbp->b_markp = curwp->w_markp; + curbp->b_marko = curwp->w_marko; + } + curbp = bp; /* Switch. */ + curwp->w_bufp = bp; + curwp->w_linep = bp->b_linep; /* For macros, ignored. */ + curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty. */ + if (bp->b_nwnd++ == 0) { /* First use. */ + curwp->w_dotp = bp->b_dotp; + curwp->w_doto = bp->b_doto; + curwp->w_markp = bp->b_markp; + curwp->w_marko = bp->b_marko; + return (TRUE); + } + wp = wheadp; /* Look for old. */ + while (wp != NULL) { + if (wp!=curwp && wp->w_bufp==bp) { + curwp->w_dotp = wp->w_dotp; + curwp->w_doto = wp->w_doto; + curwp->w_markp = wp->w_markp; + curwp->w_marko = wp->w_marko; + break; + } + wp = wp->w_wndp; + } + return (TRUE); +} + +/* + * Dispose of a buffer, by name. + * Ask for the name. Look it up (don't get too + * upset if it isn't there at all!). Get quite upset + * if the buffer is being displayed. Clear the buffer (ask + * if the buffer has been changed). Then free the header + * line and the buffer header. Bound to "C-X K". + */ +killbuffer(f, n) +{ + register BUFFER *bp; + register BUFFER *bp1; + register BUFFER *bp2; + register int s; + char bufn[NBUFN]; + + if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE) + return (s); + if ((bp=bfind(bufn, FALSE, 0)) == NULL) /* Easy if unknown. */ + return (TRUE); + if (bp->b_nwnd != 0) { /* Error if on screen. */ + mlwrite("Buffer is being displayed"); + return (FALSE); + } + if ((s=bclear(bp)) != TRUE) /* Blow text away. */ + return (s); + free((char *) bp->b_linep); /* Release header line. */ + bp1 = NULL; /* Find the header. */ + bp2 = bheadp; + while (bp2 != bp) { + bp1 = bp2; + bp2 = bp2->b_bufp; + } + bp2 = bp2->b_bufp; /* Next one in chain. */ + if (bp1 == NULL) /* Unlink it. */ + bheadp = bp2; + else + bp1->b_bufp = bp2; + free((char *) bp); /* Release buffer block */ + return (TRUE); +} + +/* + * List all of the active + * buffers. First update the special + * buffer that holds the list. Next make + * sure at least 1 window is displaying the + * buffer list, splitting the screen if this + * is what it takes. Lastly, repaint all of + * the windows that are displaying the + * list. Bound to "C-X C-B". + */ +listbuffers(f, n) +{ + register WINDOW *wp; + register BUFFER *bp; + register int s; + + if ((s=makelist()) != TRUE) + return (s); + if (blistp->b_nwnd == 0) { /* Not on screen yet. */ + if ((wp=wpopup()) == NULL) + return (FALSE); + bp = wp->w_bufp; + if (--bp->b_nwnd == 0) { + bp->b_dotp = wp->w_dotp; + bp->b_doto = wp->w_doto; + bp->b_markp = wp->w_markp; + bp->b_marko = wp->w_marko; + } + wp->w_bufp = blistp; + ++blistp->b_nwnd; + } + wp = wheadp; + while (wp != NULL) { + if (wp->w_bufp == blistp) { + wp->w_linep = lforw(blistp->b_linep); + wp->w_dotp = lforw(blistp->b_linep); + wp->w_doto = 0; + wp->w_markp = NULL; + wp->w_marko = 0; + wp->w_flag |= WFMODE|WFHARD; + } + wp = wp->w_wndp; + } + return (TRUE); +} + +/* + * This routine rebuilds the + * text in the special secret buffer + * that holds the buffer list. It is called + * by the list buffers command. Return TRUE + * if everything works. Return FALSE if there + * is an error (if there is no memory). + */ +makelist() +{ + register char *cp1; + register char *cp2; + register int c; + register BUFFER *bp; + register LINE *lp; + register int nbytes; + register int s; + register int type; + char b[6+1]; + char line[128]; + + blistp->b_flag &= ~BFCHG; /* Don't complain! */ + if ((s=bclear(blistp)) != TRUE) /* Blow old text away */ + return (s); + strcpy(blistp->b_fname, ""); + if (addline("C Size Buffer File") == FALSE + || addline("- ---- ------ ----") == FALSE) + return (FALSE); + bp = bheadp; /* For all buffers */ + while (bp != NULL) { + if ((bp->b_flag&BFTEMP) != 0) { /* Skip magic ones. */ + bp = bp->b_bufp; + continue; + } + cp1 = &line[0]; /* Start at left edge */ + if ((bp->b_flag&BFCHG) != 0) /* "*" if changed */ + *cp1++ = '*'; + else + *cp1++ = ' '; + *cp1++ = ' '; /* Gap. */ + nbytes = 0; /* Count bytes in buf. */ + lp = lforw(bp->b_linep); + while (lp != bp->b_linep) { + nbytes += llength(lp)+1; + lp = lforw(lp); + } + itoa(b, 6, nbytes); /* 6 digit buffer size. */ + cp2 = &b[0]; + while ((c = *cp2++) != 0) + *cp1++ = c; + *cp1++ = ' '; /* Gap. */ + cp2 = &bp->b_bname[0]; /* Buffer name */ + while ((c = *cp2++) != 0) + *cp1++ = c; + cp2 = &bp->b_fname[0]; /* File name */ + if (*cp2 != 0) { + while (cp1 < &line[1+1+6+1+NBUFN+1]) + *cp1++ = ' '; + while ((c = *cp2++) != 0) { + if (cp1 < &line[128-1]) + *cp1++ = c; + } + } + *cp1 = 0; /* Add to the buffer. */ + if (addline(line) == FALSE) + return (FALSE); + bp = bp->b_bufp; + } + return (TRUE); /* All done */ +} +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uebuffer2.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,157 @@ +/* + * Buffer management. + * Some of the functions are internal, + * and some are actually attached to user + * keys. Like everyone else, they set hints + * for the display system. + */ +#include <stdio.h> +#include "ueed.h" + +#ifndef OS9 +itoa(buf, width, num) +register char buf[]; +register int width; +register int num; +{ + buf[width] = 0; /* End of string. */ + while (num >= 10) { /* Conditional digits. */ + buf[--width] = (num%10) + '0'; + num /= 10; + } + buf[--width] = num + '0'; /* Always 1 digit. */ + while (width != 0) /* Pad with blanks. */ + buf[--width] = ' '; +} + +/* + * The argument "text" points to + * a string. Append this line to the + * buffer list buffer. Handcraft the EOL + * on the end. Return TRUE if it worked and + * FALSE if you ran out of room. + */ +addline(text) +char *text; +{ + register LINE *lp; + register int i; + register int ntext; + + ntext = strlen(text); + if ((lp=lalloc(ntext)) == NULL) + return (FALSE); + for (i=0; i<ntext; ++i) + lputc(lp, i, text[i]); + blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */ + lp->l_bp = blistp->b_linep->l_bp; + blistp->b_linep->l_bp = lp; + lp->l_fp = blistp->b_linep; + if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */ + blistp->b_dotp = lp; /* move it to new line */ + return (TRUE); +} +#endif + +/* + * Look through the list of + * buffers. Return TRUE if there + * are any changed buffers. Buffers + * that hold magic internal stuff are + * not considered; who cares if the + * list of buffer names is hacked. + * Return FALSE if no buffers + * have been changed. + */ +anycb() +{ + register BUFFER *bp; + + bp = bheadp; + while (bp != NULL) { + if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0) + return (TRUE); + bp = bp->b_bufp; + } + return (FALSE); +} + +/* + * Find a buffer, by name. Return a pointer + * to the BUFFER structure associated with it. If + * the named buffer is found, but is a TEMP buffer (like + * the buffer list) conplain. If the buffer is not found + * and the "cflag" is TRUE, create it. The "bflag" is + * the settings for the flags in in buffer. + */ +BUFFER *bfind(bname, cflag, bflag) +register char *bname; +{ + register BUFFER *bp; + register LINE *lp; + + bp = bheadp; + while (bp != NULL) { + if (strcmp(bname, bp->b_bname) == 0) { + if ((bp->b_flag&BFTEMP) != 0) { + mlwrite("Cannot select builtin buffer"); + return (NULL); + } + return (bp); + } + bp = bp->b_bufp; + } + if (cflag != FALSE) { + if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL) + return (NULL); + if ((lp=lalloc(0)) == NULL) { + free((char *) bp); + return (NULL); + } + bp->b_bufp = bheadp; + bheadp = bp; + bp->b_dotp = lp; + bp->b_doto = + bp->b_markp = + bp->b_marko = + bp->b_nwnd = 0; + bp->b_linep = lp; + bp->b_flag = bflag; + strcpy(bp->b_fname, ""); + strcpy(bp->b_bname, bname); + lp->l_fp = lp; + lp->l_bp = lp; + } + return (bp); +} + +/* + * This routine blows away all of the text + * in a buffer. If the buffer is marked as changed + * then we ask if it is ok to blow it away; this is + * to save the user the grief of losing text. The + * window chain is nearly always wrong if this gets + * called; the caller must arrange for the updates + * that are required. Return TRUE if everything + * looks good. + */ +bclear(bp) +register BUFFER *bp; +{ + register LINE *lp; + register int s; + + if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */ + && (bp->b_flag&BFCHG) != 0 /* Something changed */ + && (s=mlyesno("Discard changes")) != TRUE) + return (s); + bp->b_flag &= ~BFCHG; /* Not changed */ + while ((lp=lforw(bp->b_linep)) != bp->b_linep) + lfree(lp); + bp->b_dotp = bp->b_linep; /* Fix "." */ + bp->b_doto = + bp->b_markp = /* Invalidate "mark" */ + bp->b_marko = 0; + return (TRUE); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uecoco.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,106 @@ +/* + * The routines in this file provide support for the COCO /TERM terminal + * under OS9. The serial I/O services are provided by routines in + * "termio.c". + * Adapted 1/5/86 by: + * Bob Santy + * 5 Johnson Ave + * Medford, MA 02155 + * (617) 488-7160 + */ + +#include <stdio.h> +#include "ueed.h" + +/* Color Computer /TERM specifications */ +#define NROW 16 /* Screen size. */ +#define NCOL 32 /* Edit if you want to. */ +#define BEL 0x07 /* BEL character. */ +#define ESC 0x1B /* ESC character. */ +#define CURSOR 0x02 /* Commands manual p126 */ +#define CEOL 0x04 /* 1.01 Supplement */ +#define CEOS 0x0B /* 1.01 Supplement */ + +extern int ttopen(); /* Forward references. */ +extern int ttgetc(); +extern int ttputc(); +extern int ttflush(); +extern int ttclose(); +extern int cocomove(); +extern int cocoeeol(); +extern int cocoeeop(); +extern int cocobeep(); +extern int cocoopen(); + +/* + * Standard terminal interface dispatch table. Most of the fields point into + * "termio" code. + */ +TERM term = { + NROW-1, + NCOL, + cocoopen, + ttclose, + ttgetc, + ttputc, + ttflush, + cocomove, + cocoeeol, + cocoeeop, + cocobeep +}; + +/* + * Cursor move command. + */ +cocomove(row, col) +{ + ttputc(CURSOR); + cocoparm(col); + cocoparm(row); +} + +/* + * Clear to end of line. + */ +cocoeeol() +{ + ttputc(CEOL); +} + +/* + * Clear to end of screen. + */ +cocoeeop() +{ + ttputc(CEOS); +} + +/* + * Sound the horn (will work in + * OS9 Rev 2.00 + */ +cocobeep() +{ + ttputc(BEL); + ttflush(); +} + +/* + * Cursor position needs 32 added to + * X and Y coordinates. + */ +cocoparm(n) +register int n; +{ + ttputc(n + 32); +} + +/* + * Open terminal. No special codes. + */ +cocoopen() +{ + ttopen(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uedisplay.h Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,25 @@ +/* #define WFDEBUG 0 /* Window flag debug. */ + +typedef struct VIDEO { + short v_flag; /* Flags */ + char v_text[1]; /* Screen data. */ +} VIDEO; + +#define VFCHG 0x0001 /* Changed. */ + +#ifdef DISPLAY1 +int sgarbf = TRUE; /* TRUE if screen is garbage */ +int mpresf = FALSE; /* TRUE if message in last line */ +int vtrow = 0; /* Row location of SW cursor */ +int vtcol = 0; /* Column location of SW cursor */ +int ttrow = HUGE; /* Row location of HW cursor */ +int ttcol = HUGE; /* Column location of HW cursor */ +#else +extern int sgarbf; /* TRUE if screen is garbage */ +extern int mpresf; /* TRUE if message in last line */ +extern int vtrow; /* Row location of SW cursor */ +extern int vtcol; /* Column location of SW cursor */ +extern int ttrow; /* Row location of HW cursor */ +extern int ttcol; /* Column location of HW cursor */ +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uedisplay1.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,432 @@ +/* + * The functions in this file handle redisplay. There are two halves, the + * ones that update the virtual display screen, and the ones that make the + * physical display screen the same as the virtual display screen. These + * functions use hints that are left in the windows by the commands. + * + * REVISION HISTORY: + * + * ? Steve Wilhite, 1-Dec-85 + * - massive cleanup on code. + */ + +#include <stdio.h> +#include "ueed.h" +#define DISPLAY1 1 +#include "uedisplay.h" + +VIDEO **vscreen; /* Virtual screen. */ +VIDEO **pscreen; /* Physical screen. */ + +/* + * Initialize the data structures used by the display code. The edge vectors + * used to access the screens are set up. The operating system's terminal I/O + * channel is set up. All the other things get initialized at compile time. + * The original window has "WFCHG" set, so that it will get completely + * redrawn on the first call to "update". + */ +vtinit() +{ + register int i; + register VIDEO *vp; + + (*term.t_open)(); + vscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *)); + + if (vscreen == NULL) + exit(1); + + pscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *)); + + if (pscreen == NULL) + exit(1); + + for (i = 0; i < term.t_nrow; ++i) + { + vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol); + + if (vp == NULL) + exit(1); + + vscreen[i] = vp; + vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol); + + if (vp == NULL) + exit(1); + + pscreen[i] = vp; + } +} + +/* + * Clean up the virtual terminal system, in anticipation for a return to the + * operating system. Move down to the last line and clear it out (the next + * system prompt will be written in the line). Shut down the channel to the + * terminal. + */ +vttidy() +{ + movecursor(term.t_nrow, 0); + (*term.t_eeol)(); + (*term.t_close)(); +} + +/* + * Set the virtual cursor to the specified row and column on the virtual + * screen. There is no checking for nonsense values; this might be a good + * idea during the early stages. + */ +vtmove(row, col) +{ + vtrow = row; + vtcol = col; +} + +/* + * Write a character to the virtual screen. The virtual row and column are + * updated. If the line is too long put a "$" in the last column. This routine + * only puts printing characters into the virtual terminal buffers. Only + * column overflow is checked. + */ +vtputc(c) + int c; + +{ + register VIDEO *vp; + + vp = vscreen[vtrow]; + + if (vtcol >= term.t_ncol) + vp->v_text[term.t_ncol - 1] = '$'; + else if (c == '\t') + { + do + { + vtputc(' '); + } + while ((vtcol&0x07) != 0); + } + else if (c < 0x20 || c == 0x7F) + { + vtputc('^'); + vtputc(c ^ 0x40); + } + else + vp->v_text[vtcol++] = c; +} + +/* + * Erase from the end of the software cursor to the end of the line on which + * the software cursor is located. + */ +vteeol() +{ + register VIDEO *vp; + + vp = vscreen[vtrow]; + while (vtcol < term.t_ncol) + vp->v_text[vtcol++] = ' '; +} + +/* + * Make sure that the display is right. This is a three part process. First, + * scan through all of the windows looking for dirty ones. Check the framing, + * and refresh the screen. Second, make sure that "currow" and "curcol" are + * correct for the current window. Third, make the virtual and physical + * screens the same. + */ +update() +{ + register LINE *lp; + register WINDOW *wp; + register VIDEO *vp1; + register VIDEO *vp2; + register int i; + register int j; + register int c; + + wp = wheadp; + + while (wp != NULL) + { + /* Look at any window with update flags set on. */ + + if (wp->w_flag != 0) + { + /* If not force reframe, check the framing. */ + + if ((wp->w_flag & WFFORCE) == 0) + { + lp = wp->w_linep; + + for (i = 0; i < wp->w_ntrows; ++i) + { + if (lp == wp->w_dotp) + goto out; + + if (lp == wp->w_bufp->b_linep) + break; + + lp = lforw(lp); + } + } + + /* Not acceptable, better compute a new value for the line at the + * top of the window. Then set the "WFHARD" flag to force full + * redraw. + */ + i = wp->w_force; + + if (i > 0) + { + --i; + + if (i >= wp->w_ntrows) + i = wp->w_ntrows-1; + } + else if (i < 0) + { + i += wp->w_ntrows; + + if (i < 0) + i = 0; + } + else + i = wp->w_ntrows/2; + + lp = wp->w_dotp; + + while (i != 0 && lback(lp) != wp->w_bufp->b_linep) + { + --i; + lp = lback(lp); + } + + wp->w_linep = lp; + wp->w_flag |= WFHARD; /* Force full. */ + +out: + /* Try to use reduced update. Mode line update has its own special + * flag. The fast update is used if the only thing to do is within + * the line editing. + */ + lp = wp->w_linep; + i = wp->w_toprow; + + if ((wp->w_flag & ~WFMODE) == WFEDIT) + { + while (lp != wp->w_dotp) + { + ++i; + lp = lforw(lp); + } + + vscreen[i]->v_flag |= VFCHG; + vtmove(i, 0); + + for (j = 0; j < llength(lp); ++j) + vtputc(lgetc(lp, j)); + + vteeol(); + } + else if ((wp->w_flag & (WFEDIT | WFHARD)) != 0) + { + while (i < wp->w_toprow+wp->w_ntrows) + { + vscreen[i]->v_flag |= VFCHG; + vtmove(i, 0); + + if (lp != wp->w_bufp->b_linep) + { + for (j = 0; j < llength(lp); ++j) + vtputc(lgetc(lp, j)); + + lp = lforw(lp); + } + + vteeol(); + ++i; + } + } +#ifndef WFDEBUG + if ((wp->w_flag&WFMODE) != 0) + modeline(wp); + + wp->w_flag = + wp->w_force = 0; +#endif + } +#ifdef WFDEBUG + modeline(wp); + wp->w_flag = + wp->w_force = 0; +#endif + wp = wp->w_wndp; + } + + /* Always recompute the row and column number of the hardware cursor. This + * is the only update for simple moves. + */ + lp = curwp->w_linep; + currow = curwp->w_toprow; + + while (lp != curwp->w_dotp) + { + ++currow; + lp = lforw(lp); + } + + curcol = + i = 0; + + while (i < curwp->w_doto) + { + c = lgetc(lp, i++); + + if (c == '\t') + curcol |= 0x07; + else if (c < 0x20 || c == 0x7F) + ++curcol; + + ++curcol; + } + + if (curcol >= term.t_ncol) /* Long line. */ + curcol = term.t_ncol-1; + + /* Special hacking if the screen is garbage. Clear the hardware screen, + * and update your copy to agree with it. Set all the virtual screen + * change bits, to force a full update. + */ + if (sgarbf != FALSE) + { + for (i = 0; i < term.t_nrow; ++i) + { + vscreen[i]->v_flag |= VFCHG; + vp1 = pscreen[i]; + for (j = 0; j < term.t_ncol; ++j) + vp1->v_text[j] = ' '; + } + + movecursor(0, 0); /* Erase the screen. */ + (*term.t_eeop)(); + sgarbf = FALSE; /* Erase-page clears */ + mpresf = FALSE; /* the message area. */ + } + + /* Make sure that the physical and virtual displays agree. Unlike before, + * the "updateline" code is only called with a line that has been updated + * for sure. + */ + for (i = 0; i < term.t_nrow; ++i) + { + vp1 = vscreen[i]; + + if ((vp1->v_flag&VFCHG) != 0) + { + vp1->v_flag &= ~VFCHG; + vp2 = pscreen[i]; + updateline(i, &vp1->v_text[0], &vp2->v_text[0]); + } + } + + /* Finally, update the hardware cursor and flush out buffers. */ + + movecursor(currow, curcol); + (*term.t_flush)(); +} + +/* + * Update a single line. This does not know how to use insert or delete + * character sequences; we are using VT52 functionality. Update the physical + * row and column variables. It does try an exploit erase to end of line. The + * RAINBOW version of this routine uses fast video. + */ +updateline(row, vline, pline) + char vline[]; + char pline[]; +{ +#ifdef RAINBOW + register char *cp1; + register char *cp2; + register int nch; + + cp1 = &vline[0]; /* Use fast video. */ + cp2 = &pline[0]; + putline(row+1, 1, cp1); + nch = term.t_ncol; + + do + { + *cp2 = *cp1; + ++cp2; + ++cp1; + } + while (--nch); +#else + register char *cp1; + register char *cp2; + register char *cp3; + register char *cp4; + register char *cp5; + register int nbflag; + + cp1 = &vline[0]; /* Compute left match. */ + cp2 = &pline[0]; + + while (cp1!=&vline[term.t_ncol] && cp1[0]==cp2[0]) + { + ++cp1; + ++cp2; + } + + /* This can still happen, even though we only call this routine on changed + * lines. A hard update is always done when a line splits, a massive + * change is done, or a buffer is displayed twice. This optimizes out most + * of the excess updating. A lot of computes are used, but these tend to + * be hard operations that do a lot of update, so I don't really care. + */ + if (cp1 == &vline[term.t_ncol]) /* All equal. */ + return; + + nbflag = FALSE; + cp3 = &vline[term.t_ncol]; /* Compute right match. */ + cp4 = &pline[term.t_ncol]; + + while (cp3[-1] == cp4[-1]) + { + --cp3; + --cp4; + if (cp3[0] != ' ') /* Note if any nonblank */ + nbflag = TRUE; /* in right match. */ + } + + cp5 = cp3; + + if (nbflag == FALSE) /* Erase to EOL ? */ + { + while (cp5!=cp1 && cp5[-1]==' ') + --cp5; + + if (cp3-cp5 <= 3) /* Use only if erase is */ + cp5 = cp3; /* fewer characters. */ + } + + movecursor(row, cp1-&vline[0]); /* Go to start of line. */ + + while (cp1 != cp5) /* Ordinary. */ + { + (*term.t_putchar)(*cp1); + ++ttcol; + *cp2++ = *cp1++; + } + + if (cp5 != cp3) /* Erase. */ + { + (*term.t_eeol)(); + while (cp1 != cp3) + *cp2++ = *cp1++; + } +#endif +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uedisplay2.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,297 @@ +/* + * The functions in this file handle redisplay. There are two halves, the + * ones that update the virtual display screen, and the ones that make the + * physical display screen the same as the virtual display screen. These + * functions use hints that are left in the windows by the commands. + * + * REVISION HISTORY: + * + * ? Steve Wilhite, 1-Dec-85 + * - massive cleanup on code. + */ + +#include <stdio.h> +#include "ueed.h" +#include "uedisplay.h" + +extern VIDEO **vscreen; /* Virtual screen. */ + +/* + * Redisplay the mode line for the window pointed to by the "wp". This is the + * only routine that has any idea of how the modeline is formatted. You can + * change the modeline format by hacking at this routine. Called by "update" + * any time there is a dirty window. + */ +modeline(wp) + WINDOW *wp; +{ + register char *cp; + register int c; + register int n; + register BUFFER *bp; + + n = wp->w_toprow+wp->w_ntrows; /* Location. */ + vscreen[n]->v_flag |= VFCHG; /* Redraw next time. */ + vtmove(n, 0); /* Seek to right line. */ + vtputc('-'); + bp = wp->w_bufp; + + if ((bp->b_flag&BFCHG) != 0) /* "*" if changed. */ + vtputc('*'); + else + vtputc('-'); + + n = 2; + cp = " MicroEMACS -"; /* Buffer name. */ + + while ((c = *cp++) != 0) + { + vtputc(c); + ++n; + } + +#ifndef OS9 + cp = &bp->b_bname[0]; + + while ((c = *cp++) != 0) + { + vtputc(c); + ++n; + } + + vtputc(' '); + ++n; +#endif + + if (bp->b_fname[0] != 0) /* File name. */ + { + cp = " File: "; + + while ((c = *cp++) != 0) + { + vtputc(c); + ++n; + } + + cp = &bp->b_fname[0]; + + while ((c = *cp++) != 0) + { + vtputc(c); + ++n; + } + + vtputc(' '); + ++n; + } + +#ifdef WFDEBUG + vtputc('-'); + vtputc((wp->w_flag&WFMODE)!=0 ? 'M' : '-'); + vtputc((wp->w_flag&WFHARD)!=0 ? 'H' : '-'); + vtputc((wp->w_flag&WFEDIT)!=0 ? 'E' : '-'); + vtputc((wp->w_flag&WFMOVE)!=0 ? 'V' : '-'); + vtputc((wp->w_flag&WFFORCE)!=0 ? 'F' : '-'); + n += 6; +#endif + + while (n < term.t_ncol) /* Pad to full width. */ + { + vtputc('-'); + ++n; + } +} + +/* + * Send a command to the terminal to move the hardware cursor to row "row" + * and column "col". The row and column arguments are origin 0. Optimize out + * random calls. Update "ttrow" and "ttcol". + */ +movecursor(row, col) + { + if (row!=ttrow || col!=ttcol) + { + ttrow = row; + ttcol = col; + (*term.t_move)(row, col); + } + } + +/* + * Erase the message line. This is a special routine because the message line + * is not considered to be part of the virtual screen. It always works + * immediately; the terminal buffer is flushed via a call to the flusher. + */ +mlerase() + { + movecursor(term.t_nrow, 0); + (*term.t_eeol)(); + (*term.t_flush)(); + mpresf = FALSE; + } + +/* + * Ask a yes or no question in the message line. Return either TRUE, FALSE, or + * ABORT. The ABORT status is returned if the user bumps out of the question + * with a ^G. Used any time a confirmation is required. + */ +mlyesno(prompt) + char *prompt; + { + register int s; + char buf[64]; + + for (;;) + { + strcpy(buf, prompt); + strcat(buf, " [y/n]? "); + s = mlreply(buf, buf, sizeof(buf)); + + if (s == ABORT) + return (ABORT); + + if (s != FALSE) + { + if (buf[0]=='y' || buf[0]=='Y') + return (TRUE); + + if (buf[0]=='n' || buf[0]=='N') + return (FALSE); + } + } + } + +/* + * Write a prompt into the message line, then read back a response. Keep + * track of the physical position of the cursor. If we are in a keyboard + * macro throw the prompt away, and return the remembered response. This + * lets macros run at full speed. The reply is always terminated by a carriage + * return. Handle erase, kill, and abort keys. + */ +mlreply(prompt, buf, nbuf) + char *prompt; + char *buf; + { + register int cpos; + register int i; + register int c; + + cpos = 0; + + if (kbdmop != NULL) + { + while ((c = *kbdmop++) != '\0') + buf[cpos++] = c; + + buf[cpos] = 0; + + if (buf[0] == 0) + return (FALSE); + + return (TRUE); + } + + mlwrite(prompt); + + for (;;) + { + c = (*term.t_getchar)(); + + switch (c) + { + case 0x0D: /* Return, end of line */ + buf[cpos++] = 0; + + if (kbdmip != NULL) + { + if (kbdmip+cpos > &kbdm[NKBDM-3]) + { + ctrlg(FALSE, 0); + (*term.t_flush)(); + return (ABORT); + } + + for (i=0; i<cpos; ++i) + *kbdmip++ = buf[i]; + } + + (*term.t_putchar)('\r'); + ttcol = 0; + (*term.t_flush)(); + + if (buf[0] == 0) + return (FALSE); + + return (TRUE); + + case 0x07: /* Bell, abort */ + (*term.t_putchar)('^'); + (*term.t_putchar)('G'); + ttcol += 2; + ctrlg(FALSE, 0); + (*term.t_flush)(); + return (ABORT); + + case 0x7F: /* Rubout, erase */ + case 0x08: /* Backspace, erase */ + if (cpos != 0) + { + (*term.t_putchar)('\b'); + (*term.t_putchar)(' '); + (*term.t_putchar)('\b'); + --ttcol; + + if (buf[--cpos] < 0x20) + { + (*term.t_putchar)('\b'); + (*term.t_putchar)(' '); + (*term.t_putchar)('\b'); + --ttcol; + } + + (*term.t_flush)(); + } + + break; + + case 0x15: /* C-U, kill */ + while (cpos != 0) + { + (*term.t_putchar)('\b'); + (*term.t_putchar)(' '); + (*term.t_putchar)('\b'); + --ttcol; + + if (buf[--cpos] < 0x20) + { + (*term.t_putchar)('\b'); + (*term.t_putchar)(' '); + (*term.t_putchar)('\b'); + --ttcol; + } + } + + (*term.t_flush)(); + break; + + default: + if (cpos < nbuf-1) + { + buf[cpos++] = c; + + if (c < ' ') + { + (*term.t_putchar)('^'); + ++ttcol; + c ^= 0x40; + } + + (*term.t_putchar)(c); + ++ttcol; + (*term.t_flush)(); + } + } + } + } + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uedisplay3.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,160 @@ +/* + * The functions in this file handle redisplay. There are two halves, the + * ones that update the virtual display screen, and the ones that make the + * physical display screen the same as the virtual display screen. These + * functions use hints that are left in the windows by the commands. + * + * REVISION HISTORY: + * + * ? Steve Wilhite, 1-Dec-85 + * - massive cleanup on code. + */ + +#include <stdio.h> +#include "ueed.h" +#include "uedisplay.h" + +/* + * Write a message into the message line. Keep track of the physical cursor + * position. A small class of printf like format items is handled. + * This routine is probably one of the lease portable. + * Assumes all arguments (with the possible exception of the first) are passed + * in the order expected on a downward growing stack without addtional + * padding; this assumption is made by the "++" in the + * argument scan loop. It works for the two or less argument case + * on OSK despite the fact the first two arguments are passed in registers. + * Set the "message line" flag TRUE. + */ +mlwrite(fmt, arg) + char *fmt; + { + register int c; + register char *ap; + + movecursor(term.t_nrow, 0); + ap = (char *) &arg; + while ((c = *fmt++) != 0) { + if (c != '%') { + (*term.t_putchar)(c); + ++ttcol; + } + else + { + c = *fmt++; + switch (c) { + case 'd': + mlputi(*(int *)ap, 10); + ap += sizeof(int); + break; + + case 'o': + mlputi(*(int *)ap, 8); + ap += sizeof(int); + break; + + case 'x': + mlputi(*(int *)ap, 16); + ap += sizeof(int); + break; + + case 'D': /* this is %ld on many printf impleminations */ + mlputli(*(long *)ap, 10); + ap += sizeof(long); + break; + + case 's': + mlputs(*(char **)ap); + ap += sizeof(char *); + break; + + default: + (*term.t_putchar)(c); + ++ttcol; + } + } + } + (*term.t_eeol)(); + (*term.t_flush)(); + mpresf = TRUE; + } + +/* + * Write out a string. Update the physical cursor position. This assumes that + * the characters in the string all have width "1"; if this is not the case + * things will get screwed up a little. + */ +mlputs(s) + char *s; + { + register int c; + + while ((c = *s++) != 0) + { + (*term.t_putchar)(c); + ++ttcol; + } + } + +/* + * Write out an integer, in the specified radix. Update the physical cursor + * position. This will not handle any negative numbers; maybe it should. + */ +mlputi(i, r) + { + register int q; + static char hexdigits[] = "0123456789ABCDEF"; + + if (i < 0) + { + i = -i; + (*term.t_putchar)('-'); + } + + q = i/r; + + if (q != 0) + mlputi(q, r); + + (*term.t_putchar)(hexdigits[i%r]); + ++ttcol; + } + +/* + * do the same except as a long integer. + */ +mlputli(l, r) + long l; + { + register long q; + + if (l < 0) + { + l = -l; + (*term.t_putchar)('-'); + } + + q = l/r; + + if (q != 0) + mlputli(q, r); + + (*term.t_putchar)((int)(l%r)+'0'); + ++ttcol; + } + +#ifdef RAINBOW + +putline(row, col, buf) + int row, col; + char buf[]; + { + int n; + + n = strlen(buf); + if (col + n - 1 > term.t_ncol) + n = term.t_ncol - col + 1; + Put_Data(row, col, n, buf); + } +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/ueed.h Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,189 @@ +/* + * This file is the general header file for all parts of the MicroEMACS + * display editor. It contains definitions used by everyone, and it contains + * the stuff you have to edit to create a version of the editor for a specific + * operating system and terminal. + */ + +/* #define AMIGA 1 /* AmigaDOS, Lattice */ +/* #define ST520 0 /* ST520, TOS */ +/* #define MWC86 0 +/* #define V7 0 /* V7 UN*X or Coherent */ +/* #define VMS 0 /* VAX/VMS */ +/* #define CPM 0 /* CP/M-86 */ +#define OS9 1 /* os9/6809 level 1 (coco) */ +/* #define OSK 1 /* os9/68000 predefined */ +/* #define MSDOS 0 /* MS-DOS predefined */ + +/* #define ANSI 1 /* ANSI terminal (Vt100) */ +/* #define VT52 1 /* VT52 terminal (Zenith). */ +/* #define VT100 0 /* Handle VT100 style keypad. */ +/* #define LK201 0 /* Handle LK201 style keypad. */ +/* #define RAINBOW 0 /* Use Rainbow fast video. */ +/* #define TERMCAP 0 /* Use TERMCAP */ + +#define CVMVAS 1 /* C-V, M-V arg. in screens. */ + +#define NFILEN 80 /* # of bytes, file name */ +#define NBUFN 16 /* # of bytes, buffer name */ +#define NLINE 256 /* # of bytes, line */ +#define NKBDM 256 /* # of strokes, keyboard macro */ +#define NPAT 80 /* # of bytes, pattern */ +#define HUGE 1000 /* Huge number */ + +#define AGRAVE 0x60 /* M- prefix, Grave (LK201) */ +#define METACH 0x1B /* M- prefix, Control-[, ESC */ +#define CTMECH 0x1C /* C-M- prefix, Control-\ */ +#define EXITCH 0x1D /* Exit level, Control-] */ +#define CTRLCH 0x1E /* C- prefix, Control-^ */ +#define HELPCH 0x1F /* Help key, Control-_ */ + +#define CTRL 0x0100 /* Control flag, or'ed in */ +#define META 0x0200 /* Meta flag, or'ed in */ +#define CTLX 0x0400 /* ^X flag, or'ed in */ + +#define FALSE 0 /* False, no, bad, etc. */ +#define TRUE 1 /* True, yes, good, etc. */ +#define ABORT 2 /* Death, ^G, abort, etc. */ + +#define FIOSUC 0 /* File I/O, success. */ +#define FIOFNF 1 /* File I/O, file not found. */ +#define FIOEOF 2 /* File I/O, end of file. */ +#define FIOERR 3 /* File I/O, error. */ + +#define CFCPCN 0x0001 /* Last command was C-P, C-N */ +#define CFKILL 0x0002 /* Last command was a kill */ + +/* + * There is a window structure allocated for every active display window. The + * windows are kept in a big list, in top to bottom screen order, with the + * listhead at "wheadp". Each window contains its own values of dot and mark. + * The flag field contains some bits that are set by commands to guide + * redisplay; although this is a bit of a compromise in terms of decoupling, + * the full blown redisplay is just too expensive to run for every input + * character. + */ +typedef struct WINDOW { + struct WINDOW *w_wndp; /* Next window */ + struct BUFFER *w_bufp; /* Buffer displayed in window */ + struct LINE *w_linep; /* Top line in the window */ + struct LINE *w_dotp; /* Line containing "." */ + short w_doto; /* Byte offset for "." */ + struct LINE *w_markp; /* Line containing "mark" */ + short w_marko; /* Byte offset for "mark" */ + char w_toprow; /* Origin 0 top row of window */ + char w_ntrows; /* # of rows of text in window */ + char w_force; /* If NZ, forcing row. */ + char w_flag; /* Flags. */ +} WINDOW; + +#define WFFORCE 0x01 /* Window needs forced reframe */ +#define WFMOVE 0x02 /* Movement from line to line */ +#define WFEDIT 0x04 /* Editing within a line */ +#define WFHARD 0x08 /* Better to a full display */ +#define WFMODE 0x10 /* Update mode line. */ + +/* + * Text is kept in buffers. A buffer header, described below, exists for every + * buffer in the system. The buffers are kept in a big list, so that commands + * that search for a buffer by name can find the buffer header. There is a + * safe store for the dot and mark in the header, but this is only valid if + * the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for + * the buffer is kept in a circularly linked list of lines, with a pointer to + * the header line in "b_linep". + */ +typedef struct BUFFER { + struct BUFFER *b_bufp; /* Link to next BUFFER */ + struct LINE *b_dotp; /* Link to "." LINE structure */ + short b_doto; /* Offset of "." in above LINE */ + struct LINE *b_markp; /* The same as the above two, */ + short b_marko; /* but for the "mark" */ + struct LINE *b_linep; /* Link to the header LINE */ + char b_nwnd; /* Count of windows on buffer */ + char b_flag; /* Flags */ + char b_fname[NFILEN]; /* File name */ + char b_bname[NBUFN]; /* Buffer name */ +} BUFFER; + +#define BFTEMP 0x01 /* Internal temporary buffer */ +#define BFCHG 0x02 /* Changed since last write */ + +/* + * The starting position of a region, and the size of the region in + * characters, is kept in a region structure. Used by the region commands. + */ +typedef struct { + struct LINE *r_linep; /* Origin LINE address. */ + short r_offset; /* Origin LINE offset. */ + short r_size; /* Length in characters. */ +} REGION; + +/* + * All text is kept in circularly linked lists of "LINE" structures. These + * begin at the header line (which is the blank line beyond the end of the + * buffer). This line is pointed to by the "BUFFER". Each line contains a the + * number of bytes in the line (the "used" size), the size of the text array, + * and the text. The end of line is not stored as a byte; it's implied. Future + * additions will include update hints, and a list of marks into the line. + */ +typedef struct LINE { + struct LINE *l_fp; /* Link to the next line */ + struct LINE *l_bp; /* Link to the previous line */ + short l_size; /* Allocated size */ + short l_used; /* Used size */ + char l_text[1]; /* A bunch of characters. */ +} LINE; + +#define lforw(lp) ((lp)->l_fp) +#define lback(lp) ((lp)->l_bp) +#define lgetc(lp, n) ((lp)->l_text[(n)]&0xFF) +#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c)) +#define llength(lp) ((lp)->l_used) + +/* + * The editor communicates with the display using a high level interface. A + * "TERM" structure holds useful variables, and indirect pointers to routines + * that do useful operations. The low level get and put routines are here too. + * This lets a terminal, in addition to having non standard commands, have + * funny get and put character code too. The calls might get changed to + * "termp->t_field" style in the future, to make it possible to run more than + * one terminal type. + */ +typedef struct { + short t_nrow; /* Number of rows. */ + short t_ncol; /* Number of columns. */ + int (*t_open)(); /* Open terminal at the start. */ + int (*t_close)(); /* Close terminal at end. */ + int (*t_getchar)(); /* Get character from keyboard. */ + int (*t_putchar)(); /* Put character to display. */ + int (*t_flush)(); /* Flush output buffers. */ + int (*t_move)(); /* Move the cursor, origin 0. */ + int (*t_eeol)(); /* Erase to end of line. */ + int (*t_eeop)(); /* Erase to end of page. */ + int (*t_beep)(); /* Beep. */ +} TERM; + +extern int fillcol; /* Fill column */ +extern int currow; /* Cursor row */ +extern int curcol; /* Cursor column */ +extern int thisflag; /* Flags, this command */ +extern int lastflag; /* Flags, last command */ +extern int curgoal; /* Goal for C-P, C-N */ +extern int mpresf; /* Stuff in message line */ +extern int sgarbf; /* State of screen unknown */ +extern WINDOW *curwp; /* Current window */ +extern BUFFER *curbp; /* Current buffer */ +extern WINDOW *wheadp; /* Head of list of windows */ +extern BUFFER *bheadp; /* Head of list of buffers */ +extern BUFFER *blistp; /* Buffer for C-X C-B */ +extern short kbdm[]; /* Holds kayboard macro data */ +extern short *kbdmip; /* Input pointer for above */ +extern short *kbdmop; /* Output pointer for above */ +extern char pat[]; /* Search pattern */ +extern TERM term; /*(Terminal information. */ + +extern BUFFER *bfind(); /* Lookup a buffer by name */ +extern WINDOW *wpopup(); /* Pop up window creation */ +extern LINE *lalloc(); /* Allocate a line */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uefile1.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,264 @@ +/* + * The routines in this file + * handle the reading and writing of + * disk files. All of details about the + * reading and writing of the disk are + * in "fileio.c". + */ +#include <stdio.h> +#include "ueed.h" + +/* + * Read a file into the current + * buffer. This is really easy; all you do it + * find the name of the file, and call the standard + * "read a file into the current buffer" code. + * Bound to "C-X C-R". + */ +fileread(f, n) +{ + register int s; + char fname[NFILEN]; + + if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE) + return (s); + return (readin(fname)); +} + +#ifndef OS9 +/* + * Select a file for editing. + * Look around to see if you can find the + * fine in another buffer; if you can find it + * just switch to the buffer. If you cannot find + * the file, create a new buffer, read in the + * text, and switch to the new buffer. + * Bound to C-X C-V. + */ +filevisit(f, n) +{ + register BUFFER *bp; + register WINDOW *wp; + register LINE *lp; + register int i; + register int s; + char bname[NBUFN]; + char fname[NFILEN]; + + if ((s=mlreply("Visit file: ", fname, NFILEN)) != TRUE) + return (s); + for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) { + if ((bp->b_flag&BFTEMP)==0 && strcmp(bp->b_fname, fname)==0) { + if (--curbp->b_nwnd == 0) { + curbp->b_dotp = curwp->w_dotp; + curbp->b_doto = curwp->w_doto; + curbp->b_markp = curwp->w_markp; + curbp->b_marko = curwp->w_marko; + } + curbp = bp; + curwp->w_bufp = bp; + if (bp->b_nwnd++ == 0) { + curwp->w_dotp = bp->b_dotp; + curwp->w_doto = bp->b_doto; + curwp->w_markp = bp->b_markp; + curwp->w_marko = bp->b_marko; + } else { + wp = wheadp; + while (wp != NULL) { + if (wp!=curwp && wp->w_bufp==bp) { + curwp->w_dotp = wp->w_dotp; + curwp->w_doto = wp->w_doto; + curwp->w_markp = wp->w_markp; + curwp->w_marko = wp->w_marko; + break; + } + wp = wp->w_wndp; + } + } + lp = curwp->w_dotp; + i = curwp->w_ntrows/2; + while (i-- && lback(lp)!=curbp->b_linep) + lp = lback(lp); + curwp->w_linep = lp; + curwp->w_flag |= WFMODE|WFHARD; + mlwrite("[Old buffer]"); + return (TRUE); + } + } + makename(bname, fname); /* New buffer name. */ + while ((bp=bfind(bname, FALSE, 0)) != NULL) { + s = mlreply("Buffer name: ", bname, NBUFN); + if (s == ABORT) /* ^G to just quit */ + return (s); + if (s == FALSE) { /* CR to clobber it */ + makename(bname, fname); + break; + } + } + if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) { + mlwrite("Cannot create buffer"); + return (FALSE); + } + if (--curbp->b_nwnd == 0) { /* Undisplay. */ + curbp->b_dotp = curwp->w_dotp; + curbp->b_doto = curwp->w_doto; + curbp->b_markp = curwp->w_markp; + curbp->b_marko = curwp->w_marko; + } + curbp = bp; /* Switch to it. */ + curwp->w_bufp = bp; + curbp->b_nwnd++; + return (readin(fname)); /* Read it in. */ +} +#endif + +/* + * Read file "fname" into the current + * buffer, blowing away any text found there. Called + * by both the read and visit commands. Return the final + * status of the read. Also called by the mainline, + * to read in a file specified on the command line as + * an argument. + */ +readin(fname) +char fname[]; +{ + register LINE *lp1; + register LINE *lp2; + register int i; + register WINDOW *wp; + register BUFFER *bp; + register int s; + register int nbytes; + register int nline; + char line[NLINE]; + + bp = curbp; /* Cheap. */ + if ((s=bclear(bp)) != TRUE) /* Might be old. */ + return (s); + bp->b_flag &= ~(BFTEMP|BFCHG); + strcpy(bp->b_fname, fname); + if ((s=ffropen(fname)) == FIOERR) /* Hard file open. */ + goto out; + if (s == FIOFNF) { /* File not found. */ + mlwrite("[New file]"); + goto out; + } + mlwrite("[Reading file]"); + nline = 0; + while ((s=ffgetline(line, NLINE)) == FIOSUC) { + nbytes = strlen(line); + if ((lp1=lalloc(nbytes)) == NULL) { + s = FIOERR; /* Keep message on the */ + break; /* display. */ + } + lp2 = lback(curbp->b_linep); + lp2->l_fp = lp1; + lp1->l_fp = curbp->b_linep; + lp1->l_bp = lp2; + curbp->b_linep->l_bp = lp1; + for (i=0; i<nbytes; ++i) + lputc(lp1, i, line[i]); + ++nline; + } + ffclose(); /* Ignore errors. */ + if (s == FIOEOF) { /* Don't zap message! */ + if (nline == 1) + mlwrite("[Read 1 line]"); + else + mlwrite("[Read %d lines]", nline); + } +out: + for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) { + if (wp->w_bufp == curbp) { + wp->w_linep = lforw(curbp->b_linep); + wp->w_dotp = lforw(curbp->b_linep); + wp->w_doto = + wp->w_markp = + wp->w_marko = 0; + wp->w_flag |= WFMODE|WFHARD; + } + } + if (s == FIOERR) /* False if error. */ + return (FALSE); + return (TRUE); +} + +/* + * Take a file name, and from it + * fabricate a buffer name. This routine knows + * about the syntax of file names on the target system. + * I suppose that this information could be put in + * a better place than a line of code. + */ +makename(bname, fname) +char bname[]; +char fname[]; +{ + register char *cp1; + register char *cp2; + + cp1 = &fname[0]; + while (*cp1 != 0) + ++cp1; + +#ifdef AMIGA + while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='/') + --cp1; +#endif +#ifdef VMS + while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']') + --cp1; +#endif +#ifdef CPM + while (cp1!=&fname[0] && cp1[-1]!=':') + --cp1; +#endif +#ifdef MSDOS + while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\') + --cp1; +#endif +#ifdef V7 + while (cp1!=&fname[0] && cp1[-1]!='/') + --cp1; +#endif +#ifdef OSK + while (cp1!=&fname[0] && cp1[-1]!='/') + --cp1; +#endif + cp2 = &bname[0]; + while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';') + *cp2++ = *cp1++; + *cp2 = 0; +} + +/* + * Ask for a file name, and write the + * contents of the current buffer to that file. + * Update the remembered file name and clear the + * buffer changed flag. This handling of file names + * is different from the earlier versions, and + * is more compatable with Gosling EMACS than + * with ITS EMACS. Bound to "C-X C-W". + */ +filewrite(f, n) +{ + register WINDOW *wp; + register int s; + char fname[NFILEN]; + + if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE) + return (s); + if ((s=writeout(fname)) == TRUE) { + strcpy(curbp->b_fname, fname); + curbp->b_flag &= ~BFCHG; + wp = wheadp; /* Update mode lines. */ + while (wp != NULL) { + if (wp->w_bufp == curbp) + wp->w_flag |= WFMODE; + wp = wp->w_wndp; + } + } + return (s); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uefile2.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,112 @@ +/* + * The routines in this file + * handle the reading and writing of + * disk files. All of details about the + * reading and writing of the disk are + * in "fileio.c". + */ +#include <stdio.h> +#include "ueed.h" + +/* + * Save the contents of the current + * buffer in its associatd file. No nothing + * if nothing has changed (this may be a bug, not a + * feature). Error if there is no remembered file + * name for the buffer. Bound to "C-X C-S". May + * get called by "C-Z". + */ +filesave(f, n) +{ + register WINDOW *wp; + register int s; + + if ((curbp->b_flag&BFCHG) == 0) /* Return, no changes. */ + return (TRUE); + if (curbp->b_fname[0] == 0) { /* Must have a name. */ + mlwrite("No file name"); + return (FALSE); + } + if ((s=writeout(curbp->b_fname)) == TRUE) { + curbp->b_flag &= ~BFCHG; + wp = wheadp; /* Update mode lines. */ + while (wp != NULL) { + if (wp->w_bufp == curbp) + wp->w_flag |= WFMODE; + wp = wp->w_wndp; + } + } + return (s); +} + +/* + * This function performs the details of file + * writing. Uses the file management routines in the + * "fileio.c" package. The number of lines written is + * displayed. Sadly, it looks inside a LINE; provide + * a macro for this. Most of the grief is error + * checking of some sort. + */ +writeout(fn) +char *fn; +{ + register int s; + register LINE *lp; + register int nline; + + if ((s=ffwopen(fn)) != FIOSUC) /* Open writes message. */ + return (FALSE); + lp = lforw(curbp->b_linep); /* First line. */ + nline = 0; /* Number of lines. */ + while (lp != curbp->b_linep) { + if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC) + break; + ++nline; + lp = lforw(lp); + } + if (s == FIOSUC) { /* No write error. */ + s = ffclose(); + if (s == FIOSUC) { /* No close error. */ + if (nline == 1) + mlwrite("[Wrote 1 line]"); + else + mlwrite("[Wrote %d lines]", nline); + } + } else /* Ignore close error */ + ffclose(); /* if a write error. */ + if (s != FIOSUC) /* Some sort of error. */ + return (FALSE); + return (TRUE); +} + +/* + * The command allows the user + * to modify the file name associated with + * the current buffer. It is like the "f" command + * in UNIX "ed". The operation is simple; just zap + * the name in the BUFFER structure, and mark the windows + * as needing an update. You can type a blank line at the + * prompt if you wish. + */ +filename(f, n) +{ + register WINDOW *wp; + register int s; + char fname[NFILEN]; + + if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT) + return (s); + if (s == FALSE) + strcpy(curbp->b_fname, ""); + else + strcpy(curbp->b_fname, fname); + wp = wheadp; /* Update mode lines. */ + while (wp != NULL) { + if (wp->w_bufp == curbp) + wp->w_flag |= WFMODE; + wp = wp->w_wndp; + } + return (TRUE); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uefileio.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,120 @@ +/* + * The routines in this file read and write ASCII files from the disk. All of + * the knowledge about files are here. A better message writing scheme should + * be used. + */ +#include <stdio.h> +#include "ueed.h" + +FILE *ffp; /* File pointer, all functions. */ + +/* + * Open a file for reading. + */ +ffropen(fn) +char *fn; +{ + if ((ffp=fopen(fn, "r")) == NULL) + return (FIOFNF); + return (FIOSUC); +} + +/* + * Open a file for writing. Return TRUE if all is well, and FALSE on error + * (cannot create). + */ +ffwopen(fn) +char *fn; +{ +#ifdef VMS + register int fd; + + if ((fd=creat(fn, 0666, "rfm=var", "rat=cr")) < 0 + || (ffp=fdopen(fd, "w")) == NULL) { +#else + if ((ffp=fopen(fn, "w")) == NULL) { +#endif + mlwrite("Cannot open file for writing"); + return (FIOERR); + } + return (FIOSUC); +} + +/* + * Close a file. Should look at the status in all systems. + */ +ffclose() +{ +#ifdef V7 + if (fclose(ffp) != FALSE) { + mlwrite("Error closing file"); + return(FIOERR); + } + return(FIOSUC); +#endif + fclose(ffp); + return (FIOSUC); +} + +/* + * Write a line to the already opened file. The "buf" points to the buffer, + * and the "nbuf" is its length, less the free newline. Return the status. + * Check only at the newline. + */ +ffputline(buf, nbuf) +char buf[]; +{ + register int i; + for (i = 0; i < nbuf; ++i) + putc(buf[i]&0xFF, ffp); + + putc('\n', ffp); + + if (ferror(ffp)) { + mlwrite("Write I/O error"); + return (FIOERR); + } + + return (FIOSUC); +} + +/* + * Read a line from a file, and store the bytes in the supplied buffer. The + * "nbuf" is the length of the buffer. Complain about long lines and lines + * at the end of the file that don't have a newline present. Check for I/O + * errors too. Return status. + */ +ffgetline(buf, nbuf) +register char buf[]; +{ + register int c; + register int i; + + i = 0; + + while ((c = fgetc(ffp)) != EOF && c != '\n') { + if (i >= nbuf-1) { + mlwrite("File has long line"); + return (FIOERR); + } + buf[i++] = c; + } + + if (c == EOF) { + if (ferror(ffp)) { + mlwrite("File read error"); + return (FIOERR); + } + + if (i != 0) { + mlwrite("File has funny line at EOF"); + return (FIOERR); + } + return (FIOEOF); + } + + buf[i] = 0; + return (FIOSUC); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/ueline1.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,201 @@ +/* + * The functions in this file are a general set of line management utilities. + * They are the only routines that touch the text. They also touch the buffer + * and window structures, to make sure that the necessary updating gets done. + * There are routines in this file that handle the kill buffer too. It isn't + * here for any good reason. + * + * Note that this code only updates the dot and mark values in the window list. + * Since all the code acts on the current window, the buffer that we are + * editing must be being displayed, which means that "b_nwnd" is non zero, + * which means that the dot and mark values in the buffer headers are nonsense. + */ + +#include <stdio.h> +#include "ueed.h" + +#define NBLOCK 16 /* Line block chunk size */ +#define KBLOCK 256 /* Kill buffer block size */ + +char *kbufp = NULL; /* Kill buffer data */ +int kused = 0; /* # of bytes used in KB */ +int ksize = 0; /* # of bytes allocated in KB */ + +/* + * This routine allocates a block of memory large enough to hold a LINE + * containing "used" characters. The block is always rounded up a bit. Return + * a pointer to the new block, or NULL if there isn't any memory left. Print a + * message in the message line if no space. + */ +LINE *lalloc(used) +register int used; +{ + register LINE *lp; + register int size; + + size = (used+NBLOCK-1) & ~(NBLOCK-1); + if (size == 0) /* Assume that an empty */ + size = NBLOCK; /* line is for type-in. */ + if ((lp = (LINE *) malloc(sizeof(LINE)+size)) == NULL) { + mlwrite("Cannot allocate %d bytes", size); + return (NULL); + } + lp->l_size = size; + lp->l_used = used; + return (lp); +} + +/* + * Delete line "lp". Fix all of the links that might point at it (they are + * moved to offset 0 of the next line. Unlink the line from whatever buffer it + * might be in. Release the memory. The buffers are updated too; the magic + * conditions described in the above comments don't hold here. + */ +lfree(lp) +register LINE *lp; +{ + register BUFFER *bp; + register WINDOW *wp; + + wp = wheadp; + while (wp != NULL) { + if (wp->w_linep == lp) + wp->w_linep = lp->l_fp; + if (wp->w_dotp == lp) { + wp->w_dotp = lp->l_fp; + wp->w_doto = 0; + } + if (wp->w_markp == lp) { + wp->w_markp = lp->l_fp; + wp->w_marko = 0; + } + wp = wp->w_wndp; + } + bp = bheadp; + while (bp != NULL) { + if (bp->b_nwnd == 0) { + if (bp->b_dotp == lp) { + bp->b_dotp = lp->l_fp; + bp->b_doto = 0; + } + if (bp->b_markp == lp) { + bp->b_markp = lp->l_fp; + bp->b_marko = 0; + } + } + bp = bp->b_bufp; + } + lp->l_bp->l_fp = lp->l_fp; + lp->l_fp->l_bp = lp->l_bp; + free((char *) lp); +} + +/* + * This routine gets called when a character is changed in place in the current + * buffer. It updates all of the required flags in the buffer and window + * system. The flag used is passed as an argument; if the buffer is being + * displayed in more than 1 window we change EDIT t HARD. Set MODE if the + * mode line needs to be updated (the "*" has to be set). + */ +lchange(flag) +register int flag; +{ + register WINDOW *wp; + if (curbp->b_nwnd != 1) /* Ensure hard. */ + flag = WFHARD; + if ((curbp->b_flag&BFCHG) == 0) { /* First change, so */ + flag |= WFMODE; /* update mode lines. */ + curbp->b_flag |= BFCHG; + } + wp = wheadp; + while (wp != NULL) { + if (wp->w_bufp == curbp) + wp->w_flag |= flag; + wp = wp->w_wndp; + } +} + +/* + * Insert "n" copies of the character "c" at the current location of dot. In + * the easy case all that happens is the text is stored in the line. In the + * hard case, the line has to be reallocated. When the window list is updated, + * take special care; I screwed it up once. You always update dot in the + * current window. You update mark, and a dot in another window, if it is + * greater than the place where you did the insert. Return TRUE if all is + * well, and FALSE on errors. + */ +linsert(n, c) +{ + register char *cp1; + register char *cp2; + register LINE *lp1; + register LINE *lp2; + register LINE *lp3; + register int doto; + register int i; + register WINDOW *wp; + + lchange(WFEDIT); + lp1 = curwp->w_dotp; /* Current line */ + if (lp1 == curbp->b_linep) { /* At the end: special */ + if (curwp->w_doto != 0) { + mlwrite("bug: linsert"); + return (FALSE); + } + if ((lp2=lalloc(n)) == NULL) /* Allocate new line */ + return (FALSE); + lp3 = lp1->l_bp; /* Previous line */ + lp3->l_fp = lp2; /* Link in */ + lp2->l_fp = lp1; + lp1->l_bp = lp2; + lp2->l_bp = lp3; + for (i=0; i<n; ++i) + lp2->l_text[i] = c; + curwp->w_dotp = lp2; + curwp->w_doto = n; + return (TRUE); + } + doto = curwp->w_doto; /* Save for later. */ + if (lp1->l_used+n > lp1->l_size) { /* Hard: reallocate */ + if ((lp2=lalloc(lp1->l_used+n)) == NULL) + return (FALSE); + cp1 = &lp1->l_text[0]; + cp2 = &lp2->l_text[0]; + while (cp1 != &lp1->l_text[doto]) + *cp2++ = *cp1++; + cp2 += n; + while (cp1 != &lp1->l_text[lp1->l_used]) + *cp2++ = *cp1++; + lp1->l_bp->l_fp = lp2; + lp2->l_fp = lp1->l_fp; + lp1->l_fp->l_bp = lp2; + lp2->l_bp = lp1->l_bp; + free((char *) lp1); + } else { /* Easy: in place */ + lp2 = lp1; /* Pretend new line */ + lp2->l_used += n; + cp2 = &lp1->l_text[lp1->l_used]; + cp1 = cp2-n; + while (cp1 != &lp1->l_text[doto]) + *--cp2 = *--cp1; + } + for (i=0; i<n; ++i) /* Add the characters */ + lp2->l_text[doto+i] = c; + wp = wheadp; /* Update windows */ + while (wp != NULL) { + if (wp->w_linep == lp1) + wp->w_linep = lp2; + if (wp->w_dotp == lp1) { + wp->w_dotp = lp2; + if (wp==curwp || wp->w_doto>doto) + wp->w_doto += n; + } + if (wp->w_markp == lp1) { + wp->w_markp = lp2; + if (wp->w_marko > doto) + wp->w_marko += n; + } + wp = wp->w_wndp; + } + return (TRUE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/ueline2.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,284 @@ +/* + * The functions in this file are a general set of line management utilities. + * They are the only routines that touch the text. They also touch the buffer + * and window structures, to make sure that the necessary updating gets done. + * There are routines in this file that handle the kill buffer too. It i +sn't + * here for any good reason. + * + * Note that this code only updates the dot and mark values in the window list. + * Since all the code acts on the current window, the buffer that we are + * editing must be being displayed, which means that "b_nwnd" is non zero, + * which means that the dot and mark values in the buffer headers are nonsense. + */ + +#include <stdio.h> +#include "ueed.h" + +#define NBLOCK 16 /* Line block chunk size */ +#define KBLOCK 256 /* Kill buffer block size */ + +extern char *kbufp; /* Kill buffer data */ +extern int kused; /* # of bytes used in KB */ +extern int ksize; /* # of bytes allocated in KB */ + +/* + * Insert a newline into the buffer at the current location of dot in the + * current window. The funny ass-backwards way it does things is not a botch; + * it just makes the last line in the file not a special case. Return TRUE if + * everything works out and FALSE on error (memory allocation failure). The + * update of dot and mark is a bit easier then in the above case, because the + * split forces more updating. + */ +lnewline() +{ + register char *cp1; + register char *cp2; + register LINE *lp1; + register LINE *lp2; + register int doto; + register WINDOW *wp; + + lchange(WFHARD); + lp1 = curwp->w_dotp; /* Get the address and */ + doto = curwp->w_doto; /* offset of "." */ + if ((lp2=lalloc(doto)) == NULL) /* New first half line */ + return (FALSE); + cp1 = &lp1->l_text[0]; /* Shuffle text around */ + cp2 = &lp2->l_text[0]; + while (cp1 != &lp1->l_text[doto]) + *cp2++ = *cp1++; + cp2 = &lp1->l_text[0]; + while (cp1 != &lp1->l_text[lp1->l_used]) + *cp2++ = *cp1++; + lp1->l_used -= doto; + lp2->l_bp = lp1->l_bp; + lp1->l_bp = lp2; + lp2->l_bp->l_fp = lp2; + lp2->l_fp = lp1; + wp = wheadp; /* Windows */ + while (wp != NULL) { + if (wp->w_linep == lp1) + wp->w_linep = lp2; + if (wp->w_dotp == lp1) { + if (wp->w_doto < doto) + wp->w_dotp = lp2; + else + wp->w_doto -= doto; + } + if (wp->w_markp == lp1) { + if (wp->w_marko < doto) + wp->w_markp = lp2; + else + wp->w_marko -= doto; + } + wp = wp->w_wndp; + } + return (TRUE); +} + +/* + * This function deletes "n" bytes, starting at dot. It understands how do deal + * with end of lines, etc. It returns TRUE if all of the characters were + * deleted, and FALSE if they were not (because dot ran into the end of the + * buffer. The "kflag" is TRUE if the text should be put in the kill buffer. + */ +ldelete(n, kflag) +{ + register char *cp1; + register char *cp2; + register LINE *dotp; + register int doto; + register int chunk; + register WINDOW *wp; + + while (n != 0) { + dotp = curwp->w_dotp; + doto = curwp->w_doto; + if (dotp == curbp->b_linep) /* Hit end of buffer. */ + return (FALSE); + chunk = dotp->l_used-doto; /* Size of chunk. */ + if (chunk > n) + chunk = n; + if (chunk == 0) { /* End of line, merge. */ + lchange(WFHARD); + if (ldelnewline() == FALSE + || (kflag!=FALSE && kinsert('\n')==FALSE)) + return (FALSE); + --n; + continue; + } + lchange(WFEDIT); + cp1 = &dotp->l_text[doto]; /* Scrunch text. */ + cp2 = cp1 + chunk; + if (kflag != FALSE) { /* Kill? */ + while (cp1 != cp2) { + if (kinsert(*cp1) == FALSE) + return (FALSE); + ++cp1; + } + cp1 = &dotp->l_text[doto]; + } + while (cp2 != &dotp->l_text[dotp->l_used]) + *cp1++ = *cp2++; + dotp->l_used -= chunk; + wp = wheadp; /* Fix windows */ + while (wp != NULL) { + if (wp->w_dotp==dotp && wp->w_doto>=doto) { + wp->w_doto -= chunk; + if (wp->w_doto < doto) + wp->w_doto = doto; + } + if (wp->w_markp==dotp && wp->w_marko>=doto) { + wp->w_marko -= chunk; + if (wp->w_marko < doto) + wp->w_marko = doto; + } + wp = wp->w_wndp; + } + n -= chunk; + } + return (TRUE); +} + +/* + * Delete a newline. Join the current line with the next line. If the next line + * is the magic header line always return TRUE; merging the last line with the + * header line can be thought of as always being a successful operation, even + * if nothing is done, and this makes the kill buffer work "right". Easy cases + * can be done by shuffling data around. Hard cases require that lines be moved + * about in memory. Return FALSE on error and TRUE if all looks ok. Called by + * "ldelete" only. + */ +ldelnewline() +{ + register char *cp1; + register char *cp2; + register LINE *lp1; + register LINE *lp2; + register LINE *lp3; + register WINDOW *wp; + + lp1 = curwp->w_dotp; + lp2 = lp1->l_fp; + if (lp2 == curbp->b_linep) { /* At the buffer end. */ + if (lp1->l_used == 0) /* Blank line. */ + lfree(lp1); + return (TRUE); + } + if (lp2->l_used <= lp1->l_size-lp1->l_used) { + cp1 = &lp1->l_text[lp1->l_used]; + cp2 = &lp2->l_text[0]; + while (cp2 != &lp2->l_text[lp2->l_used]) + *cp1++ = *cp2++; + wp = wheadp; + while (wp != NULL) { + if (wp->w_linep == lp2) + wp->w_linep = lp1; + if (wp->w_dotp == lp2) { + wp->w_dotp = lp1; + wp->w_doto += lp1->l_used; + } + if (wp->w_markp == lp2) { + wp->w_markp = lp1; + wp->w_marko += lp1->l_used; + } + wp = wp->w_wndp; + } + lp1->l_used += lp2->l_used; + lp1->l_fp = lp2->l_fp; + lp2->l_fp->l_bp = lp1; + free((char *) lp2); + return (TRUE); + } + if ((lp3=lalloc(lp1->l_used+lp2->l_used)) == NULL) + return (FALSE); + cp1 = &lp1->l_text[0]; + cp2 = &lp3->l_text[0]; + while (cp1 != &lp1->l_text[lp1->l_used]) + *cp2++ = *cp1++; + cp1 = &lp2->l_text[0]; + while (cp1 != &lp2->l_text[lp2->l_used]) + *cp2++ = *cp1++; + lp1->l_bp->l_fp = lp3; + lp3->l_fp = lp2->l_fp; + lp2->l_fp->l_bp = lp3; + lp3->l_bp = lp1->l_bp; + wp = wheadp; + while (wp != NULL) { + if (wp->w_linep==lp1 || wp->w_linep==lp2) + wp->w_linep = lp3; + if (wp->w_dotp == lp1) + wp->w_dotp = lp3; + else if (wp->w_dotp == lp2) { + wp->w_dotp = lp3; + wp->w_doto += lp1->l_used; + } + if (wp->w_markp == lp1) + wp->w_markp = lp3; + else if (wp->w_markp == lp2) { + wp->w_markp = lp3; + wp->w_marko += lp1->l_used; + } + wp = wp->w_wndp; + } + free((char *) lp1); + free((char *) lp2); + return (TRUE); +} + +/* + * Delete all of the text saved in the kill buffer. Called by commands when a + * new kill context is being created. The kill buffer array is released, just + * in case the buffer has grown to immense size. No errors. + */ +kdelete() +{ + if (kbufp != NULL) { + free((char *) kbufp); + kbufp = NULL; + kused = 0; + ksize = 0; + } +} + +/* + * Insert a character to the kill buffer, enlarging the buffer if there isn't + * any room. Always grow the buffer in chunks, on the assumption that if you + * put something in the kill buffer you are going to put more stuff there too + * later. Return TRUE if all is well, and FALSE on errors. + */ +kinsert(c) +{ + register char *nbufp; + register int i; + + if (kused == ksize) { + if ((nbufp=malloc(ksize+KBLOCK)) == NULL) + return (FALSE); + for (i=0; i<ksize; ++i) + nbufp[i] = kbufp[i]; + if (kbufp != NULL) + free((char *) kbufp); + kbufp = nbufp; + ksize += KBLOCK; + } + kbufp[kused++] = c; + return (TRUE); +} + +/* + * This function gets characters from the kill buffer. If the character index + * "n" is off the end, it returns "-1". This lets the caller just scan along + * until it gets a "-1" back. + */ +kremove(n) +{ + if (n >= kused) + return (-1); + else + return (kbufp[n] & 0xFF); +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemacs.doc Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,68 @@ + MicroEMACS control sequences for 6809 OS9 version + For Os9/68000 consult the source code. + +Note: For the Color Computer /TERM version, the <esc> key is <clear> and + <break> keys together. <ctrl> is the <clear> key. del is the <<-> + key. + + The window commands have been deleted. Therefore, there is only + one window. + +<ctrl-@> Set Mark at current position. +<ctrl-A> Move cursor to beginning of line. +<ctrl-B> Move cursor BACK one character. +<ctrl-C> Push to a new interactive command shell. +<ctrl-D> DELETE current current character. +<ctrl-E> Move cursor to END of line. +<ctrl-F> Move cursor FORWARD one character. +<ctrl-G> Abort any command. (shades of Teco). +<ctrl-H> (backspace) delete previous character. +<ctrl-K> KILL (delete) to end of line. +<ctrl-L> Redisplay screen. +<ctrl-N> Move cursor to NEXT line. +<ctrl-O> OPEN a new line. +<ctrl-P> Move to PREVIOUS line. +<ctrl-Q> QUOTE the next character (insert the next character typed). +<ctrl-R> REVERSE Search. +<ctrl-S> Forward SEARCH. +<ctrl-T> TRANSPOSE characters. +<ctrl-U> Enter repeat count for next command. +<ctrl-V> VIEW the next screen (scroll up one screen). +<ctrl-W> Kill region (all text between cursor and last mark set). +<ctrl-Y> YANK (undelete) last text killed (deleted). +<ctrl-Z> Save file in current buffer and exit. + +<ctrl-X>= Show buffer statistics: + X=cc Y=ll CH=$$ .=loc (nn% of total chars) +<ctrl-X>( Begin keyboard Macro. +<ctrl-X>) End keyboard Macro. +<ctrl-X>E EXECUTE keyboard macro. + +<ctrl-X><ctrl-C> Exit without saving buffers. +<ctrl-X><ctrl-N> Scroll current window up by repeat count lines. +<ctrl-X><ctrl-P> Scroll current window down by repeat count lines. + +<ctrl-X><ctrl-R> READ file into current buffer. +<ctrl-X><ctrl-S> SAVE (write) current buffer into its file. +<ctrl-X><ctrl-W> WRITE buffer to file. + +<ctrl-X><ctrl-U> UPPERCASE region between cursor and mark. +<ctrl-X><ctrl-L> LOWERCASE region between cursor and mark. + +<ctrl-X><ctrl-X> Swap cursor and mark positions. + +<del> delete previous character. + +<esc>. Set Mark at current position. +<esc>! Move current line to repeat count lines from top of window. +<esc>> Move cursor to end of buffer. +<esc>< Move cursor to beginning of buffer. +<esc>B Move cursor BACK one word. +<esc>C CAPITALIZE (Capitalize) word. +<esc>D DELETE next word. +<esc><del> DELETE previous word. +<esc>F Move cursor FORWARD one word. +<esc>L LOWERCASE (lowercase) next word. +<esc>U UPPERCASE (UPPERCASE) next word. +<esc>V VIEW the previous screen (scroll down one screen). +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemacs.hlp Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,14 @@ +Instalation: + +Os9/68000: + Vt52: rename uemacs.mak to makefile and use make. + Other: Modify makefile to use appropriate terminal module (i.e. ansi) + rather than the vt52 module. + +Os9/6809: See uemacs.mak to see what modules are needed. + +Known Problem: + The 68000 version seems to have problems editing large (or many small) +files (long before memory is exausted). The malloc routine apperently +does not work well for many small allocations. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemacs.mak Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,19 @@ +# makefile for Micro emacs for os9/68000 +# temp files on ram disk +CFLAGS = -t=/r0 + +MAINR = uemain1.r uemain2.r uemain3.r uemain4.r uemaintable.r +DISPR = uedisplay1.r uedisplay2.r uedisplay3.r +RESTR = uebasic.r uebuffer1.r uebuffer2.r uefile1.r uefile2.r uefileio.r \ + ueline1.r ueline2.r uerandom1.r uerandom2.r ueregion.r uesearch.r uespawn.r \ + uetermio.r uevt52.r uewindow.r ueword.r +RFILES = $(MAINR) $(DISPR) $(RESTR) + +# use cio libarary +umacs: $(RFILES) + cc -i $(RFILES) -f=umacs + +$(MAINR): ueed.h uemain.h +$(DISPR): ueed.h uedisplay.h +$(RESTR): ueed.h +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemain.h Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,272 @@ +/* Main header */ + +#ifdef MAINTABLE +int currow; /* Working cursor row */ +int curcol; /* Working cursor column */ +int fillcol; /* Current fill column */ +int thisflag; /* Flags, this command */ +int lastflag; /* Flags, last command */ +int curgoal; /* Goal column */ +BUFFER *curbp; /* Current buffer */ +WINDOW *curwp; /* Current window */ +BUFFER *bheadp; /* BUFFER listhead */ +WINDOW *wheadp; /* WINDOW listhead */ +BUFFER *blistp; /* Buffer list BUFFER */ +short kbdm[NKBDM] = {CTLX|')'}; /* Macro */ +short *kbdmip; /* Input for above */ +short *kbdmop; /* Output for above */ +char pat[NPAT]; /* Pattern */ +#else +extern int currow; /* Working cursor row */ +extern int curcol; /* Working cursor column */ +extern int fillcol; /* Current fill column */ +extern int thisflag; /* Flags, this command */ +extern int lastflag; /* Flags, last command */ +extern int curgoal; /* Goal column */ +extern BUFFER *curbp; /* Current buffer */ +extern WINDOW *curwp; /* Current window */ +extern BUFFER *bheadp; /* BUFFER listhead */ +extern WINDOW *wheadp; /* WINDOW listhead */ +extern BUFFER *blistp; /* Buffer list BUFFER */ +extern short kbdm[]; /* Macro */ +extern short *kbdmip; /* Input for above */ +extern short *kbdmop; /* Output for above */ +extern char pat[]; /* Pattern */ +#endif + +typedef struct { + short k_code; /* Key code */ + int (*k_fp)(); /* Routine to handle it */ +} KEYTAB; + +/* + * Command table. + * This table is *roughly* in ASCII order, left to right across the + * characters of the command. This expains the funny location of the + * control-X commands. + */ +#ifdef MAINTABLE + +extern int ctrlg(); /* Abort out of things */ +extern int quit(); /* Quit */ +extern int ctlxlp(); /* Begin macro */ +extern int ctlxrp(); /* End macro */ +extern int ctlxe(); /* Execute macro */ +extern int fileread(); /* Get a file, read only */ +extern int filevisit(); /* Get a file, read write */ +extern int filewrite(); /* Write a file */ +extern int filesave(); /* Save current file */ +extern int filename(); /* Adjust file name */ +extern int getccol(); /* Get current column */ +extern int gotobol(); /* Move to start of line */ +extern int forwchar(); /* Move forward by characters */ +extern int gotoeol(); /* Move to end of line */ +extern int backchar(); /* Move backward by characters */ +extern int forwline(); /* Move forward by lines */ +extern int backline(); /* Move backward by lines */ +extern int forwpage(); /* Move forward by pages */ +extern int backpage(); /* Move backward by pages */ +extern int gotobob(); /* Move to start of buffer */ +extern int gotoeob(); /* Move to end of buffer */ +extern int setfillcol(); /* Set fill column. */ +extern int setmark(); /* Set mark */ +extern int swapmark(); /* Swap "." and mark */ +extern int forwsearch(); /* Search forward */ +extern int backsearch(); /* Search backwards */ +extern int showcpos(); /* Show the cursor position */ +#ifndef OS9 +extern int nextwind(); /* Move to the next window */ +extern int prevwind(); /* Move to the previous window */ +extern int onlywind(); /* Make current window only one */ +extern int splitwind(); /* Split current window */ +extern int mvdnwind(); /* Move window down */ +extern int mvupwind(); /* Move window up */ +extern int enlargewind(); /* Enlarge display window. */ +extern int shrinkwind(); /* Shrink window. */ +extern int listbuffers(); /* Display list of buffers */ +extern int usebuffer(); /* Switch a window to a buffer */ +extern int killbuffer(); /* Make a buffer go away. */ +#endif +extern int reposition(); /* Reposition window */ +extern int refresh(); /* Refresh the screen */ +extern int twiddle(); /* Twiddle characters */ +extern int tab(); /* Insert tab */ +extern int newline(); /* Insert CR-LF */ +extern int indent(); /* Insert CR-LF, then indent */ +extern int openline(); /* Open up a blank line */ +extern int deblank(); /* Delete blank lines */ +extern int quote(); /* Insert literal */ +extern int backword(); /* Backup by words */ +extern int forwword(); /* Advance by words */ +extern int forwdel(); /* Forward delete */ +extern int backdel(); /* Backward delete */ +extern int killer(); /* Kill forward */ +extern int yank(); /* Yank back from killbuffer. */ +extern int upperword(); /* Upper case word. */ +extern int lowerword(); /* Lower case word. */ +extern int upperregion(); /* Upper case region. */ +extern int lowerregion(); /* Lower case region. */ +extern int capword(); /* Initial capitalize word. */ +extern int delfword(); /* Delete forward word. */ +extern int delbword(); /* Delete backward word. */ +extern int killregion(); /* Kill region. */ +extern int copyregion(); /* Copy region to kill buffer. */ +extern int spawncli(); /* Run CLI in a subjob. */ +extern int spawn(); /* Run a command in a subjob. */ +extern int quickexit(); /* low keystroke style exit. */ + +KEYTAB keytab[] = { + CTRL|'@', setmark, + CTRL|'A', gotobol, + CTRL|'B', backchar, + CTRL|'C', spawncli, /* Run CLI in subjob. */ + CTRL|'D', forwdel, + CTRL|'E', gotoeol, + CTRL|'F', forwchar, + CTRL|'G', ctrlg, + CTRL|'H', backdel, + CTRL|'I', tab, + CTRL|'J', indent, + CTRL|'K', killer, + CTRL|'L', refresh, + CTRL|'M', newline, + CTRL|'N', forwline, + CTRL|'O', openline, + CTRL|'P', backline, + CTRL|'Q', quote, /* Often unreachable */ + CTRL|'R', backsearch, + CTRL|'S', forwsearch, /* Often unreachable */ + CTRL|'T', twiddle, + CTRL|'V', forwpage, + CTRL|'W', killregion, + CTRL|'Y', yank, + CTRL|'Z', quickexit, /* quick save and exit */ +#ifndef OS9 + CTLX|CTRL|'B', listbuffers, +#endif + CTLX|CTRL|'C', quit, /* Hard quit. */ + CTLX|CTRL|'F', filename, + CTLX|CTRL|'L', lowerregion, + CTLX|CTRL|'O', deblank, +#ifndef OS9 + CTLX|CTRL|'N', mvdnwind, + CTLX|CTRL|'P', mvupwind, +#endif + CTLX|CTRL|'R', fileread, + CTLX|CTRL|'S', filesave, /* Often unreachable */ + CTLX|CTRL|'U', upperregion, +#ifndef OS9 + CTLX|CTRL|'V', filevisit, +#endif + CTLX|CTRL|'W', filewrite, + CTLX|CTRL|'X', swapmark, +#ifndef OS9 + CTLX|CTRL|'Z', shrinkwind, +#endif + CTLX|'!', spawn, /* Run 1 command. */ + CTLX|'=', showcpos, + CTLX|'(', ctlxlp, + CTLX|')', ctlxrp, +#ifndef OS9 + CTLX|'1', onlywind, + CTLX|'2', splitwind, + CTLX|'B', usebuffer, +#endif + CTLX|'E', ctlxe, + CTLX|'F', setfillcol, +#ifndef OS9 + CTLX|'K', killbuffer, + CTLX|'N', nextwind, + CTLX|'P', prevwind, + CTLX|'Z', enlargewind, +#endif + META|CTRL|'H', delbword, + META|'!', reposition, + META|'.', setmark, + META|'>', gotoeob, + META|'<', gotobob, + META|'B', backword, + META|'C', capword, + META|'D', delfword, + META|'F', forwword, + META|'L', lowerword, + META|'U', upperword, + META|'V', backpage, +#ifndef OS9 + META|'W', copyregion, +#endif + META|0x7F, delbword, + 0x7F, backdel, + 0, 0 /* Signals end of table */ +}; +#else +extern KEYTAB keytab[]; +#endif + +#define NKEYTAB (sizeof(keytab)/sizeof(keytab[0])) + +#ifdef RAINBOW + +#include "rainbow.h" + +/* + * Mapping table from the LK201 function keys to the internal EMACS character. + */ + +short lk_map[][2] = { + Up_Key, CTRL+'P', + Down_Key, CTRL+'N', + Left_Key, CTRL+'B', + Right_Key, CTRL+'F', + Shift+Left_Key, META+'B', + Shift+Right_Key, META+'F', + Control+Left_Key, CTRL+'A', + Control+Right_Key, CTRL+'E', + Prev_Scr_Key, META+'V', + Next_Scr_Key, CTRL+'V', + Shift+Up_Key, META+'<', + Shift+Down_Key, META+'>', + Cancel_Key, CTRL+'G', + Find_Key, CTRL+'S', + Shift+Find_Key, CTRL+'R', + Insert_Key, CTRL+'Y', + Options_Key, CTRL+'D', + Shift+Options_Key, META+'D', + Remove_Key, CTRL+'W', + Shift+Remove_Key, META+'W', + Select_Key, CTRL+'@', + Shift+Select_Key, CTLX+CTRL+'X', + Interrupt_Key, CTRL+'U', + Keypad_PF2, META+'L', + Keypad_PF3, META+'C', + Keypad_PF4, META+'U', + Shift+Keypad_PF2, CTLX+CTRL+'L', + Shift+Keypad_PF4, CTLX+CTRL+'U', + Keypad_1, CTLX+'1', + Keypad_2, CTLX+'2', + Do_Key, CTLX+'E', + Keypad_4, CTLX+CTRL+'B', + Keypad_5, CTLX+'B', + Keypad_6, CTLX+'K', + Resume_Key, META+'!', + Control+Next_Scr_Key, CTLX+'N', + Control+Prev_Scr_Key, CTLX+'P', + Control+Up_Key, CTLX+CTRL+'P', + Control+Down_Key, CTLX+CTRL+'N', + Help_Key, CTLX+'=', + Shift+Do_Key, CTLX+'(', + Control+Do_Key, CTLX+')', + Keypad_0, CTLX+'Z', + Shift+Keypad_0, CTLX+CTRL+'Z', + Main_Scr_Key, CTRL+'C', + Keypad_Enter, CTLX+'!', + Exit_Key, CTLX+CTRL+'C', + Shift+Exit_Key, CTRL+'Z' + }; + +#define lk_map_size (sizeof(lk_map)/2) + +#endif + +#define NULL 0 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemain1.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,129 @@ +/* + * This program is in public domain; written by Dave G. Conroy. + * This file contains the main driving routine, and some keyboard processing + * code, for the MicroEMACS screen editor. + * + * REVISION HISTORY: + * + * 1.0 Steve Wilhite, 30-Nov-85 + * - Removed the old LK201 and VT100 logic. Added code to support the + * DEC Rainbow keyboard (which is a LK201 layout) using the the Level + * 1 Console In ROM INT. See "rainbow.h" for the function key definitions +. + * + * 2.0 George Jones, 12-Dec-85 + * - Ported to Amiga. + * + * 3.0 Bob Santy, 5-Jan-86 + * - Ported to Tandy Color Computer OS9. + * - COCO version has window functions + * removed to save memory. + * - Source modules split into more, + * smaller files. + * ?.? Robert Larson + * - Os9/68000 version (OSK) + * - Fixes to ^X= command + */ + +/* #include <stdio.h> */ +#include "ueed.h" +#ifdef VMS +#include <ssdef.h> +#define GOOD (SS$_NORMAL) +#endif + +#ifndef GOOD +#define GOOD 0 +#endif + +#define MAIN1 1 +#include "uemain.h" + +main(argc, argv) +char *argv[]; +{ + register int c; + register int f; + register int n; + register int mflag; + char bname[NBUFN]; + + strcpy(bname, "main"); /* Work out the name of */ + if (argc > 1) /* the default buffer. */ + makename(bname, argv[1]); + edinit(bname); /* Buffers, windows. */ + vtinit(); /* Displays. */ + if (argc > 1) { + update(); /* You have to update */ + readin(argv[1]); /* in case "[New file]" */ + } + lastflag = 0; /* Fake last flags. */ +loop: + update(); /* Fix up the screen */ + c = getkey(); + if (mpresf != FALSE) { + mlerase(); + update(); + if (c == ' ') /* ITS EMACS does this */ + goto loop; + } + f = FALSE; + n = 1; + if (c == (CTRL|'U')) { /* ^U, start argument */ + f = TRUE; + n = 4; /* with argument of 4 */ + mflag = 0; /* that can be discarded. */ + mlwrite("Arg: 4"); + while ((c=getkey()) >='0' && c<='9' || c==(CTRL|'U') || c=='-'){ + if (c == (CTRL|'U')) + n = n*4; + /* + * If dash, and start of argument string, set arg. + * to -1. Otherwise, insert it. + */ + else if (c == '-') { + if (mflag) + break; + n = 0; + mflag = -1; + } + /* + * If first digit entered, replace previous argument + * with digit and set sign. Otherwise, append to arg. + */ + else { + if (!mflag) { + n = 0; + mflag = 1; + } + n = 10*n + c - '0'; + } + mlwrite("Arg: %d", (mflag >=0) ? n : (n ? -n : -1)); + } + /* + * Make arguments preceded by a minus sign negative and change + * the special argument "^U -" to an effective "^U -1". + */ + if (mflag == -1) { + if (n == 0) + n++; + n = -n; + } + } + if (c == (CTRL|'X')) /* ^X is a prefix */ + c = CTLX | getctl(); + if (kbdmip != NULL) { /* Save macro strokes. */ + if (c!=(CTLX|')') && kbdmip>&kbdm[NKBDM-6]) { + ctrlg(FALSE, 0); + goto loop; + } + if (f != FALSE) { + *kbdmip++ = (CTRL|'U'); + *kbdmip++ = n; + } + *kbdmip++ = c; + } + execute(c, f, n); /* Do it. */ + goto loop; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemain2.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,150 @@ +/* + * This program is in public domain; written by Dave G. Conroy. + * This file contains the main driving routine, and some keyboard processing + * code, for the MicroEMACS screen editor. + * + * REVISION HISTORY: + * + * 1.0 Steve Wilhite, 30-Nov-85 + * - Removed the old LK201 and VT100 logic. Added code to support the + * DEC Rainbow keyboard (which is a LK201 layout) using the the Level + * 1 Console In ROM INT. See "rainbow.h" for the function key definitions +. + * + * 2.0 George Jones, 12-Dec-85 + * - Ported to Amiga. + */ +#include <stdio.h> +#include "ueed.h" +#ifdef VMS +#include <ssdef.h> +#define GOOD (SS$_NORMAL) +#endif + +#ifndef GOOD +#define GOOD 0 +#endif + +#include "uemain.h" + +/* + * This is the general command execution routine. It handles the fake binding + * of all the keys to "self-insert". It also clears out the "thisflag" word, + * and arranges to move it to the "lastflag", so that the next command can + * look at it. Return the status of command. + */ +execute(c, f, n) +int c,f,n; +{ + register KEYTAB *ktp; + int status; + + status = TRUE; + ktp = &keytab[0]; /* Look in key table. */ + while (ktp->k_code) { + if (ktp->k_code == c) { + thisflag = 0; + status = (*ktp->k_fp)(f, n); + lastflag = thisflag; + return(status); + } + ++ktp; + } + + /* + * If a space was typed, fill column is defined, the argument is non- + * negative, and we are now past fill column, perform word wrap. + */ + if (c == ' ' && fillcol > 0 && n>=0 && getccol(FALSE) > fillcol) + wrapword(); + + if ((c>=0x20 && c<=0x7E) /* Self inserting. */ + || (c>=0xA0 && c<=0xFE)) { + if (n <= 0) { /* Fenceposts. */ + lastflag = 0; + } + thisflag = 0; /* For the future. */ + linsert(n, c); + lastflag = thisflag; + return(TRUE); + } else { + lastflag = 0; /* Fake last flags. */ + return(FALSE); + } +} + +/* + * Read in a key. + * Do the standard keyboard preprocessing. Convert the keys to the internal + * character set. + */ +getkey() +{ + register int c; + + c = (*term.t_getchar)(); +#ifdef DEBUG + printf("%4X",c); +#endif + +#ifdef RAINBOW + + if (c & Function_Key) + { + int i; + + for (i = 0; i < lk_map_size; i++) + if (c == lk_map[i][0]) + return lk_map[i][1]; + } + else if (c == Shift + 015) return CTRL | 'J'; + else if (c == Shift + 0x7F) return META | 0x7F; +#endif + + if (c == METACH) { /* Apply M- prefix */ +#ifdef DEBUG + printf("META"); +#endif + c = getctl(); +#ifdef DEBUG + printf("CTL=%4X",c); +#endif + return (META | c); + } + + if (c>=0x00 && c<=0x1F) /* C0 control -> C- */ + c = CTRL | (c+'@'); +#ifdef DEBUG + printf("CTRL=%4X",c); +#endif + return (c); +} + +/* + * Get a key. + * Apply control modifications to the read key. + */ +getctl() +{ + register int c; + + c = (*term.t_getchar)(); + if (c>='a' && c<='z') /* Force to upper */ + c -= 0x20; + if (c>=0x00 && c<=0x1F) /* C0 control -> C- */ + c = CTRL | (c+'@'); + return (c); +} + +/* + * Fancy quit command, as implemented by Norm. If the current buffer has + * changed do a write current buffer and exit emacs, otherwise simply exit. + */ +quickexit(f, n) +{ + if ((curbp->b_flag&BFCHG) != 0 /* Changed. */ + && (curbp->b_flag&BFTEMP) == 0) /* Real. */ + filesave(f, n); + quit(f, n); /* conditionally quit */ +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemain3.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,129 @@ +/* + * This program is in public domain; written by Dave G. Conroy. + * This file contains the main driving routine, and some keyboard processing + * code, for the MicroEMACS screen editor. + * + * REVISION HISTORY: + * + * 1.0 Steve Wilhite, 30-Nov-85 + * - Removed the old LK201 and VT100 logic. Added code to support the + * DEC Rainbow keyboard (which is a LK201 layout) using the the Level + * 1 Console In ROM INT. See "rainbow.h" for the function key definitions + * + * 2.0 George Jones, 12-Dec-85 + * - Ported to Amiga. + */ +#include <stdio.h> +#include "ueed.h" +#ifdef VMS +#include <ssdef.h> +#define GOOD (SS$_NORMAL) +#endif + +#ifndef GOOD +#define GOOD 0 +#endif + +#include "uemain.h" + +/* + * Quit command. If an argument, always quit. Otherwise confirm if a buffer + * has been changed and not written out. Normally bound to "C-X C-C". + */ +quit(f, n) +{ + register int s; + + if (f != FALSE /* Argument forces it. */ + || anycb() == FALSE /* All buffers clean. */ + || (s=mlyesno("Quit")) == TRUE) { /* User says it's OK. */ + vttidy(); + exit(GOOD); + } +} + +/* + * Begin a keyboard macro. + * Error if not at the top level in keyboard processing. Set up variables and + * return. + */ +ctlxlp(f, n) +int f,n; +{ + if (kbdmip!=NULL || kbdmop!=NULL) { + mlwrite("Not now"); + return(FALSE); + } + mlwrite("[Start macro]"); + kbdmip = &kbdm[0]; + return(TRUE); +} + +/* + * End keyboard macro. Check for the same limit conditions as the above + * routine. Set up the variables and return to the caller. + */ +ctlxrp(f, n) +int f,n; +{ + if (kbdmip == NULL) { + mlwrite("Not now"); + return(FALSE); + } + mlwrite("[End macro]"); + kbdmip = NULL; + return(TRUE); +} + +/* + * Execute a macro. + * The command argument is the number of times to loop. Quit as soon as a + * command gets an error. Return TRUE if all ok, else FALSE. + */ +ctlxe(f, n) +int f,n; +{ + register int c; + register int af; + register int an; + register int s; + + if (kbdmip!=NULL || kbdmop!=NULL) { + mlwrite("Not now"); + return(FALSE); + } + if (n <= 0) + return(FALSE); + do { + kbdmop = &kbdm[0]; + do { + af = FALSE; + an = 1; + if ((c = *kbdmop++) == (CTRL|'U')) { + af = TRUE; + an = *kbdmop++; + c = *kbdmop++; + } + s = TRUE; + } while (c!=(CTLX|')')&&(s=execute(c, af, an))==TRUE); + kbdmop = NULL; + } while (s==TRUE && --n); + return(s); +} + +/* + * Abort. + * Beep the beeper. Kill off any keyboard macro, etc., that is in progress. + * Sometimes called as a routine, to do general aborting of stuff. + */ +ctrlg(f, n) +{ + (*term.t_beep)(); + if (kbdmip != NULL) { + kbdm[0] = (CTLX|')'); + kbdmip = NULL; + } + return(TRUE); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemain4.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,63 @@ +/* + * This program is in public domain; written by Dave G. Conroy. + * This file contains the main driving routine, and some keyboard processing + * code, for the MicroEMACS screen editor. + * + * REVISION HISTORY: + * + * 1.0 Steve Wilhite, 30-Nov-85 + * - Removed the old LK201 and VT100 logic. Added code to support the + * DEC Rainbow keyboard (which is a LK201 layout) using the the Level + * 1 Console In ROM INT. See "rainbow.h" for the function key definitions + * + * 2.0 George Jones, 12-Dec-85 + * - Ported to Amiga. + */ +#include <stdio.h> +#include "ueed.h" +#ifdef VMS +#include <ssdef.h> +#define GOOD (SS$_NORMAL) +#endif + +#ifndef GOOD +#define GOOD 0 +#endif + +#define MAIN1 1 +#include "uemain.h" + +/* + * Initialize all of the buffers and windows. The buffer name is passed down + * as an argument, because the main routine may have been told to read in a + * file by default, and we want the buffer name to be right. + */ +edinit(bname) +char bname[]; +{ + register BUFFER *bp; + register WINDOW *wp; + + bp = bfind(bname, TRUE, 0); /* First buffer */ + blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */ + wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */ + if (bp==NULL || wp==NULL || blistp==NULL) + exit(1); + curbp = bp; /* Make this current */ + wheadp = wp; + curwp = wp; + wp->w_bufp = bp; + bp->b_nwnd = 1; /* Displayed. */ + wp->w_linep = bp->b_linep; + wp->w_dotp = bp->b_linep; + wp->w_wndp = /* Initialize window */ + wp->w_doto = + wp->w_markp = + wp->w_marko = + wp->w_toprow = + wp->w_force = 0; + wp->w_ntrows = term.t_nrow-1; /* "-1" for mode line. */ + wp->w_flag = WFMODE|WFHARD; /* Full. */ +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uemaintable.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,32 @@ +/* + * This program is in public domain; written by Dave G. Conroy. + * This file contains the main driving routine, and some keyboard processing + * code, for the MicroEMACS screen editor. + * + * REVISION HISTORY: + * + * 1.0 Steve Wilhite, 30-Nov-85 + * - Removed the old LK201 and VT100 logic. Added code to support the + * DEC Rainbow keyboard (which is a LK201 layout) using the the Level + * 1 Console In ROM INT. See "rainbow.h" for the function key definitions + * + * 2.0 George Jones, 12-Dec-85 + * - Ported to Amiga. + * + * 3.0 Bob Santy, 28-Dec-85 + * - Ported to OS9 Level I + */ +/* #include <stdio.h> */ +#include "ueed.h" +#ifdef VMS +#include <ssdef.h> +#define GOOD (SS$_NORMAL) +#endif + +#ifndef GOOD +#define GOOD 0 +#endif + +#define MAINTABLE 1 +#include "uemain.h" +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uerandom1.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,259 @@ +/* + * This file contains the command processing functions for a number of random + * commands. There is no functional grouping here, for sure. + */ + +#include <stdio.h> +#include "ueed.h" + +int tabsize; /* Tab size (0: use real tabs) */ + +/* + * Set fill column to n. + */ +setfillcol(f, n) +{ + fillcol = n; + return(TRUE); +} + +/* + * Display the current position of the cursor, in origin 1 X-Y coordinates, + * the character that is under the cursor (in hex), and the fraction of the + * text that is before the cursor. The displayed column is not the current + * column, but the column that would be used on an infinite width display. + * Normally this is bound to "C-X =". + */ +showcpos(f, n) +{ + register LINE *clp; + register long nch; + register long nbc; + register int cac; + register int ratio; + register int col; + register int i; + register int c; + register int nl; + register int cl; +#ifdef OSK + char mline[80]; +#endif + + clp = lforw(curbp->b_linep); /* Grovel the data. */ + nch = 0; + nl = 0; + while (clp != curbp->b_linep) { + if (clp == curwp->w_dotp) { + nbc = nch + curwp->w_doto; + cac = (curwp->w_doto < llength(clp)) + ? lgetc(clp, curwp->w_doto) + : '\n'; + cl = nl; + } + nch += llength(clp)+1; + + clp = lforw(clp); + nl++; + } + if (clp == curwp->w_dotp) { /* special case for end of buffer */ + nbc = nch; + cac = '\n'; + cl = nl; + } + col = getccol(FALSE); /* Get real column. */ + ratio = 0; /* Ratio before dot. */ + if (nch != 0) + ratio = (100L*nbc) / nch; +#ifdef OSK + /* osk objects to this varargs technique with more than 2 arguments */ + /* while I was changing things I made it display more info */ + sprintf(mline, +"X=%d Y=%d CH=0x%02X (%s%c) Line %d of %d; Char %ld of %ld (%d%%%%)", + col+1, currow+1, cac, (cac<' ')?"^":"", (cac<' ')?cac+'@':cac, + cl, nl, nbc, nch, ratio); + mlwrite(mline); +#else + /* note nl (number of lines) and cl (current line) arn't yet displayed */ + mlwrite("X=%d Y=%d CH=0x%x .=%D (%d%% of %D)", + col+1, currow+1, cac, nbc, ratio, nch); +#endif + return (TRUE); +} + +/* + * Return current column. Stop at first non-blank given TRUE argument. + */ +getccol(bflg) +int bflg; +{ + register int c, i, col; + col = 0; + for (i=0; i<curwp->w_doto; ++i) { + c = lgetc(curwp->w_dotp, i); + if (c!=' ' && c!='\t' && bflg) + break; + if (c == '\t') + col |= 0x07; + else if (c<0x20 || c==0x7F) + ++col; + ++col; + } + return(col); +} + +/* + * Twiddle the two characters on either side of dot. If dot is at the end of + * the line twiddle the two characters before it. Return with an error if dot + * is at the beginning of line; it seems to be a bit pointless to make this + * work. This fixes up a very common typo with a single stroke. Normally bound + * to "C-T". This always works within a line, so "WFEDIT" is good enough. + */ +twiddle(f, n) +{ + register LINE *dotp; + register int doto; + register int cl; + register int cr; + + dotp = curwp->w_dotp; + doto = curwp->w_doto; + if (doto==llength(dotp) && --doto<0) + return (FALSE); + cr = lgetc(dotp, doto); + if (--doto < 0) + return (FALSE); + cl = lgetc(dotp, doto); + lputc(dotp, doto+0, cr); + lputc(dotp, doto+1, cl); + lchange(WFEDIT); + return (TRUE); +} + +/* + * Quote the next character, and insert it into the buffer. All the characters + * are taken literally, with the exception of the newline, which always has + * its line splitting meaning. The character is always read, even if it is + * inserted 0 times, for regularity. Bound to "M-Q" (for me) and "C-Q" (for + * Rich, and only on terminals that don't need XON-XOFF). + */ +quote(f, n) +{ + register int s; + register int c; + + c = (*term.t_getchar)(); + if (n < 0) + return (FALSE); + if (n == 0) + return (TRUE); + if (c == '\n') { + do { + s = lnewline(); + } while (s==TRUE && --n); + return (s); + } + return (linsert(n, c)); +} + +/* + * Set tab size if given non-default argument (n <> 1). Otherwise, insert a + * tab into file. If given argument, n, of zero, change to true tabs. + * If n > 1, simulate tab stop every n-characters using spaces. This has to be + * done in this slightly funny way because the tab (in ASCII) has been turned + * into "C-I" (in 10 bit code) already. Bound to "C-I". + */ +tab(f, n) +{ + if (n < 0) + return (FALSE); + if (n == 0 || n > 1) { + tabsize = n; + return(TRUE); + } + if (! tabsize) + return(linsert(1, '\t')); + return(linsert(tabsize - (getccol(FALSE) % tabsize), ' ')); +} + +/* + * Open up some blank space. The basic plan is to insert a bunch of newlines, + * and then back up over them. Everything is done by the subcommand + * procerssors. They even handle the looping. Normally this is bound to "C-O". + */ +openline(f, n) +{ + register int i; + register int s; + + if (n < 0) + return (FALSE); + if (n == 0) + return (TRUE); + i = n; /* Insert newlines. */ + do { + s = lnewline(); + } while (s==TRUE && --i); + if (s == TRUE) /* Then back up overtop */ + s = backchar(f, n); /* of them all. */ + return (s); +} + +/* + * Insert a newline. Bound to "C-M". If you are at the end of the line and the + * next line is a blank line, just move into the blank line. This makes "C-O" + * and "C-X C-O" work nicely, and reduces the ammount of screen update that + * has to be done. This would not be as critical if screen update were a lot + * more efficient. + */ +newline(f, n) +{ + int nicol; + register LINE *lp; + register int s; + + if (n < 0) + + return (FALSE); + while (n--) { + lp = curwp->w_dotp; + if (llength(lp) == curwp->w_doto + && lp != curbp->b_linep + && llength(lforw(lp)) == 0) { + if ((s=forwchar(FALSE, 1)) != TRUE) + return (s); + } else if ((s=lnewline()) != TRUE) + return (s); + } + return (TRUE); +} + +/* + * Delete blank lines around dot. What this command does depends if dot is + * sitting on a blank line. If dot is sitting on a blank line, this command + * deletes all the blank lines above and below the current line. If it is + * sitting on a non blank line then it deletes all of the blank lines after + * the line. Normally this command is bound to "C-X C-O". Any argument is + * ignored. + */ +deblank(f, n) +{ + register LINE *lp1; + register LINE *lp2; + register int nld; + + lp1 = curwp->w_dotp; + while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep) + lp1 = lp2; + lp2 = lp1; + nld = 0; + while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0) + ++nld; + if (nld == 0) + return (TRUE); + curwp->w_dotp = lforw(lp1); + curwp->w_doto = 0; + return (ldelete(nld)); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uerandom2.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,156 @@ +/* + * This file contains the command processing functions for a number of random + * commands. There is no functional grouping here, for sure. + */ + +#include <stdio.h> +#include "ueed.h" + +/* + * Insert a newline, then enough tabs and spaces to duplicate the indentation + * of the previous line. Assumes tabs are every eight characters. Quite simple. + * Figure out the indentation of the current line. Insert a newline by calling + * the standard routine. Insert the indentation by inserting the right number + * of tabs and spaces. Return TRUE if all ok. Return FALSE if one of the + * subcomands failed. Normally bound to "C-J". + */ +indent(f, n) +{ + register int nicol; + register int c; + register int i; + + if (n < 0) + return (FALSE); + while (n--) { + nicol = 0; + for (i=0; i<llength(curwp->w_dotp); ++i) { + c = lgetc(curwp->w_dotp, i); + if (c!=' ' && c!='\t') + break; + if (c == '\t') + nicol |= 0x07; + ++nicol; + } + if (lnewline() == FALSE + || ((i=nicol/8)!=0 && linsert(i, '\t')==FALSE) + || ((i=nicol%8)!=0 && linsert(i, ' ')==FALSE)) + return (FALSE); + } + return (TRUE); +} + +/* + * Delete forward. This is real easy, because the basic delete routine does + * all of the work. Watches for negative arguments, and does the right thing. + * If any argument is present, it kills rather than deletes, to prevent loss + * of text if typed with a big arg +ument. Normally bound to "C-D". + */ +forwdel(f, n) +{ + if (n < 0) + return (backdel(f, -n)); + + if (f != FALSE) { /* Really a kill. */ + if ((lastflag&CFKILL) == 0) + kdelete(); + thisflag |= CFKILL; + } + return (ldelete(n, f)); +} + +/* + * Delete backwards. This is quite easy too, because it's all done with other + * functions. Just move the cursor back, and delete forwards. Like delete + * forward, this actually does a kill if presented with an argument. Bound to + * both "RUBOUT" and "C-H". + */ +backdel(f, n) +{ + register int s; + + if (n < 0) + return (forwdel(f, -n)); + if (f != FALSE) { /* Really a kill. */ + if ((lastflag&CFKILL) == 0) + kdelete(); + thisflag |= CFKILL; + } + if ((s=backchar(f, n)) == TRUE) + s = ldelete(n, f); + return (s); +} + +/* + * Kill text. If called without an argument, it kills from dot to the end of + * the line, unless it is at the end of the line, when it kills the newline. + * If called with an argument of 0, it kills from the start of the line to dot. + * If called with a positive argument, it kills from dot forward over that + * number of newlines. If called with a negative argument it kills backwards + * that number of newlines. Normally bound to "C-K". + */ +killer(f, n) +int f,n; +{ + register int chunk; + register LINE *nextp; + + if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */ + kdelete(); /* last wasn't a kill. */ + thisflag |= CFKILL; + if (f == FALSE) { + chunk = llength(curwp->w_dotp)-curwp->w_doto; + if (chunk == 0) + chunk = 1; + } else if (n == 0) { + chunk = curwp->w_doto; + curwp->w_doto = 0; + } else if (n > 0) { + chunk = llength(curwp->w_dotp)-curwp->w_doto+1; + nextp = lforw(curwp->w_dotp); + while (--n) { + if (nextp == curbp->b_linep) + return (FALSE); + chunk += llength(nextp)+1; + nextp = lforw(nextp); + } + } else { + mlwrite("neg kill"); + return (FALSE); + } + return (ldelete(chunk, TRUE)); +} + +/* + * Yank text back from the kill buffer. This is really easy. All of the work + * is done by the standard insert routines. All you do is run the loop, and + * check for errors. Bound to "C-Y". The blank lines are inserted with a call + * to "newline" instead of a call to "lnewline" so that the magic stuff that + * happens when you type a carriage return also happens when a carriage return + * is yanked back from the kill buffer. + */ +yank(f, n) +{ + register int c; + register int i; + extern int kused; + + if (n < 0) + return (FALSE); + while (n--) { + i = 0; + while ((c=kremove(i)) >= 0) { + if (c == '\n') { + if (newline(FALSE, 1) == FALSE) + return (FALSE); + } else { + if (linsert(1, c) == FALSE) + return (FALSE); + } + ++i; + } + } + return (TRUE); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/ueregion.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,201 @@ +/* + * The routines in this file + * deal with the region, that magic space + * between "." and mark. Some functions are + * commands. Some functions are just for + * internal use. + */ +#include <stdio.h> +#include "ueed.h" + +/* + * Kill the region. Ask "getregion" + * to figure out the bounds of the region. + * Move "." to the start, and kill the characters. + * Bound to "C-W". + */ +killregion(f, n) +{ + register int s; + REGION region; + + if ((s=getregion(®ion)) != TRUE) + return (s); + if ((lastflag&CFKILL) == 0) /* This is a kill type */ + kdelete(); /* command, so do magic */ + thisflag |= CFKILL; /* kill buffer stuff. */ + curwp->w_dotp = region.r_linep; + curwp->w_doto = region.r_offset; + return (ldelete(region.r_size, TRUE)); +} + +/* + * Copy all of the characters in the + * region to the kill buffer. Don't move dot + * at all. This is a bit like a kill region followed + * by a yank. Bound to "M-W". + */ +copyregion(f, n) +{ + register LINE *linep; + register int loffs; + register int s; + REGION region; + + if ((s=getregion(®ion)) != TRUE) + return (s); + if ((lastflag&CFKILL) == 0) /* Kill type command. */ + kdelete(); + thisflag |= CFKILL; + linep = region.r_linep; /* Current line. */ + loffs = region.r_offset; /* Current offset. */ + while (region.r_size--) { + if (loffs == llength(linep)) { /* End of line. */ + if ((s=kinsert('\n')) != TRUE) + return (s); + linep = lforw(linep); + loffs = 0; + } else { /* Middle of line. */ + if ((s=kinsert(lgetc(linep, loffs))) != TRUE) + return (s); + ++loffs; + } + } + return (TRUE); +} + +/* + * Lower case region. Zap all of the upper + * case characters in the region to lower case. Use + * the region code to set the limits. Scan the buffer, + * doing the changes. Call "lchange" to ensure that + * redisplay is done in all buffers. Bound to + * "C-X C-L". + */ +lowerregion(f, n) +{ + register LINE *linep; + register int loffs; + register int c; + register int s; + REGION region; + + if ((s=getregion(®ion)) != TRUE) + return (s); + lchange(WFHARD); + linep = region.r_linep; + loffs = region.r_offset; + while (region.r_size--) { + if (loffs == llength(linep)) { + linep = lforw(linep); + loffs = 0; + } else { + c = lgetc(linep, loffs); + if (c>='A' && c<='Z') + lputc(linep, loffs, c+'a'-'A'); + ++loffs; + } + } + return (TRUE); +} + +/* + * Upper case region. Zap all of the lower + * case characters in the region to upper case. Use + * the region code to set the limits. Scan the buffer, + * doing the changes. Call "lchange" to ensure that + * redisplay is done in all buffers. Bound to + * "C-X C-L". + */ +upperregion(f, n) +{ + register LINE *linep; + register int loffs; + register int c; + register int s; + REGION region; + + if ((s=getregion(®ion)) != TRUE) + return (s); + lchange(WFHARD); + linep = region.r_linep; + loffs = region.r_offset; + while (region.r_size--) { + if (loffs == llength(linep)) { + linep = lforw(linep); + loffs = 0; + } else { + c = lgetc(linep, loffs); + if (c>='a' && c<='z') + lputc(linep, loffs, c-'a'+'A'); + ++loffs; + } + } + return (TRUE); +} + +/* + * This routine figures out the + * bounds of the region in the current window, and + * fills in the fields of the "REGION" structure pointed + * to by "rp". Because the dot and mark are usually very + * close together, we scan outward from dot looking for + * mark. This should save time. Return a standard code. + * Callers of this routine should be prepared to get + * an "ABORT" status; we might make this have the + * conform thing later. + */ +getregion(rp) +register REGION *rp; +{ + register LINE *flp; + register LINE *blp; + register int fsize; + register int bsize; + + if (curwp->w_markp == NULL) { + mlwrite("No mark set in this window"); + return (FALSE); + } + if (curwp->w_dotp == curwp->w_markp) { + rp->r_linep = curwp->w_dotp; + if (curwp->w_doto < curwp->w_marko) { + rp->r_offset = curwp->w_doto; + rp->r_size = curwp->w_marko-curwp->w_doto; + } else { + rp->r_offset = curwp->w_marko; + rp->r_size = curwp->w_doto-curwp->w_marko; + } + return (TRUE); + } + blp = curwp->w_dotp; + bsize = curwp->w_doto; + flp = curwp->w_dotp; + fsize = llength(flp)-curwp->w_doto+1; + while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) { + if (flp != curbp->b_linep) { + flp = lforw(flp); + if (flp == curwp->w_markp) { + rp->r_linep = curwp->w_dotp; + rp->r_offset = curwp->w_doto; + rp->r_size = fsize+curwp->w_marko; + return (TRUE); + } + fsize += llength(flp)+1; + } + if (lback(blp) != curbp->b_linep) { + blp = lback(blp); + bsize += llength(blp)+1; + if (blp == curwp->w_markp) { + rp->r_linep = blp; + rp->r_offset = curwp->w_marko; + rp->r_size = bsize - curwp->w_marko; + return (TRUE); + } + } + } + mlwrite("Bug: lost mark"); + return (FALSE); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uesearch.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,243 @@ +/* + * The functions in this file implement commands that search in the forward + * and backward directions. There are no special characters in the search + * strings. Probably should have a regular expression search, or something + * like that. + * + * REVISION HISTORY: + * + * ? Steve Wilhite, 1-Dec-85 + * - massive cleanup on code. + */ + +#include <stdio.h> +#include "ueed.h" + +/* + * Search forward. Get a search string from the user, and search, beginning at + * ".", for the string. If found, reset the "." to be just after the match + * string, and [perhaps] repaint the display. Bound to "C-S". + */ +forwsearch(f, n) + { + register LINE *clp; + register int cbo; + register LINE*tlp; + register int tbo; + register int c; + register char *pp; + register int s; + + if ((s = readpattern("Search")) != TRUE) + return (s); + + clp = curwp->w_dotp; + cbo = curwp->w_doto; + + while (clp != curbp->b_linep) + { + if (cbo == llength(clp)) + { + clp = lforw(clp); + cbo = 0; + c = '\n'; + } + else + c = lgetc(clp, cbo++); + + if (eq(c, pat[0]) != FALSE) + { + tlp = clp; + tbo = cbo; + pp = &pat[1]; + + while (*pp != 0) + { + if (tlp == curbp->b_linep) + goto fail; + + if (tbo == llength(tlp)) + { + tlp = lforw(tlp); + tbo = 0; + c = '\n'; + } + else + c = lgetc(tlp, tbo++); + + if (eq(c, *pp++) == FALSE) + goto fail; + } + + curwp->w_dotp = tlp; + curwp->w_doto = tbo; + curwp->w_flag |= WFMOVE; + return (TRUE); + } +fail:; + } + + mlwrite("Not found"); + return (FALSE); + } + +/* + * Reverse search. Get a search string from the user, and search, starting at + * "." and proceeding toward the front of the buffer. If found "." is left + * pointing at the first character of the pattern [the last character that was + j matched]. Bound to "C-R". + */ +backsearch(f, n) + { + register LINE *clp; + register int cbo; + register LINE *tlp; + register int tbo; + register int c; + register char *epp; + register char *pp; + register int s; + + if ((s = readpattern("Reverse search")) != TRUE) + return (s); + + for (epp = &pat[0]; epp[1] != 0; ++epp) + ; + + clp = curwp->w_dotp; + cbo = curwp->w_doto; + + for (;;) + { + if (cbo == 0) + { + clp = lback(clp); + + if (clp == curbp->b_linep) + { + mlwrite("Not found"); + return (FALSE); + } + + cbo = llength(clp)+1; + } + + if (--cbo == llength(clp)) + c = '\n'; + else + c = lgetc(clp, cbo); + + if (eq(c, *epp) != FALSE) + { + tlp = clp; + tbo = cbo; + pp = epp; + + while (pp != &pat[0]) + { + if (tbo == 0) + { + tlp = lback(tlp); + if (tlp == curbp->b_linep) + goto fail; + + tbo = llength(tlp)+1; + } + + if (--tbo == llength(tlp)) + c = '\n'; + else + c = lgetc(tlp, tbo); + + if (eq(c, *--pp) == FALSE) + goto fail; + } + + curwp->w_dotp = tlp; + curwp->w_doto = tbo; + curwp->w_flag |= WFMOVE; + return (TRUE); + } +fail:; + } + } + +/* + * Compare two characters. The "bc" comes from the buffer. It has it's case + * folded out. The "pc" is from the pattern. + */ +eq(bc, pc) + int bc; + int pc; + { + if (bc>='a' && bc<='z') + bc -= 0x20; + + if (pc>='a' && pc<='z') + pc -= 0x20; + + if (bc == pc) + return (TRUE); + + return (FALSE); + } + +/* + * Read a pattern. Stash it in the external variable "pat". The "pat" is not + * updated if the user types in an empty line. If the user typed an empty line, + * and there is no old pattern, it is an error. Display the old pattern, in the + * style of Jeff Lomicka. There is some do-it-yourself control expansion. + */ +readpattern(prompt) + char *prompt; + { + register char *cp1; + register char *cp2; + register int c; + register int s; + char tpat[NPAT+20]; + + cp1 = &tpat[0]; /* Copy prompt */ + cp2 = prompt; + + while ((c = *cp2++) != '\0') + *cp1++ = c; + + if (pat[0] != '\0') /* Old pattern */ + { + *cp1++ = ' '; + *cp1++ = '['; + cp2 = &pat[0]; + + while ((c = *cp2++) != 0) + { + if (cp1 < &tpat[NPAT+20-6]) /* "??]: \0" */ + { + if (c<0x20 || c==0x7F) { + *cp1++ = '^'; + c ^= 0x40; + } + else if (c == '%') /* Map "%" to */ + *cp1++ = c; /* "%%". */ + + *cp1++ = c; + } + } + + *cp1++ = ']'; + } + + *cp1++ = ':'; /* Finish prompt */ + *cp1++ = ' '; + *cp1++ = '\0'; + s = mlreply(tpat, tpat, NPAT); /* Read pattern */ + + if (s == TRUE) /* Specified */ + strcpy(pat, tpat); + else if (s == FALSE && pat[0] != 0) /* CR, but old one */ + s = TRUE; + + return (s); + } + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uespawn.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,256 @@ +/* + * The routines in this file are called to create a subjob running a command + * interpreter. This code is a big fat nothing on CP/M-86. You lose. + */ +#include <stdio.h> +#include "ueed.h" + +#ifdef AMIGA +#define NEW 1006 +#endif + +#ifdef VMS +#define EFN 0 /* Event flag. */ + +#include <ssdef.h> /* Random headers. */ +#include <stsdef.h> +#include <descrip.h> +#include <iodef.h> + +extern int oldmode[]; /* In "termio.c" */ +extern int newmode[]; /* In "termio.c" */ +extern short iochan; /* In "termio.c" */ +#endif + +#ifdef MSDOS +#include <dos.h> +#endif + +#ifdef V7 +#include <signal.h> +#endif + +#ifdef OSK +#include <sgstat.h> +extern struct sgbuf ostate; /* In "termio.c" */ +extern struct sgbuf nstate; /* In "termio.c" */ +#endif + +/* + * Create a subjob with a copy of the command intrepreter in it. When the + * command interpreter exits, mark the screen as garbage so that you do a full + * repaint. Bound to "C-C". The message at the start in VMS puts out a newline. + * Under some (unknown) condition, you don't get one free when DCL starts up. + */ +spawncli(f, n) +{ +#ifdef AMIGA + long newcli; + + newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW); + mlwrite("[Starting new CLI]"); + sgarbf = TRUE; + Execute("", newcli, 0); + Close(newcli); + return(TRUE); +#endif +#ifdef VMS + movecursor(term.t_nrow, 0); /* In last line. */ + mlputs("[Starting DCL]\r\n"); + (*term.t_flush)(); /* Ignore "ttcol". */ + sgarbf = TRUE; + return (sys(NULL)); /* NULL => DCL. */ +#endif +#ifdef CPM + mlwrite("Not in CP/M-86"); +#endif +#ifdef MSDOS + movecursor(term.t_nrow, 0); /* Seek to last line. */ + (*term.t_flush)(); + sys("\\command.com", ""); /* Run CLI. */ + sgarbf = TRUE; + return(TRUE); +#endif +#ifdef V7 + register char *cp; + char *getenv(); + movecursor(term.t_nrow, 0); /* Seek to last line. */ + (*term.t_flush)(); + ttclose(); /* stty to old settings */ + if ((cp = getenv("SHELL")) != NULL && *cp != '\0') + system(cp); + else + system("exec /bin/sh"); + sgarbf = TRUE; + sleep(2); + ttopen(); + return(TRUE); +#endif +#ifdef OSK + register char *cp; + char *getenv(); + movecursor(term.t_nrow, 0); /* Seek to last line. */ + (*term.t_flush)(); + setstat(0, 0, &ostate); /* stty to old settings */ + if ((cp = getenv("SHELL")) != NULL && *cp != '\0') + system(cp); + else + system("shell"); + sgarbf = TRUE; + setstat(0, 0, &nstate); + return(TRUE); +#endif +} + +/* + * Run a one-liner in a subjob. When the command returns, wait for a single + * character to be typed, then mark the screen as garbage so a full repaint is + * done. Bound to "C-X !". + */ +spawn(f, n) +{ + register int s; + char line[NLINE]; +#ifdef AMIGA + long newcli; + + newcli = Open("CON:1/1/639/199/MicroEmacs Subprocess", NEW); + if ((s=mlreply("CLI command: ", line, NLINE)) != TRUE) + return (s); + Execute(line,0,newcli); + Close(newcli); + while ((*term.t_getchar)() != '\r') /* Pause. */ + ; + sgarbf = TRUE; + return(TRUE); +#endif +#ifdef VMS + if ((s=mlreply("DCL command: ", line, NLINE)) != TRUE) + return (s); + (*term.t_putchar)('\n'); /* Already have '\r' */ + (*term.t_flush)(); + s = sys(line); /* Run the command. */ + mlputs("\r\n\n[End]"); /* Pause. */ + (*term.t_flush)(); + while ((*term.t_getchar)() != '\r') + ; + sgarbf = TRUE; + return (s); +#endif +#ifdef CPM + mlwrite("Not in CP/M-86"); + return (FALSE); +#endif +#ifdef MSDOS + if ((s=mlreply("MS-DOS command: ", line, NLINE)) != TRUE) + return (s); + system(line); + while ((*term.t_getchar)() != '\r') /* Pause. */ + ; + sgarbf = TRUE; + return (TRUE); +#endif +#ifdef V7 + if ((s=mlreply("! ", line, NLINE)) != TRUE) + return (s); + (*term.t_putchar)('\n'); /* Already have '\r' */ + (*term.t_flush)(); + ttclose(); /* stty to old modes */ + system(line); + sleep(2); + ttopen(); + mlputs("[End]"); /* Pause. */ + (*term.t_flush)(); + while ((s = (*term.t_getchar)()) != '\r' && s != ' ') + ; + sgarbf = TRUE; + return (TRUE); +#endif +#ifdef OSK + if ((s=mlreply("! ", line, NLINE)) != TRUE) + return (s); + (*term.t_putchar)('\l'); /* Already have '\r' */ + (*term.t_flush)(); + setstat(0, 0, &ostate); /* stty to old modes */ + s=system(line); + setstat(0, 0, &nstate); + mlputs("[End]"); /* Pause. */ + (*term.t_flush)(); + while ((s = (*term.t_getchar)()) != '\r' && s != ' ') + ; + sgarbf = TRUE; + return (TRUE); +#endif +} + +#ifdef VMS +/* + * Run a command. The "cmd" is a pointer to a command string, or NULL if you + * want to run a copy of DCL in the subjob (this is how the standard routine + * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in + * and the way out, because DCL does not want the channel to be in raw mode. + */ +sys(cmd) +register char *cmd; +{ + struct dsc$descriptor cdsc; + struct dsc$descriptor *cdscp; + long status; + long substatus; + long iosb[2]; + + status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, + oldmode, sizeof(oldmode), 0, 0, 0, 0); + if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) + return (FALSE); + cdscp = NULL; /* Assume DCL. */ + if (cmd != NULL) { /* Build descriptor. */ + cdsc.dsc$a_pointer = cmd; + cdsc.dsc$w_length = strlen(cmd); + cdsc.dsc$b_dtype = DSC$K_DTYPE_T; + cdsc.dsc$b_class = DSC$K_CLASS_S; + cdscp = &cdsc; + } + status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0); + if (status != SS$_NORMAL) + substatus = status; + status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, + newmode, sizeof(newmode), 0, 0, 0, 0); + if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) + return (FALSE); + if ((substatus&STS$M_SUCCESS) == 0) /* Command failed. */ + return (FALSE); + return (TRUE); +} +#endif + +#ifdef MSDOS +/* + * This routine, once again by Bob McNamara, is a C translation of the "system" + * routine in the MWC-86 run time library. It differs from the "system" routine + * in that it does not unconditionally append the string ".exe" to the end of + * the command name. We needed to do this because we want to be able to spawn + * off "command.com". We really do not understand what it does, but if you don't + * do it exactly "malloc" starts doing very very strange things. + */ +sys(cmd, tail) +char *cmd; +char *tail; +{ +#ifdef MWC_86 + register unsigned n; + extern char *__end; + + n = __end + 15; + n >>= 4; + n = ((n + dsreg() + 16) & 0xFFF0) + 16; + return(execall(cmd, tail, n)); +#endif + +#ifdef LATTICE + return forklp(cmd, tail, NULL); +#endif +} +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uetcap.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,130 @@ +#include <stdio.h> +#include "ueed.h" + +#ifdef TERMCAP + +#define NROW 24 +#define NCOL 80 +#define BEL 0x07 +#define ESC 0x1B + + +extern int ttopen(); +extern int ttgetc(); +extern int ttputc(); +extern int ttflush(); +extern int ttclose(); +extern int tcapmove(); +extern int tcapeeol(); +extern int tcapeeop(); +extern int tcapbeep(); +extern int tcapopen(); +extern int tput(); +extern char *tgoto(); + +#define TCAPSLEN 315 + +char tcapbuf[TCAPSLEN]; +char PC, + *CM, + *CL, + *CE, + *UP, + *CD; + + +TERM term = { + NROW-1, + NCOL, + &tcapopen, + &ttclose, + &ttgetc, + &ttputc, + &ttflush, + &tcapmove, + &tcapeeol, + &tcapeeop, + &tcapbeep +}; + +tcapopen() + +{ + char *getenv(); + char *t, *p, *tgetstr(); + char tcbuf[1024]; + char *tv_stype; + char err_str[72]; + + if ((tv_stype = getenv("TERM")) == NULL) + { + puts("Environment variable TERM not defined!"); + exit(1); + } + + if((tgetent(tcbuf, tv_stype)) != 1) + { + sprintf(err_str, "Unknown terminal type %s!", tv_stype); + puts(err_str); + exit(1); + } + + p = tcapbuf; + t = tgetstr("pc", &p); + if(t) + PC = *t; + + CD = tgetstr("cd", &p); + CM = tgetstr("cm", &p); + CE = tgetstr("ce", &p); + UP = tgetstr("up", &p); + + if(CD == NULL || CM == NULL || CE == NULL || UP == NULL) + { + puts("Incomplete termcap entry\n"); + exit(1); + } + + if (p >= &tcapbuf[TCAPSLEN]) + { + puts("Terminal description too big!\n"); + exit(1); + } + ttopen(); +} +tcapmove(row, col) +register int row, col; +{ + putpad(tgoto(CM, col, row)); +} + +tcapeeol() +{ + putpad(CE); +} + +tcapeeop() +{ + putpad(CD); + +} + +tcapbeep() +{ + ttputc(BEL); +} + +putpad(str) +char *str; +{ + tputs(str, 1, ttputc); +} + +putnpad(str, n) +char *str; +{ + tputs(str, n, ttputc); +} +#endif TERMCAP + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uetermio.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,384 @@ +/* + * The functions in this file negotiate with the operating system for + * characters, and write characters in a barely buffered fashion on the display. + * All operating systems. + */ +#include <stdio.h> +#include "ueed.h" + +#ifdef AMIGA +#define NEW 1006 +#define LEN 1 + +static long terminal; +#endif + +#ifdef VMS +#include <stsdef.h> +#include <ssdef.h> +#include <descrip.h> +#include <iodef.h> +#include <ttdef.h> + +#define NIBUF 128 /* Input buffer size */ +#define NOBUF 1024 /* MM says bug buffers win! */ +#define EFN 0 /* Event flag */ + + +char obuf[NOBUF]; /* Output buffer */ +int nobuf; /* # of bytes in above */ +char ibuf[NIBUF]; /* Input buffer */ +int nibuf; /* # of bytes in above */ +int ibufi; /* Read index */ +int oldmode[2]; /* Old TTY mode bits */ +int newmode[2]; /* New TTY mode bits */ +short iochan; /* TTY I/O channel */ +#endif + +#ifdef CPM +#include <bdos.h> +#endif + +#ifdef MSDOS +#undef LATTICE +#include <dos.h> +#endif + +#ifdef RAINBOW +#include "rainbow.h" +#endif + +#ifdef V7 +#include <sgtty.h> /* for stty/gtty functions */ + +struct sgttyb ostate; /* saved tty state */ +struct sgttyb nstate; /* values for editor mode */ +#endif + +#ifdef OS9 +#include <sgstat.h> /* for stty/gtty functions */ +struct sgbuf ostate; /* saved tty state */ +struct sgbuf nstate; /* values for editor mode */ +#endif + +#ifdef OSK +#include <sgstat.h> /* same as os9/6809 */ +struct sgbuf ostate; +struct sgbuf nstate; +#endif + +/* + * This function is called once to set up the terminal device streams. + * On VMS, it translates SYS$INPUT until it finds the terminal, then assigns + * a channel to it and sets it raw. On CPM it is a no-op. + */ +ttopen() +{ +#ifdef AMIGA + terminal = Open("RAW:1/1/639/199/MicroEmacs", NEW); +#endif +#ifdef VMS + struct dsc$descriptor idsc; + struct dsc$descriptor odsc; + char oname[40]; + int iosb[2]; + int status; + + odsc.dsc$a_pointer = "SYS$INPUT"; + odsc.dsc$w_length = strlen(odsc.dsc$a_pointer); + odsc.dsc$b_dtype = DSC$K_DTYPE_T; + odsc.dsc$b_class = DSC$K_CLASS_S; + idsc.dsc$b_dtype = DSC$K_DTYPE_T; + idsc.dsc$b_class = DSC$K_CLASS_S; + do { + idsc.dsc$a_pointer = odsc.dsc$a_pointer; + idsc.dsc$w_length = odsc.dsc$w_length; + odsc.dsc$a_pointer = &oname[0]; + odsc.dsc$w_length = sizeof(oname); + status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc); + if (status!=SS$_NORMAL && status!=SS$_NOTRAN) + exit(status); + if (oname[0] == 0x1B) { + odsc.dsc$a_pointer += 4; + odsc.dsc$w_length -= 4; + } + } while (status == SS$_NORMAL); + status = SYS$ASSIGN(&odsc, &iochan, 0, 0); + if (status != SS$_NORMAL) + exit(status); + status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0, + oldmode, sizeof(oldmode), 0, 0, 0, 0); + if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) + exit(status); + newmode[0] = oldmode[0]; + newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO; + status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, + newmode, sizeof(newmode), 0, 0, 0, 0); + if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) + exit(status); +#endif +#ifdef CPM +#endif +#ifdef MSDOS +#endif +#ifdef V7 + gtty(1, &ostate); /* save old state */ + gtty(1, &nstate); /* get base of new state */ + nstate.sg_flags |= RAW; + nstate.sg_flags &= ~(ECHO|CRMOD); /* no echo for now... */ + stty(1, &nstate); /* set mode */ +#endif +#ifdef OS9 + getstat(0, 0, &ostate); /* save old state */ + getstat(0, 0, &nstate); /* get base of new state * +/ + nstate.sg_echo = 0; /* no echo for now... */ + nstate.sg_bellch = 0; + nstate.sg_bsech = 0; + nstate.sg_kbach = 0; + nstate.sg_kbich = 0; + nstate.sg_psch = 0; + nstate.sg_dulnch = 0; + nstate.sg_rlnch = 0; + nstate.sg_eofch = 0; + nstate.sg_eorch = 0; + nstate.sg_dlnch = 0; + nstate.sg_bspch = 0; + nstate.sg_pause = 0; + nstate.sg_alf = 0; + nstate.sg_backsp = 0; + setstat(0, 0, &nstate); /* set mode */ + stdin->_flag &= ~_SCF; + stdin->_flag |= _RBF; + stdout->_flag &= ~_SCF; + stdout->_flag |= _RBF; + setbuf(stdout,0); +#endif +#ifdef OSK + getstat(0, 0, &ostate); /* save old state */ + getstat(0, 0, &nstate); /* get base of new state * +/ + nstate.sg_echo = 0; /* no echo for now... */ + nstate.sg_bellch = 0; + nstate.sg_bsech = 0; + nstate.sg_kbach = 0; + + nstate.sg_kbich = 0; + nstate.sg_psch = 0; + nstate.sg_dulnch = 0; + nstate.sg_rlnch = 0; + nstate.sg_eofch = 0; + nstate.sg_eorch = 0; + nstate.sg_dlnch = 0; + nstate.sg_bspch = 0; + nstate.sg_pause = 0; + nstate.sg_alf = 0; + nstate.sg_backsp = 0; + nstate.sg_xoff =0; /* new for OSK */ + nstate.sg_xon =0; + setstat(0, 0, &nstate); /* set mode */ + stdin->_flag &= ~_SCF; + stdin->_flag |= _RBF; + stdout->_flag &= ~_SCF; + stdout->_flag |= _RBF; + setbuf(stdout,0); +#endif +} + +/* + * This function gets called just before we go back home to the command + * interpreter. On VMS it puts the terminal back in a reasonable state. + * Another no-operation on CPM. + */ +ttclose() +{ +#ifdef AMIGA + Close(terminal); +#endif +#ifdef VMS + int status; + int iosb[1]; + + ttflush(); + status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, + oldmode, sizeof(oldmode), 0, 0, 0, 0); + if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) + exit(status); + status = SYS$DASSGN(iochan); + if (status != SS$_NORMAL) + exit(status); +#endif +#ifdef CPM +#endif +#ifdef MSDOS +#endif +#ifdef V7 + stty(1, &ostate); +#endif +#ifdef OS9 + setstat(0, 0, &ostate); +#endif +#ifdef OSK + setstat(0, 0, &ostate); +#endif +} + +/* + * Write a character to the display. On VMS, terminal output is buffered, and + * we just put the characters in the big array, after checking for overflow. + * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on + * MS-DOS (use the very very raw console output routine). + */ +ttputc(c) +char c; +{ +#ifdef AMIGA + Write(terminal, &c, LEN); +#endif +#ifdef VMS + if (nobuf >= NOBUF) + ttflush(); + obuf[nobuf++] = c; +#endif + +#ifdef CPM + bios(BCONOUT, c, 0); +#endif + +#ifdef MSDOS & CWC86 + dosb(CONDIO, c, 0); +#endif + +#ifdef RAINBOW + Put_Char(c); /* fast video */ +#endif + +#ifdef V7 + fputc(c, stdout); +#endif +#ifdef OS9 + putc(c, stdout); +#endif +#ifdef OSK + putc(c, stdout); +#endif +} + +/* + * Flush terminal buffer. Does real work where the terminal output is buffered + * up. A no-operation on systems where byte at a time terminal I/O is done. + */ +ttflush() +{ +#ifdef AMIGA +#endif +#ifdef VMS + int status; + int iosb[2]; + + status = SS$_NORMAL; + if (nobuf != 0) { + status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT, + iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0); + if (status == SS$_NORMAL) + status = iosb[0] & 0xFFFF; + nobuf = 0; + } + return (status); +#endif +#ifdef CPM +#endif +#ifdef MSDOS +#endif +#ifdef V7 + fflush(stdout); +#endif +#ifdef OS9 + fflush(stdout); +#endif +#ifdef OSK + fflush(stdout); +#endif +} + +/* + * Read a character from the terminal, performing no editing and doing no echo + * at all. More complex in VMS that almost anyplace else, which figures. Very + * simple on CPM, because the system can do exactly what you want. + */ +ttgetc() +{ +#ifdef AMIGA + char ch; + + Read(terminal, &ch, LEN); + return (int) ch; +#endif +#ifdef VMS + int status; + int iosb[2]; + int term[2]; + + while (ibufi >= nibuf) { + ibufi = 0; + term[0] = 0; + term[1] = 0; + status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED, + iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0); + if (status != SS$_NORMAL) + exit(status); + status = iosb[0] & 0xFFFF; + if (status!=SS$_NORMAL && status!=SS$_TIMEOUT) + exit(status); + nibuf = (iosb[0]>>16) + (iosb[1]>>16); + if (nibuf == 0) { + status = SYS$QIOW(EFN, iochan, IO$_READLBLK, + iosb, 0, 0, ibuf, 1, 0, term, 0, 0); + if (status != SS$_NORMAL + || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL) + exit(status); + nibuf = (iosb[0]>>16) + (iosb[1]>>16); + } + } + return (ibuf[ibufi++] & 0xFF); /* Allow multinational */ +#endif + +#ifdef CPM + return (biosb(BCONIN, 0, 0)); +#endif + +#ifdef RAINBOW + int Ch; + + while ((Ch = Read_Keyboard()) < 0); + + if ((Ch & Function_Key) == 0) + if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177)) + Ch &= 0xFF; + + return Ch; +#endif + +#ifdef MSDOS +#ifdef MWC86 + return (dosb(CONRAW, 0, 0)); +#endif +#endif + +#ifdef V7 + return(fgetc(stdin)); +#endif +#ifdef OS9 + char ch; + + read(0, &ch, 1); + return((int)ch); +#endif +#ifdef OSK + char ch; + + read(0, &ch, 1); + return((int)ch); +#endif +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uevt52.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,99 @@ +/* + * The routines in this file + * provide support for VT52 style terminals + * over a serial line. The serial I/O services are + * provided by routines in "termio.c". It compiles + * into nothing if not a VT52 style device. The + * bell on the VT52 is terrible, so the "beep" + * routine is conditionalized on defining BEL. + */ +#include <stdio.h> +#include "ueed.h" + +#ifdef VT52 + +#define NROW 24 /* Screen size. */ +#define NCOL 80 /* Edit if you want to. */ +#define BIAS 0x20 /* Origin 0 coordinate bias. */ +#define ESC 0x1B /* ESC character. */ +#define BEL 0x07 /* ascii bell character */ + +extern int ttopen(); /* Forward references. */ +extern int ttgetc(); +extern int ttputc(); +extern int ttflush(); +extern int ttclose(); +extern int vt52move(); +extern int vt52eeol(); +extern int vt52eeop(); +extern int vt52beep(); +extern int vt52open(); + +/* + * Dispatch table. All the + * hard fields just point into the + * terminal I/O code. + */ +TERM term = { + NROW-1, + NCOL, + vt52open, + ttclose, + ttgetc, + ttputc, + ttflush, + vt52move, + vt52eeol, + vt52eeop, + vt52beep +}; + +vt52move(row, col) +{ + ttputc(ESC); + ttputc('Y'); + ttputc(row+BIAS); + ttputc(col+BIAS); +} + +vt52eeol() +{ + ttputc(ESC); + ttputc('K'); +} + +vt52eeop() +{ + ttputc(ESC); + ttputc('J'); +} + +vt52beep() +{ +#ifdef BEL + ttputc(BEL); + ttflush(); +#endif +} + +#endif + +vt52open() +{ +#ifdef V7 + register char *cp; + char *getenv(); + + if ((cp = getenv("TERM")) == NULL) { + puts("Shell variable TERM not defined!"); + exit(1); + } + if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) { + puts("Terminal type not 'vt52'or 'z19' !"); + exit(1); + } +#endif + ttopen(); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/uewindow.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,381 @@ +/* + * Window management. Some of the functions are internal, and some are + * attached to keys that the user actually types. + */ + +#include <stdio.h> +#include "ueed.h" + +/* + * Reposition dot in the current window to line "n". If the argument is + * positive, it is that line. If it is negative it is that line from the + * bottom. If it is 0 the window is centered (this is what the standard + * redisplay code does). With no argument it defaults to 1. Bound to M-!. + * Because of the default, it works like in Gosling. + */ +reposition(f, n) + { + curwp->w_force = n; + curwp->w_flag |= WFFORCE; + return (TRUE); + } + +/* + * Refresh the screen. With no argument, it just does the refresh. With an + * argument it recenters "." in the current window. Bound to "C-L". + */ +refresh(f, n) + { + if (f == FALSE) + sgarbf = TRUE; + else + { + curwp->w_force = 0; /* Center dot. */ + curwp->w_flag |= WFFORCE; + } + + return (TRUE); + } + +#ifndef OS9 +/* + * The command make the next window (next => down the screen) the current + * window. There are no real errors, although the command does nothing if + * there is only 1 window on the screen. Bound to "C-X C-N". + */ +nextwind(f, n) + { + register WINDOW *wp; + + if ((wp = curwp->w_wndp) == NULL) + wp = wheadp; + + curwp = wp; + curbp = wp->w_bufp; + return (TRUE); + } + +/* + * This command makes the previous window (previous => up the screen) the + * current window. There arn't any errors, although the command does not do a + * lot if there is 1 window. + */ +prevwind(f, n) + { + register WINDOW *wp1; + register WINDOW *wp2; + + wp1 = wheadp; + + wp2 = curwp; + + if (wp1 == wp2) + wp2 = NULL; + + while (wp1->w_wndp != wp2) + wp1 = wp1->w_wndp; + + curwp = wp1; + curbp = wp1->w_bufp; + return (TRUE); + } + +/* + * This command moves the current window down by "arg" lines. Recompute the + * top line in the window. The move up and move down code is almost completely + * the same; most of the work has to do with reframing the window, and picking + * a new dot. We share the code by having "move down" just be an interface to + * "move up". Magic. Bound to "C-X C-N". + */ +mvdnwind(f, n) + int n; + { + return (mvupwind(f, -n)); + } + +/* + * Move the current window up by "arg" lines. Recompute the new top line of + * the window. Look to see if "." is still on the screen. If it is, you win. + * If it isn't, then move "." to center it in the new framing of the window + * (this command does not really move "."; it moves the frame). Bound to + * "C-X C-P". + */ +mvupwind(f, n) + int n; + { + register LINE *lp; + register int i; + + lp = curwp->w_linep; + + if (n < 0) + { + while (n++ && lp!=curbp->b_linep) + lp = lforw(lp); + } + else + { + while (n-- && lback(lp)!=curbp->b_linep) + lp = lback(lp); + } + + curwp->w_linep = lp; + curwp->w_flag |= WFHARD; /* Mode line is OK. */ + + for (i = 0; i < curwp->w_ntrows; ++i) + { + if (lp == curwp->w_dotp) + return (TRUE); + if (lp == curbp->b_linep) + break; + lp = lforw(lp); + } + + lp = curwp->w_linep; + i = curwp->w_ntrows/2; + + while (i-- && lp != curbp->b_linep) + lp = lforw(lp); + + curwp->w_dotp = lp; + curwp->w_doto = 0; + return (TRUE); + } + +/* + * This command makes the current window the only window on the screen. Bound + * to "C-X 1". Try to set the framing so that "." does not have to move on the + * display. Some care has to be taken to keep the values of dot and mark in + * the buffer structures right if the distruction of a window makes a buffer + * become undisplayed. + */ +onlywind(f, n) +{ + register WINDOW *wp; + register LINE *lp; + register int i; + + while (wheadp != curwp) { + wp = wheadp; + wheadp = wp->w_wndp; + if (--wp->w_bufp->b_nwnd == 0) { + wp->w_bufp->b_dotp = wp->w_dotp; + wp->w_bufp->b_doto = wp->w_doto; + wp->w_bufp->b_markp = wp->w_markp; + wp->w_bufp->b_marko = wp->w_marko; + } + free((char *) wp); + } + while (curwp->w_wndp != NULL) { + wp = curwp->w_wndp; + curwp->w_wndp = wp->w_wndp; + if (--wp->w_bufp->b_nwnd == 0) { + wp->w_bufp->b_dotp = wp->w_dotp; + wp->w_bufp->b_doto = wp->w_doto; + wp->w_bufp->b_markp = wp->w_markp; + wp->w_bufp->b_marko = wp->w_marko; + } + free((char *) wp); + } + lp = curwp->w_linep; + i = curwp->w_toprow; + while (i!=0 && lback(lp)!=curbp->b_linep) { + --i; + lp = lback(lp); + } + curwp->w_toprow = 0; + curwp->w_ntrows = term.t_nrow-1; + curwp->w_linep = lp; + curwp->w_flag |= WFMODE|WFHARD; + return (TRUE); +} + +/* + * Split the current window. A window smaller than 3 lines cannot be split. + * The only other error that is possible is a "malloc" failure allocating the + * structure for the new window. Bound to "C-X 2". + */ +splitwind(f, n) +{ + register WINDOW *wp; + register LINE *lp; + register int ntru; + register int ntrl; + register int ntrd; + register WINDOW *wp1; + register WINDOW *wp2; + + if (curwp->w_ntrows < 3) { + mlwrite("Cannot split a %d line window", curwp->w_ntrows); + return (FALSE); + } + if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) { + mlwrite("Cannot allocate WINDOW block"); + return (FALSE); + } + ++curbp->b_nwnd; /* Displayed twice. */ + wp->w_bufp = curbp; + wp->w_dotp = curwp->w_dotp; + wp->w_doto = curwp->w_doto; + wp->w_markp = curwp->w_markp; + wp->w_marko = curwp->w_marko; + wp->w_flag = 0; + wp->w_force = 0; + ntru = (curwp->w_ntrows-1) / 2; /* Upper size */ + ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */ + lp = curwp->w_linep; + ntrd = 0; + while (lp != curwp->w_dotp) { + ++ntrd; + lp = lforw(lp); + } + lp = curwp->w_linep; + if (ntrd <= ntru) { /* Old is upper window. */ + if (ntrd == ntru) /* Hit mode line. */ + lp = lforw(lp); + curwp->w_ntrows = ntru; + wp->w_wndp = curwp->w_wndp; + curwp->w_wndp = wp; + wp->w_toprow = curwp->w_toprow+ntru+1; + wp->w_ntrows = ntrl; + } else { /* Old is lower window */ + wp1 = NULL; + wp2 = wheadp; + while (wp2 != curwp) { + wp1 = wp2; + wp2 = wp2->w_wndp; + } + if (wp1 == NULL) + wheadp = wp; + else + wp1->w_wndp = wp; + wp->w_wndp = curwp; + wp->w_toprow = curwp->w_toprow; + wp->w_ntrows = ntru; + ++ntru; /* Mode line. */ + curwp->w_toprow += ntru; + curwp->w_ntrows = ntrl; + while (ntru--) + lp = lforw(lp); + } + curwp->w_linep = lp; /* Adjust the top lines */ + wp->w_linep = lp; /* if necessary. */ + curwp->w_flag |= WFMODE|WFHARD; + wp->w_flag |= WFMODE|WFHARD; + + return (TRUE); +} + +/* + * Enlarge the current window. Find the window that loses space. Make sure it + * is big enough. If so, hack the window descriptions, and ask redisplay to do + * all the hard work. You don't just set "force reframe" because dot would + * move. Bound to "C-X Z". + */ +enlargewind(f, n) +{ + register WINDOW *adjwp; + register LINE *lp; + register int i; + + if (n < 0) + return (shrinkwind(f, -n)); + if (wheadp->w_wndp == NULL) { + mlwrite("Only one window"); + return (FALSE); + } + if ((adjwp=curwp->w_wndp) == NULL) { + adjwp = wheadp; + while (adjwp->w_wndp != curwp) + adjwp = adjwp->w_wndp; + } + if (adjwp->w_ntrows <= n) { + mlwrite("Impossible change"); + return (FALSE); + } + if (curwp->w_wndp == adjwp) { /* Shrink below. */ + lp = adjwp->w_linep; + for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i) + lp = lforw(lp); + adjwp->w_linep = lp; + adjwp->w_toprow += n; + } else { /* Shrink above. */ + lp = curwp->w_linep; + for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i) + lp = lback(lp); + curwp->w_linep = lp; + curwp->w_toprow -= n; + } + curwp->w_ntrows += n; + adjwp->w_ntrows -= n; + curwp->w_flag |= WFMODE|WFHARD; + adjwp->w_flag |= WFMODE|WFHARD; + return (TRUE); +} + +/* + * Shrink the current window. Find the window that gains space. Hack at the + * window descriptions. Ask the redisplay to do all the hard work. Bound to + * "C-X C-Z". + */ +shrinkwind(f, n) +{ + register WINDOW *adjwp; + register LINE *lp; + register int i; + + if (n < 0) + return (enlargewind(f, -n)); + if (wheadp->w_wndp == NULL) { + mlwrite("Only one window"); + return (FALSE); + } + if ((adjwp=curwp->w_wndp) == NULL) { + adjwp = wheadp; + while (adjwp->w_wndp != curwp) + adjwp = adjwp->w_wndp; + } + if (curwp->w_ntrows <= n) { + mlwrite("Impossible change"); + return (FALSE); + } + if (curwp->w_wndp == adjwp) { /* Grow below. */ + lp = adjwp->w_linep; + for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i) + lp = lback(lp); + adjwp->w_linep = lp; + adjwp->w_toprow -= n; + } else { /* Grow above. */ + lp = curwp->w_linep; + for (i=0; i<n && lp!=curbp->b_linep; ++i) + lp = lforw(lp); + curwp->w_linep = lp; + curwp->w_toprow += n; + } + curwp->w_ntrows -= n; + adjwp->w_ntrows += n; + curwp->w_flag |= WFMODE|WFHARD; + adjwp->w_flag |= WFMODE|WFHARD; + return (TRUE); +} + +/* + * Pick a window for a pop-up. Split the screen if there is only one window. + * Pick the uppermost window that isn't the current window. An LRU algorithm + * might be better. Return a pointer, or NULL on error. + */ +WINDOW * +wpopup() +{ + register WINDOW *wp; + + if (wheadp->w_wndp == NULL /* Only 1 window */ + && splitwind(FALSE, 0) == FALSE) /* and it won't split */ + return (NULL); + wp = wheadp; /* Find window to use */ + while (wp!=NULL && wp==curwp) + wp = wp->w_wndp; + return (wp); +} +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/uemacs/ueword.c Sun Feb 23 21:26:32 2003 +0000 @@ -0,0 +1,274 @@ +/* + * The routines in this file implement commands that work word at a time. + * There are all sorts of word mode commands. If I do any sentence and/or + * paragraph mode commands, they are likely to be put in this file. + */ + +#include <stdio.h> +#include "ueed.h" + + +/* Word wrap on n-spaces. Back-over whatever precedes the point on the current + * line and stop on the first word-break or the beginning of the line. If we + * reach the beginning of the line, jump back to the end of the word and start + * a new line. Otherwise, break the line at the word-break, eat it, and jump + * back to the end of the word. + * NOTE: This function may leaving trailing blanks. + * Returns TRUE on success, FALSE on errors. + */ +wrapword(n) +int n; +{ + register int cnt, oldp; + oldp = curwp->w_dotp; + cnt = -1; + do { + cnt++; + if (! backchar(NULL, 1)) + return(FALSE); + } + while (! inword()); + if (! backword(NULL, 1)) + return(FALSE); + if (oldp == (int) (curwp->w_dotp && curwp->w_doto)) { + if (! backdel(NULL, 1)) + return(FALSE); + if (! newline(NULL, 1)) + return(FALSE); + } + return(forwword(NULL, 1) && forwchar(NULL, cnt)); +} + +/* + * Move the cursor backward by "n" words. All of the details of motion are + * performed by the "backchar" and "forwchar" routines. Error if you try to + * move beyond the buffers. + */ +backword(f, n) +{ + if (n < 0) + return (forwword(f, -n)); + if (backchar(FALSE, 1) == FALSE) + return (FALSE); + while (n--) { + while (inword() == FALSE) { + if (backchar(FALSE, 1) == FALSE) + return (FALSE); + } + while (inword() != FALSE) { + if (backchar(FALSE, 1) == FALSE) + return (FALSE); + } + } + return (forwchar(FALSE, 1)); +} + +/* + * Move the cursor forward by the specified number of words. All of the motion + * is done by "forwchar". Error if you try and move beyond the buffer's end. + */ +forwword(f, n) +{ + if (n < 0) + return (backword(f, -n)); + while (n--) { + while (inword() == FALSE) { + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + while (inword() != FALSE) { + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + } + return (TRUE); +} + +/* + * Move the cursor forward by the specified number of words. As you move, + * convert any characters to upper case. Error if you try and move beyond the + * end of the buffer. Bound to "M-U". + */ +upperword(f, n) +{ + register int c; + + if (n < 0) + return (FALSE); + while (n--) { + while (inword() == FALSE) { + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + while (inword() != FALSE) { + c = lgetc(curwp->w_dotp, curwp->w_doto); + if (c>='a' && c<='z') { + c -= 'a'-'A'; + lputc(curwp->w_dotp, curwp->w_doto, c); + lchange(WFHARD); + } + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + } + return (TRUE); +} + +/* + * Move the cursor forward by the specified number of words. As you move + * convert characters to lower case. Error if you try and move over the end of + * the buffer. Bound to "M-L". + */ +lowerword(f, n) +{ + register int c; + + if (n < 0) + return (FALSE); + while (n--) { + while (inword() == FALSE) { + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + while (inword() != FALSE) { + c = lgetc(curwp->w_dotp, curwp->w_doto); + if (c>='A' && c<='Z') { + c += 'a'-'A'; + lputc(curwp->w_dotp, curwp->w_doto, c); + lchange(WFHARD); + } + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + } + return (TRUE); +} + +/* + * Move the cursor forward by the specified number of words. As you move + * convert the first character of the word to upper case, and subsequent + * characters to lower case. Error if you try and move past the end of the + * buffer. Bound to "M-C". + */ +capword(f, n) +{ + register int c; + + if (n < 0) + return (FALSE); + while (n--) { + while (inword() == FALSE) { + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + if (inword() != FALSE) { + c = lgetc(curwp->w_dotp, curwp->w_doto); + if (c>='a' && c<='z') { + c -= 'a'-'A'; + lputc(curwp->w_dotp, curwp->w_doto, c); + lchange(WFHARD); + } + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + while (inword() != FALSE) { + c = lgetc(curwp->w_dotp, curwp->w_doto); + if (c>='A' && c<='Z') { + c += 'a'-'A'; + lputc(curwp->w_dotp, curwp->w_doto, c); + lchange(WFHARD); + } + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + } + } + } + return (TRUE); +} + +/* + * Kill forward by "n" words. Remember the location of dot. Move forward by + * the right number of words. Put dot back where it was and issue the kill + * command for the right number of characters. Bound to "M-D". + */ +delfword(f, n) +{ + register int size; + register LINE *dotp; + register int doto; + + if (n < 0) + return (FALSE); + dotp = curwp->w_dotp; + doto = curwp->w_doto; + size = 0; + while (n--) { + while (inword() == FALSE) { + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + ++size; + } + while (inword() != FALSE) { + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + ++size; + + } + } + curwp->w_dotp = dotp; + curwp->w_doto = doto; + return (ldelete(size, TRUE)); +} + +/* + * Kill backwards by "n" words. Move backwards by the desired number of words, + * counting the characters. When dot is finally moved to its resting place, + * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace". + */ +delbword(f, n) +{ + register int size; + + if (n < 0) + return (FALSE); + if (backchar(FALSE, 1) == FALSE) + return (FALSE); + size = 0; + while (n--) { + while (inword() == FALSE) { + if (backchar(FALSE, 1) == FALSE) + return (FALSE); + ++size; + } + while (inword() != FALSE) { + if (backchar(FALSE, 1) == FALSE) + return (FALSE); + ++size; + } + } + if (forwchar(FALSE, 1) == FALSE) + return (FALSE); + return (ldelete(size, TRUE)); +} + +/* + * Return TRUE if the character at dot is a character that is considered to be + * part of a word. The word character list is hard coded. Should be setable. + */ +inword() +{ + register int c; + + if (curwp->w_doto == llength(curwp->w_dotp)) + return (FALSE); + c = lgetc(curwp->w_dotp, curwp->w_doto); + if (c>='a' && c<='z') + return (TRUE); + if (c>='A' && c<='Z') + return (TRUE); + if (c>='0' && c<='9') + return (TRUE); + if (c=='$' || c=='_') /* For identifiers */ + return (TRUE); + return (FALSE); +} +