home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume2 / accell-text / Part2 < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  58.5 KB

  1. From: ustel@well.UUCP (Mark Hargrove)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i051: Unify TEXT fields from ACCELL Part 2/5
  4. Message-ID: <7219@ncoast.UUCP>
  5. Date: 11 Feb 88 00:46:35 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. Comp.sources.misc: Volume 2, Issue 51
  9. Submitted-By: "Mark Hargrove" <ustel@well.UUCP>
  10. Archive-Name: accell-text/Part2
  11.  
  12. #!/bin/sh
  13. # to extract, remove the header and type "sh filename"
  14. if `test ! -s ./fileio.c`
  15. then
  16. echo "writing ./fileio.c"
  17. cat > ./fileio.c << '\Rogue\Monster\'
  18. /*
  19.  * Name:    MicroEMACS
  20.  *         System V file I/O
  21.  */
  22. #include    "def.h"
  23.  
  24. # ifndef F_OK
  25. # define F_OK    0
  26. # define X_OK    1
  27. # define W_OK    2
  28. # define R_OK    4
  29. # endif
  30.  
  31. /*
  32.  * Move bytes, overlaps OK (daveb).
  33.  *
  34.  * Doesn't really belong here, but it's system specific since it
  35.  * is in assembler in some C libraries.
  36.  */
  37. bcopy( from, to, cnt )
  38. char *from;
  39. char *to;
  40. int cnt;
  41. {
  42.     if ( from == to )
  43.         return;
  44.  
  45.     if( from > to )
  46.     {
  47.         while( cnt-- )
  48.             *to++ = *from++;
  49.     }
  50.     else
  51.     {
  52.         to += cnt;
  53.         from += cnt;
  54.         while( cnt-- )
  55.             *--to = *--from;
  56.     }
  57. }
  58.  
  59.  
  60. static    FILE    *ffp;
  61.  
  62. /*
  63.  * Open a file for reading.
  64.  */
  65. ffropen(fn)
  66. char    *fn;
  67. {
  68.     if ((ffp=fopen(fn, "r")) == NULL)
  69.         return (FIOFNF);
  70.     return (FIOSUC);
  71. }
  72.  
  73. /*
  74.  * Open a file for writing.
  75.  * Return TRUE if all is well, and
  76.  * FALSE on error (cannot create).
  77.  */
  78. ffwopen(fn)
  79. char    *fn;
  80. {
  81.     if ((ffp=fopen(fn, "w")) == NULL) {
  82.         ewprintf("Cannot open file for writing");
  83.         return (FIOERR);
  84.     }
  85.     return (FIOSUC);
  86. }
  87.  
  88. /*
  89.  * Close a file.
  90.  * Should look at the status.
  91.  */
  92. ffclose()
  93. {
  94.     (VOID) fclose(ffp);
  95.     return (FIOSUC);
  96. }
  97.  
  98. /*
  99.  * Write a line to the already
  100.  * opened file. The "buf" points to the
  101.  * buffer, and the "nbuf" is its length, less
  102.  * the free newline. Return the status.
  103.  * Check only at the newline.
  104.  */
  105. ffputline(buf, nbuf)
  106. register char    buf[];
  107. {
  108.     register int    i;
  109.  
  110.     for (i=0; i<nbuf; ++i)
  111.         putc(buf[i]&0xFF, ffp);
  112.     putc('\n', ffp);
  113.     if (ferror(ffp) != FALSE) {
  114.         ewprintf("Write I/O error");
  115.         return (FIOERR);
  116.     }
  117.     return (FIOSUC);
  118. }
  119.  
  120. /*
  121.  * Read a line from a file, and store the bytes
  122.  * in the supplied buffer. Stop on end of file or end of
  123.  * line. Don't get upset by files that don't have an end of
  124.  * line on the last line; this seem to be common on CP/M-86 and
  125.  * MS-DOS (the suspected culprit is VAX/VMS kermit, but this
  126.  * has not been confirmed. If this is sufficiently researched
  127.  * it may be possible to pull this kludge). Delete any CR
  128.  * followed by an LF. This is mainly for runoff documents,
  129.  * both on VMS and on Ultrix (they get copied over from
  130.  * VMS systems with DECnet).
  131.  */
  132. ffgetline(buf, nbuf)
  133. register char    buf[];
  134. {
  135.     register int    c;
  136.     register int    i;
  137.  
  138.     i = 0;
  139.     for (;;) {
  140.         c = getc(ffp);
  141.         if (c == '\r') {        /* Delete any non-stray    */
  142.             c = getc(ffp);        /* carriage returns.    */
  143.             if (c != '\n') {
  144.                 if (i >= nbuf-1) {
  145.                     ewprintf("File has long line");
  146.                     return (FIOERR);
  147.                 }
  148.                 buf[i++] = '\r';
  149.             }
  150.         }
  151.         if (c==EOF || c=='\n')        /* End of line.        */
  152.             break;
  153.         if (i >= nbuf-1) {
  154.             ewprintf("File has long line");
  155.             return (FIOERR);
  156.         }
  157.         buf[i++] = c;
  158.     }
  159.     if (c == EOF) {                /* End of file.        */
  160.         if (ferror(ffp) != FALSE) {
  161.             ewprintf("File read error");
  162.             return (FIOERR);
  163.         }
  164.         if (i == 0)            /* Don't get upset if    */
  165.             return (FIOEOF);    /* no newline at EOF.    */
  166.     }
  167.     buf[i] = 0;
  168.     return (FIOSUC);
  169. }
  170.  
  171. #if    BACKUP
  172. /*
  173.  * Rename the file "fname" into a backup
  174.  * copy. On Unix the backup has the same name as the
  175.  * original file, with a "~" on the end; this seems to
  176.  * be newest of the new-speak. The error handling is
  177.  * all in "file.c". The "unlink" is perhaps not the
  178.  * right thing here; I don't care that much as
  179.  * I don't enable backups myself.
  180.  */
  181. fbackupfile(fname)
  182. char    *fname;
  183. {
  184.     register char    *nname;
  185.  
  186.     if ((nname=malloc(strlen(fname)+1+1)) == NULL)
  187.         return (ABORT);
  188.     (void) strcpy(nname, fname);
  189.     (void) strcat(nname, "~");
  190.     (void) unlink(nname);            /* Ignore errors.    */
  191.  
  192.     /* no rename on System V, so do it dangerous way. */
  193.     if ( link(fname, nname) < 0 || unlink(fname) < 0 ) {
  194.         free(nname);
  195.         return (FALSE);
  196.     }
  197.     free(nname);
  198.     return (TRUE);
  199. }
  200. #endif
  201.  
  202. /*
  203.  * The string "fn" is a file name.
  204.  * Perform any required case adjustments. All sustems
  205.  * we deal with so far have case insensitive file systems.
  206.  * We zap everything to lower case. The problem we are trying
  207.  * to solve is getting 2 buffers holding the same file if
  208.  * you visit one of them with the "caps lock" key down.
  209.  * On UNIX file names are dual case, so we leave
  210.  * everything alone.
  211.  */
  212. /*ARGSUSED*/
  213. adjustcase(fn)
  214. register char    *fn;
  215. {
  216. #if    0
  217.     register int    c;
  218.  
  219.     while ((c = *fn) != 0) {
  220.         if (c>='A' && c<='Z')
  221.             *fn = c + 'a' - 'A';
  222.         ++fn;
  223.     }
  224. #endif
  225. }
  226.  
  227.  
  228.  
  229. #ifdef    STARTUP
  230. #include <sys/types.h>
  231. #include <sys/file.h>
  232. /*
  233.  * find the users startup file, and return it's name. Check for
  234.  * $HOME/.mg then for $HOME/.emacs, then give up.
  235.  */
  236. char *
  237. startupfile() 
  238. {
  239.     register char    *file;
  240.     static char    home[NFILEN];
  241.     char        *getenv();
  242.  
  243.     if ( (file = getenv("HOME")) == NULL 
  244.          || strlen(file)+7 >= NFILEN - 1 ) 
  245.         return NULL;
  246.     (VOID) strcpy(home, file);
  247.     file = &(home[strlen(home)]);
  248.     *file++ = '/';
  249.  
  250.     (VOID) strcpy(file, ".mg");
  251.     if (access(home, F_OK ) == 0) return home;
  252.  
  253.     (VOID) strcpy(file, ".emacs");
  254.     if (access(home, F_OK) == 0) return home;
  255.  
  256.     return NULL;
  257. }
  258. #endif
  259. \Rogue\Monster\
  260. else
  261.   echo "will not over write ./fileio.c"
  262. fi
  263. if `test ! -s ./kbd.c`
  264. then
  265. echo "writing ./kbd.c"
  266. cat > ./kbd.c << '\Rogue\Monster\'
  267. /*
  268.  *        Terminal independent keyboard handling.
  269.  */
  270. #include    "def.h"
  271.  
  272. static mapin();
  273.  
  274. #ifdef    DPROMPT
  275. #define    PROMPTL    80
  276.   char    prompt[PROMPTL], *promptp;
  277. #endif
  278.  
  279. /*
  280.  * All input from the user (should!) go through
  281.  * getkey. Quotep is true to get raw keys, false to
  282.  * get 11-bit code keys.
  283.  * Getkey is responsible for putting keystrokes away
  284.  * for macros. It also takes keystrokes out of the macro,
  285.  * though other input routines will can also do this.
  286.  * Read in a key, doing the terminal
  287.  * independent prefix handling. The terminal specific
  288.  * "getkbd" routine gets the first swing, and may return
  289.  * one of the special codes used by the special keys
  290.  * on the keyboard. The "getkbd" routine returns the
  291.  * C0 controls as received; this routine moves them to
  292.  * the right spot in 11 bit code.
  293.  * If the KPROMPT bit in the flags is set and DPROMPT is
  294.  * defined, do delayed prompting.  (dprompt routine is 
  295.  * in sys/???/ttyio.c)
  296.  */
  297. KEY
  298. getkey(f)
  299.    register int f;
  300. {
  301.     register KEY    c;
  302.     KEY        keychar();
  303.     int        getkbd(), ttgetc();
  304.  
  305.     if (kbdmop != NULL)
  306.         return *kbdmop++;
  307. #ifdef    DPROMPT
  308.     if(!(f&KPROMPT))
  309.         prompt[0] = '\0';
  310. #endif
  311.     c = (KEY) mapin(getkbd);
  312. #ifdef    DPROMPT
  313.     if(f&KPROMPT)
  314.     {
  315.         if(promptp > prompt)
  316.             *(promptp-1) = ' ';
  317.         if(promptp >= &prompt[PROMPTL-8])
  318.             f &= ~KPROMPT;
  319.                 /* must have a lot of prefixes.... */
  320.     }
  321. #endif
  322.     if ((f&KQUOTE) == 0)
  323.     {
  324. #ifdef    DO_METAKEY
  325.         if ((c & ~KCHAR) == KCTRL)    /* Function key        */
  326.             c = ((char) c) & KCHAR;/* remove wrapping    */
  327.         else if ((c >= 0x80) && (c <= 0xFF))
  328.         {        /* real meta key    */
  329.             c = ((char) c) & 0x7f;    /* Get the key and mode map it */
  330.             if ((mode&MFLOW) != 0)
  331.                 if (c == CCHR('^')) c = CCHR('Q');
  332.                 else if (c == CCHR('\\')) c = CCHR('S');
  333.             if ((mode&MBSMAP) != 0)
  334.                 if (c == CCHR('H')) c = 0x7f;
  335.                 else if (c == 0x7f) c = CCHR('H');
  336.             c = KMETA | keychar(c & ~0x80, TRUE);
  337.         }
  338. #endif
  339. #ifdef    DPROMPT
  340.         if(f&KPROMPT)
  341.         {
  342.             keyname(promptp, (c<=0x1F && c>=0x00)?KCTRL|(c+'@'):c);
  343.             strcat(promptp, "-");
  344.         }
  345. #endif
  346.         if (c == METACH)        /* M-            */
  347.             c = KMETA | keychar(mapin(ttgetc), TRUE);
  348.         else if (c == CTRLCH)        /* C-            */
  349.             c = KCTRL | keychar(mapin(ttgetc), TRUE);
  350.         else if (c == CTMECH)        /* C-M-            */
  351.             c = KCTRL | KMETA | keychar(mapin(ttgetc), TRUE);
  352.         else if (c<=0x1F && c>=0x00)    /* Relocate control.    */
  353.             c = KCTRL | (c+'@');
  354.         if (c == (KCTRL|'X'))        /* C-X            */
  355.             c = KCTLX | keychar(mapin(ttgetc), TRUE);
  356.     }
  357.  
  358.     if ((f&KNOMAC) == 0 && kbdmip != NULL)
  359.     {
  360.         if (kbdmip+1 > &kbdm[NKBDM-3])
  361.         {    /* macro overflow */
  362.             (VOID) ctrlg(FALSE, 0, KRANDOM);
  363.             ewprintf("Keyboard macro overflow");
  364.             ttflush();
  365.             return (KCTRL|'G');        /* ^G it for us    */
  366.         }
  367.         *kbdmip++ = c;
  368.     }
  369. #ifdef    DPROMPT
  370.     if(f&KPROMPT)
  371.     {
  372.         keyname(promptp, c);
  373.         promptp += strlen(promptp);
  374.         *promptp++ = '-';
  375.         *promptp = '\0';
  376.     }
  377. #endif
  378.     return (c);
  379. }
  380.  
  381. /*
  382.  * go get a key, and run it through whatever mapping the modes
  383.  * specify.
  384.  */
  385. static mapin(get) int (*get)();
  386. {
  387.     register int    c;
  388.  
  389. #ifdef    DPROMPT
  390.     if(prompt[0]!='\0' && ttwait())
  391.     {
  392.         ewprintf("%s", prompt);        /* avoid problems with % */
  393.         update();            /* put the cursor back     */
  394.         epresf = KPROMPT;
  395.     }
  396. #endif
  397.     c = (*get)();
  398.     if ((mode&MFLOW) != 0)
  399.     {
  400.         while (c == CCHR('S') || c == CCHR('Q'))
  401.             c = (*get)();
  402.         if (c == CCHR('^')) c = CCHR('Q');
  403.         else if (c == CCHR('\\')) c = CCHR('S');
  404.     }
  405.     if ((mode&MBSMAP) != 0)
  406.         if (c == CCHR('H')) c = 0x7f;
  407.         else if (c == 0x7f) c = CCHR('H');
  408.     return c;
  409. }
  410. /*
  411.  * Transform a key code into a name,
  412.  * using a table for the special keys and combination
  413.  * of some hard code and some general processing for
  414.  * the rest. None of this code is terminal specific any
  415.  * more. This makes adding keys easier.
  416.  */
  417. VOID
  418. keyname(cp, k) register char *cp; register int k;
  419. {
  420.     register char    *np;
  421.     register int    c;
  422.     char        nbuf[3];
  423.  
  424.     static    char    hex[] = {
  425.         '0',    '1',    '2',    '3',
  426.         '4',    '5',    '6',    '7',
  427.         '8',    '9',    'A',    'B',
  428.         'C',    'D',    'E',    'F'
  429.     };
  430.  
  431.     if ((k&KCTLX) != 0) {            /* C-X prefix.        */
  432.         *cp++ = 'C';
  433.         *cp++ = '-';
  434.         *cp++ = 'x';
  435.         *cp++ = ' ';
  436.     }
  437.     if ((k&KMETA) != 0) {            /* Add M- mark.        */
  438.         *cp++ = 'E';
  439.         *cp++ = 'S';
  440.         *cp++ = 'C';
  441.         *cp++ = ' ';
  442.     }
  443.     if ((k&KCHAR)>=KFIRST && (k&KCHAR)<=KLAST)
  444.     {
  445.         if ((np=keystrings[(k&KCHAR)-KFIRST]) != NULL)
  446.         {
  447.             if ((k&KCTRL) != 0)
  448.             {
  449.                 *cp++ = 'C';
  450.                 *cp++ = '-';
  451.             }
  452.             (VOID) strcpy(cp, np);
  453.             return;
  454.         }
  455.     }
  456.     c = k & ~(KMETA|KCTLX);
  457.     if (c == (KCTRL|'I'))    /* Some specials.    */
  458.         np = "TAB";
  459.     else if (c == (KCTRL|'M'))
  460.         np = "RET";
  461.     else if (c == (KCTRL|'J'))
  462.         np = "LFD";
  463.     else if (c == ' ')
  464.         np = "SPC";
  465.     else if (c == 0x7F)
  466.         np = "DEL";
  467.     else if (c == (KCTRL|'['))
  468.         np = "ESC";
  469.     else
  470.     {
  471.         if ((k&KCTRL) != 0)
  472.         {        /* Add C- mark.        */
  473.             *cp++ = 'C';
  474.             *cp++ = '-';
  475.         }
  476.         if ((k&(KCTRL|KMETA|KCTLX)) != 0 && ISUPPER(k&KCHAR) != FALSE)
  477.             k = TOLOWER(k&KCHAR);
  478.         np = &nbuf[0];
  479.         if (((k&KCHAR)>=0x20 && (k&KCHAR)<=0x7E)
  480.                 ||  ((k&KCHAR)>=0xA0 && (k&KCHAR)<=0xFE))
  481.         {
  482.             nbuf[0] = k&KCHAR;    /* Graphic.        */
  483.             nbuf[1] = 0;
  484.         }
  485.         else
  486.         {            /* Non graphic.        */
  487.             nbuf[0] = hex[(k>>4)&0x0F];
  488.             nbuf[1] = hex[k&0x0F];
  489.             nbuf[2] = 0;
  490.         }
  491.     }
  492.     (VOID) strcpy(cp, np);
  493. }
  494.  
  495. /*
  496.  * turn a key into an internal char.
  497.  */
  498. KEY
  499. keychar(c, f) register int c, f;
  500. {
  501.  
  502.     if (f == TRUE && ISLOWER(c) != FALSE)
  503.         c = TOUPPER(c);
  504.     else if (c>=0x00 && c<=0x1F)        /* Relocate control.    */
  505.         c = (KCTRL|(c+'@'));
  506.     return (KEY) c;
  507. }
  508. \Rogue\Monster\
  509. else
  510.   echo "will not over write ./kbd.c"
  511. fi
  512. if `test ! -s ./line.c`
  513. then
  514. echo "writing ./line.c"
  515. cat > ./line.c << '\Rogue\Monster\'
  516. /*
  517.  *        Text line handling.
  518.  * The functions in this file
  519.  * are a general set of line management
  520.  * utilities. They are the only routines that
  521.  * touch the text. They also touch the buffer
  522.  * and window structures, to make sure that the
  523.  * necessary updating gets done. There are routines
  524.  * in this file that handle the kill buffer too.
  525.  * It isn't here for any good reason.
  526.  *
  527.  * Note that this code only updates the dot and
  528.  * mark values in the window list. Since all the code
  529.  * acts on the current window, the buffer that we
  530.  * are editing must be being displayed, which means
  531.  * that "b_nwnd" is non zero, which means that the
  532.  * dot and mark values in the buffer headers are
  533.  * nonsense.
  534.  */
  535. #include    "def.h"
  536.  
  537. #define    NBLOCK    16            /* Line block chunk size    */
  538.  
  539. #ifndef    KBLOCK
  540. #define    KBLOCK    256            /* Kill buffer block size.    */
  541. #endif
  542.  
  543. static char    *kbufp    = NULL;        /* Kill buffer data.        */
  544. static RSIZE    kused    = 0;        /* # of bytes used in KB.    */
  545. static RSIZE    ksize    = 0;        /* # of bytes allocated in KB.    */
  546. static RSIZE    kstart  = 0;        /* # of first used byte in KB.    */
  547. char    *malloc();
  548. /*
  549.  * This routine allocates a block
  550.  * of memory large enough to hold a LINE
  551.  * containing "used" characters. The block is
  552.  * always rounded up a bit. Return a pointer
  553.  * to the new block, or NULL if there isn't
  554.  * any memory left. Print a message in the
  555.  * message line if no space.
  556.  */
  557. LINE    *
  558. lalloc(used) register RSIZE used;
  559. {
  560.     register LINE    *lp;
  561.     register int    size;
  562.  
  563.     /*NOSTRICT*/
  564.     size = (NBLOCK-1+used) & ~(NBLOCK-1);
  565.     if (size == 0)                /* Assume that an empty    */
  566.         size = NBLOCK;            /* line is for type-in.    */
  567.     /*NOSTRICT*/
  568.     if ((lp=(LINE *)malloc(sizeof(LINE)+size)) == NULL)
  569.     {
  570.         ewprintf("Can't get %d bytes", sizeof(LINE) + size);
  571.         return (NULL);
  572.     }
  573.     lp->l_size = size;
  574.     /*NOSTRICT*/
  575.     lp->l_used = used;
  576.     return (lp);
  577. }
  578.  
  579. /*
  580.  * Delete line "lp". Fix all of the
  581.  * links that might point at it (they are
  582.  * moved to offset 0 of the next line.
  583.  * Unlink the line from whatever buffer it
  584.  * might be in. Release the memory. The
  585.  * buffers are updated too; the magic conditions
  586.  * described in the above comments don't hold
  587.  * here.
  588.  */
  589. VOID
  590. lfree(lp) register LINE *lp;
  591. {
  592.     register BUFFER    *bp;
  593.     register WINDOW    *wp;
  594.  
  595.     wp = wheadp;
  596.     while (wp != NULL)
  597.     {
  598.         if (wp->w_linep == lp)
  599.             wp->w_linep = lp->l_fp;
  600.         if (wp->w_dotp  == lp)
  601.         {
  602.             wp->w_dotp  = lp->l_fp;
  603.             wp->w_doto  = 0;
  604.         }
  605.         if (wp->w_markp == lp)
  606.         {
  607.             wp->w_markp = lp->l_fp;
  608.             wp->w_marko = 0;
  609.         }
  610.         wp = wp->w_wndp;
  611.     }
  612.     bp = bheadp;
  613.     while (bp != NULL)
  614.     {
  615.         if (bp->b_nwnd == 0)
  616.         {
  617.             if (bp->b_dotp  == lp)
  618.             {
  619.                 bp->b_dotp = lp->l_fp;
  620.                 bp->b_doto = 0;
  621.             }
  622.             if (bp->b_markp == lp)
  623.             {
  624.                 bp->b_markp = lp->l_fp;
  625.                 bp->b_marko = 0;
  626.             }
  627.         }
  628.         bp = bp->b_bufp;
  629.     }
  630.     lp->l_bp->l_fp = lp->l_fp;
  631.     lp->l_fp->l_bp = lp->l_bp;
  632.     free((char *) lp);
  633. }
  634.  
  635. /*
  636.  * This routine gets called when
  637.  * a character is changed in place in the
  638.  * current buffer. It updates all of the required
  639.  * flags in the buffer and window system. The flag
  640.  * used is passed as an argument; if the buffer is being
  641.  * displayed in more than 1 window we change EDIT to
  642.  * HARD. Set MODE if the mode line needs to be
  643.  * updated (the "*" has to be set).
  644.  * Modified by Walter Bright to reduce update times.
  645.  */
  646. VOID
  647. lchange(flag) register int flag;
  648. {
  649.     register WINDOW    *wp;
  650.  
  651.     if ((curbp->b_flag&BFCHG) == 0)
  652.     {    /* First change, so     */
  653.         flag |= WFMODE;            /* update mode lines.    */
  654.         curbp->b_flag |= BFCHG;
  655.     }
  656.     wp = wheadp;
  657.     while (wp != NULL)
  658.     {
  659.         if (wp->w_bufp == curbp)
  660.         {
  661.             wp->w_flag |= flag;
  662.             if (wp != curwp) wp->w_flag |= WFHARD;
  663.             }
  664.         wp = wp->w_wndp;
  665.     }
  666. }
  667.  
  668. /*
  669.  * Insert "n" copies of the character "c"
  670.  * at the current location of dot. In the easy case
  671.  * all that happens is the text is stored in the line.
  672.  * In the hard case, the line has to be reallocated.
  673.  * When the window list is updated, take special
  674.  * care; I screwed it up once. You always update dot
  675.  * in the current window. You update mark, and a
  676.  * dot in another window, if it is greater than
  677.  * the place where you did the insert. Return TRUE
  678.  * if all is well, and FALSE on errors.
  679.  *
  680.  * Added 11-1-87 by s.k.henry: overstrike mode for text insertion.
  681.  * Not too hard, mostly just modifies the meaning of 'n'.
  682.  */
  683. linsert(n, c) RSIZE n;
  684. {
  685.     register char    *cp1;
  686.     register char    *cp2;
  687.     register LINE    *lp1;
  688.     LINE        *lp2;
  689.     LINE        *lp3;
  690.     register int    doto;
  691.     register RSIZE    i;
  692.     WINDOW        *wp;
  693. #ifndef max
  694. #define max(a,b) ((a) > (b)) ? (a) : (b)
  695. #endif
  696.  
  697.     lchange(WFEDIT);
  698.     lp1 = curwp->w_dotp;            /* Current line        */
  699.     if (lp1 == curbp->b_linep)        /* At the end: special    */
  700.     {
  701.         if (curwp->w_doto != 0)
  702.         {
  703.             ewprintf("bug: linsert");
  704.             return (FALSE);
  705.         }
  706.         if ((lp2=lalloc(n)) == NULL)    /* Allocate new line    */
  707.             return (FALSE);
  708.         lp3 = lp1->l_bp;        /* Previous line    */
  709.         lp3->l_fp = lp2;        /* Link in        */
  710.         lp2->l_fp = lp1;
  711.         lp1->l_bp = lp2;
  712.         lp2->l_bp = lp3;
  713.         for (i=0; i<n; ++i)
  714.             lp2->l_text[i] = c;
  715.         wp = wheadp;            /* Update windows    */
  716.         while (wp != NULL)
  717.         {
  718.             if (wp->w_linep == lp1)
  719.                 wp->w_linep = lp2;
  720.             if (wp->w_dotp == lp1)
  721.                 wp->w_dotp = lp2;
  722.             if (wp->w_markp == lp1)
  723.                 wp->w_markp = lp2;
  724.             wp = wp->w_wndp;
  725.         }
  726.         /*NOSTRICT*/
  727.         curwp->w_doto = n;
  728.         return (TRUE);
  729.     }
  730.     doto = curwp->w_doto;            /* Save for later.    */
  731.  
  732. #define INS_MODE ((mode & MOVRSTK) == 0)
  733. #define OVR_MODE ((mode & MOVRSTK) == MOVRSTK)
  734.  
  735.     /*NOSTRICT*/
  736.     if ((OVR_MODE && (doto+n > lp1->l_size))
  737.         || (INS_MODE && (lp1->l_used+n > lp1->l_size)))
  738.     {                    /* Hard: reallocate    */
  739.         if ((lp2=lalloc((RSIZE) (lp1->l_used+n))) == NULL)
  740.             return (FALSE);
  741.         cp1 = &lp1->l_text[0];
  742.         cp2 = &lp2->l_text[0];
  743.         while (cp1 != &lp1->l_text[doto])
  744.             *cp2++ = *cp1++;
  745.         if (INS_MODE)
  746.         {
  747.             /*NOSTRICT*/
  748.             cp2 += n;
  749.             while (cp1 != &lp1->l_text[lp1->l_used])
  750.                 *cp2++ = *cp1++;
  751.         }
  752.         lp1->l_bp->l_fp = lp2;
  753.         lp2->l_fp = lp1->l_fp;
  754.         lp1->l_fp->l_bp = lp2;
  755.         lp2->l_bp = lp1->l_bp;
  756.         free((char *) lp1);
  757.     }
  758.     else
  759.     {                    /* Easy: in place    */
  760.         lp2 = lp1;            /* Pretend new line    */
  761.         if (INS_MODE)
  762.         {
  763.             /*NOSTRICT*/
  764.             lp2->l_used += n;
  765.             cp2 = &lp1->l_text[lp1->l_used];
  766.  
  767.             cp1 = cp2-n;
  768.             while (cp1 != &lp1->l_text[doto])
  769.                 *--cp2 = *--cp1;
  770.         }
  771.         else
  772.         {
  773.             /*NOSTRICT*/
  774.             lp2->l_used = max( (doto+n), (lp2->l_used));
  775.         }
  776.     }
  777.     for (i=0; i<n; ++i)            /* Add the characters    */
  778.         lp2->l_text[doto+i] = c;
  779.     wp = wheadp;                /* Update windows    */
  780.     while (wp != NULL)
  781.     {
  782.         if (wp->w_linep == lp1)
  783.             wp->w_linep = lp2;
  784.         if (wp->w_dotp == lp1)
  785.         {
  786.             wp->w_dotp = lp2;
  787.             if (wp==curwp || wp->w_doto>doto)
  788.                 /*NOSTRICT*/
  789.                 wp->w_doto += n;
  790.         }
  791.         if (wp->w_markp == lp1)
  792.         {
  793.             wp->w_markp = lp2;
  794.             if (wp->w_marko > doto)
  795.                 /*NOSTRICT*/
  796.                 wp->w_marko += n;
  797.         }
  798.         wp = wp->w_wndp;
  799.     }
  800.     return (TRUE);
  801. }
  802.  
  803. /*
  804.  * Insert a newline into the buffer
  805.  * at the current location of dot in the current
  806.  * window. The funny ass-backwards way it does things
  807.  * is not a botch; it just makes the last line in
  808.  * the file not a special case. Return TRUE if everything
  809.  * works out and FALSE on error (memory allocation
  810.  * failure). The update of dot and mark is a bit
  811.  * easier then in the above case, because the split
  812.  * forces more updating.
  813.  */
  814. lnewline()
  815. {
  816.     register char    *cp1;
  817.     register char    *cp2;
  818.     register LINE    *lp1;
  819.     LINE        *lp2;
  820.     register int    doto;
  821.     WINDOW        *wp;
  822.  
  823.     lchange(WFHARD);
  824.     lp1  = curwp->w_dotp;            /* Get the address and    */
  825.     doto = curwp->w_doto;            /* offset of "."    */
  826.     if ((lp2=lalloc((RSIZE) doto)) == NULL)    /* New first half line    */
  827.         return (FALSE);
  828.     cp1 = &lp1->l_text[0];            /* Shuffle text around    */
  829.     cp2 = &lp2->l_text[0];
  830.     while (cp1 != &lp1->l_text[doto])
  831.         *cp2++ = *cp1++;
  832.     cp2 = &lp1->l_text[0];
  833.     while (cp1 != &lp1->l_text[lp1->l_used])
  834.         *cp2++ = *cp1++;
  835.     lp1->l_used -= doto;
  836.     lp2->l_bp = lp1->l_bp;
  837.     lp1->l_bp = lp2;
  838.     lp2->l_bp->l_fp = lp2;
  839.     lp2->l_fp = lp1;
  840.     wp = wheadp;                /* Windows        */
  841.     while (wp != NULL)
  842.     {
  843.         if (wp->w_linep == lp1)
  844.             wp->w_linep = lp2;
  845.         if (wp->w_dotp == lp1)
  846.         {
  847.             if (wp->w_doto < doto)
  848.                 wp->w_dotp = lp2;
  849.             else
  850.                 wp->w_doto -= doto;
  851.         }
  852.         if (wp->w_markp == lp1)
  853.         {
  854.             if (wp->w_marko < doto)
  855.                 wp->w_markp = lp2;
  856.             else
  857.                 wp->w_marko -= doto;
  858.         }
  859.         wp = wp->w_wndp;
  860.     }    
  861.     return (TRUE);
  862. }
  863.  
  864. /*
  865.  * This function deletes "n" bytes,
  866.  * starting at dot. It understands how do deal
  867.  * with end of lines, etc. It returns TRUE if all
  868.  * of the characters were deleted, and FALSE if
  869.  * they were not (because dot ran into the end of
  870.  * the buffer. The "kflag" indicates either no insertion,
  871.  * or direction of insertion into the kill buffer.
  872.  */
  873. ldelete(n, kflag) RSIZE n;
  874. {
  875.     register char    *cp1;
  876.     register char    *cp2;
  877.     register LINE    *dotp;
  878.     register int    doto;
  879.     register RSIZE    chunk;
  880.     WINDOW        *wp;
  881.  
  882.     /*
  883.      * HACK - doesn't matter, and fixes back-over-nl bug for empty
  884.      *    kill buffers.
  885.      */
  886.     if (kused == kstart) kflag = KFORW;
  887.  
  888.     while (n != 0)
  889.     {
  890.         dotp = curwp->w_dotp;
  891.         doto = curwp->w_doto;
  892.         if (dotp == curbp->b_linep)    /* Hit end of buffer.    */
  893.             return (FALSE);
  894.         chunk = dotp->l_used-doto;    /* Size of chunk.    */
  895.         if (chunk > n)
  896.             chunk = n;
  897.         if (chunk == 0)
  898.         {        /* End of line, merge.    */
  899.             lchange(WFHARD);
  900.             if (ldelnewline() == FALSE
  901.             || (kflag!=KNONE && kinsert('\n', kflag)==FALSE))
  902.                 return (FALSE);
  903.             --n;
  904.             continue;
  905.         }
  906.         lchange(WFEDIT);
  907.         cp1 = &dotp->l_text[doto];    /* Scrunch text.    */
  908.         cp2 = cp1 + chunk;
  909.         if (kflag == KFORW)
  910.         {
  911.             while (ksize - kused < chunk)
  912.                 if (kgrow(FALSE) == FALSE) return FALSE;
  913.             bcopy(cp1, &(kbufp[kused]), (int) chunk);
  914.             kused += chunk;
  915.         }
  916.         else if (kflag == KBACK)
  917.         {
  918.             while (kstart < chunk)
  919.                 if (kgrow(TRUE) == FALSE) return FALSE;
  920.             bcopy(cp1, &(kbufp[kstart-chunk]), (int) chunk);
  921.             kstart -= chunk;
  922.         } else if (kflag != KNONE) panic("broken ldelete call");
  923.         while (cp2 != &dotp->l_text[dotp->l_used])
  924.             *cp1++ = *cp2++;
  925.         dotp->l_used -= (int) chunk;
  926.         wp = wheadp;            /* Fix windows        */
  927.         while (wp != NULL)
  928.         {
  929.             if (wp->w_dotp==dotp && wp->w_doto>=doto)
  930.             {
  931.                 /*NOSTRICT*/
  932.                 wp->w_doto -= chunk;
  933.                 if (wp->w_doto < doto)
  934.                     wp->w_doto = doto;
  935.             }    
  936.             if (wp->w_markp==dotp && wp->w_marko>=doto)
  937.             {
  938.                 /*NOSTRICT*/
  939.                 wp->w_marko -= chunk;
  940.                 if (wp->w_marko < doto)
  941.                     wp->w_marko = doto;
  942.             }
  943.             wp = wp->w_wndp;
  944.         }
  945.         n -= chunk;
  946.     }
  947.     return (TRUE);
  948. }
  949.  
  950. /*
  951.  * Delete a newline. Join the current line
  952.  * with the next line. If the next line is the magic
  953.  * header line always return TRUE; merging the last line
  954.  * with the header line can be thought of as always being a
  955.  * successful operation, even if nothing is done, and this makes
  956.  * the kill buffer work "right". Easy cases can be done by
  957.  * shuffling data around. Hard cases require that lines be moved
  958.  * about in memory. Return FALSE on error and TRUE if all
  959.  * looks ok.
  960.  */
  961. ldelnewline()
  962. {
  963.     register char    *cp1;
  964.     register char    *cp2;
  965.     register LINE    *lp1;
  966.     LINE        *lp2;
  967.     LINE        *lp3;
  968.     WINDOW        *wp;
  969.  
  970.     lp1 = curwp->w_dotp;
  971.     lp2 = lp1->l_fp;
  972.     if (lp2 == curbp->b_linep)
  973.     {        /* At the buffer end.    */
  974.         if (lp1->l_used == 0)        /* Blank line.        */
  975.             lfree(lp1);
  976.         return (TRUE);
  977.     }
  978.     if (lp2->l_used <= lp1->l_size-lp1->l_used)
  979.     {
  980.         cp1 = &lp1->l_text[lp1->l_used];
  981.         cp2 = &lp2->l_text[0];
  982.         while (cp2 != &lp2->l_text[lp2->l_used])
  983.             *cp1++ = *cp2++;
  984.         wp = wheadp;
  985.         while (wp != NULL)
  986.         {
  987.             if (wp->w_linep == lp2)
  988.                 wp->w_linep = lp1;
  989.             if (wp->w_dotp == lp2)
  990.             {
  991.                 wp->w_dotp  = lp1;
  992.                 wp->w_doto += lp1->l_used;
  993.             }
  994.             if (wp->w_markp == lp2)
  995.             {
  996.                 wp->w_markp  = lp1;
  997.                 wp->w_marko += lp1->l_used;
  998.             }
  999.             wp = wp->w_wndp;
  1000.         }        
  1001.         lp1->l_used += lp2->l_used;
  1002.         lp1->l_fp = lp2->l_fp;
  1003.         lp2->l_fp->l_bp = lp1;
  1004.         free((char *) lp2);
  1005.         return (TRUE);
  1006.     }
  1007.     if ((lp3=lalloc((RSIZE) (lp1->l_used+lp2->l_used))) == NULL)
  1008.         return (FALSE);
  1009.     cp1 = &lp1->l_text[0];
  1010.     cp2 = &lp3->l_text[0];
  1011.     while (cp1 != &lp1->l_text[lp1->l_used])
  1012.         *cp2++ = *cp1++;
  1013.     cp1 = &lp2->l_text[0];
  1014.     while (cp1 != &lp2->l_text[lp2->l_used])
  1015.         *cp2++ = *cp1++;
  1016.     lp1->l_bp->l_fp = lp3;
  1017.     lp3->l_fp = lp2->l_fp;
  1018.     lp2->l_fp->l_bp = lp3;
  1019.     lp3->l_bp = lp1->l_bp;
  1020.     wp = wheadp;
  1021.     while (wp != NULL)
  1022.     {
  1023.         if (wp->w_linep==lp1 || wp->w_linep==lp2)
  1024.             wp->w_linep = lp3;
  1025.         if (wp->w_dotp == lp1)
  1026.             wp->w_dotp  = lp3;
  1027.         else if (wp->w_dotp == lp2)
  1028.         {
  1029.             wp->w_dotp  = lp3;
  1030.             wp->w_doto += lp1->l_used;
  1031.         }
  1032.         if (wp->w_markp == lp1)
  1033.             wp->w_markp  = lp3;
  1034.         else if (wp->w_markp == lp2)
  1035.         {
  1036.             wp->w_markp  = lp3;
  1037.             wp->w_marko += lp1->l_used;
  1038.         }
  1039.         wp = wp->w_wndp;
  1040.     }
  1041.     free((char *) lp1);
  1042.     free((char *) lp2);
  1043.     return (TRUE);
  1044. }
  1045.  
  1046. /*
  1047.  * Replace plen characters before dot with argument string.
  1048.  * Control-J characters in st are interpreted as newlines.
  1049.  * There is a casehack disable flag (normally it likes to match
  1050.  * case of replacement to what was there).
  1051.  */
  1052. lreplace(plen, st, f)
  1053. register RSIZE    plen;            /* length to remove        */
  1054. char        *st;            /* replacement string        */
  1055. int        f;            /* case hack disable        */
  1056. {
  1057.     register RSIZE    rlen;        /* replacement length        */
  1058.     register int    rtype;        /* capitalization         */
  1059.     register int    c;        /* used for random characters    */
  1060.     register int    doto;        /* offset into line        */
  1061.  
  1062.     /*
  1063.      * Find the capitalization of the word that was found.
  1064.      * f says use exact case of replacement string (same thing that
  1065.      * happens with lowercase found), so bypass check.
  1066.      */
  1067.     /*NOSTRICT*/
  1068.     (VOID) backchar(TRUE, (int) plen, KRANDOM);
  1069.     rtype = _L;
  1070.     c = lgetc(curwp->w_dotp, curwp->w_doto);
  1071.     if (ISUPPER(c)!=FALSE  &&  f==FALSE)
  1072.     {
  1073.         rtype = _U|_L;
  1074.         if (curwp->w_doto+1 < llength(curwp->w_dotp))
  1075.         {
  1076.             c = lgetc(curwp->w_dotp, curwp->w_doto+1);
  1077.             if (ISUPPER(c) != FALSE)
  1078.             {
  1079.                 rtype = _U;
  1080.             }
  1081.         }
  1082.     }
  1083.  
  1084.     /*
  1085.      * make the string lengths match (either pad the line
  1086.      * so that it will fit, or scrunch out the excess).
  1087.      * be careful with dot's offset.
  1088.      */
  1089.     rlen = strlen(st);
  1090.     doto = curwp->w_doto;
  1091.     if (plen > rlen)
  1092.         (VOID) ldelete((RSIZE) (plen-rlen), KNONE);
  1093.     else if (plen < rlen)
  1094.     {
  1095.         if (linsert((RSIZE) (rlen-plen), ' ') == FALSE)
  1096.             return (FALSE);
  1097.     }
  1098.     curwp->w_doto = doto;
  1099.  
  1100.     /*
  1101.      * do the replacement:  If was capital, then place first 
  1102.      * char as if upper, and subsequent chars as if lower.  
  1103.      * If inserting upper, check replacement for case.
  1104.      */
  1105.     while ((c = *st++&0xff) != '\0')
  1106.     {
  1107.         if ((rtype&_U)!=0  &&  ISLOWER(c)!=0)
  1108.             c = TOUPPER(c);
  1109.         if (rtype == (_U|_L))
  1110.             rtype = _L;
  1111.         if (c == SEOL)
  1112.         {
  1113.             if (curwp->w_doto == llength(curwp->w_dotp))
  1114.                 (VOID) forwchar(FALSE, 1, KRANDOM);
  1115.             else
  1116.             {
  1117.                 if (ldelete((RSIZE) 1, KNONE) != FALSE)
  1118.                     (VOID) lnewline();
  1119.             }
  1120.         }
  1121.         else if (curwp->w_dotp == curbp->b_linep)
  1122.         {
  1123.             (VOID) linsert((RSIZE) 1, c);
  1124.         }
  1125.         else if (curwp->w_doto == llength(curwp->w_dotp))
  1126.         {
  1127.             if (ldelete((RSIZE) 1, KNONE) != FALSE)
  1128.                 (VOID) linsert((RSIZE) 1, c);
  1129.         } else
  1130.             lputc(curwp->w_dotp, curwp->w_doto++, c);
  1131.     }
  1132.     lchange(WFHARD);
  1133.     return (TRUE);
  1134. }
  1135.  
  1136. /*
  1137.  * Delete all of the text
  1138.  * saved in the kill buffer. Called by commands
  1139.  * when a new kill context is being created. The kill
  1140.  * buffer array is released, just in case the buffer has
  1141.  * grown to immense size. No errors.
  1142.  */
  1143. VOID
  1144. kdelete()
  1145. {
  1146.     if (kbufp != NULL)
  1147.     {
  1148.         free((char *) kbufp);
  1149.         kbufp = NULL;
  1150.         kstart = kused = ksize = 0;
  1151.     }
  1152. }
  1153.  
  1154. /*
  1155.  * Insert a character to the kill buffer,
  1156.  * enlarging the buffer if there isn't any room. Always
  1157.  * grow the buffer in chunks, on the assumption that if you
  1158.  * put something in the kill buffer you are going to put
  1159.  * more stuff there too later. Return TRUE if all is
  1160.  * well, and FALSE on errors. Print a message on
  1161.  * errors. Dir says whether to put it at back or front.
  1162.  */
  1163. kinsert(c, dir)
  1164. {
  1165.  
  1166.     if (kused == ksize && dir == KFORW && kgrow(FALSE) == FALSE)
  1167.         return FALSE;
  1168.     if (kstart == 0 && dir == KBACK && kgrow(TRUE) == FALSE)
  1169.         return FALSE;
  1170.     if (dir == KFORW) kbufp[kused++] = c;
  1171.     else if (dir == KBACK) kbufp[--kstart] = c;
  1172.     else panic("broken kinsert call");        /* Oh shit! */
  1173.     return (TRUE);
  1174. }
  1175.  
  1176. /*
  1177.  * kgrow - just get more kill buffer for the callee. back is true if
  1178.  * we are trying to get space at the beginning of the kill buffer.
  1179.  */
  1180. kgrow(back)
  1181. {
  1182.     register int    nstart;
  1183.     register char    *nbufp;
  1184.  
  1185.     if ((nbufp=malloc((int)(ksize+KBLOCK))) == NULL)
  1186.     {
  1187.         ewprintf("Can't get %ld bytes", (long)(ksize+KBLOCK));
  1188.         return (FALSE);
  1189.     }
  1190.     nstart = (back == TRUE) ? (kstart + KBLOCK) : (KBLOCK / 4) ;
  1191.     bcopy(&(kbufp[kstart]), &(nbufp[nstart]), (int) (kused-kstart));
  1192.     if (kbufp != NULL)
  1193.         free((char *) kbufp);
  1194.     kbufp  = nbufp;
  1195.     ksize += KBLOCK;
  1196.     kused = kused - kstart + nstart;
  1197.     kstart = nstart;
  1198.     return TRUE;
  1199. }
  1200.  
  1201. /*
  1202.  * This function gets characters from
  1203.  * the kill buffer. If the character index "n" is
  1204.  * off the end, it returns "-1". This lets the caller
  1205.  * just scan along until it gets a "-1" back.
  1206.  */
  1207. kremove(n)
  1208. {
  1209.     if (n < 0 || n + kstart >= kused)
  1210.         return (-1);
  1211.     return (kbufp[n + kstart] & 0xFF);
  1212. }
  1213. \Rogue\Monster\
  1214. else
  1215.   echo "will not over write ./line.c"
  1216. fi
  1217. if `test ! -s ./main.c`
  1218. then
  1219. echo "writing ./main.c"
  1220. cat > ./main.c << '\Rogue\Monster\'
  1221. /*
  1222.  *        Mainline, macro commands.
  1223.  */
  1224. #include    "def.h"
  1225.  
  1226. int    thisflag;            /* Flags, this command        */
  1227. int    lastflag;            /* Flags, last command        */
  1228. int    curgoal;            /* Goal column            */
  1229. BUFFER    *curbp;                /* Current buffer        */
  1230. WINDOW    *curwp;                /* Current window        */
  1231. BUFFER    *bheadp;            /* BUFFER listhead        */
  1232. WINDOW    *wheadp = (WINDOW *)NULL;    /* WINDOW listhead        */
  1233. KEY    kbdm[NKBDM] = {(KCTLX|')')};    /* Macro            */
  1234. KEY    *kbdmip;            /* Input  for above        */
  1235. KEY    *kbdmop;            /* Output for above        */
  1236. char    pat[NPAT];            /* Pattern            */
  1237. #ifdef    HASH
  1238. SYMBOL    *symbol[NSHASH];        /* Symbol table listhead.    */
  1239. #else
  1240. /* should really be a *symbol, but don't want to break the hash code yet */
  1241. SYMBOL  *symbol[1] = {(SYMBOL *)NULL};
  1242. #endif
  1243. SYMBOL    *binding[NKEYS];        /* Key bindings.        */
  1244. #ifdef    DPROMPT
  1245. extern char prompt[], *promptp;        /* delayed prompting        */
  1246. #endif
  1247. VOID    edinit();
  1248.  
  1249. VOID
  1250. main(argc, argv)
  1251.    int  argc;
  1252.    char *argv[];
  1253. {
  1254.     register KEY    c;
  1255.     register int    f;
  1256.     register int    n;
  1257.     register int    mflag;
  1258. #ifdef    STARTUP
  1259.     char        *sfile, *startupfile();
  1260. #endif
  1261.     char        bname[NBUFN];
  1262.  
  1263. #ifdef SYSINIT
  1264.     SYSINIT;                /* system dependent.    */
  1265. #endif
  1266.     vtinit();                /* Virtual terminal.    */
  1267.     edinit();                /* Buffers, windows.    */
  1268.     keymapinit();                /* Symbols, bindings.    */
  1269.     /* doing update() before reading files causes the error messages from
  1270.      * the file I/O show up on the screen.  (and also an extra display
  1271.      * of the mode line if there are files specified on the command line.)
  1272.      */
  1273.     update();
  1274. #ifdef    STARTUP                    /* User startup file.    */
  1275.     if ((sfile = startupfile()) != NULL)
  1276.         (VOID) load(sfile);
  1277. #endif
  1278.     while (--argc > 0) {
  1279.         adjustcase(*++argv);
  1280.                 makename(bname, *argv);
  1281.         curbp = bfind(bname, TRUE);
  1282.         (VOID) showbuffer(curbp, curwp, 0);
  1283.         (VOID) readin(*argv);
  1284.     }
  1285.     lastflag = 0;                /* Fake last flags.    */
  1286. loop:
  1287. #ifdef    DPROMPT
  1288.     *(promptp = prompt) = '\0';
  1289.     if(epresf == KPROMPT) eerase();
  1290. #endif
  1291.     update();                /* Fix up the screen.    */
  1292.     c = getkey(KPROMPT);
  1293.     if (epresf == TRUE)
  1294.     {
  1295.         eerase();
  1296.         update();
  1297.     }
  1298.     f = FALSE;
  1299.     n = 1;
  1300.     if (((KMETA|'0') <= c && c <= (KMETA|'9')) || c == (KMETA|'-'))
  1301.     {
  1302.         f = TRUE;
  1303.         c = c & ~KMETA;
  1304.     }
  1305.     else if (c == (KCTRL|'U'))
  1306.     {
  1307.         f = TRUE;
  1308.         n = 4;
  1309.         while ((c=getkey(KNOMAC | KPROMPT)) == (KCTRL|'U')) 
  1310.             n *= 4;
  1311.     }
  1312.     if (f == TRUE)
  1313.     {
  1314.         if ((c>='0' && c<='9') || c=='-')
  1315.         {
  1316.             if (c == '-')
  1317.             {
  1318.                 n = 0;
  1319.                 mflag = TRUE;
  1320.             }
  1321.             else
  1322.             {
  1323.                 n = ((int) c) - '0';
  1324.                 mflag = FALSE;
  1325.             }
  1326.             while ((c=getkey(KNOMAC | KPROMPT))>='0' && c<='9')
  1327.                 n = 10*n + ((int) c) - '0';
  1328.             if (mflag != FALSE)
  1329.                 n = -n;
  1330.         }
  1331.     }
  1332.     if (kbdmip != NULL)
  1333.     {            /* Terminate macros.    */
  1334.         if (c!=(KCTLX|')') && kbdmip>&kbdm[NKBDM-6])
  1335.         {
  1336.             (VOID) ctrlg(FALSE, 0, KRANDOM);
  1337.             goto loop;
  1338.         }
  1339.         if (f != FALSE)
  1340.         {
  1341.             kbdmip[-1] = (KEY) (KCTRL|'U');/* overwrite ESC */
  1342.             *kbdmip++ = (KEY) n;
  1343.             *kbdmip++ = (KEY) c;
  1344.         }
  1345.     }
  1346.     switch (execute(c, f, n))
  1347.     {        /* Do it.        */
  1348.         case TRUE: break;
  1349.         case ABORT:
  1350.             ewprintf("Quit");    /* and fall through */
  1351.         case FALSE:
  1352.         default:
  1353.             ttbeep();
  1354.             if (kbdmip != NULL)
  1355.             {
  1356.                 kbdm[0] = (KEY) (KCTLX|')');
  1357.                 kbdmip = NULL;
  1358.             }
  1359.     }
  1360.     goto loop;
  1361. }
  1362.  
  1363. /*
  1364.  * Command execution. Look up the binding in the the
  1365.  * binding array, and do what it says. Return a very bad status
  1366.  * if there is no binding, or if the symbol has a type that
  1367.  * is not usable (there is no way to get this into a symbol table
  1368.  * entry now). Also fiddle with the flags.
  1369.  */
  1370. execute(c, f, n)
  1371.    KEY c;
  1372. {
  1373.     register SYMBOL    *sp;
  1374.     register int    status;
  1375.  
  1376.     if ((sp=binding[c]) != NULL)
  1377.     {
  1378.         thisflag = 0;
  1379.         status = (*sp->s_funcp)(f, n, c);
  1380.         lastflag = thisflag;
  1381.         return (status);
  1382.     }
  1383.     lastflag = 0;
  1384.     return (FALSE);
  1385. }
  1386.  
  1387. /*
  1388.  * Initialize all of the buffers
  1389.  * and windows. The buffer name is passed down as
  1390.  * an argument, because the main routine may have been
  1391.  * told to read in a file by default, and we want the
  1392.  * buffer name to be right.
  1393.  */
  1394. VOID
  1395. edinit()
  1396. {
  1397.     register BUFFER    *bp;
  1398.     register WINDOW    *wp;
  1399.  
  1400.     bheadp = NULL;
  1401.     bp = bfind("*scratch*", TRUE);        /* Text buffer.        */
  1402.     wp = (WINDOW *)malloc(sizeof(WINDOW));    /* Initial window.    */
  1403.     if (bp==NULL || wp==NULL) panic("edinit");
  1404.     curbp  = bp;                /* Current ones.    */
  1405.     wheadp = wp;
  1406.     curwp  = wp;
  1407.     wp->w_wndp  = NULL;            /* Initialize window.    */
  1408.     wp->w_bufp  = bp;
  1409.     bp->b_nwnd  = 1;            /* Displayed.        */
  1410.     wp->w_linep = bp->b_linep;
  1411.     wp->w_dotp  = bp->b_linep;
  1412.     wp->w_doto  = 0;
  1413.     wp->w_markp = NULL;
  1414.     wp->w_marko = 0;
  1415.     wp->w_toprow = 0;
  1416.     wp->w_ntrows = nrow-2;            /* 2 = mode, echo.    */
  1417.     wp->w_force = 0;
  1418.     wp->w_flag  = WFMODE|WFHARD;        /* Full.        */
  1419. }
  1420.  
  1421. /*
  1422.  * Quit command. If an argument, always
  1423.  * quit. Otherwise confirm if a buffer has been
  1424.  * changed and not written out. Normally bound
  1425.  * to "C-X C-C".
  1426.  */
  1427. /*ARGSUSED*/
  1428. quit(f, n, k)
  1429. {
  1430.     register int    s;
  1431.  
  1432.     if (f == FALSE)
  1433.     {
  1434.         if ((s = anycb(FALSE)) == ABORT)
  1435.             return ABORT;
  1436.         if (s == FALSE
  1437.             || eyesno("The text is modified, really exit") == TRUE)
  1438.         {
  1439.             vttidy();
  1440.             exit(GOOD);
  1441.         }
  1442.     }
  1443.     else
  1444.     {
  1445.         vttidy();
  1446.         exit(GOOD);
  1447.     }
  1448.     return TRUE;
  1449. }
  1450.  
  1451.  
  1452. /*
  1453.  * User abort. Should be called by any input routine that sees a C-g
  1454.  * to abort whatever C-g is aborting these days. Currently does
  1455.  * nothing.
  1456.  */
  1457. /*ARGSUSED*/
  1458. ctrlg(f, n, k)
  1459. {
  1460.     return (ABORT);
  1461. }
  1462. \Rogue\Monster\
  1463. else
  1464.   echo "will not over write ./main.c"
  1465. fi
  1466. if `test ! -s ./match.c`
  1467. then
  1468. echo "writing ./match.c"
  1469. cat > ./match.c << '\Rogue\Monster\'
  1470. /*
  1471.  * Name:    MicroEMACS
  1472.  *         Limited parenthesis matching routines
  1473.  * Version:    Gnu30
  1474.  * Last edit:    13-Jul-86
  1475.  * Created:    19-May-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1476.  *
  1477.  * The hacks in this file implement automatic matching
  1478.  * of (), [], {}, and other characters.  It would be
  1479.  * better to have a full-blown syntax table, but there's
  1480.  * enough overhead in the editor as it is.
  1481.  *
  1482.  * Since I often edit Scribe code, I've made it possible to
  1483.  * blink arbitrary characters -- just bind delimiter characters
  1484.  * to "blink-matching-paren-hack"
  1485.  */
  1486. #include    "def.h"
  1487.  
  1488. #ifndef TINY
  1489.  
  1490. static int balance();
  1491. static displaymatch();
  1492.  
  1493. /* Balance table. When balance() encounters a character
  1494.  * that is to be matched, it first searches this table
  1495.  * for a balancing left-side character.  If the character
  1496.  * is not in the table, the character is balanced by itself.
  1497.  * This is to allow delimiters in Scribe documents to be matched.
  1498.  */    
  1499.  
  1500. static struct balance {
  1501.     char left, right;
  1502. } bal[] = {
  1503.     { '(', ')' },
  1504.     { '[', ']' },
  1505.     { '{', '}' },
  1506.     { '<', '>' },
  1507.     { '\0','\0'}
  1508. };
  1509.  
  1510. /*
  1511.  * Fake the GNU "blink-matching-paren" variable.
  1512.  * If the argument exists, nonzero means show,
  1513.  * zero means don't.  If it doesn't exist,
  1514.  * pretend it's nonzero.
  1515.  */
  1516.  
  1517. blinkparen(f, n, k)
  1518. {
  1519.     register char    *command;
  1520.     register SYMBOL    *sp;
  1521.  
  1522.     if (f == FALSE)
  1523.         n = 1;
  1524.     command = (n == 0) ? "self-insert-command" :
  1525.                  "blink-matching-paren-hack";
  1526.     if ((sp=symlookup(command)) == NULL)
  1527.     {
  1528.         ewprintf("blinkparen: no binding for %s",command);
  1529.         return (FALSE);
  1530.     }
  1531.     binding[(KEY) ')'] = sp;        /* rebind paren        */
  1532.     return (TRUE);    
  1533. }
  1534.  
  1535. /*
  1536.  * Self-insert character, then show matching character,
  1537.  * if any.  Bound to "blink-matching-paren-command".
  1538.  */
  1539.  
  1540. showmatch(f, n, k)
  1541. {
  1542.     register int  i, s;
  1543.  
  1544.     if (k == KRANDOM)
  1545.         return(FALSE);
  1546.     for (i = 0; i < n; i++)
  1547.     {
  1548.         if ((s = selfinsert(f, 1, k)) != TRUE)
  1549.             return(s);
  1550.         if (balance(k) != TRUE)    /* unbalanced -- warn user */
  1551.             ttbeep();
  1552.     }
  1553.     return (TRUE);
  1554. }
  1555.  
  1556. /*
  1557.  * Search for and display a matching character.
  1558.  *
  1559.  * This routine does the real work of searching backward
  1560.  * for a balancing character.  If such a balancing character
  1561.  * is found, it uses displaymatch() to display the match.
  1562.  */
  1563.  
  1564. static balance(k)
  1565. int k;
  1566. {
  1567.     register LINE    *clp;
  1568.     register int    cbo;
  1569.     int    c;
  1570.     int    i;
  1571.     int    rbal, lbal;
  1572.     int    depth;
  1573.  
  1574.     rbal = k & KCHAR;
  1575.     if ((k&KCTRL)!=0 && rbal>='@' && rbal<='_') /* ASCII-ify.    */
  1576.         rbal -= '@';
  1577.  
  1578.     /* See if there is a matching character -- default to the same */
  1579.  
  1580.     lbal = rbal;
  1581.     for (i = 0; bal[i].right != '\0'; i++)
  1582.         if (bal[i].right == rbal)
  1583.         {
  1584.             lbal = bal[i].left;
  1585.             break;
  1586.         }
  1587.  
  1588.     /* Move behind the inserted character.  We are always guaranteed    */
  1589.     /* that there is at least one character on the line, since one was  */
  1590.     /* just self-inserted by blinkparen.                    */
  1591.  
  1592.     clp = curwp->w_dotp;
  1593.     cbo = curwp->w_doto - 1;
  1594.  
  1595.     depth = 0;            /* init nesting depth        */
  1596.  
  1597.     for (;;)
  1598.     {
  1599.         if (cbo == 0)
  1600.         {            /* beginning of line    */
  1601.             clp = lback(clp);
  1602.             if (clp == curbp->b_linep)
  1603.                 return (FALSE);
  1604.             cbo = llength(clp)+1;
  1605.         }
  1606.         if (--cbo == llength(clp))    /* end of line        */
  1607.             c = '\n';
  1608.         else
  1609.             c = lgetc(clp,cbo);    /* somewhere in middle    */
  1610.  
  1611.         /* Check for a matching character.  If still in a nested */
  1612.         /* level, pop out of it and continue search.  This check */
  1613.         /* is done before the nesting check so single-character     */
  1614.         /* matches will work too.                 */
  1615.         if (c == lbal)
  1616.         {
  1617.             if (depth == 0)
  1618.             {
  1619.                 displaymatch(clp,cbo);
  1620.                 return (TRUE);
  1621.             }
  1622.             else
  1623.                 depth--;
  1624.         }
  1625.         /* Check for another level of nesting.  */
  1626.         if (c == rbal)
  1627.             depth++;
  1628.     }
  1629.     /*NOTREACHED*/
  1630. }
  1631.  
  1632.  
  1633. /*
  1634.  * Display matching character.
  1635.  * Matching characters that are not in the current window
  1636.  * are displayed in the echo line. If in the current
  1637.  * window, move dot to the matching character,
  1638.  * sit there a while, then move back.
  1639.  */
  1640.  
  1641. static displaymatch(clp, cbo)
  1642. register LINE *clp;
  1643. register int  cbo;
  1644. {
  1645.     register LINE    *tlp;
  1646.     register int    tbo;
  1647.     register int    cp;
  1648.     register int    bufo;
  1649.     register int    c;
  1650.     int        inwindow;
  1651.     char         buf[NLINE];
  1652.  
  1653.     /* Figure out if matching char is in current window by    */
  1654.     /* searching from the top of the window to dot.        */
  1655.  
  1656.     inwindow = FALSE;
  1657.     for (tlp = curwp->w_linep; tlp != lforw(curwp->w_dotp); tlp = lforw(tlp))
  1658.         if (tlp == clp)
  1659.             inwindow = TRUE;
  1660.  
  1661.     if (inwindow == TRUE)
  1662.     {
  1663.         tlp = curwp->w_dotp;    /* save current position */
  1664.         tbo = curwp->w_doto;
  1665.  
  1666.         curwp->w_dotp  = clp;    /* move to new position */
  1667.         curwp->w_doto  = cbo;
  1668.         curwp->w_flag |= WFMOVE;
  1669.  
  1670.         update();        /* show match */
  1671.         sleep(1);        /* wait a bit */
  1672.  
  1673.         curwp->w_dotp   = tlp;    /* return to old position */
  1674.         curwp->w_doto   = tbo;
  1675.         curwp->w_flag  |= WFMOVE;
  1676.         update();
  1677.     }
  1678.     else
  1679.     {    /* match not in this window so display line in echo area */
  1680.         bufo = 0;
  1681.         for (cp = 0; cp < llength(clp); cp++)
  1682.         {    /* expand tabs    */
  1683.             c = lgetc(clp,cp);
  1684.                         if (
  1685. #ifdef    NOTAB
  1686.                 (mode&MNOTAB) ||
  1687. #endif
  1688.                 c != '\t')
  1689.                     if(ISCTRL(c))
  1690.                 {
  1691.                     buf[bufo++] = '^';
  1692.                     buf[bufo++] = c ^ 0x40;
  1693.                 } else buf[bufo++] = c;
  1694.             else
  1695.                 do {
  1696.                     buf[bufo++] = ' ';
  1697.                 } while (bufo & 7);
  1698.         }
  1699.         buf[bufo++] = '\0';
  1700.         ewprintf("Matches %s",buf);
  1701.     }
  1702.     return (TRUE);
  1703. }
  1704. #endif
  1705. \Rogue\Monster\
  1706. else
  1707.   echo "will not over write ./match.c"
  1708. fi
  1709. if `test ! -s ./newlog.c`
  1710. then
  1711. echo "writing ./newlog.c"
  1712. cat > ./newlog.c << '\Rogue\Monster\'
  1713. /*************************************************************************
  1714. *
  1715. *  newlog - set up a header for a new log entry
  1716. *
  1717. **************************************************************************/
  1718.  
  1719. #ifdef MISLOG
  1720. #include "def.h"
  1721. #include <stdio.h>
  1722. #include <pwd.h>
  1723. #include <time.h>
  1724.  
  1725. int newlog( f, n, k)
  1726.    int f, n, k;
  1727. {
  1728.  
  1729.    FILE *fp, *fopen(); 
  1730.    struct passwd *pw_entry, *getpwnam();
  1731.    char *fs_file, basename[80], author[80], date[80],
  1732.         *getlogin(), *asctime(), *login_name, buf[80],
  1733.         *tmpnam();
  1734.    struct tm *timenow, *localtime();
  1735.    long clock, time();
  1736.    int n;
  1737.  
  1738.    login_name = getlogin();
  1739.    pw_entry = getpwnam(login_name);
  1740.    strcpy(author, pw_entry->pw_gecos);
  1741.  
  1742.    clock = time((long *) 0);
  1743.    timenow = localtime(&clock);
  1744.  
  1745.    fs_file = tmpnam();
  1746.    fp = fopen(fs_file, "w");
  1747.    sprintf(date, "%s", asctime(timenow));
  1748.    fprintf(fp,
  1749.     "----------------------------------------------------------------------\n");
  1750.    date[strlen(date) - 1] = '\0';
  1751.    fprintf(fp, "%s         %s\n\n", date, author);
  1752.  
  1753.    fclose(fp);
  1754.    gotoeob( FALSE, 0, 0);
  1755.    insertfile( fs_file, (char *)0);
  1756.    unlink( fs_file);
  1757.    gotoeob( FALSE, 0, 0);
  1758.  
  1759.    return TRUE;
  1760. }
  1761. #endif
  1762. \Rogue\Monster\
  1763. else
  1764.   echo "will not over write ./newlog.c"
  1765. fi
  1766. if `test ! -s ./paragraph.c`
  1767. then
  1768. echo "writing ./paragraph.c"
  1769. cat > ./paragraph.c << '\Rogue\Monster\'
  1770. /*
  1771.  * Code for dealing with paragraphs and filling. Adapted from MicroEMACS 3.6
  1772.  * and GNU-ified by mwm@ucbvax.  Several bug fixes by blarson@usc-oberon.
  1773.  */
  1774. #include "def.h"
  1775.  
  1776. static int    fillcol = 70 ;
  1777. #define    MAXWORD    256
  1778.  
  1779. /*
  1780.  * go back to the begining of the current paragraph
  1781.  * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
  1782.  * combination to delimit the begining of a paragraph
  1783.  */
  1784. /*ARGSUSED*/
  1785. gotobop(f, n, k)
  1786. {
  1787.     register int suc;    /* success of last backchar */
  1788.  
  1789.     if (n < 0)    /* the other way...*/
  1790.         return(gotoeop(f, -n, KRANDOM));
  1791.  
  1792.     while (n-- > 0)
  1793.     {    /* for each one asked for */
  1794.  
  1795.         /* first scan back until we are in a word */
  1796.         suc = backchar(FALSE, 1, KRANDOM);
  1797.         while (!inword() && suc)
  1798.             suc = backchar(FALSE, 1, KRANDOM);
  1799.         curwp->w_doto = 0;    /* and go to the B-O-Line */
  1800.  
  1801.         /* and scan back until we hit a <NL><SP> <NL><TAB> or <NL><NL> */
  1802.         while (lback(curwp->w_dotp) != curbp->b_linep)
  1803.             if (llength(lback(curwp->w_dotp)) 
  1804.                 && lgetc(curwp->w_dotp,0) != ' '
  1805.                 && lgetc(curwp->w_dotp,0) != '\t')
  1806.                 curwp->w_dotp = lback(curwp->w_dotp);
  1807.             else
  1808.                 break;
  1809.     }
  1810.     curwp->w_flag |= WFMOVE;    /* force screen update */
  1811.     return TRUE;
  1812. }
  1813.  
  1814. /*
  1815.  * go forword to the end of the current paragraph
  1816.  * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
  1817.  * combination to delimit the begining of a paragraph
  1818.  */
  1819. /*ARGSUSED*/
  1820. gotoeop(f, n, k)
  1821. {
  1822.     register int suc;    /* success of last backchar */
  1823.  
  1824.     if (n < 0)    /* the other way...*/
  1825.         return(gotobop(f, -n, KRANDOM));
  1826.  
  1827.     while (n-- > 0)
  1828.     {    /* for each one asked for */
  1829.  
  1830.         /* Find the first word on/after the current line */
  1831.         curwp->w_doto = 0;
  1832.         suc = forwchar(FALSE, 1, KRANDOM);
  1833.         while (!inword() && suc)
  1834.             suc = forwchar(FALSE, 1, KRANDOM);
  1835.         curwp->w_doto = 0;
  1836.         if (curwp->w_dotp == curbp->b_linep)
  1837.             break;                /* check for eob */
  1838.         curwp->w_dotp = lforw(curwp->w_dotp);
  1839.  
  1840.         /* and scan forword until we hit a <NL><SP> or ... */
  1841.         while (curwp->w_dotp != curbp->b_linep)
  1842.         {
  1843.             if (llength(curwp->w_dotp)
  1844.                 && lgetc(curwp->w_dotp,0) != ' '
  1845.                 && lgetc(curwp->w_dotp,0) != '\t')
  1846.                 curwp->w_dotp = lforw(curwp->w_dotp);
  1847.             else
  1848.                 break;
  1849.         }
  1850.     }
  1851.     curwp->w_flag |= WFMOVE;    /* force screen update */
  1852.     return TRUE;
  1853. }
  1854.  
  1855. /*
  1856.  * Fill the current paragraph according to the current
  1857.  * fill column
  1858.  */
  1859. /*ARGSUSED*/
  1860. fillpara(f, n, k)
  1861. {
  1862.     register int    c;        /* current char durring scan    */
  1863.     register int    wordlen;    /* length of current word    */
  1864.     register int    clength;    /* position on line during fill    */
  1865.     register int    i;        /* index during word copy    */
  1866.     register int    eopflag;    /* Are we at the End-Of-Paragraph? */
  1867.     int         firstflag;    /* first word? (needs no space)    */
  1868.     int        newlength;    /* tentative new line length    */
  1869.     int        eolflag;    /* was at end of line        */
  1870.     LINE         *eopline;    /* pointer to line just past EOP */
  1871.     char wbuf[MAXWORD];        /* buffer for current word    */
  1872.     int        old_mode;    /* saved mode value        */
  1873.  
  1874.     /* save the mode and put into insert mode for duration of fill */
  1875.     old_mode = mode;
  1876.     mode &= !MOVRSTK;
  1877.  
  1878.     /* record the pointer to the line just past the EOP */
  1879.     (VOID) gotoeop(FALSE, 1, KRANDOM);
  1880.     eopline = curwp->w_dotp;
  1881.  
  1882.     /* and back top the begining of the paragraph */
  1883.     (VOID) gotobop(FALSE, 1, KRANDOM);
  1884.  
  1885.     /* initialize various info */
  1886.     i = TRUE;
  1887.     while (i == TRUE && !inword())
  1888.         i = forwchar(FALSE, 1, KRANDOM);
  1889.     clength = curwp->w_doto;
  1890.     wordlen = 0;
  1891.  
  1892.     /* scan through lines, filling words */
  1893.     firstflag = TRUE;
  1894.     eopflag = FALSE;
  1895.     while (!eopflag)
  1896.     {
  1897.         /* get the next character in the paragraph */
  1898.         if (eolflag=(curwp->w_doto == llength(curwp->w_dotp)))
  1899.         {
  1900.             c = ' ';
  1901.             if (lforw(curwp->w_dotp) == eopline)
  1902.                 eopflag = TRUE;
  1903.         } else
  1904.             c = lgetc(curwp->w_dotp, curwp->w_doto);
  1905.  
  1906.         /* and then delete it */
  1907.         if (ldelete((RSIZE) 1, KNONE) == FALSE)
  1908.         {
  1909.             mode = old_mode;
  1910.             return FALSE ;
  1911.         }
  1912.  
  1913.         /* if not a separator, just add it in */
  1914.         if (c != ' ' && c != '\t')
  1915.         {
  1916.             if (wordlen < MAXWORD - 1)
  1917.                 wbuf[wordlen++] = c;
  1918.             else
  1919.             {
  1920.                 /* You loose chars beyond MAXWORD if the word
  1921.                  * is to long. I'm to lazy to fix it now; it
  1922.                  * just silently truncated the word before, so
  1923.                  * I get to feel smug.
  1924.                  */
  1925.                 ewprintf("Word too long!");
  1926.             }
  1927.         }
  1928.         else if (wordlen)
  1929.         {
  1930.             /* calculate tenatitive new length with word added */
  1931.             newlength = clength + 1 + wordlen;
  1932.             /* if at end of line or at doublespace and previous
  1933.              * character was one of '.','?','!' doublespace here.
  1934.              */
  1935.             if((eolflag || curwp->w_doto==llength(curwp->w_dotp)
  1936.                 || (c=lgetc(curwp->w_dotp,curwp->w_doto))==' '
  1937.                 || c=='\t')
  1938.                   && ISEOSP(wbuf[wordlen-1])
  1939.                   && wordlen<MAXWORD-1)
  1940.                 wbuf[wordlen++] = ' ';
  1941.             /* at a word break with a word waiting */
  1942.              if (newlength <= fillcol)
  1943.             {
  1944.                 /* add word to current line */
  1945.                 if (!firstflag)
  1946.                 {
  1947.                     (VOID) linsert((RSIZE) 1, ' ');
  1948.                     ++clength;
  1949.                 }
  1950.                 firstflag = FALSE;
  1951.             }
  1952.             else
  1953.             {
  1954.                 if(curwp->w_doto > 0 &&
  1955.                     lgetc(curwp->w_dotp,curwp->w_doto-1)==' ')
  1956.                 {
  1957.                         curwp->w_doto -= 1;
  1958.                     (VOID) ldelete((RSIZE) 1, KNONE);
  1959.                 }
  1960.                 /* start a new line */
  1961.                 (VOID) lnewline();
  1962.                 clength = 0;
  1963.             }
  1964.  
  1965.             /* and add the word in in either case */
  1966.             for (i=0; i<wordlen; i++)
  1967.             {
  1968.                 (VOID) linsert((RSIZE) 1, wbuf[i]);
  1969.                 ++clength;
  1970.             }
  1971.             wordlen = 0;
  1972.         }
  1973.     }
  1974.     /* and add a last newline for the end of our new paragraph */
  1975.     (VOID) lnewline();
  1976.     /* we realy should wind up where we started, (which is hard to keep
  1977.      * track of) but I think the end of the last line is better than the
  1978.      * begining of the blank line.     */
  1979.     (VOID) backchar(FALSE, 1, KRANDOM);
  1980.     mode = old_mode;
  1981.     return TRUE;
  1982. }
  1983.  
  1984. /* delete n paragraphs starting with the current one */
  1985. /*ARGSUSED*/
  1986. killpara(f, n, k)
  1987. {
  1988.     register int status;    /* returned status of functions */
  1989.  
  1990.     while (n--)
  1991.     {        /* for each paragraph to delete */
  1992.  
  1993.         /* mark out the end and begining of the para to delete */
  1994.         (VOID) gotoeop(FALSE, 1, KRANDOM);
  1995.  
  1996.         /* set the mark here */
  1997.             curwp->w_markp = curwp->w_dotp;
  1998.             curwp->w_marko = curwp->w_doto;
  1999.  
  2000.         /* go to the begining of the paragraph */
  2001.         (VOID) gotobop(FALSE, 1, KRANDOM);
  2002.         curwp->w_doto = 0;    /* force us to the begining of line */
  2003.     
  2004.         /* and delete it */
  2005.         if ((status = killregion(FALSE, 1, KRANDOM)) != TRUE)
  2006.             return(status);
  2007.  
  2008.         /* and clean up the 2 extra lines */
  2009.         (VOID) ldelete((RSIZE) 1, KFORW);
  2010.     }
  2011.     return(TRUE);
  2012. }
  2013.  
  2014. /*
  2015.  * check to see if we're past fillcol, and if so,
  2016.  * justify this line. As a last step, justify the line.
  2017.  */
  2018. /*ARGSUSED*/
  2019. fillword(f, n, k)
  2020. {
  2021.     register char    c;
  2022.     register int    col, i, nce;
  2023.  
  2024.     for (i = col = 0; col <= fillcol; ++i, ++col)
  2025.     {
  2026.         if (i == curwp->w_doto) return selfinsert(f, n, k) ;
  2027.         c = lgetc(curwp->w_dotp, i);
  2028.         if (
  2029. #ifdef    NOTAB
  2030.             !(mode&MNOTAB) &&
  2031. #endif
  2032.             c == '\t') col |= 0x07;
  2033.         else if (ISCTRL(c) != FALSE) ++col;
  2034.     }
  2035.     if (curwp->w_doto != llength(curwp->w_dotp))
  2036.     {
  2037.         (VOID) selfinsert(f, n, k);
  2038.         nce = llength(curwp->w_dotp) - curwp->w_doto;
  2039.     }
  2040.     else nce = 0;
  2041.     curwp->w_doto = i;
  2042.  
  2043.     if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t')
  2044.         do {
  2045.             (VOID) backchar(FALSE, 1, KRANDOM);
  2046.         } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
  2047.               && c != '\t' && curwp->w_doto > 0);
  2048.  
  2049.     if (curwp->w_doto == 0)
  2050.         do {
  2051.             (VOID) forwchar(FALSE, 1, KRANDOM);
  2052.         } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
  2053.               && c != '\t' && curwp->w_doto < llength(curwp->w_dotp));
  2054.  
  2055.     (VOID) delwhite(FALSE, 1, KRANDOM);
  2056.     (VOID) lnewline();
  2057.     curwp->w_doto = llength(curwp->w_dotp) - nce;
  2058.     curwp->w_flag |= WFMOVE;
  2059.     if (nce == 0 && curwp->w_doto != 0) return fillword(f, n, k);
  2060.     return TRUE;
  2061. }
  2062.  
  2063. /* Set fill column to n. */
  2064. /*ARGSUSED*/
  2065. setfillcol(f, n, k)
  2066. {
  2067.     extern int    getcolpos() ;
  2068.  
  2069.     fillcol = ((f == FALSE) ? getcolpos() : n);
  2070.     if (kbdmop == NULL)
  2071.         ewprintf("Fill column set to %d", fillcol);
  2072.         return(TRUE);
  2073. }
  2074. \Rogue\Monster\
  2075. else
  2076.   echo "will not over write ./paragraph.c"
  2077. fi
  2078. if `test ! -s ./prefix.c`
  2079. then
  2080. echo "writing ./prefix.c"
  2081. cat > ./prefix.c << '\Rogue\Monster\'
  2082. /*
  2083.  * This code is a kludge for the two prefix sequences from GNU (well,
  2084.  * the two I want) that uemacs doesn't have. Rather than quadruple the table
  2085.  * space for keys, plus have to test for them everywhere, I'll just kludge
  2086.  * it with functions that are bound to those keys. Later, maybe I'll do
  2087.  * prefixes right.
  2088.  */
  2089.  
  2090. #include "def.h"
  2091.  
  2092. #ifndef TINY
  2093. /*ARGSUSED*/
  2094. ctlx4hack(f, n, k)
  2095. {
  2096.     register KEY    c;
  2097.  
  2098.     if ((c = getkey(KPROMPT)) == 'b' || c == 'B')
  2099.         return poptobuffer(f, n, KRANDOM);
  2100.     if (c == 'f' || c == (KCTRL|'F') || c == 'F')
  2101.         return poptofile(f, n, KRANDOM);
  2102.     
  2103.     if (c == (KCTRL|'G') || c == (KCTLX|KCTRL|'G')
  2104.             ||  c == (KMETA|KCTRL|'G'))
  2105.     {
  2106.         (VOID) ctrlg(FALSE, 1, KRANDOM);
  2107.         return ABORT;
  2108.     }
  2109.     return FALSE;
  2110. }
  2111.  
  2112. /*ARGSUSED*/
  2113. help(f, n, k)
  2114. {
  2115.     register KEY    c;
  2116.  
  2117.     c = getkey(KPROMPT);
  2118.     while (c == (KCTRL|'H'))
  2119.     {
  2120.         ewprintf("B C: ");
  2121.         c = getkey(0);
  2122.     }
  2123.     if (c == 'b' || c == 'B')
  2124.         return wallchart(f, n, KRANDOM);
  2125.     if (c == 'c' || c == 'C')
  2126.         return desckey(f, n, KRANDOM);
  2127.  
  2128.     if (c == (KCTRL|'G') || c == (KCTLX|KCTRL|'G')
  2129.             ||  c == (KMETA|KCTRL|'G'))
  2130.     {
  2131.         (VOID) ctrlg(FALSE, 1, KRANDOM);
  2132.         return ABORT;
  2133.     }
  2134.     return FALSE;
  2135. }
  2136. #endif
  2137. \Rogue\Monster\
  2138. else
  2139.   echo "will not over write ./prefix.c"
  2140. fi
  2141. if `test ! -s ./random.c`
  2142. then
  2143. echo "writing ./random.c"
  2144. cat > ./random.c << '\Rogue\Monster\'
  2145. /*
  2146.  *        Assorted commands.
  2147.  * The file contains the command
  2148.  * processors for a large assortment of unrelated
  2149.  * commands. The only thing they have in common is
  2150.  * that they are all command processors.
  2151.  */
  2152. #include    "def.h"
  2153.  
  2154. /*
  2155.  * Display a bunch of useful information about
  2156.  * the current location of dot. The character under the
  2157.  * cursor (in octal), the current line, row, and column, and
  2158.  * approximate position of the cursor in the file (as a percentage)
  2159.  * is displayed. The column position assumes an infinite position
  2160.  * display; it does not truncate just because the screen does.
  2161.  * This is normally bound to "C-X =".
  2162.  */
  2163. /*ARGSUSED*/
  2164. showcpos(f, n, k)
  2165. {
  2166.     register LINE    *clp;
  2167.     register long    nchar;
  2168.     long        cchar;
  2169.     register int    nline, row;
  2170.     int        cline, cbyte;    /* Current line/char/byte */
  2171.     int        ratio;
  2172.     KEY        keychar();
  2173.  
  2174.     clp = lforw(curbp->b_linep);        /* Collect the data.    */
  2175.     nchar = 0;
  2176.     nline = 0;
  2177.     for (;;)
  2178.     {
  2179.         ++nline;            /* Count this line    */
  2180.         if (clp == curwp->w_dotp)
  2181.         {
  2182.             cline = nline;        /* Mark line        */
  2183.             cchar = nchar + curwp->w_doto;
  2184.             if (curwp->w_doto == llength(clp))
  2185.                 cbyte = '\n';
  2186.             else
  2187.                 cbyte = lgetc(clp, curwp->w_doto);
  2188.         }
  2189.         nchar += llength(clp) + 1;    /* Now count the chars    */
  2190.         if (clp == curbp->b_linep) break ;
  2191.         clp = lforw(clp);
  2192.     }
  2193.     row = curwp->w_toprow;            /* Determine row.    */
  2194.     clp = curwp->w_linep;
  2195.     while (clp!=curbp->b_linep && clp!=curwp->w_dotp)
  2196.     {
  2197.         ++row;
  2198.         clp = lforw(clp);
  2199.     }
  2200.     ++row;                    /* Convert to origin 1.    */
  2201.     /*NOSTRICT*/    
  2202.     /* nchar can't be zero (because of the "bonus" \n at end of file) */
  2203.     ratio = (100L*cchar) / nchar;
  2204.     ewprintf("Char: %c (0%o)  point=%ld(%d%%)  line=%d  row=%d  col=%d",
  2205.         (int) keychar(cbyte, FALSE), cbyte, cchar, ratio, cline, row,
  2206.         getcolpos());
  2207.     return (TRUE);
  2208. }
  2209.  
  2210. getcolpos()
  2211. {
  2212.     register int    col, i, c;
  2213.  
  2214.     col = 0;                /* Determine column.    */
  2215.     for (i=0; i<curwp->w_doto; ++i)
  2216.     {
  2217.         c = lgetc(curwp->w_dotp, i);
  2218.         if (
  2219. #ifdef    NOTAB
  2220.             !(mode & MNOTAB) &&
  2221. #endif
  2222.             c == '\t')
  2223.             col |= 0x07;
  2224.         else if (ISCTRL(c) != FALSE)
  2225.             ++col;
  2226.         ++col;
  2227.     }
  2228.     return col + 1;                /* Convert to origin 1.    */
  2229. }
  2230.  
  2231.  
  2232. /*
  2233.  * Ordinary text characters are bound to this function,
  2234.  * which inserts them into the buffer. Characters marked as control
  2235.  * characters (using the CTRL flag) may be remapped to their ASCII
  2236.  * equivalent. This makes TAB (C-I) work right, and also makes the
  2237.  * world look reasonable if a control character is bound to this
  2238.  * this routine by hand. Any META or CTLX flags on the character
  2239.  * are discarded. This is the only routine that actually looks
  2240.  * the the "k" argument.
  2241.  */
  2242. /*ARGSUSED*/
  2243. selfinsert(f, n, k)
  2244. {
  2245.     register int    c;
  2246.  
  2247.     if (n < 0)
  2248.         return (FALSE);
  2249.     if (n == 0)
  2250.         return (TRUE);
  2251.     c = k & KCHAR;
  2252.     if ((k&KCTRL)!=0 && c>='@' && c<='_')    /* ASCII-ify.        */
  2253.         c -= '@';
  2254.     return (linsert((RSIZE) n, c));
  2255. }
  2256.  
  2257. /*
  2258.  * Open up some blank space. The basic plan
  2259.  * is to insert a bunch of newlines, and then back
  2260.  * up over them. Everything is done by the subcommand
  2261.  * procerssors. They even handle the looping. Normally
  2262.  * this is bound to "C-O".
  2263.  */
  2264. /*ARGSUSED*/
  2265. openline(f, n, k)
  2266. {
  2267.     register int    i;
  2268.     register int    s;
  2269.  
  2270.     if (n < 0)
  2271.         return (FALSE);
  2272.     if (n == 0)
  2273.         return (TRUE);
  2274.     gotobol( FALSE, 0, KRANDOM);
  2275.     i = n;                    /* Insert newlines.    */
  2276.     do {
  2277.         s = lnewline();
  2278.     } while (s==TRUE && --i);
  2279.     if (s == TRUE)                /* Then back up overtop    */
  2280.         s = backchar(f, n, KRANDOM);    /* of them all.        */
  2281.     return (s);
  2282. }
  2283.  
  2284. /*
  2285.  * Insert a newline.
  2286.  * If you are at the end of the line and the
  2287.  * next line is a blank line, just move into the
  2288.  * blank line. This makes "C-O" and "C-X C-O" work
  2289.  * nicely, and reduces the ammount of screen
  2290.  * update that has to be done. This would not be
  2291.  * as critical if screen update were a lot
  2292.  * more efficient.
  2293.  */
  2294. /*ARGSUSED*/
  2295. newline(f, n, k)
  2296. {
  2297.     register LINE    *lp;
  2298.     register int    s;
  2299.  
  2300.     if (n < 0)
  2301.         return (FALSE);
  2302.     while (n--)
  2303.     {
  2304.         lp = curwp->w_dotp;
  2305.         if (llength(lp) == curwp->w_doto
  2306.         && lp != curbp->b_linep
  2307.         && llength(lforw(lp)) == 0)
  2308.         {
  2309.             if ((s=forwchar(FALSE, 1, KRANDOM)) != TRUE)
  2310.                 return (s);
  2311.         } else if ((s=lnewline()) != TRUE)
  2312.             return (s);
  2313.     }
  2314.     return (TRUE);
  2315. }
  2316.  
  2317.  
  2318. /*
  2319.  * Delete any whitespace around dot.
  2320.  */
  2321. /*ARGSUSED*/
  2322. delwhite(f, n, k)
  2323. {
  2324.     register int    col, c, s;
  2325.  
  2326.     col = curwp->w_doto;
  2327.     while ((c = lgetc(curwp->w_dotp, col)) == ' ' || c == '\t')
  2328.         ++col;
  2329.     do
  2330.         if ((s = backchar(FALSE, 1, KRANDOM)) == FALSE) break;
  2331.     while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ' || c == '\t') ;
  2332.  
  2333.     if (s == TRUE) (VOID) forwchar(FALSE, 1, KRANDOM);
  2334.     (VOID) ldelete((RSIZE)(col - curwp->w_doto), KNONE);
  2335.     return (TRUE);
  2336. }
  2337.  
  2338.  
  2339. /*
  2340.  * Delete forward. This is real
  2341.  * easy, because the basic delete routine does
  2342.  * all of the work. Watches for negative arguments,
  2343.  * and does the right thing. If any argument is
  2344.  * present, it kills rather than deletes, to prevent
  2345.  * loss of text if typed with a big argument.
  2346.  * Normally bound to "C-D".
  2347.  */
  2348. /*ARGSUSED*/
  2349. forwdel(f, n, k)
  2350. {
  2351.     if (n < 0)
  2352.         return (backdel(f, -n, KRANDOM));
  2353.     if (f != FALSE)
  2354.     {            /* Really a kill.    */
  2355.         if ((lastflag&CFKILL) == 0)
  2356.             kdelete();
  2357.         thisflag |= CFKILL;
  2358.     }
  2359.     return (ldelete((RSIZE) n, f ? KFORW : KNONE));
  2360. }
  2361.  
  2362. /*
  2363.  * Delete backwards. This is quite easy too,
  2364.  * because it's all done with other functions. Just
  2365.  * move the cursor back, and delete forwards.
  2366.  * Like delete forward, this actually does a kill
  2367.  * if presented with an argument.
  2368.  */
  2369. /*ARGSUSED*/
  2370. backdel(f, n, k)
  2371. {
  2372.     register int    s;
  2373.  
  2374.     if (n < 0)
  2375.         return (forwdel(f, -n, KRANDOM));
  2376.     if (f != FALSE)
  2377.     {            /* Really a kill.    */
  2378.         if ((lastflag&CFKILL) == 0)
  2379.             kdelete();
  2380.         thisflag |= CFKILL;
  2381.     }
  2382.     if ((s=backchar(f, n, KRANDOM)) == TRUE)
  2383.         s = ldelete((RSIZE) n, f ? KFORW : KNONE);
  2384.     return (s);
  2385. }
  2386.  
  2387. /*
  2388.  * Kill line. If called without an argument,
  2389.  * it kills from dot to the end of the line, unless it
  2390.  * is at the end of the line, when it kills the newline.
  2391.  * If called with an argument of 0, it kills from the
  2392.  * start of the line to dot. If called with a positive
  2393.  * argument, it kills from dot forward over that number
  2394.  * of newlines. If called with a negative argument it
  2395.  * kills any text before dot on the current line,
  2396.  * then it kills back abs(arg) lines.
  2397.  */
  2398. /*ARGSUSED*/
  2399. killline(f, n, k)
  2400. {
  2401.     register RSIZE    chunk;
  2402.     register LINE    *nextp;
  2403.     register int    i, c;
  2404.  
  2405.     if ((lastflag&CFKILL) == 0)        /* Clear kill buffer if    */
  2406.         kdelete();            /* last wasn't a kill.    */
  2407.     thisflag |= CFKILL;
  2408.     if (f == FALSE)
  2409.     {
  2410.         for (i = curwp->w_doto; i < llength(curwp->w_dotp); ++i)
  2411.             if ((c = lgetc(curwp->w_dotp, i)) != ' ' && c != '\t')
  2412.                 break;
  2413.         if (i == llength(curwp->w_dotp))
  2414.             chunk = llength(curwp->w_dotp)-curwp->w_doto + 1;
  2415.         else
  2416.         {
  2417.             chunk = llength(curwp->w_dotp)-curwp->w_doto;
  2418.             if (chunk == 0)
  2419.                 chunk = 1;
  2420.         }
  2421.     }
  2422.     else if (n > 0)
  2423.     {
  2424.         chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
  2425.         nextp = lforw(curwp->w_dotp);
  2426.         i = n;
  2427.         while (--i)
  2428.         {
  2429.             if (nextp == curbp->b_linep)
  2430.                 break;
  2431.             chunk += llength(nextp)+1;
  2432.             nextp = lforw(nextp);
  2433.         }
  2434.     }
  2435.     else
  2436.     {                /* n <= 0        */
  2437.         chunk = curwp->w_doto;
  2438.         curwp->w_doto = 0;
  2439.         i = n;
  2440.         while (i++)
  2441.         {
  2442.             if (lback(curwp->w_dotp) == curbp->b_linep)
  2443.                 break;
  2444.             curwp->w_dotp = lback(curwp->w_dotp);
  2445.             curwp->w_flag |= WFMOVE;
  2446.             chunk += llength(curwp->w_dotp)+1;
  2447.         }
  2448.     }
  2449.     /*
  2450.      * KFORW here is a bug. Should be KBACK/KFORW, but we need to
  2451.      * rewrite the ldelete code (later)?
  2452.      */
  2453.     return (ldelete(chunk,  KFORW));
  2454. }
  2455.  
  2456.  
  2457. /*
  2458.  * Commands to toggle the five modes. Without an argument, sets the
  2459.  * mode on, with an argument, sets the mode off.
  2460.  */
  2461. /*ARGSUSED*/
  2462. bsmapmode(f, n, k)
  2463. {
  2464.  
  2465.     if ((mode&MBSMAP) != MBSMAP)
  2466.         mode |= MBSMAP;
  2467.     else
  2468.         mode &= ~MBSMAP;
  2469.     upmodes((BUFFER *) NULL);
  2470.     return TRUE;
  2471. }
  2472.  
  2473. /*ARGSUSED*/
  2474. flowmode(f, n, k)
  2475. {
  2476.     if ((mode&MFLOW) != MFLOW)
  2477.         mode |= MFLOW;
  2478.     else
  2479.         mode &= ~MFLOW;
  2480.     upmodes((BUFFER *) NULL);
  2481.     return TRUE;
  2482. }
  2483.  
  2484.  
  2485. /*ARGSUSED*/
  2486. fillmode(f, n, k)
  2487. {
  2488.  
  2489.     if ((mode&MFILL) != MFILL)
  2490.     {
  2491.         mode |= MFILL;
  2492.         if ((binding[' '] = symlookup("insert-with-wrap")) == NULL)
  2493.             panic("no insert-with-wrap in fillmode");
  2494.     } else
  2495.     {
  2496.         mode &= ~MFILL;
  2497.         if ((binding[' '] = symlookup("self-insert-command")) == NULL)
  2498.             panic("no self-insert-command in fillmode");
  2499.     }
  2500.     upmodes((BUFFER *) NULL);
  2501.     return TRUE;
  2502. }
  2503. #ifdef  NOTAB
  2504.  
  2505. space_tabpos(f, n, k)
  2506. int f, n;
  2507. {
  2508.     int stat;
  2509.  
  2510.     if(n<0)
  2511.         return FALSE;
  2512.     if(n==0)
  2513.         return TRUE;
  2514.     return linsert(((RSIZE)n<<3) - (curwp->w_doto & 7), ' ');
  2515. }
  2516.  
  2517. notabmode(f, n, k)
  2518. {
  2519.     if((mode&MNOTAB) != MNOTAB)
  2520.     {
  2521.         mode |= MNOTAB;
  2522.         if ((binding[KCTRL|'I'] = symlookup("space-to-tabstop")) == NULL)
  2523.             panic("no space-to-tabstop in notabmode");
  2524.     }
  2525.     else
  2526.     {
  2527.         mode &= ~ MNOTAB;
  2528.         if ((binding[KCTRL|'I'] = symlookup("self-insert-command")) == NULL)
  2529.             panic("no self-insert-command in notabmode");
  2530.     }
  2531.     upmodes((BUFFER *) NULL);
  2532.     return TRUE;
  2533. }
  2534. #endif
  2535.  
  2536. /*
  2537.  * This function toggles the state of the 
  2538.  * insert/overstrike flag.  The editor will come up in
  2539.  * one mode or the other, and can be changed by this
  2540.  * function. No argument or 0 will toggle the value, >0 will
  2541.  * set to insert mode, <0 will set to overstrike.
  2542.  */
  2543. /*ARGSUSED*/
  2544. insovrmode( f, n, k)
  2545. {
  2546.     if (f == FALSE || n == 0)
  2547.     {
  2548.         if ((mode & MOVRSTK) == MOVRSTK)
  2549.             mode &= ~MOVRSTK;
  2550.         else
  2551.             mode |= MOVRSTK;
  2552.     }
  2553.     else if (n > 0)
  2554.         mode &= ~MOVRSTK;
  2555.     else
  2556.         mode |= MOVRSTK;
  2557.  
  2558.     upmodes((BUFFER *) NULL);
  2559.     return TRUE;
  2560. }
  2561.  
  2562. /*
  2563.  * Yank text back from the kill buffer. This
  2564.  * is really easy. All of the work is done by the
  2565.  * standard insert routines. All you do is run the loop,
  2566.  * and check for errors. The blank
  2567.  * lines are inserted with a call to "newline"
  2568.  * instead of a call to "lnewline" so that the magic
  2569.  * stuff that happens when you type a carriage
  2570.  * return also happens when a carriage return is
  2571.  * yanked back from the kill buffer.
  2572.  * An attempt has been made to fix the cosmetic bug
  2573.  * associated with a yank when dot is on the top line of
  2574.  * the window (nothing moves, because all of the new
  2575.  * text landed off screen).
  2576.  */
  2577. /*ARGSUSED*/
  2578. yank(f, n, k)
  2579. {
  2580.     register int    c;
  2581.     register int    i;
  2582.     register LINE    *lp;
  2583.     register int    nline;
  2584.  
  2585.     if (n < 0)
  2586.         return (FALSE);
  2587.     nline = 0;                /* Newline counting.    */
  2588.     while (n--) {
  2589.         isetmark();            /* mark around last yank */
  2590.         i = 0;
  2591.         while ((c=kremove(i)) >= 0) {
  2592.             if (c == '\n') {
  2593.                 if (newline(FALSE, 1, KRANDOM) == FALSE)
  2594.                     return (FALSE);
  2595.                 ++nline;
  2596.             } else {
  2597.                 if (linsert((RSIZE) 1, c) == FALSE)
  2598.                     return (FALSE);
  2599.             }
  2600.             ++i;
  2601.         }
  2602.     }
  2603.     lp = curwp->w_linep;            /* Cosmetic adjustment    */
  2604.     if (curwp->w_dotp == lp) {        /* if offscreen insert.    */
  2605.         while (nline-- && lback(lp)!=curbp->b_linep)
  2606.             lp = lback(lp);
  2607.         curwp->w_linep = lp;        /* Adjust framing.    */
  2608.         curwp->w_flag |= WFHARD;
  2609.     }
  2610.     return (TRUE);
  2611. }
  2612.  
  2613. \Rogue\Monster\
  2614. else
  2615.   echo "will not over write ./random.c"
  2616. fi
  2617. echo "Finished archive 2 of 5"
  2618. exit
  2619. -- 
  2620. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  2621. Mark A. Hargrove                                             U.S. TeleCenters
  2622. Voice: 408-496-1800                                          Santa Clara, CA
  2623. uucp : {dual, hoptoad, hplabs, portal, ptsfa}!well!ustel
  2624.