🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #24757

Uemail source (2 of 12)

#24757
From: RDROYA01
Date: Wed, 04 Feb 1987 13:35
1363 lines
52730 bytes
#       This is a shell archive.
#       Remove everything above and including the cut line.
#       Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
#       Run the following text with /bin/sh to create:
#       main.c
#       keybrd.c
# This archive created: Tue Feb  3 19:12:55 1987
cat << \SHAR_EOF > main.c
/*
 * This program is in public domain; written by Dave G. Conroy.
 * This file contains the main driving routine for the Micro-
 * EMACS screen editor.  This version began as the original
 * small version by DGC.  It has been extensively expanded
 * using versions 35 (a hybrid) and 36 (a direct descendent).
 * This version includes a number of text functions that are
 * not found in others and a word wrap algorithm different from
 * 35 or 36.  It also contains a kermit module, real page movement,
 * printer support and a shell command.  It is sort of a cross
 * between ME and Perfect Writer version 1.03.
 */
 
#include <stdio.h>
#include <ctype.h>
#include <osbind.h>
#include "ed.h"
#if ST
#include "keycode.h"
#endif
 
#if     VMS
#include        <ssdef.h>
#define GOOD    (SS$_NORMAL)
#endif
 
#ifndef GOOD
#define GOOD    0
#endif
 
char *version = "v. 33 25-January-1987";
 
int     currow;                         /* Working cursor row           */
int     curcol;                         /* Working cursor column        */
int     fillcol = 76;                   /* Current fill column          */
int     indcol;                         /* Current indent column        */
int     thisflag;                       /* Flags, this command          */
int     lastflag;                       /* Flags, last command          */
int     curgoal;                        /* Goal column                  */
int     isnprint;                       /* Print buffer in use          */
int     glmode = BMNWRAP;               /* Begin in fundamental mode    */
BUFFER  *curbp;                         /* Current buffer               */
WINDOW  *curwp;                         /* Current window               */
BUFFER  *bheadp;                        /* BUFFER listhead              */
WINDOW  *wheadp;                        /* WINDOW listhead              */
BUFFER  *blistp = NULL;                 /* Buffer list BUFFER           */
BUFFER  *bmacrp = NULL;                 /* Compiled macros BUFFER       */
short   kbdm[NKBDM] = CTLX|')';         /* Macro                        */
short   *kbdmip;                        /* Input  for above             */
short   *kbdmop;                        /* Output for above             */
char    pat[NPAT];                      /* Pattern                      */
char    rpat[NPAT];                     /* Replacement pattern          */
char    prnhdr[NPAT];                   /* Print header                 */
char    prndate[NPAT];                  /* Print date                   */
char    lastbuf[NBUFN];                 /* Last buffer name             */
char    defpath[128];                   /* default path name            */
int     defdrive;                       /* default drive                */
long    buserr;                         /* Address of gemdos busserr    */
long    adderr;                         /* Address of gemdos address err*/
long    progend;                        /* end of program after init    */
 
main(argc, argv)
int argc;
char *argv[];
{
        register int    c;
        register int    f;
        register int    n;
        register int    mflag;
        register int    prncnt;
        register int    basec;
        extern   int    errexit();
        extern   long   sbrk();
 
#if     ALCYON
        fclose(stdin);                          /* reduce overhead for */
        fclose(stdout);                         /* unused file pointers */
        fclose(stderr);
#endif
        isnprint = FALSE;
        prncnt = 0;
 
        if (access("cc.ini",4) == NULL)         /* cc drive assignments */
                commfil(FALSE,HUGE);            /* and function key bind*/
        strcpy(lastbuf, "main");                /* Work out the name of */
        if (argc > 1)                           /* the default buffer.  */
                makename(lastbuf, argv[1]);
        edinit(lastbuf);                        /* Buffers, windows.    */
        vtinit();                               /* Displays.            */
        update();
#if     ST
        defdrive = Dgetdrv();
        Dgetpath(defpath,0);
        buserr = Setexc(2,-1L);
        adderr = Setexc(3,-1L);
        Setexc(2,&errexit);                     /* Clean up screen on err */
        Setexc(3,&errexit);
#endif
        if (access("uemail.mcr",4) == NULL)     /* default macro file   */
                {
                update();
                loadmac(FALSE);
                }
        progend = sbrk(0);
        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    */
 
        /* This is the print buffer code.  It's very rudimentary, but it
         * works as long as the buffer in the printer does not get filled.
         * On the initial call to the function print(), the printer is
         * sent one 1536 byte buffer of data and isnprint is set to
         * TRUE.  From then on the printer is sent 384 bytes of data after
         * an arbitrary number of keystrokes is entered if the printer
         * is ready.
         */
 
        if(isnprint)                            /* We are printing a file */
                if (prncnt++ > 16)              /* Keystroke count      */
                        if(PRNRDY)              /* Check LST: status */
                                {
                                prnbuf();       /* Send a buffer full */
                                prncnt = 0;
                                }
        f = getkey();
        if (shiftstatus == 17 || shiftstatus == 18)     /* CapsLock + Shift */
                c = tolower(f);
        else
                c = f;
        if (mpresf != FALSE) {
                mlerase();
                update();
        }
        f = FALSE;
        n = 1;
 
        /* do META-# processing if needed */
 
        basec = c & ~META;              /* strip meta char off if there */
        if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) {
                 f = TRUE;               /* there is a # arg */
                 n = 0;             /* start with a zero default */
                 mflag = 1;             /* current minus flag */
                 c = basec;             /* strip the META */
                 while ((c >= '0' && c <= '9') || (c == '-')) {
                          if (c == '-') {
                                   /* already hit a minus or digit? */
                                   if ((mflag == -1) || (n != 0))
                                            break;
                                   mflag = -1;
                          } else {
                                   n = n * 10 + (c - '0');
                          }
                          if ((n == 0) && (mflag == -1))  /* lonely - */
                                   mlwrite("Arg:");
                          else
                                   mlwrite("Arg: %d",n * mflag);
 
                          c = getkey();   /* get the next key */
                 }
                 n = n * mflag;  /* figure in the sign */
        }
 
        /* ^U expansion */
 
        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       */
                mlwrite("C-X: ");
                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;
}
 
/*
 * 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         */
        wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window         */
        if (bp==NULL || wp==NULL)
                exit(1);
        curbp  = bp;                            /* Make this current    */
        wheadp = wp;
        curwp  = wp;
        wp->w_wndp  = NULL;                     /* Initialize window    */
        wp->w_bufp  = bp;
        bp->b_nwnd  = 1;                        /* Displayed.           */
        wp->w_linep = bp->b_linep;
        wp->w_dotp  = bp->b_linep;
        wp->w_doto  = 0;
        wp->w_markp = wp->w_dotp;
        wp->w_marko = 0;
        wp->w_toprow = 0;
        wp->w_ntrows = term.t_nrow-1;           /* "-1" for mode line.  */
        wp->w_force = 0;
        wp->w_flag  = WFMODE|WFHARD;            /* Full.                */
}
 
/*
 * Read in a key.
 * Do the standard keyboard preprocessing.
 * Convert the keys to the internal character set. On
 * the LK201, which lacks a reasonable ESC key, make the
 * grave accent a meta key too; this is a fairly common
 * customization around Digital. Also read and decode
 * the arrow keys, and other special keys. This is
 * done in Rainbow mode; does this work on all
 * the terminals with LK201 keyboards?
 */
getkey()
{
        register int    c;
#if     LK201
        register int    n;
loop:
        c = (*term.t_getchar)();
        if (c == AGRAVE) {                      /* Alternate M- prefix. */
                c = getctl();
                return (META | c);
        }
        if (c == METACH) {                      /* M-, or special key.  */
                c = (*term.t_getchar)();
                if (c == '[') {                 /* Arrows and extras.   */
                        c = (*term.t_getchar)();
                        if (c == 'A')
                                return (CTRL | 'P');
                        if (c == 'B')
                                return (CTRL | 'N');
                        if (c == 'C')
                                return (CTRL | 'F');
                        if (c == 'D')
                                return (CTRL | 'B');
                        if (c>='0' && c<='9') {
                                n = 0;
                                do {
                                        n = 10*n + c - '0';
                                        c = (*term.t_getchar)();
                                } while (c>='0' && c<='9');
                                if (c=='~' && n<=34 && (c=lkmap[n])!=0)
                                        return (c);
                        }
                        goto loop;
                }
                if (c == 'O') {
                        c = (*term.t_getchar)();
                        if (c == 'P')           /* PF1 => M-X (Future)  */
                                return (META | 'X');
                        if (c == 'Q')           /* PF2 => C-Q           */
                                return (CTRL | 'Q');
                        if (c == 'R')           /* PF3 => C-S           */
                                return (CTRL | 'S');
                        if (c == 'S')           /* PF4 => C-R           */
                                return (CTRL | 'R');
                        goto loop;
                }
                if (c>='a' && c<='z')           /* Force to upper       */
                        c -= 0x20;
                if (c>=0x00 && c<=0x1F)         /* C0 control -> C-     */
                        c = CTRL | (c+'@');
                return (META | c);
        }
#endif
#if     VT100
loop:
        c = (*term.t_getchar)();
        if (c == METACH) {                      /* Apply M- prefix      */
                c = (*term.t_getchar)();
                if (c == '[') {                 /* Arrow keys.          */
                        c = (*term.t_getchar)();
                        if (c == 'A')
                                return (CTRL | 'P');
                        if (c == 'B')
                                return (CTRL | 'N');
                        if (c == 'C')
                                return (CTRL | 'F');
                        if (c == 'D')
                                return (CTRL | 'B');
                        goto loop;
                }
                if (c == 'O') {
                        c = (*term.t_getchar)();
                        if (c == 'P')           /* PF1 => M-X (Future)  */
                                return (META | 'X');
                        if (c == 'Q')           /* PF2 => C-Q           */
                                return (CTRL | 'Q');
                        if (c == 'R')           /* PF3 => C-S           */
                                return (CTRL | 'S');
                        if (c == 'S')           /* PF4 => C-R           */
                                return (CTRL | 'R');
                        goto loop;
                }
                if (c>='a' && c<='z')           /* Force to upper       */
                        c -= 0x20;
                if (c>=0x00 && c<=0x1F)         /* C0 control -> C-     */
                        c = CTRL | (c+'@');
                return (META | c);
        }
#endif
        c = (*term.t_getchar)();
#if     ST
        if (scancode == 0x70 && shiftstatus != 16)
                return (CTRL|'X');
#endif
        if (c == METACH) {                      /* Apply M- prefix      */
                mlwrite("Meta: ");
                c = getctl();
                return (META | c);
        }
        if (c == CTRLCH) {                      /* Apply C- prefix      */
                c = getctl();
                return (CTRL | c);
        }
        if (c == CTMECH) {                      /* Apply C-M- prefix    */
                c = getctl();
                return (CTRL | META | c);
        }
#if     ST
        /* use special keys or number pad (code >= 0x63) ?
         * 0x03 = scancode for ^@ (setmark).
         */
        if ((c == NULL && scancode != 0x03) || scancode >= 0x4a)
                if (scancode > 0x32)
                        {
                        /* if CapsLock and number pad, use real numbers */
                        if (shiftstatus == 16 && (scancode > 0x62 ||
                                scancode == 0x4a || scancode == 0x4e))
                                return(c);
                        else
                                return (SPEC | scancode);
                        }
                else    {
                        c = keyscan[scancode];
                        return (META | c);
                        }
#endif
        if (c>=0x00 && c<=0x1F)                 /* C0 control -> C-     */
                c = CTRL | (c+'@');
        return (c);
}
 
/*
 * Get a key.
 * Apply control modifications
 * to the read key.
 */
getctl()
{
        register int    c;
 
        c = (*term.t_getchar)();
#if     ST
        if (scancode == 0x70 && shiftstatus != 16)
                return (SPEC|'p');
#endif
        if (c>='a' && c<='z')                   /* Force to upper       */
                c -= 0x20;
        if (c>=0x00 && c<=0x1F)                 /* C0 control -> C-     */
                c = CTRL | (c+'@');
        return (c);
}
 
#if     ST
/* ERREXIT  Since this toy insists on Bus errors for so many memory
 * accesses, we need a way to exit gracefully.
 */
errexit()
{
        if(mlyesno("FATAL: Buss error. Attempt to save files")!=TRUE)
                quit(TRUE,FALSE);
        quit(FALSE,FALSE);
        exit(-1);
}
#endif
 
/*
/*
 * Fancy quit command, as implemented
 * by Norm. If any buffer has changed
 * write that buffer out. Otherwise simply exit.
 */
quickexit(f, n)
int f, n;
{
        register BUFFER *bp;    /* for buffer scan */
 
        bp = bheadp;
        while (bp != NULL) {
                if ((bp->b_flag&BFCHG) != 0     /* Changed.             */
                && (bp->b_flag&BFTEMP) == 0){   /* Real.        */
                        curbp = bp;
                        mlwrite("[Saving %s]",bp->b_fname);
                                filesave(f, n);
                }
        bp = bp->b_bufp;                /* next buffer */
        }
        quit(f, n);                             /* conditionally quit   */
}
 
/*
 * 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)
int f, n;
{
        register BUFFER *bp;    /* for buffer scan */
        register int    s;
 
        bp = bheadp;
        if (f != FALSE                          /* Argument forces it.  */
        || (anycb() == FALSE                    /* All buffers clean.   */
        && isnprint == FALSE)) {                /* Are we printing?     */
                vttidy();
#if     ST
                Dsetdrv(defdrive);
                Dsetpath(defpath);
                Setexc(2,buserr);
                Setexc(3,adderr);
#endif
                exit((n!=FALSE) ? GOOD: -1);
        }
        if (isnprint)
                if ((s=mlyesno("Abandon printing")) != TRUE)
                        return(s);
        while (bp != NULL) {
                if ((bp->b_flag&BFCHG) != 0     /* Changed.     */
                && (bp->b_flag&BFTEMP) == 0){   /* Real.        */
                        curbp = bp;
                        mlwrite("Save %s [y/n]?",bp->b_fname);
                        switch(ttgetc()) {
                                case 'Y':
                                case 'y':
                                        filesave(f, n);
                                        break;
                                case 0x07:
                                        return(ctrlg(f,n));
                                default:
                                        break;
                        }
                }
        bp = bp->b_bufp;                /* next buffer */
        }
        if (anycb())    /* check once more */
                if ((s=mlyesno("Abandon modified buffers")) != TRUE)
                        return(s);
        vttidy();
#if     ST
        Setexc(2,buserr);
        Setexc(3,adderr);
#endif
        exit((n!=FALSE) ? GOOD : -1);
}
 
/*
 * 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)
register 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 (TRUE);
        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)
int f, n;
{
        (*term.t_beep)();
        if (kbdmip != NULL) {
                kbdm[0] = (CTLX|')');
                kbdmip  = NULL;
        }
        mlwrite("Aborting");
        return (ABORT);
}
 
/* CLEARFLAG clears buffer change flag.  Bound to M-~
 */
clearflag(f, n)
register int f, n;
{
        curwp->w_bufp->b_flag &= ~BFCHG;
        upmode();
        return(TRUE);
}
 
/* UNKNCOM  Returns abort and beeps keyboard.  Bound to unused keys.
 */
unkncom(f, n)
register int f, n;
{
        mlwrite("Unbound command!");
        (*term.t_beep)();
        return(ABORT);
}
 
/* RETVERSION  Returns version string.  Bound to CTLX *.
 */
retversion(f, n)
register int f, n;
{
        return(mlwrite("Writer: D. G. Conroy Revised: R. D. Royar (%s)",
        version));
}
SHAR_EOF
cat << \SHAR_EOF > keybrd.c
/* KEYBRD.C this file contain the
 * keyboard processing code, for the
 * MicroEMACS screen editor.
 */
#include        <stdio.h>
#include        "ed.h"
 
#define FLEN    14                      /* Maximum length of function name */
 
typedef struct  {
        short   k_code;                 /* Key code                     */
        int     (*k_fp)();              /* Routine to handle it         */
        char    k_mfunc[FLEN];          /* function name                */
}       KEYTAB;
 
extern  int     clearflag();            /* Clear changed buffer flag    */
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     fileinsert();           /* Insert existing file at point*/
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     setindcol();            /* Set indent column            */
extern  int     setmark();              /* Set mark                     */
extern  int     swapmark();             /* Swap "." and mark            */
extern  int     forwsearch();           /* Search forward               */
extern  int     backsearch();           /* Search backward              */
extern  int     forwisearch();          /* I-search forward             */
extern  int     backisearch();          /* I-search backward            */
extern  int     replace();              /* Search and replace           */
extern  int     showcpos();             /* Show the cursor position     */
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     paintbuffer();          /* Set background buffer color  */
extern  int     usebuffer();            /* Switch a window to a buffer  */
extern  int     killbuffer();           /* Make a buffer go away.       */
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     kill();                 /* 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     writereg();             /* write defined region to file */
extern  int     quickexit();            /* low keystroke style exit.    */
extern  int     goteop();               /* goto end of paragraph */
extern  int     gotbop();               /* goto beginning of paragraph */
extern  int     unkncom();              /* unknown command BEEP */
extern  int     ftopunct();             /* move forward to next punctuation */
extern  int     btopunct();             /* move backward to last punctuation */
extern  int     forwsent();             /* forward to end of sentence */
extern  int     backsent();             /* backward to beginning of sentence */
extern  int     fillpar();              /* fill paragraph to fill column */
extern  int     setpage();              /* set page size from arg */
extern  int     paginate();             /* insert '\f' every page */
extern  int     pageforw();             /* move forward set page length */
extern  int     pageback();             /* move back set page length */
extern  int     print();                /* print buffer with heading */
extern  int     wc();                   /* word and line count of buffer */
extern  int     retversion();           /* version date */
extern  int     kermit();               /* file transfer */
 
/* From here on the commands are from misc.c */
extern  int     mdropln();              /* drop current line and move up*/
extern  int     mindnl();               /* indent subsequent NL same as this */
extern  int     mdeleln();              /* delete entire line from beginning */
extern  int     mdelwln();              /* delete entire line including NL   */
extern  int     mdelind();              /* delete beginning line indentation */
extern  int     markpar();              /* mark paragraph sets mark */
extern  int     tglcase();              /* toggle case of letter at point */
extern  int     killsent();             /* kill sentence forward sets mark */
extern  int     grtw();                 /* remove trailing white space */
extern  int     twaddle();              /* transpaose two words in place */
extern  int     clowsp();               /* close up intervening white space */
extern  int     mrflush();              /* flush right current line */
extern  int     mcenter();              /* center current line */
extern  int     setmode();              /* set a mode for a buffer */
extern  int     sglmode();              /* set global mode      */
extern  int     rettpa();               /* show available memory and usage */
extern  int     showtime();             /* return current time  */
extern  int     goline();               /* goto line in text */
extern  int     enumerate();            /* start or incr. counter variable */
extern  int     gospell();              /* search forward for spell mark */
extern  int     mdoncom();              /* execute a named command */
 
/* functions in macros.c to allow 26 keyboard macros */
extern  int     putmacro();             /* print line macros in text    */
extern  int     getmacro();             /* copy cureent key-mac to key  */
 
/* shell commands */
extern  int     shell();                /* run one command or run cc    */
extern  int     commfil();              /* read alias file              */
extern  int     setpath();              /* get/set path and drive       */
 
/*
 * 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.
 */
KEYTAB  keytab[] = {
        CTRL|'@',               &setmark,
        "setmark",
        CTRL|'A',               &gotobol,
        "gotobol",
        CTRL|'B',               &backchar,
        "backchar",
        CTRL|'C',               &shell,
        "shell",
        CTRL|'D',               &forwdel,
        "forwdel",
        CTRL|'E',               &gotoeol,
        "gotoeol",
        CTRL|'F',               &forwchar,
        "forwchar",
        CTRL|'G',               &ctrlg,
        "ctrlg",
        CTRL|'H',               &backchar,
        "backchar",
        CTRL|'I',               &tab,
        "tab",
        CTRL|'J',               &indent,
        "indent",
        CTRL|'K',               &mdeleln,
        "mdeleln",
        CTRL|'L',               &refresh,
        "refresh",
        CTRL|'M',               &newline,
        "newline",
        CTRL|'N',               &forwline,
        "forwline",
        CTRL|'O',               &openline,
        "openline",
        CTRL|'P',               &backline,
        "backline",
        CTRL|'Q',               &quote,
        "quote",
        CTRL|'R',               &backsearch,
        "backsearch",
        CTRL|'S',               &forwsearch,
        "forwsearch",
        CTRL|'T',               &twiddle,
        "twiddle",
        CTRL|'V',               &forwpage,
        "forwpage",
        CTRL|'W',               &killregion,
        "killregion",
        CTRL|'Y',               &yank,
        "yank",
        CTRL|'Z',               &quickexit,
        "quickexit",
        CTRL|'\\',              &unkncom,
        "unkncom",
        CTRL|'_',               &kermit,
        "kermit",
        CTRL|'^',               &unkncom,
        "unkncom",
        CTLX|CTRL|'A',          &unkncom,
        "unkncom",
        CTLX|CTRL|'B',          &listbuffers,
        "listbuffers",
        CTLX|CTRL|'C',          &quit,
        "quit",
        CTLX|CTRL|'D',          &unkncom,
        "unkncom",
        CTLX|CTRL|'E',          &commfil,
        "commfil",
        CTLX|CTRL|'F',          &filename,
        "filename",
        CTLX|CTRL|'G',          &ctrlg,
        "ctrlg",
        CTLX|CTRL|'H',          &unkncom,
        "unkncom",
        CTLX|CTRL|'I',          &print,
        "print",
        CTLX|CTRL|'J',          &unkncom,
        "unkncom",
        CTLX|CTRL|'K',          &unkncom,
        "unkncom",
        CTLX|CTRL|'L',          &lowerregion,
        "lowerregion",
        CTLX|CTRL|'M',          &unkncom,
        "unkncom",
        CTLX|CTRL|'N',          &mvdnwind,
        "mvdnwind",
        CTLX|CTRL|'O',          &deblank,
        "deblank",
        CTLX|CTRL|'P',          &mvupwind,
        "mvupwind",
        CTLX|CTRL|'Q',          &unkncom,
        "unkncom",
        CTLX|CTRL|'R',          &fileread,
        "fileread",
        CTLX|CTRL|'S',          &filesave,
        "filesave",
        CTLX|CTRL|'T',          &showtime,
        "showtime",
        CTLX|CTRL|'U',          &upperregion,
        "upperregion",
        CTLX|CTRL|'V',          &filevisit,
        "filevisit",
        CTLX|CTRL|'W',          &filewrite,
        "filewrite",
        CTLX|CTRL|'X',          &swapmark,
        "swapmark",
        CTLX|CTRL|'Y',          &unkncom,
        "unkncom",
        CTLX|CTRL|'Z',          &shrinkwind,
        "shrinkwind",
        CTLX|'!',               &paginate,
        "paginate",
        CTLX|'#',               &setpage,
        "setpage",
        CTLX|'+',               &pageforw,
        "pageforw",
        CTLX|'-',               &pageback,
        "pageback",
        CTLX|'.',               &setindcol,
        "setindcol",
        CTLX|'(',               &ctlxlp,
        "ctlxlp",
        CTLX|')',               &ctlxrp,
        "ctlxrp",
        CTLX|'*',               &retversion,
        "retversion",
        CTLX|'<',               &btopunct,
        "btopunct",
        CTLX|'=',               &showcpos,
        "showcpos",
        CTLX|'>',               &ftopunct,
        "ftopunct",
        CTLX|'0',               &unkncom,
        "unkncom",
        CTLX|'1',               &onlywind,
        "onlywind",
        CTLX|'2',               &splitwind,
        "splitwind",
        CTLX|'3',               &unkncom,
        "unkncom",
        CTLX|'4',               &unkncom,
        "unkncom",
        CTLX|'5',               &unkncom,
        "unkncom",
        CTLX|'6',               &unkncom,
        "unkncom",
        CTLX|'7',               &unkncom,
        "unkncom",
        CTLX|'8',               &unkncom,
        "unkncom",
        CTLX|'9',               &unkncom,
        "unkncom",
        CTLX|'A',               &unkncom,
        "unkncom",
        CTLX|'B',               &usebuffer,
        "usebuffer",
        CTLX|'C',               &paintbuffer,
        "paintbuffer",
        CTLX|'D',               &setpath,
        "setpath",
        CTLX|'E',               &ctlxe,
        "ctlxe",
        CTLX|'F',               &setfillcol,
        "setfillcol",
        CTLX|'H',               &unkncom,
        "unkncom",
        CTLX|'I',               &fileinsert,
        "fileinsert",
        CTLX|'J',               &unkncom,
        "unkncom",
        CTLX|'K',               &killbuffer,
        "killbuffer",
        CTLX|'L',               &unkncom,
        "unkncom",
        CTLX|'M',               &setmode,
        "setmode",
        CTLX|'N',               &nextwind,
        "nextwind",
        CTLX|'O',               &prevwind,
        "prevwind",
        CTLX|'P',               &prevwind,
        "prevwind",
        CTLX|'Q',               &unkncom,
        "unkncom",
        CTLX|'R',               &writereg,
        "writereg",
        CTLX|'S',               &gospell,
        "gospell",
        CTLX|'T',               &unkncom,
        "unkncom",
        CTLX|'U',               &unkncom,
        "unkncom",
        CTLX|'V',               &unkncom,
        "unkncom",
        CTLX|'W',               &wc,
        "wc",
        CTLX|'Y',               &unkncom,
        "unkncom",
        CTLX|'Z',               &enlargewind,
        "enlargewind",
        CTLX|'\\',              &grtw,
        "grtw",
        CTLX|'`',               &getmacro,
        "getmacro",
        CTLX|'~',               &shell,
        "shell",
        CTLX|SPEC|'p',          &swapmark,
        "swapmark",
        META|CTRL|'B',          &backword,
        "backword",
        META|CTRL|'C',          &mcenter,
        "mcenter",
        META|CTRL|'F',          &forwword,
        "forwword",
        META|CTRL|'G',          &ctrlg,
        "ctrlg",
        META|CTRL|'H',          &backword,
        "backword",
        META|CTRL|'I',          &kill,
        "kill",
        META|CTRL|'K',          &mdelwln,
        "mdelwln",
        META|CTRL|'M',          &unkncom,
        "unkncom",
        META|CTRL|'N',          &enumerate,
        "enumerate",
        META|CTRL|'O',          &clowsp,
        "clowsp",
        META|CTRL|'P',          &tglcase,
        "tglcase",
        META|CTRL|'R',          &mrflush,
        "mrflush",
        META|CTRL|'S',          &forwisearch,
        "forwisearch",
        META|CTRL|'T',          &backisearch,
        "backisearch",
        META|'!',               &reposition,
        "reposition",
        META|'.',               &gotoeob,
        "gotoeob",
        META|',',               &gotobob,
        "gotobob",
        META|'>',               &gotoeob,
        "gotoeob",
        META|'<',               &gotobob,
        "gotobob",
        META|' ',               &setmark,
        "setmark",
        META|'@',               &rettpa,
        "rettpa",
        META|'A',               &backsent,
        "backsent",
        META|'B',               &backword,
        "backword",
        META|'C',               &capword,
        "capword",
        META|'D',               &delfword,
        "delfword",
        META|'E',               &forwsent,
        "forwsent",
        META|'F',               &forwword,
        "forwword",
        META|'G',               &goline,
        "goline",
        META|'H',               &markpar,
        "markpar",
        META|'I',               &unkncom,
        "unkncom",
        META|'J',               &mindnl,
        "mindnl",
        META|'K',               &killsent,
        "killsent",
        META|'L',               &lowerword,
        "lowerword",
        META|'M',               &sglmode,
        "sglmode",
        META|'N',               &goteop,
        "goteop",
        META|'O',               &mdropln,
        "mdropln",
        META|'P',               &gotbop,
        "gotbop",
        META|'Q',               &fillpar,
        "fillpar",
        META|'R',               &replace,
        "replace",
        META|'S',               &unkncom,
        "unkncom",
        META|'T',               &twaddle,
        "twaddle",
        META|'U',               &upperword,
        "upperword",
        META|'V',               &backpage,
        "backpage",
        META|'W',               &copyregion,
        "copyregion",
        META|'X',               &mdoncom,
        "mdoncom",
        META|'Y',               &unkncom,
        "unkncom",
        META|'Z',               &unkncom,
        "unkncom",
        META|'\\',              &mdelind,
        "mdelind",
        META|'~',               &clearflag,
        "clearflag",
        META|0x7F,              &delbword,
        "delbword",
#if     ST
        SPEC|'H',               &backline,
        "backline",
        SPEC|'P',               &forwline,
        "forwline",
        SPEC|'K',               &backchar,
        "backchar",
        SPEC|'M',               &forwchar,
        "forwchar",
        SPEC|'b',               &kermit,
        "kermit",
        SPEC|'a',               &yank,
        "yank",
        SPEC|'R',               &openline,
        "openline",
        SPEC|'S',               &backdel,
        "backdel",
        SPEC|'G',               &refresh,
        "refresh",
        SPEC|'q',               &forwdel,
        "forwdel",
        SPEC|'r',               &indent,
        "indent",
        SPEC|'c',               &backword,
        "backword",
        SPEC|'d',               &forwword,
        "forwword",
        SPEC|'e',               &grtw,
        "grtw",
        SPEC|'f',               &retversion,
        "retversion",
        SPEC|'g',               &gotobol,
        "gotobol",
        SPEC|'h',               &gotoeol,
        "gotoeol",
        SPEC|'i',               &unkncom,
        "unkncom",
        SPEC|'J',               &pageback,
        "pageback",
        SPEC|'N',               &pageforw,
        "pageforw",
        SPEC|'j',               &backsent,
        "backsent",
        SPEC|'k',               &forwsent,
        "forwsent",
        SPEC|'l',               &unkncom,
        "unkncom",
        SPEC|'m',               &gotbop,
        "gotbop",
        SPEC|'n',               &goteop,
        "goteop",
        SPEC|'o',               &unkncom,
        "unkncom",
        SPEC|'D',               &quickexit,
        "quickexit",
        SPEC|'C',               &filesave,
        "filesave",
        SPEC|'B',               &filewrite,
        "filewrite",
        SPEC|'A',               &filevisit,
        "filevisit",
        SPEC|'@',               &fileread,
        "fileread",
        SPEC|'?',               &fileinsert,
        "fileinsert",
        SPEC|'>',               &writereg,
        "writereg",
        SPEC|'=',               &filename,
        "filename",
        SPEC|'<',               &listbuffers,
        "listbuffers",
        SPEC|';',               &setmark,
        "setmark",
#endif
        AGRAVE,                 &putmacro,
        "putmacro",
        0x7F,                   &backdel,
        "backdel"
};
 
#define NKEYTAB (sizeof(keytab)/sizeof(keytab[0]))
 
#if     LK201
/*
 * Mapping table for all of the funny
 * keys with the numeric parameters on the LK201.
 * Indexed by the code, which is between 0 (unused) and
 * 34 (F20). An entry of 0 means no mapping. The map
 * goes to command keys. If I had a "special" bit,
 * I could use the code in the escape sequence as a
 * key code, and return (for example) "do" as
 * SPECIAL + 29. Then the dispatch would be
 * done by the default keymap. This is probably a
 * better way to go.
 */
short   lkmap[] = {
        0,
        CTRL|'S',                       /* 1    Find                    */
        CTRL|'Y',                       /* 2    Insert here             */
        CTRL|'W',                       /* 3    Remove                  */
        CTRL|'@',                       /* 4    Select                  */
        META|'V',                       /* 5    Previous screen         */
        CTRL|'V',                       /* 6    Next screen             */
        0,
        0,
        0,
        0,                              /* 10   Compose                 */
        0,
        0,                              /* 12   Print screen            */
        0,
        0,                              /* 14   F4                      */
        0,
        0,
        0,                              /* 17   F6                      */
        0,                              /* 18   F7                      */
        0,                              /* 19   F8                      */
        0,                              /* 20   F9                      */
        0,                              /* 21   F10                     */
        0,
        0,
        0,
        0,
        0,                              /* 26   F14                     */
        0,
        0,                              /* 28   Help                    */
        CTLX|'E',                       /* 29   Do      C-X E           */
        0,
        CTLX|'P',                       /* 31   F17     C-X P           */
        CTLX|'N',                       /* 32   F18     C-X N           */
        CTLX|'Z',                       /* 33   F19     C-X Z           */
        CTLX|CTRL|'Z'                   /* 34   F20     C-X C-Z         */
};
#endif
 
/*
 * 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)
register int c, f, n;
{
        register KEYTAB *ktp;
        register int    status;
 
        ktp = &keytab[0];                       /* Look in key table.   */
        while (ktp < &keytab[NKEYTAB]) {
                if (ktp->k_code == c) {
                        thisflag = 0;
                        status   = (*ktp->k_fp)(f, n);
                        lastflag = thisflag;
                        return (status);
                }
                ++ktp;
        }
 
        /*
         * If inwrap a space was typed, fill column is defined, the argument
         * is non-negative, and we are now past fill column, perform word wrap.
         */
        if ((curbp->b_bmode&BMWRAP) != 0 && c == ' ' && fillcol > 0
                && n>=0 && getccol(FALSE) > fillcol)
                {
                linsert(1, c);  /* we want the space */
                wrapword(FALSE, NULL);
                }
        if ((c>=0x20 && c<=0x7E)                /* Self inserting.      */
        ||  (c>=0xA0 && c<=0xFE)) {
                if (n <= 0) {                   /* Fenceposts.          */
                        lastflag = 0;
                        return (n<0 ? FALSE : TRUE);
                }
                thisflag = 0;                   /* For the future.      */
                status   = linsert(n, c);
                lastflag = thisflag;
                return (status);
        }
        lastflag = 0;                           /* Fake last flags.     */
        return (FALSE);
}
 
bindkey(code,name)
register short code;
register char *name;
{
        register KEYTAB *oktp,*nktp;
        int found = FALSE;
 
        nktp = &keytab[0];      /* bind to this key */
        oktp = &keytab[0];      /* the function to bind */
        /* look through to find keytab assoc with "name" */
        while (oktp < &keytab[NKEYTAB]) {
                if (strcmp(oktp->k_mfunc,name)==NULL) {
                        found = TRUE;
                        break;
                }
                ++oktp;
        }
        if (found)
                /* search for key */
                while (nktp < &keytab[NKEYTAB]) {
                        if (nktp->k_code == code) {
                                strcpy(nktp->k_mfunc,oktp->k_mfunc);
                                nktp->k_fp=oktp->k_fp;
                                return(TRUE);
                        }
                        ++nktp;
                }
        return(FALSE);
}
 
/* given a keycode value, return a pointer to the name of that function
 * and get the function's name into `name'.
 */
char *
getfname(kcode,name)
register short kcode;
char name[];
{
        register KEYTAB *ktp;
 
        ktp = &keytab[0];       /* the function to find */
        /* look through to find keytab assoc with "code" */
        while (ktp < &keytab[NKEYTAB]) {
                if (ktp->k_code == kcode)
                        {
                        strcpy(name,ktp->k_mfunc);
                        return(ktp->k_mfunc);
                        }
                ++ktp;
        }
        return((char *)NULL);   /* not found */
}
 
/* return the code associated with `name' */
short
getktpcode(name)
char name[];
{
        register KEYTAB *ktp;
 
        ktp = &keytab[0];       /* the function to find */
        /* look through to find keytab assoc with "name" */
        while (ktp < &keytab[NKEYTAB]) {
                if (strcmp(ktp->k_mfunc,name) == NULL)
                        return(ktp->k_code);
                ++ktp;
        }
        return(NULL);
}
SHAR_EOF
#       End of shell archive
exit 0
%NONAME-W-NOMSG, Message number 00000000
Technical Details
Message-ID: <8702041534.AA15666@ucbvax.Berkeley.EDU>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!cbatt!ucbvax!ULKYVX.BITNET!RDROYA01

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!cbatt!ucbvax!ULKYVX.BITNET!RDROYA01
From: RDROYA01@ULKYVX.BITNET.UUCP
Newsgroups: comp.sys.atari.st
Subject: Uemail source (2 of 12)
Message-ID: <8702041534.AA15666@ucbvax.Berkeley.EDU>
Date: Wed, 4-Feb-87 08:35:00 EST
Article-I.D.: ucbvax.8702041534.AA15666
Posted: Wed Feb  4 08:35:00 1987
Date-Received: Sat, 7-Feb-87 05:03:34 EST
Sender: daemon@ucbvax.BERKELEY.EDU
Organization: University of Louisville
Lines: 1363