[comp.sys.amiga] MED SHAR part II of II

dillon@CORY.BERKELEY.EDU.UUCP (01/28/87)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	command.c
#	main.c
#	text.c
#	defs.h
# This archive created: Tue Jan 27 18:59:35 1987
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'command.c'" '(6612 characters)'
if test -f 'command.c'
then
	echo shar: "will not over-write existing file 'command.c'"
else
cat << \!Funky!Stuff! > 'command.c'

/*
 * COMMAND.C
 *
 * 'c                single character
 * `string'          string of characters w/ embedded `' allowed!
 *
 * name arg arg      command name. The arguments are interpreted as strings
 *                   for the command.
 *
 * Any string arguments not part of a command are considered to be typed
 * text.
 *
 *
 */

#include "defs.h"

extern char *breakout();

short ComLineMode;

typedef struct {
   char *name;    /* command name                                       */
   short args;    /* # of arguments                                     */
   short sl;      /* 1 if stays within bounds of the current line       */
   int (*func)(); /* function                                           */
} COMM;

extern int do_map(), do_unmap(), do_up(), do_down(), do_left(), do_right(),
            do_return(), do_bs(), do_del(), do_esc(), do_downadd(),
            do_lastcolumn(), do_firstcolumn(), do_edit(), do_tab(),
            do_backtab(), do_save(), do_saveas(), do_deline(), do_insline(),
            do_top(), do_bottom(), do_source(), do_firstnb(),
            do_quit(), do_find(), do_pageup(), do_pagedown(),
            do_split(), do_goto(), do_screentop(), do_screenbottom(),
            do_join(), do_repeat(), do_tabstop(), do_insertmode(),
            do_block(), do_bdelete(), do_bcopy(), do_bmove(), do_bsave();

COMM Comm[] = {
   "esc",           0, 1, do_esc,
   "escimm",        1, 0, do_esc,
   "last",          0, 1, do_lastcolumn,
   "first",         0, 1, do_firstcolumn,
   "downadd",       0, 0, do_downadd,
   "map",           2, 0, do_map,
   "unmap",         1, 0, do_unmap,
   "up",            0, 0, do_up,
   "down",          0, 0, do_down,
   "pageup",        0, 0, do_pageup,
   "pagedown",      0, 0, do_pagedown,
   "left",          0, 1, do_left,
   "right",         0, 1, do_right,
   "return",        0, 1, do_return,    /* special meaning in command line mode */
   "bs",            0, 1, do_bs,
   "back",          0, 1, do_bs,
   "del",           0, 1, do_del,
   "insline",       0, 0, do_insline,
   "deline",        0, 0, do_deline,
   "tab",           0, 1, do_tab,
   "backtab",       0, 1, do_backtab,
   "newfile",       1, 0, do_edit,
   "insfile",       1, 0, do_edit,
   "saveold",       0, 0, do_save,
   "saveas",        1, 0, do_saveas,
   "top",           0, 0, do_top,
   "bottom",        0, 0, do_bottom,
   "source",        1, 0, do_source,
   "firstnb",       0, 1, do_firstnb,
   "quit",          0, 0, do_quit,
   "find",          1, 0, do_find,
   "next",          0, 0, do_find,
   "prev",          0, 0, do_find,
   "split",         0, 0, do_split,
   "join",          0, 0, do_join,
   "repeat",        2, 1, do_repeat,
   "tabstop",       1, 1, do_tabstop,
   "insertmode",    1, 1, do_insertmode,
   "screentop",     0, 0, do_screentop,
   "screenbottom",  0, 0, do_screenbottom,
   "goto",          1, 0, do_goto,
   "block",         0, 0, do_block,
   "unblock",       0, 0, do_block,
   "bcopy",         0, 0, do_bcopy,
   "bmove",         0, 0, do_bmove,
   "bdelete",       0, 0, do_bdelete,
   "bsave",         1, 0, do_bsave,
   NULL, 0, 0, NULL
};


do_command(str)
char *str;
{
   char *arg;
   char quoted;
   short i, j;

   while (arg = breakout(&str, &quoted)) {
      if (quoted) {
         text_write(arg);
         continue;
      }
      for (i = 0; arg[i]; ++i) {
          if (arg[i] >= 'A' && arg[i] <= 'Z')
              arg[i] = arg[i] + 'a' - 'A';
      }
      for (i = 0; Comm[i].name; ++i) {
         if (strcmp(arg, Comm[i].name) == 0) {
            av[0] = Comm[i].name;
            for (j = 1; j <= Comm[i].args; ++j) {
               av[j] = breakout(&str, &quoted);
               if (!av[j]) {
                  title("Bad argument");
                  return(0);
               }
            }
            if (Comm[i].sl || !ComLineMode)
               (*Comm[i].func)();
            goto loop;
         }
      }
      title("Unknown Command");
      return(0);
loop:
   }
   return(1);
}

do_source()
{
   char buf[256];
   long fi;

   if (fi = xopen(av[1], "r", 256)) {
      while (xgets(fi, buf, 255))
         do_command(buf);
      xclose(fi);
   } else {
      if (av[0])
         title("File not found");
   }
}


do_quit()
{
   extern char Quitflag;

   Quitflag = 1;
}

/*
 * repeat X command
 *
 * Since repeat takes up 512+ stack, it should not be nested more than
 * twice.
 *
 * (if X is not a number it can be abbr. with 2 chars)
 *
 * X =  N     -number of repeats
 *      line  -current line # (lines begin at 1)
 *      lbot  -#lines to the bottom, inc. current
 *      cleft -column # (columns begin at 0)
 *              (thus is also chars to the left)
 *      cright-#chars to eol, including current char
 *      tr    -#char positions to get to next tab stop
 *      tl    -#char positions to get to next backtab stop
 */

#define SC(a,b) ((a)<<8|(b))

do_repeat()
{
   char *ptr = av[1];
   char buf1[256];
   char buf2[256];
   long n;

   strcpy(buf1, av[2]);
   switch((ptr[0]<<8)+ptr[1]) {
   case SC('l','i'):
      n = text_lineno();
      break;
   case SC('l','b'):
      n = text_lines() - text_lineno() + 1;
      break;
   case SC('c','l'):
      n = text_colno();
      break;
   case SC('c','r'):
      n = text_cols() - text_colno();
      break;
   case SC('t','r'):
      n = text_tabsize()-(text_colno() % text_tabsize());
      break;
   case SC('t','l'):
      n = text_colno() % text_tabsize();
      if (n == 0)
         n = text_tabsize();
      break;
   default:
      n = atoi(av[1]);
      break;
   }
   while (n > 0) {
      strcpy(buf2, buf1);
      do_command(buf2);
      --n;
   }
}


char *
breakout(ptr, quoted)
char **ptr, *quoted;
{
   char *str = *ptr;
   char *base = str;

   *quoted = 0;
   while (*str == ' ')
      ++str;
   if (!*str)
      return(NULL);
   if (*str == '\'') {
      if (str[1]) {
         *quoted = 1;
         base = str + 1;
         if (str[2])
            ++str;
         *str = '\0';
         *ptr = str;
         return(base);
      }
      return(NULL);
   }
   if (*str == '`') {
      short count = 1;
      base = ++str;
      while (*str && count) {
         if (*str == '`')
            ++count;
         if (*str == '\'')
            --count;
         ++str;
      }
      if (count == 0) {
         --str;
         *quoted = 1;
         *str = '\0';
         *ptr = str + 1;
         return(base);
      }
   }
   base = str;
   while (*str && *str != ' ')
      ++str;
   if (*str) {
      *str = '\0';
      *ptr = str + 1;
      return(base);
   }
   *ptr = str;
   return(base);
}


!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'main.c'" '(14917 characters)'
if test -f 'main.c'
then
	echo shar: "will not over-write existing file 'main.c'"
else
cat << \!Funky!Stuff! > 'main.c'

/*
 * MAIN.C
 */

#include <exec/types.h>
#include <intuition/intuition.h>
#include <typedefs.h>
#include "xmisc.h"
#include "defs.h"

#define KEY_LSHIFT   (1 << 0)
#define KEY_RSHIFT   (1 << 1)
#define KEY_CAPS     (1 << 2)
#define KEY_CTRL     (1 << 3)
#define KEY_ALTL     (1 << 4)
#define KEY_ALTR     (1 << 5)
#define KEY_AMIGAL   (1 << 6)
#define KEY_AMIGAR   (1 << 7)

#define QUAL_SHIFT   0x01
#define QUAL_CTRL    0x02
#define QUAL_AMIGA   0x04
#define QUAL_ALT     0x08


NW Nw = {
   0, 1, 640, 199, -1, -1,
   CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW,
   ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP,
   NULL, NULL, "MED V1.01 (c)CopyRight 1986 Matthew Dillon,  All Rights Reserved                  ",
   NULL, NULL,
   32, 32, -1, -1,
   WBENCHSCREEN
};

WIN *Win;
RP  *Rp;

short Xsize, Ysize;           /* font character sizes                */
short Rows, Columns;          /* character rows/cols available       */
short Xbase, Ybase;           /* offset pixel base for display       */
short XTbase, YTbase;         /* used for text display               */
short Xpixs, Ypixs;           /* actual # X/Y pixels available       */

char *av[8];
char Quitflag;
char Overide;

extern ED E;
extern char memoryfail;

main(mac, mav)
char *mav[];
{
   IMESS *im;
   char notdone;
   char iawm;

   if (!openlibs(INTUITION_LIB|GRAPHICS_LIB))
      exiterr("cannot open intuition or graphics library");
   Win = OpenWindow(&Nw);
   if (Win == NULL)
      exiterr("cannot open window");
   Rp = Win->RPort;
   set_window_params();
   resethash();
   text_init();
   text_redisplay();

   if (mac == 2) {
      av[0] = "newfile";
      av[1] = mav[1];
      do_edit();
   }
   mountrequest(0);
   av[0] = NULL;
   av[1] = "c:.edrc";
   do_source();
   av[0] = NULL;
   av[1] = ".edrc";
   do_source();
   mountrequest(1);

   text_titleupdate();
loop:
    text_cursor(1);
   for (notdone = 1, iawm = 0; !Quitflag && notdone;) {
      window_title();
      WaitPort(Win->UserPort);
      while (im = (IMESS *)GetMsg(Win->UserPort)) {
         switch(im->Class) {
         case NEWSIZE:
            if (ComLineMode)
                escapecomlinemode();
            set_window_params();
            if (!text_sync())
               text_redisplay();
            text_cursor(1);
            break;
         case RAWKEY:
            text_cursor(0);
            keyctl(im->Code);
            text_cursor(1);
            break;
         case CLOSEWINDOW:
            if (ComLineMode)
                escapecomlinemode();
            notdone = 0;
            break;
         case ACTIVEWINDOW:
            iawm = 1;
            break;
         case MOUSEBUTTONS:
            if (iawm) {
                iawm = 0;
                break;
            }
            if (ComLineMode)
                escapecomlinemode();
            text_cursor(0);
            switch(im->Code) {
            case SELECTDOWN:        /* position cursor      */
                if (im->MouseY >= Ybase)
                    text_position((im->MouseX-Xbase)/Xsize,(im->MouseY-Ybase)/Ysize);
                else
                    text_position((im->MouseX-Xbase)/Xsize,-1);
                break;
            case MENUDOWN:          /* percentage placement */
                {
                    int line = 1 + (im->MouseY-(Ybase+4))*text_lines()/(Ypixs-8);
                    char buf[16];
                    if (line > text_lines())
                        line = text_lines();
                    if (line < 1)
                        line = 1;
                    sprintf(buf, "%ld", line);
                    av[1] = buf;
                    do_goto();
                }
                break;
            }
            text_cursor(1);
            break;
         }
         ReplyMsg(im);
      }
   }
   if (E.Modified && !Overide) {
      Overide = 1;
      SetWindowTitles(Win, "MED: File has been modified", NULL);
      Quitflag = 0;
      goto loop;
   }
   text_uninit();
   if (Win)
      CloseWindow(Win);
   closelibs(INTUITION_LIB|GRAPHICS_LIB);
   free_memory();
}

getyn(text)
char *text;
{
    int result;
    ITEXT *body, *pos, *neg;

    body = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    pos  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    neg  = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
    bzero(body, sizeof(ITEXT));
    bzero(pos , sizeof(ITEXT));
    bzero(neg , sizeof(ITEXT));
    body->BackPen = pos->BackPen = neg->BackPen = 1;
    body->DrawMode= pos->DrawMode= neg->DrawMode= AUTODRAWMODE;
    body->LeftEdge = 10;
    body->TopEdge  = 12;
    body->IText    = text;
    pos->LeftEdge = AUTOLEFTEDGE;
    pos->TopEdge = AUTOTOPEDGE;
    pos->IText = "OK";
    neg->LeftEdge = AUTOLEFTEDGE;
    neg->TopEdge = AUTOTOPEDGE;
    neg->IText = "CANCEL";
    result = AutoRequest(Win,body,pos,neg,0,0,320,58);
    FreeMem(body, sizeof(ITEXT));
    FreeMem(pos , sizeof(ITEXT));
    FreeMem(neg , sizeof(ITEXT));
    return(result);
}


char ShowTitle;

title(buf)
char *buf;
{
    SetWindowTitles(Win, buf, -1);
    ShowTitle = 1;
}


window_title()
{
   static char title[130];
   static char cmodified;
   int len;
   char *mod;

    if (memoryfail) {
        SetWindowTitles(Win, " -- NO MEMORY -- ", -1);
        text_redisplay();
        memoryfail = 0;
        return(0);
    }
    if (ShowTitle) {
        ShowTitle = 0;
        return(0);
    }
    if (text_titleupdate() || cmodified != E.Modified) {
        cmodified = E.Modified;
        mod = (E.Modified) ? " (modified)" : "";
        sprintf(title, "%3ld/%-3ld %s%s", text_lineno(), text_lines(), text_name(), mod);
        len = strlen(title);
        if (len < Columns && Columns < 128) {
            bset(title+len, Columns - len + 1, ' ');
            title[Columns + 1] = 0;
        }
        SetWindowTitles(Win, title, -1);
    }
}

inversemode(n)
{
   int v;

   v = JAM2;
   if (n)
      v = JAM2|INVERSVID;
   SetDrMd(Rp, v);
}

set_window_params()
{
   Xsize = Rp->Font->tf_XSize;
   Ysize = Rp->Font->tf_YSize;
   Xbase = Win->BorderLeft;
   Ybase = Win->BorderTop;
   Xpixs   = Win->Width - Win->BorderRight - Xbase;
   Ypixs   = Win->Height- Win->BorderBottom- Ybase;
   Columns = Xpixs / Xsize;
   Rows    = Ypixs / Ysize;
   XTbase   =  Xbase;
   YTbase   =  Ybase + Rp->Font->tf_Baseline;
}

exiterr(str)
char *str;
{
   puts(str);
   free_memory();
   exit(1);
}


#define HASHSIZE  64

typedef struct _HASH {
   struct _HASH *next;     /* next hash   */
   char code;              /* keycode     */
   char mask;              /* qual. mask  */
   char qual;              /* qual. comp  */
   char stat;              /* string static? */
   char *str;              /* command string */
} HASH;

HASH *Hash[HASHSIZE];

static char isalpha[] = {  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                           1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
                           1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
                           0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 };

static char ctoa[] = {
   '`','1','2','3','4','5','6','7','8','9','0','-','=','\\',0,'0',
   'q','w','e','r','t','y','u','i','o','p','[',']',0,'1','2','3',
   'a','s','d','f','g','h','j','k','l',';','\'',0,0,'4','5','6',
    0 ,'z','x','c','v','b','n','m',',','.','/',0,'.','7','8','9',
   ' ',0,0,0,0,0,0,0,0,0,'-',0,0,0,0,0
};

static char cstoa[]  = {
   '~','!','@','#','$','%','^','&','*','(',')','_','+','|',0,'0',
   'Q','W','E','R','T','Y','U','I','O','P','{','}',0,'1','2','3',
   'A','S','D','F','G','H','J','K','L',':','\"',0,0,'4','5','6',
    0 ,'Z','X','C','V','B','N','M','<','>','?',0,'.','7','8','9',
   ' ',0,0,0,0,0,0,0,0,0,'-',0,0,0,0,0
};

resethash()
{
    short i;
    register HASH *hash, *hnext = NULL;
    static struct {
        char *from, *to;
    } defmap[] = {
        "esc",      "esc",
        "return",   "return insline up firstnb down",
        "enter",    "return",
        "up",       "up",
        "down",     "down",
        "right",    "right",
        "left",     "left",
        "bs",       "bs",
        "del",      "del",
        "help",     "help",
        "tab",      "tab",
        "s-up",     "top",
        "s-down",   "bottom",
        "s-right",  "last",
        "s-left",   "first",
        "s-tab",    "backtab",
        "s-del",    "deline",
        "c-i",      "insertmode on",
        "c-o",      "insertmode off",
        "c-j",      "join",
        "c-s",      "split first down",
        "c-del",    "deline",
        "c-n",      "next",
        "c-p",      "prev",
        "c-/",      "escimm `find '",
        "c-up",     "pageup",
        "c-down",   "pagedown",
        "f1",       "escimm `insfile '",
        "f2",       "escimm `newfile '",
        "f9",       "escimm `bsave '",
        "f10",      "saveold quit",
        "c-b",      "block",
        "c-u",      "unblock",
        "a-d",      "bdelete",
        "a-c",      "bcopy",
        "a-m",      "bmove",
        NULL, NULL
    };

    for (i = 0; i < HASHSIZE; ++i) {
        for (hash = Hash[i]; hash; hash = hnext) {
            hnext = hash->next;
            if (!hash->stat)
                free(hash->str);
            free(hash);
        }
        Hash[i] = NULL;
    }
    for (i = 0; defmap[i].from; ++i) {
        char code, qual;
        if (get_codequal(defmap[i].from, &code, &qual))
            addhash(code, 1, -1, qual, defmap[i].to);
    }
}

returnoveride(n)
{
    HASH *hash;
    static char *str;
    static int stat;

    for (hash = Hash[0x44 % HASHSIZE]; hash; hash = hash->next) {
        if (hash->code == 0x44 && hash->qual == 0) {
            if (n) {
                str = hash->str;
                stat= hash->stat;
                hash->str = "return";
                hash->stat = 1;
            } else {
                if (str == NULL) {
                    remhash(0x44, -1, 0);
                } else {
                    hash->str = str;
                    hash->stat= stat;
                }
            }
            return(0);
        }
    }
    if (n) {
        addhash(0x44,1,-1,0,"return");
        str = NULL;
    }
}



addhash(code, stat, mask, qual, str)
char *str;
{
   register HASH **p, *hash;

   hash = *(p = &Hash[code % HASHSIZE]);
   while (hash) {
      if (hash->code == code && hash->qual == qual && hash->mask == mask) {
         if (!hash->stat)
            free(hash->str);
         goto newstr;
      }
      hash = *(p = &hash->next);
   }
   *p = hash = (HASH *)malloc(sizeof(HASH));
   hash->next = NULL;
newstr:
   hash->code = code;
   hash->stat = stat;
   hash->mask = mask;
   hash->qual = qual;
   hash->str = str;
   if (!stat)           /* if not static */
      hash->str = (char *)strcpy(malloc(strlen(str)+1), str);
}


remhash(code, mask, qual)
{
   HASH *hash, **p;

   hash = *(p = &Hash[code % HASHSIZE]);
   while (hash) {
      if (hash->code == code && hash->qual == qual && hash->mask == mask) {
         if (!hash->stat)
            free(hash->str);
         *p = hash->next;
         free(hash);
         return(1);
      }
      hash = *(p = &hash->next);
   }
   return(0);
}


keyctl(code)
char code;
{
   static char state;
   register char c, c2;
   register HASH *hash;

   if ((code & 0x78) == 0x60) {
      c2 = 1 << (code & 7);
      if (code & 0x80)
         state &= ~c2;
      else
         state |= c2;
      return(0);
   }
   if (code & 0x80)
      return(0);
   c2 = 0;
   if (state & (KEY_LSHIFT|KEY_RSHIFT))   c2 |= QUAL_SHIFT;
   if (state & (KEY_CTRL             ))   c2 |= QUAL_CTRL;
   if (state & (KEY_AMIGAL|KEY_AMIGAR))   c2 |= QUAL_AMIGA;
   if (state & (KEY_ALTL  |KEY_ALTR  ))   c2 |= QUAL_ALT;
   if ((state & KEY_CAPS) && (code <= 0x37) && (isalpha[code]))
         c2 |= QUAL_SHIFT;
   for (hash = Hash[code % HASHSIZE]; hash; hash = hash->next) {
      if (hash->code == code) {
         if ((c2 & hash->mask) == hash->qual)
            break;
      }
   }
   if (hash) {
      char buf[256];
      strcpy(buf, hash->str);
      do_command(buf);
   } else {
      /* disallow CTL, ALT, and non-ascii keys. form: 'c or "ccc.."  */
      if (code < 0x50) {
         c = (c2 & QUAL_SHIFT) ? cstoa[code] : ctoa[code];
         if (c) {
            char buf[3];
            buf[0] = '\'';
            buf[1] = c;
            buf[2] = 0;
            do_command(buf);
         }
      }
   }
}

#define LN(a,b,c,d)  ((a<<24)|(b<<16)|(c<<8)|d)

long lname[] = {
   LN('e','s','c',0x45), LN('f','1', 0 ,0x50), LN('f','2', 0 ,0x51),
   LN('f','3', 0 ,0x52), LN('f','4', 0 ,0x53), LN('f','5', 0 ,0x54),
   LN('f','6', 0 ,0x55), LN('f','7', 0 ,0x56), LN('f','8', 0 ,0x57),
   LN('f','9', 0 ,0x58), LN('f','1','0',0x59), LN('d','e','l',0x46),
   LN('b','a','c',0x41), LN('b','s', 0 ,0x41), LN('t','a','b',0x42),
   LN('h','e','l',0x5F), LN('r','e','t',0x44), LN('u','p', 0 ,0x4C),
   LN('d','o','w',0x4D), LN('r','i','g',0x4E), LN('l','e','f',0x4F),
   LN('e','n','t',0x43), LN('n','k','-',0x4A), LN('n','k','.',0x3C),
   LN('n','k','0',0x0F),
   LN('n','k','1',0x1D), LN('n','k','2',0x1E), LN('n','k','3',0x1F),
   LN('n','k','4',0x2D), LN('n','k','5',0x2E), LN('n','k','6',0x2F),
   LN('n','k','7',0x3D), LN('n','k','8',0x3E), LN('n','k','9',0x3F),
   0
};


get_codequal(str, pcode, pqual)
char *pcode, *pqual;
char *str;
{
   char qual;
   register short i;

   qual = 0;
   if (strlen(str) > 1) {
      for (; *str && *str != '-'; ++str) {
         if (*str == 's')
            qual |= QUAL_SHIFT;
         if (*str == 'c')
            qual |= QUAL_CTRL;
         if (*str == 'a')
            qual |= QUAL_ALT;
         if (!qual)
            goto notqual;
      }
      if (*str)
         ++str;
   }
notqual:
   *pqual = qual;
   if (strlen(str) != 1) {           /* long name   */
      register short shift = 24;
      register long mult = 0;

      while (*str && shift >= 8) {
         if (*str >= 'A' && *str <= 'Z')
            *str = *str - 'A' + 'a';
         mult |= *str << shift;
         shift -= 8;
         ++str;
      }
      for (i = 0; lname[i]; ++i) {
         if (mult == (lname[i] & 0xFFFFFF00)) {
            *pcode = lname[i] & 0x7F;
            return(1);
         }
      }
   } else {                         /* short name  */
      for (i = 0; i < sizeof(ctoa); ++i) {
         if (*str == ctoa[i]) {
            *pcode = i;
            return(1);
         }
      }
      for (i = 0; i < sizeof(cstoa); ++i) {
         if (*str == cstoa[i]) {
            *pcode = i;
            *pqual |= QUAL_SHIFT;
            return(1);
         }
      }
   }
   return(0);
}

do_map()
{
    char code, qual;

    if (get_codequal(av[1], &code, &qual)) {
        addhash(code, 0, -1, qual, av[2]);
    } else {
        title("Unknown Command");
    }
}

do_unmap()        /* key   */
{
   char code, qual;

   if (get_codequal(av[1], &code, &qual)) {
      remhash(code, -1, qual);
   } else {
        title("Unknown Command");
   }
}

do_clearmap()
{
   resethash();
}

!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'text.c'" '(20909 characters)'
if test -f 'text.c'
then
	echo shar: "will not over-write existing file 'text.c'"
else
cat << \!Funky!Stuff! > 'text.c'

/*
 * TEXT.C
 *
 */

#include "defs.h"

#define TU          titleupdate = 1
#define nomemory()  {memoryfail = 1; TU;}

ED E;                           /* Current File                 */
ED *Base;                       /* doubly linked list of Files  */

char titleupdate;
char memoryfail;
char Current[256];
short Clen;

extern long Rp;
extern char *AllocMem(), *Allocate();

text_init()
{
   E.Insertmode = 1;
   E.Tabstop = 4;
   E.Lines = 1;
   E.Maxlines = 32;
   E.List = (char **)Allocate(sizeof(char *) * E.Maxlines);
   E.List[0] = Allocate(1);
   E.List[0][0] = Current[0] = Clen = 0;
   E.BSline = E.BEline = -1;
   text_cursor(1);
}

text_sync()
{
   char redraw = 0;
   short len;
   char *ptr;

    if (strlen(Current) != Clen)
        puts ("LENGTH FAIL");
    for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
    Current[len] = '\0';
    Clen = len + 1;
    if (!ComLineMode) {
        if (strlen(E.List[E.Line]) != Clen) {
            if (ptr = Allocate(Clen+1)) {
                E.Modified = 1;
                FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1);
                E.List[E.Line] = ptr;
            } else {
                nomemory();
                strcpy(Current, E.List[E.Line]);
                Clen = strlen(Current);
            }
        } else {
            if (strcmp(E.List[E.Line], Current))
                E.Modified = 1;
        }
        strcpy(E.List[E.Line], Current);
    }
    if (E.Column - E.Topcolumn >= Columns || E.Column < E.Topcolumn) {
        redraw = 1;
        E.Topcolumn = E.Column - (Columns>>1);
        if (E.Topcolumn < 0)
            E.Topcolumn = 0;
    }
    if (E.Line - E.Topline >= Rows || E.Line < E.Topline) {
        redraw = 1;
        E.Topline = E.Line - (Rows>>1);
        if (E.Topline < 0)
            E.Topline = 0;
    }
    while (E.Column > Clen)
        Current[Clen++] = ' ';
    Current[Clen] = '\0';
    if (redraw)
        text_redisplay();
    return((int)redraw);
}

text_load()
{
    if (ComLineMode)
        return(0);
   strcpy(Current, E.List[E.Line]);
   Clen = strlen(Current);
   while (E.Column > Clen)
      Current[Clen++] = ' ';
   Current[Clen] = '\0';
}

text_titleupdate()
{
   int r = titleupdate;
   titleupdate = 0;
   return(r);
}

text_lineno()
{
   return(E.Line + 1);
}

text_lines()
{
   return(E.Lines);
}

text_colno()
{
   return(E.Column);
}

text_cols()
{
   return((int)Clen);
}

text_tabsize()
{
   return((int)E.Tabstop);
}

char *
text_name()
{
   return(E.Name);
}

text_uninit()
{
   register int i;

   for (i = 0; i < E.Lines; ++i)
      FreeMem(E.List[i], strlen(E.List[i])+1);
   FreeMem(E.List, E.Maxlines * sizeof(char *));
}

text_cursor(n)
{
   Move(Rp, XTbase+(E.Column-E.Topcolumn)*Xsize, YTbase+(E.Line-E.Topline)*Ysize);
   inversemode(n);
   if (Current[E.Column])
      Text(Rp, Current+E.Column, 1);
   else
      Text(Rp, " ", 1);
   inversemode(0);
}


text_position(col, row)
{
    TU;
    text_sync();
    if (col == 0)
        col = -1;
    E.Column = E.Topcolumn + col;
    if (E.Column > 254)
        E.Column = 254;
    if (E.Column < 0)
        E.Column = 0;
    E.Line = E.Topline + row;
    if (E.Line >= E.Lines)
        E.Line = E.Lines - 1;
    if (E.Line < 0)
        E.Line = 0;
    text_load();
    text_sync();
}


text_displayseg(start, n)
{
   register short i, c;
   register char *ptr;

    for (i = start; i < start+n && E.Topline + i < E.Lines; ++i) {
        if (ComLineMode) {
            if (E.Topline + i != E.Line)
                continue;
            ptr = Current;
        } else {
            ptr = E.List[E.Topline + i];
        }
        for (c = E.Topcolumn; c && *ptr; ++ptr, --c);
        if (*ptr) {
            c = strlen(ptr);
            Move(Rp, XTbase, YTbase + i * Ysize);
            Text(Rp, ptr, (c > Columns) ? Columns : c);
        }
    }
}

text_redisplay()
{
    SetAPen(Rp, 0);
    if (ComLineMode) {
        RectFill(Rp, Xbase, Ybase+(Ysize*(Rows-1)), Xbase+Xpixs, Ybase+(Ysize*Rows));
    } else {
        RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs);
    }
    SetAPen(Rp, 1);
    text_displayseg(0,Rows);
}

text_write(str)
char *str;
{
   short len = strlen(str);
   short i;

   if (Clen + len >= 255) {
      text_sync();
      text_load();
   }
   if (E.Insertmode == 0) {
      i = len;
      if (E.Column + len < 255) {
         bmov(str, Current + E.Column, len);
         if (E.Column + len >= Clen)
            Clen = E.Column + len;
         Current[Clen] = 0;
         goto bin;
      }
      return(0);
   }
   if (Clen + len < 255) {
      bmov(Current + E.Column, Current + E.Column + len, Clen+1-E.Column);
      bmov(str, Current + E.Column, len);
      Clen += len;
      ScrollRaster(Rp, -len * Xsize, 0 ,
                  Xbase + (E.Column - E.Topcolumn) * Xsize,
                  Ybase + (E.Line - E.Topline) * Ysize,
                  Xbase + Columns * Xsize - 1,
                  Ybase + Ysize - 1 + (E.Line - E.Topline) * Ysize);
      i = (E.Column - E.Topcolumn + len > Columns) ? Columns - E.Column + E.Topcolumn : len;
bin:
      Move(Rp, XTbase + (E.Column - E.Topcolumn) * Xsize,
               YTbase + (E.Line - E.Topline) * Ysize);
      Text(Rp, str, i);
      E.Column += len;
      if (E.Column - E.Topcolumn >= Columns)
         text_sync();
   }
}


do_up()
{
   if (E.Line) {
      TU;
      text_sync();
      --E.Line;
      text_load();
      if (E.Line < E.Topline) {
         ScrollRaster(Rp,0,-Ysize,Xbase,Ybase,Xbase+Xpixs,Ybase+Ypixs);
         --E.Topline;
         text_displayseg(0, 1);
      }
   }
}

do_down()
{
   if (E.Line + 1 < E.Lines) {
      TU;
      text_sync();
      ++E.Line;
      text_load();
      if (E.Line - E.Topline >= Rows) {
         ScrollRaster(Rp,0,Ysize,Xbase,Ybase,Xbase+Xpixs,Ybase+Ypixs);
         ++E.Topline;
         text_displayseg(Rows-1, 1);
      }
   }
}

do_pagedown()
{
    text_sync();
    TU;
    E.Line += Rows;
    E.Topline += Rows;
    if (E.Line >= E.Lines)
        E.Line = E.Lines - 1;
    if (E.Topline >= E.Lines)
        E.Topline = E.Lines - Rows - 1;
    if (E.Topline < 0)
        E.Topline = 0;
    text_load();
    if (!text_sync())
        text_redisplay();
}

do_pageup()
{
    text_sync();
    TU;
    E.Line -= Rows;
    E.Topline -= Rows;
    if (E.Line < 0)
        E.Line = 0;
    if (E.Topline < 0)
        E.Topline = 0;
    text_load();
    if (!text_sync())
        text_redisplay();
}

do_downadd()
{
    char *ptr;

    if (E.Line + 1 == E.Lines) {
        E.Modified = 1;
        if (makeroom(32) && (ptr = Allocate(1))) {
            E.List[E.Lines] = ptr;
            *ptr = 0;
            ++E.Lines;
        } else {
            nomemory();
        }
    }
    do_down();
}


do_left()
{
   if (E.Column) {
      --E.Column;
      if (E.Column < E.Topcolumn)
         text_sync();
   }
}

do_right()
{
   if (E.Column != 254) {
      if (Current[E.Column] == 0) {
         Current[E.Column] = ' ';
         Current[E.Column+1]= '\0';
         ++Clen;
      }
      ++E.Column;
      if (E.Column - E.Topcolumn >= Columns)
         text_sync();
   }
}

do_tab()
{
   register short n;

   for (n = E.Tabstop-(E.Column % E.Tabstop); n > 0; --n)
      do_right();
}

do_backtab()
{
   register short n;

   n = E.Column % E.Tabstop;
   if (!n)
      n = E.Tabstop;
   for (; n > 0; --n)
      do_left();
}

do_return()
{
    char buf[256];
    if (ComLineMode) {
        strcpy(buf, Current);
        escapecomlinemode();
        do_command(buf);
    } else {
        E.Column = 0;
        text_sync();
        do_downadd();
    }
}

do_bs()
{
   if (E.Column) {
      bmov(Current + E.Column, Current + E.Column - 1, Clen - E.Column + 1);
      --E.Column;
      --Clen;
      if (E.Column < E.Topcolumn) {
         text_sync();
      } else {
         ScrollRaster(Rp, Xsize, 0,
            Xbase + (E.Column - E.Topcolumn) * Xsize,
            Ybase + (E.Line - E.Topline) * Ysize,
            Xbase + Columns * Xsize - 1,
            Ybase + (E.Line - E.Topline) * Ysize + Ysize - 1);
         if (Clen >= E.Topcolumn + Columns) {
            Move(Rp, XTbase+(Columns-1)*Xsize, YTbase+(E.Line-E.Topline)*Ysize);
            Text(Rp, Current+E.Topcolumn+Columns-1, 1);
         }
      }
   }
}


/*
 * esc, escimm
 */

int Savetopline, Savecolumn, Savetopcolumn;

do_esc()
{
    if (ComLineMode)
        return(escapecomlinemode());
    text_sync();
    if (av[0][3] == 'i')
        strcpy(Current, av[1]);
    else
        Current[0] = 0;
    Clen = strlen(Current);
    ComLineMode = 1;
    returnoveride(1);
    Savetopline = E.Topline;
    Savecolumn  = E.Column;
    Savetopcolumn = E.Topcolumn;
    E.Column    = Clen;
    E.Topcolumn = 0;
    E.Topline   = E.Line - Rows + 1;
    SetAPen(Rp, 0);
    RectFill(Rp, Xbase, Ybase+(Ysize*(Rows-1)), Xbase+Xpixs, Ybase+Ypixs);
    SetAPen(Rp, 1);
    Move(Rp, Xbase, Ybase+(Ysize*(Rows-1))-1);
    Draw(Rp, Xbase+Xpixs, Ybase+(Ysize*(Rows-1))-1);
    text_displayseg(Rows-1,1);
}


escapecomlinemode()
{
    if (ComLineMode) {
        ComLineMode = 0;
        returnoveride(0);
        E.Topline = Savetopline;
        E.Column  = Savecolumn;
        E.Topcolumn = Savetopcolumn;
        text_load();
        SetAPen(Rp, 0);
        RectFill(Rp, Xbase, Ybase+(Ysize*(Rows-1))-1, Xbase+ Xpixs,Ybase+(Ysize*Rows));
        SetAPen(Rp, 1);
        text_displayseg(Rows-2,2);
    }
}


do_del()
{
   if (Current[E.Column]) {
      bmov(Current + E.Column + 1, Current + E.Column, Clen - E.Column);
      --Clen;
      ScrollRaster(Rp, Xsize, 0,
         Xbase + (E.Column - E.Topcolumn) * Xsize,
         Ybase + (E.Line - E.Topline) * Ysize,
         Xbase + Columns * Xsize - 1,
         Ybase + (E.Line - E.Topline) * Ysize + Ysize - 1);
      if (Clen >= E.Topcolumn + Columns) {
         Move(Rp, XTbase+(Columns-1)*Xsize, YTbase+(E.Line-E.Topline)*Ysize);
         Text(Rp, Current+E.Topcolumn+Columns-1, 1);
      }
   }
}

do_top()
{
   text_sync();
   E.Line = 0;
   TU;
   text_load();
   text_sync();
}

do_bottom()
{
   text_sync();
   E.Line = E.Lines - 1;
   TU;
   text_load();
   text_sync();
}

do_firstcolumn()
{
   if (E.Column) {
      E.Column = 0;
      text_sync();
   }
}

do_firstnb()
{
   for (E.Column = 0; Current[E.Column] == ' '; ++E.Column);
   if (Current[E.Column] == 0)
      E.Column = 0;
   text_sync();
}

do_lastcolumn()
{
   short i;

   text_sync();
   i = (ComLineMode) ? Clen : strlen(E.List[E.Line]);
   if (i != E.Column) {
      E.Column = i;
      text_sync();
   }
}

do_goto()
{
   int n = atoi(av[1]) - 1;

   if (n >= 0 && n < E.Lines) {
      text_sync();
      E.Line = n;
      TU;
      text_load();
      text_sync();
   }
}

do_screentop()
{
    text_sync();
    TU;
    E.Line = E.Topline;
    text_load();
    text_sync();
}

do_screenbottom()
{
    text_sync();
    TU;
    if (E.Topline + Rows - 1 >= E.Lines)
        E.Line = E.Lines;
    else
        E.Line = E.Topline + Rows - 1;
    text_load();
    text_sync();
}

/*
 * find, next, prev
 */

do_find()
{
    static char fstr[256];
    int n;
    int col;
    int i = E.Line;
    int sign = 1;
    int len;

    TU;
    text_sync();
    switch(av[0][0]) {
    case 'f':
        strcpy(fstr, av[1]);
        break;
    case 'p':
        sign = -1;
        break;
    }
    len = strlen(fstr);
    if (!len)
        return(0);
    for (n = E.Lines, i = E.Line, col = E.Column; n; --n) {
        for (; col >= 0 && E.List[i][col]; col += sign) {
            if (strncmp(fstr, E.List[i]+col, len) == 0) {
                if (n == E.Lines)
                    continue;
                E.Line = i;
                E.Column = col;
                text_load();
                text_sync();
                return(1);
            }
        }
        i += sign;
        if (i < 0       )  i = E.Lines - 1;
        if (i >= E.Lines)  i = 0;
        col = 0;
        if (sign < 0) {
            col = strlen(E.List[i]) - 1;
            if (col < 0)
                col = 0;
        }
    }
    title("Pattern Not Found");
    return(0);
}

do_split()              /* split line in two at cursor pos      */
{
   char buf[256];
   strcpy(buf, Current+E.Column);
   Current[Clen = E.Column] = '\0';
   text_sync();
   SetAPen(Rp, 0);
   RectFill(Rp, Xbase, Ybase+(E.Line-E.Topline)*Ysize, Xbase+Xpixs, Ybase+(E.Line-E.Topline+1)*Ysize);
   SetAPen(Rp, 1);
   text_displayseg(E.Line - E.Topline, 1);
   do_downadd();
   do_insline();
   strcpy(Current, buf);
   Clen = strlen(Current);
   text_sync();
   text_displayseg(E.Line - E.Topline, 1);
   do_up();
}

do_join()
{
   if (E.Line + 1 < E.Lines && strlen(E.List[E.Line+1])+Clen <= 255) {
      strcat(Current, E.List[E.Line+1]);
      Clen = strlen(Current);
      text_sync();
      text_displayseg(E.Line - E.Topline, 1);
      do_down();
      do_deline();
      do_up();
   }
}

do_tabstop()
{
   E.Tabstop = atoi(av[1]);
}

do_insertmode()
{
    if (av[1][0]) {
        switch(av[1][1] & 0x1F) {
        case 'n'&0x1F:
            E.Insertmode = 1;
            break;
        case 'f'&0x1F:
            E.Insertmode = 0;
            break;
        case 'o'&0x1F:
            E.Insertmode = 1 - E.Insertmode;
            break;
        }
        if (E.Insertmode)
            title("Insert mode on");
        else
            title("Insert mode off");
    }
}

do_insline()
{
    char *ptr;

    TU;
    E.Modified = 1;
    text_sync();
    if (makeroom(32) && (ptr = Allocate(1))) {
        bmov(E.List+E.Line, E.List+E.Line+1, sizeof(char *) * (E.Lines-E.Line));
        E.List[E.Line] = ptr;
        *ptr = 0;
        ++E.Lines;
        if (E.Line < E.BSline)
            ++E.BSline;
        if (E.Line <= E.BEline)
            ++E.BEline;
    } else {
        nomemory();
    }
    text_load();
    ScrollRaster(Rp,0,-Ysize,
        Xbase,Ybase+(E.Line - E.Topline)*Ysize,
        Xbase+Xpixs,Ybase+Ypixs);
    text_displayseg(E.Line - E.Topline, 1);
}

do_deline()
{
   if (E.Lines > 1) {
      TU;
      E.Modified = 1;
      text_sync();
      FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1);
      bmov(E.List+E.Line+1, E.List+E.Line, sizeof(char *) * (E.Lines-E.Line-1));
      if (E.Line < E.BSline)
        --E.BSline;
      if (E.Line <= E.BEline)
        --E.BEline;
      if (E.Line >= --E.Lines) {
         if (--E.Line < E.Topline) {
            text_load();
            E.Topline = E.Line - (Rows>>1);
            if (E.Topline < 0)
               E.Topline = 0;
            text_redisplay();
            return(0);
         }
      }
      text_load();
      ScrollRaster(Rp,0,Ysize,
            Xbase,Ybase+(E.Line - E.Topline)*Ysize,
            Xbase+Xpixs,Ybase+Ypixs);
      text_displayseg(Rows-1, 1);
   }
}

do_edit()
{
    long fi;
    long lines;
    char buf[256];
    char ebuf[256];
    char *ptr;
    char failed = 1;

    TU;
    text_sync();
    if (*av[0] == 'n') {        /* newfile or insfile   */
        if (E.Modified && getyn("Delete modified Image?") == 0)
            return(0);
        text_uninit();
        text_init();
        E.Modified = 0;
        E.Line = 0;
        strncpy(E.Name, av[1], 63);
    } else {
        E.Modified = 1;
    }
    lines = E.Lines;
    if (fi = xopen(av[1], "r", 4096)) {
        register int i, j;
        while (xgets(fi, buf, 255)) {
            failed = 0;
            for(i = j = 0; buf[i] && j < 254; ++i) {
                if (buf[i] == 9) {                  /* expand tabs (always 8)   */
                    do {
                        ebuf[j++] = ' ';
                    } while ((j % 8) && j < 254);
                } else {
                    ebuf[j++] = buf[i];
                }
            }
            while (j && ebuf[j-1] == ' ')
                --j;
            ebuf[j] = 0;
            if (makeroom(256) && (ptr = Allocate(j+1))) {
                E.List[E.Lines++] = ptr;
                bmov(ebuf, ptr, j+1);
            } else {
                nomemory();
                break;
            }
        }
    } else {
        title("File Not Found");
    }
    xclose(fi);
    if (E.Lines != 1 && lines == 1 && E.List[0][0] == 0) {
        E.Modified = 0;
        E.Line = 0;
        FreeMem(E.List[0], strlen(E.List[0])+1);
        bmov(E.List+1, E.List, sizeof(char *) * (--E.Lines));
    } else {
        if (!failed && lines <= E.Lines - 1) {
            E.BSline = lines;
            E.BEline = E.Lines-1;
            do_bmove();
        }
    }
    text_load();
    text_redisplay();
}

static char blockmode;

do_bsave()
{
    blockmode = 1;
    do_saveas();
}


do_save()
{
   av[1] = E.Name;
   do_saveas();
}

do_saveas()
{
    long fi;
    long i;
    long xs, xe;

    if (blockmode && blockok()) {
        xs = E.BSline;
        xe = E.BEline + 1;
    } else {
        xs = 0;
        xe = E.Lines;
    }
    blockmode = 0;
    text_sync();
    if (fi = xopen(av[1], "w", 4096)) {
        for (i = xs; i < xe; ++i) {
            xwrite(fi, E.List[i], strlen(E.List[i]));
            xwrite(fi, "\n", 1);
        }
        xclose(fi);
        E.Modified = 0;
   } else {
        title("Unable to open write file");
   }
}


do_block()          /* block, unblock   */
{
    switch(av[0][0]) {
    case 'b':
        if (E.BSline < 0) {
            E.BSline = E.Line;
            title("Block Begin");
        } else {
            if (E.BEline >= 0) {
                title("Block Already Marked");
                break;
            }
            title("Block End");
            E.BEline = E.Line;
            if (E.BSline > E.BEline) {
                E.BEline = E.BSline;
                E.BSline = E.Line;
            }
        }
        break;
    case 'u':
        E.BSline = E.BEline = -1;
        title ("Block Unmarked");
        break;
    }
}

blockok()
{
    if (E.BSline >= 0 && E.BEline >= 0 && E.BSline <= E.BEline && E.BEline < E.Lines)
        return(1);
    E.BSline = E.BEline = -1;
    title("Block Not Specified");
    return(0);
}

do_bdelete()
{
    int i;
    int n;

    if (blockok()) {
        text_sync();
        n = E.BEline - E.BSline + 1;
        if (E.Line >= E.BSline && E.Line <= E.BEline)
            E.Line = E.BSline;
        if (E.Line > E.BEline)
            E.Line -= n;
        for (i = E.BSline; i < E.BEline; ++i)
            FreeMem(E.List[i], strlen(E.List[i])+1);
        bmov(E.List+E.BEline+1,E.List+E.BSline,(E.Lines-E.BEline-1)*sizeof(E.List[0]));
        E.Lines -= n;
        if (E.Line < 0 || E.Line >= E.Lines)
            E.Line = 0;
        if (E.Lines == 0) {
            text_uninit();
            text_init();
        }
        TU;
        text_load();
        E.BSline = E.BEline = -1;
        if (!text_sync())
            text_redisplay();
    }
}


do_bcopy()
{
    char **list;
    int lines, i;

    if (blockok()) {
        text_sync();
        lines = E.BEline - E.BSline + 1;
        list = (char **)Allocate(sizeof(char *) * (E.Lines+lines));
        if (list) {
            for (i = 0; i < lines; ++i) {
                list[E.Line + i] = Allocate(strlen(E.List[E.BSline+i])+1);
                strcpy(list[E.Line + i], E.List[E.BSline+i]);
            }
            bmov(E.List+0, list, E.Line * sizeof(char *));
            bmov(E.List+E.Line, list + E.Line + lines, (E.Lines-E.Line)*sizeof(char *));
        }
        FreeMem(E.List, E.Maxlines * 4);
        E.List = list;
        E.Lines += lines;
        E.Maxlines = E.Lines;
        text_load();
        E.BSline = E.BEline = -1;
        if (!text_sync())
            text_redisplay();
    }
}

do_bmove()
{
    int lines;
    char **temp;

    if (blockok()) {
        if (E.Line >= E.BSline && E.Line <= E.BEline) {
            title("Cannot Move into self");
            return(0);
        }
        text_sync();
        lines = E.BEline - E.BSline + 1;
        temp = (char **)Allocate(lines * sizeof(char *));
        bmov(E.List + E.BSline, temp, lines * sizeof(char *));
        if (E.Line > E.BSline) {
            bmov(E.List+E.BEline+1, E.List+E.BSline, (E.Line-E.BEline-1)*4);
            bmov(temp, E.List + E.Line - lines, lines * 4);
        } else {
            bmov(E.List+E.Line, E.List+E.Line+lines, (E.BSline-E.Line)*4);
            bmov(temp, E.List + E.Line, lines * 4);
        }
        FreeMem(temp, lines * sizeof(char *));
        E.BSline = E.BEline = -1;
        text_load();
        if (!text_sync())
            text_redisplay();
    }
}


char *
Allocate(bytes)
{
   return(AllocMem(bytes, 0));
}


makeroom(n)
{
    char **Newlist;

    if (E.Lines >= E.Maxlines) {
        Newlist = (char **)Allocate(sizeof(char *) * (E.Maxlines + n));
        if (Newlist) {
            bmov(E.List, Newlist, sizeof(char *) * E.Maxlines);
            FreeMem(E.List, sizeof(char *) * E.Maxlines);
            E.List = Newlist;
            E.Maxlines += n;
            return(1);
        } else {
            nomemory();
        }
        return(0);
    }
    return(1);
}

!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'defs.h'" '(537 characters)'
if test -f 'defs.h'
then
	echo shar: "will not over-write existing file 'defs.h'"
else
cat << \!Funky!Stuff! > 'defs.h'

/*
 * DEFS.H
 *
 */

extern short Xsize, Ysize;
extern short XTbase, YTbase;
extern short Rows, Columns;
extern short Xbase, Ybase;
extern short Xpixs, Ypixs;
extern char *av[];

extern short ComLineMode;

typedef struct _ED {
    struct _ED *next, **prev;
    long Topline, Topcolumn;
    long Line, Column;
    long Lines, Maxlines;
    char **List;
    char Name[64];
    char Modified;
    char Tabstop;
    char Insertmode;

    long BSline, BEline;    /* block start and end lines    */
} ED;


#ifndef NULL
#define NULL 0
#endif
!Funky!Stuff!
fi  # end of overwriting check
exit 0
#	End of shell archive