home *** CD-ROM | disk | FTP | other *** search
/ ftp.update.uu.se / ftp.update.uu.se.2014.03.zip / ftp.update.uu.se / pub / rainbow / cpm / emacs / emacssrc.lzh / linsert.c < prev    next >
C/C++ Source or Header  |  1992-03-11  |  3KB  |  98 lines

  1. #include    "stdio.h"
  2. #include    "ed.h"
  3.  
  4. /*
  5.  * Insert "n" copies of the character "c"
  6.  * at the current location of dot. In the easy case
  7.  * all that happens is the text is stored in the line.
  8.  * In the hard case, the line has to be reallocated.
  9.  * When the window list is updated, take special
  10.  * care; I screwed it up once. You always update dot
  11.  * in the current window. You update mark, and a
  12.  * dot in another window, if it is greater than
  13.  * the place where you did the insert. Return TRUE
  14.  * if all is well, and FALSE on errors.
  15.  */
  16. linsert(n, c)
  17. {
  18. #define cp1 (*(char **)0xa0)
  19. #define cp2 (*(char **)0xa2)
  20.     register LINE    *lp1;    /* 23 times. */
  21. #define lp2 (*(LINE **)0xa8)
  22. #define lp3 (*(LINE **)0xa4)
  23. #define doto (*(int *)0xa6)
  24.     register WINDOW    *wp;    /* 15 times, but the best! */
  25. #define localn (*(int *)0xaa)
  26.  
  27.     lchange( WFEDIT );
  28.     wp = curwp;
  29.     localn = n;
  30.  
  31.     if (( lp1 = wp->w_dotp ) == curbp->b_linep )
  32.     {    /* At the end: special. Assert that w_doto == 0 */
  33.         /* There is no line at all here, so we must
  34.         ** allocate a new line ( lp2 ) and link it in.
  35.         */
  36.         if ( ( lp2 = lalloc( localn )) == NULL )
  37.         {    /* must be out of memory. */
  38. retfalse:        return ( 0 );
  39.         }
  40.  
  41.         ( lp3 = lp1->l_bp )->l_fp = lp2;
  42.         lp2->l_fp = lp1;
  43.         ( wp->w_dotp = lp1->l_bp = lp2)->l_bp = lp3;
  44.  
  45. #ifdef SANITY
  46.         if ( wp->w_doto = localn )
  47.         {    /* not zero count. */
  48.             clear( &lp2->l_text[0], localn, c );
  49.         }
  50. #else
  51.         clear( &lp2->l_text[0], ( wp->w_doto = localn ), c );
  52. #endif
  53. rettrue:    return ( 1 );
  54.     }
  55.     doto = wp->w_doto;
  56.     if ( ( lp1->l_used + localn ) > lp1->l_size )
  57.     {    /* The lp1 line grows and must be reallocated. */
  58.         if ( ( lp2 = lalloc( lp1->l_used + localn )) == NULL )
  59.             goto retfalse;
  60.  
  61.         blockmv( lp2, lp1, 4 );
  62.             /* lp2->l_fp = lp1->l_fp; */
  63.             /* lp2->l_bp = lp1->l_bp; */
  64.         blockmv( lp2->l_text, lp1->l_text, doto );
  65.         blockmv( &lp2->l_text[ localn + doto ], 
  66.             &lp1->l_text[ doto ],
  67.             lp1->l_used - doto );
  68.         lp1->l_fp->l_bp = lp1->l_bp->l_fp = lp2;
  69.         free((char *) lp1);
  70.     } else
  71.     {    /* Easy: in place    */
  72.         (lp2 = lp1)->            /* Pretend new line    */
  73.             l_used += localn;
  74.         cp2 = &lp1->l_text[lp1->l_used];
  75.         cp1 = cp2-localn;
  76.         while (cp1 != &lp1->l_text[doto])
  77.             *--cp2 = *--cp1;
  78.     }
  79.     if ( localn ) clear( &lp2->l_text[doto], localn, c );
  80.     wp = wheadp;                /* Update windows    */
  81.     while (wp != NULL)
  82.     {    if (wp->w_linep == lp1)
  83.             wp->w_linep = lp2;
  84.         if (wp->w_dotp == lp1)
  85.         {    wp->w_dotp = lp2;
  86.             if ( wp == curwp || wp->w_doto > doto )
  87.             {    wp->w_doto += localn;
  88.             }
  89.         }
  90.         if ( wp->w_markp == lp1 )
  91.         {    wp->w_markp = lp2;
  92.             if ( wp->w_marko > doto ) wp->w_marko += localn;
  93.         }
  94.         wp = wp->w_wndp;
  95.     }
  96.     return (TRUE);
  97. }
  98.