home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / ex / ex_subr.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  9KB  |  744 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #include "ex.h"
  3. #include "ex_re.h"
  4. #include "ex_tty.h"
  5. #include "ex_vis.h"
  6.  
  7. /*
  8.  * Random routines, in alphabetical order.
  9.  */
  10.  
  11. any(c, s)
  12.     int c;
  13.     register char *s;
  14. {
  15.     register int x;
  16.  
  17.     while (x = *s++)
  18.         if (x == c)
  19.             return (1);
  20.     return (0);
  21. }
  22.  
  23. backtab(i)
  24.     register int i;
  25. {
  26.     register int j;
  27.  
  28.     j = i % value(SHIFTWIDTH);
  29.     if (j == 0)
  30.         j = value(SHIFTWIDTH);
  31.     i -= j;
  32.     if (i < 0)
  33.         i = 0;
  34.     return (i);
  35. }
  36.  
  37. change()
  38. {
  39.  
  40.     tchng++;
  41.     chng = tchng;
  42. }
  43.  
  44. /*
  45.  * Column returns the number of
  46.  * columns occupied by printing the
  47.  * characters through position cp of the
  48.  * current line.
  49.  */
  50. column(cp)
  51.     register char *cp;
  52. {
  53.  
  54.     if (cp == 0)
  55.         cp = &linebuf[LBSIZE - 2];
  56.     return (qcolumn(cp, (char *) 0));
  57. }
  58.  
  59. Copy(to, from, size)
  60.     register char *from, *to;
  61.     register int size;
  62. {
  63.  
  64.     if (size > 0)
  65.         do
  66.             *to++ = *from++;
  67.         while (--size > 0);
  68. }
  69.  
  70. copyw(to, from, size)
  71.     register line *from, *to;
  72.     register int size;
  73. {
  74.  
  75.     if (size > 0)
  76.         do
  77.             *to++ = *from++;
  78.         while (--size > 0);
  79. }
  80.  
  81. copywR(to, from, size)
  82.     register line *from, *to;
  83.     register int size;
  84. {
  85.  
  86.     while (--size >= 0)
  87.         to[size] = from[size];
  88. }
  89.  
  90. ctlof(c)
  91.     int c;
  92. {
  93.  
  94.     return (c == TRIM ? '?' : c | ('A' - 1));
  95. }
  96.  
  97. dingdong()
  98. {
  99.  
  100.     if (VB)
  101.         putpad(VB);
  102.     else if (value(ERRORBELLS))
  103.         putch('\207');
  104. }
  105.  
  106. fixindent(indent)
  107.     int indent;
  108. {
  109.     register int i;
  110.     register char *cp;
  111.  
  112.     i = whitecnt(genbuf);
  113.     cp = vpastwh(genbuf);
  114.     if (*cp == 0 && i == indent && linebuf[0] == 0) {
  115.         genbuf[0] = 0;
  116.         return (i);
  117.     }
  118.     CP(genindent(i), cp);
  119.     return (i);
  120. }
  121.  
  122. filioerr(cp)
  123.     char *cp;
  124. {
  125.     register int oerrno = errno;
  126.  
  127.     lprintf("\"%s\"", cp);
  128.     errno = oerrno;
  129.     syserror();
  130. }
  131.  
  132. char *
  133. genindent(indent)
  134.     register int indent;
  135. {
  136.     register char *cp;
  137.  
  138.     for (cp = genbuf; indent >= value(TABSTOP); indent -= value(TABSTOP))
  139.         *cp++ = '\t';
  140.     for (; indent > 0; indent--)
  141.         *cp++ = ' ';
  142.     return (cp);
  143. }
  144.  
  145. getDOT()
  146. {
  147.  
  148.     getline(*dot);
  149. }
  150.  
  151. line *
  152. getmark(c)
  153.     register int c;
  154. {
  155.     register line *addr;
  156.     
  157.     for (addr = one; addr <= dol; addr++)
  158.         if (names[c - 'a'] == (*addr &~ 01)) {
  159.             return (addr);
  160.         }
  161.     return (0);
  162. }
  163.  
  164. getn(cp)
  165.     register char *cp;
  166. {
  167.     register int i = 0;
  168.  
  169.     while (isdigit(*cp))
  170.         i = i * 10 + *cp++ - '0';
  171.     if (*cp)
  172.         return (0);
  173.     return (i);
  174. }
  175.  
  176. ignnEOF()
  177. {
  178.     register int c = getchar();
  179.  
  180.     if (c == EOF)
  181.         ungetchar(c);
  182. }
  183.  
  184. iswhite(c)
  185.     int c;
  186. {
  187.  
  188.     return (c == ' ' || c == '\t');
  189. }
  190.  
  191. junk(c)
  192.     register int c;
  193. {
  194.  
  195.     if (c && !value(BEAUTIFY))
  196.         return (0);
  197.     if (c >= ' ' && c != TRIM)
  198.         return (0);
  199.     switch (c) {
  200.  
  201.     case '\t':
  202.     case '\n':
  203.     case '\f':
  204.         return (0);
  205.  
  206.     default:
  207.         return (1);
  208.     }
  209. }
  210.  
  211. killed()
  212. {
  213.  
  214.     killcnt(addr2 - addr1 + 1);
  215. }
  216.  
  217. killcnt(cnt)
  218.     register int cnt;
  219. {
  220.  
  221.     if (inopen) {
  222.         notecnt = cnt;
  223.         notenam = notesgn = "";
  224.         return;
  225.     }
  226.     if (!notable(cnt))
  227.         return;
  228.     printf("%d lines", cnt);
  229.     if (value(TERSE) == 0) {
  230.         printf(" %c%s", Command[0] | ' ', Command + 1);
  231.         if (Command[strlen(Command) - 1] != 'e')
  232.             putchar('e');
  233.         putchar('d');
  234.     }
  235.     putNFL();
  236. }
  237.  
  238. lineno(a)
  239.     line *a;
  240. {
  241.  
  242.     return (a - zero);
  243. }
  244.  
  245. lineDOL()
  246. {
  247.  
  248.     return (lineno(dol));
  249. }
  250.  
  251. lineDOT()
  252. {
  253.  
  254.     return (lineno(dot));
  255. }
  256.  
  257. markDOT()
  258. {
  259.  
  260.     markpr(dot);
  261. }
  262.  
  263. markpr(which)
  264.     line *which;
  265. {
  266.  
  267.     if ((inglobal == 0 || inopen) && which <= endcore) {
  268.         names['z'-'a'+1] = *which & ~01;
  269.         if (inopen)
  270.             ncols['z'-'a'+1] = cursor;
  271.     }
  272. }
  273.  
  274. markreg(c)
  275.     register int c;
  276. {
  277.  
  278.     if (c == '\'' || c == '`')
  279.         return ('z' + 1);
  280.     if (c >= 'a' && c <= 'z')
  281.         return (c);
  282.     return (0);
  283. }
  284.  
  285. /*
  286.  * Mesg decodes the terse/verbose strings. Thus
  287.  *    'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy'
  288.  *    'xxx|yyy' -> 'xxx' if terse, else 'yyy'
  289.  * All others map to themselves.
  290.  */
  291. char *
  292. mesg(str)
  293.     register char *str;
  294. {
  295.     register char *cp;
  296.  
  297.     str = strcpy(genbuf, str);
  298.     for (cp = str; *cp; cp++)
  299.         switch (*cp) {
  300.  
  301.         case '@':
  302.             if (value(TERSE))
  303.                 *cp = 0;
  304.             else
  305.                 *cp = ' ';
  306.             break;
  307.  
  308.         case '|':
  309.             if (value(TERSE) == 0)
  310.                 return (cp + 1);
  311.             *cp = 0;
  312.             break;
  313.         }
  314.     return (str);
  315. }
  316.  
  317. /*VARARGS2*/
  318. merror(seekpt, i)
  319. #ifdef lint
  320.     char *seekpt;
  321. #else
  322.     int seekpt;
  323. #endif
  324.     int i;
  325. {
  326.     register char *cp = linebuf;
  327.  
  328.     if (seekpt == 0)
  329.         return;
  330.     merror1(seekpt);
  331.     if (*cp == '\n')
  332.         putnl(), cp++;
  333.     if (inopen && CE)
  334.         vclreol();
  335.     if (SO && SE)
  336.         putpad(SO);
  337.     printf(mesg(cp), i);
  338.     if (SO && SE)
  339.         putpad(SE);
  340. }
  341.  
  342. merror1(seekpt)
  343. #ifdef lint
  344.     char *seekpt;
  345. #else
  346.     int seekpt;
  347. #endif
  348. {
  349.  
  350.     lseek(erfile, (long) seekpt, 0);
  351.     if (read(erfile, linebuf, 128) < 2)
  352.         CP(linebuf, "ERROR");
  353. }
  354.  
  355. morelines()
  356. {
  357.  
  358.     if ((int) sbrk(1024 * sizeof (line)) == -1)
  359.         return (-1);
  360.     endcore += 1024;
  361.     return (0);
  362. }
  363.  
  364. nonzero()
  365. {
  366.  
  367.     if (addr1 == zero) {
  368.         notempty();
  369.         error("Nonzero address required@on this command");
  370.     }
  371. }
  372.  
  373. notable(i)
  374.     int i;
  375. {
  376.  
  377.     return (hush == 0 && !inglobal && i > value(REPORT));
  378. }
  379.  
  380.  
  381. notempty()
  382. {
  383.  
  384.     if (dol == zero)
  385.         error("No lines@in the buffer");
  386. }
  387.  
  388.  
  389. netchHAD(cnt)
  390.     int cnt;
  391. {
  392.  
  393.     netchange(lineDOL() - cnt);
  394. }
  395.  
  396. netchange(i)
  397.     register int i;
  398. {
  399.     register char *cp;
  400.  
  401.     if (i > 0)
  402.         notesgn = cp = "more ";
  403.     else
  404.         notesgn = cp = "fewer ", i = -i;
  405.     if (inopen) {
  406.         notecnt = i;
  407.         notenam = "";
  408.         return;
  409.     }
  410.     if (!notable(i))
  411.         return;
  412.     printf(mesg("%d %slines@in file after %s"), i, cp, Command);
  413.     putNFL();
  414. }
  415.  
  416. putmark(addr)
  417.     line *addr;
  418. {
  419.  
  420.     putmk1(addr, putline());
  421. }
  422.  
  423. putmk1(addr, n)
  424.     register line *addr;
  425.     int n;
  426. {
  427.     register line *markp;
  428.  
  429.     *addr &= ~1;
  430.     for (markp = (anymarks ? names : &names['z'-'a'+1]); markp <= &names['z'-'a'+1]; markp++)
  431.         if (*markp == *addr)
  432.             *markp = n;
  433.     *addr = n;
  434. }
  435.  
  436. char *
  437. plural(i)
  438.     long i;
  439. {
  440.  
  441.     return (i == 1 ? "" : "s");
  442. }
  443.  
  444. int    qcount();
  445. short    vcntcol;
  446.  
  447. qcolumn(lim, gp)
  448.     register char *lim, *gp;
  449. {
  450.     register int x;
  451.     int (*OO)();
  452.  
  453.     OO = Outchar;
  454.     Outchar = qcount;
  455.     vcntcol = 0;
  456.     if (lim != NULL)
  457.         x = lim[1], lim[1] = 0;
  458.     pline(0);
  459.     if (lim != NULL)
  460.         lim[1] = x;
  461.     if (gp)
  462.         while (*gp)
  463.             putchar(*gp++);
  464.     Outchar = OO;
  465.     return (vcntcol);
  466. }
  467.  
  468. int
  469. qcount(c)
  470.     int c;
  471. {
  472.  
  473.     if (c == '\t') {
  474.         vcntcol += value(TABSTOP) - vcntcol % value(TABSTOP);
  475.         return;
  476.     }
  477.     vcntcol++;
  478. }
  479.  
  480. reverse(a1, a2)
  481.     register line *a1, *a2;
  482. {
  483.     register line t;
  484.  
  485.     for (;;) {
  486.         t = *--a2;
  487.         if (a2 <= a1)
  488.             return;
  489.         *a2 = *a1;
  490.         *a1++ = t;
  491.     }
  492. }
  493.  
  494. save(a1, a2)
  495.     line *a1;
  496.     register line *a2;
  497. {
  498.     register int more;
  499.  
  500.     undkind = UNDNONE;
  501.     undadot = dot;
  502.     more = (a2 - a1 + 1) - (unddol - dol);
  503.     while (more > (endcore - truedol))
  504.         if (morelines() < 0)
  505.             error("Out of memory@saving lines for undo - try using ed or re");
  506.     if (more)
  507.         (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
  508.             (truedol - unddol));
  509.     unddol += more;
  510.     truedol += more;
  511.     copyw(dol + 1, a1, a2 - a1 + 1);
  512.     undkind = UNDALL;
  513.     unddel = a1 - 1;
  514.     undap1 = a1;
  515.     undap2 = a2 + 1;
  516. }
  517.  
  518. save12()
  519. {
  520.  
  521.     save(addr1, addr2);
  522. }
  523.  
  524. saveall()
  525. {
  526.  
  527.     save(one, dol);
  528. }
  529.  
  530. span()
  531. {
  532.  
  533.     return (addr2 - addr1 + 1);
  534. }
  535.  
  536. sync()
  537. {
  538.  
  539.     chng = 0;
  540.     tchng = 0;
  541.     xchng = 0;
  542. }
  543.  
  544.  
  545. skipwh()
  546. {
  547.     register int wh;
  548.  
  549.     wh = 0;
  550.     while (iswhite(peekchar())) {
  551.         wh++;
  552.         ignchar();
  553.     }
  554.     return (wh);
  555. }
  556.  
  557. /*VARARGS2*/
  558. smerror(seekpt, cp)
  559. #ifdef lint
  560.     char *seekpt;
  561. #else
  562.     int seekpt;
  563. #endif
  564.     char *cp;
  565. {
  566.  
  567.     if (seekpt == 0)
  568.         return;
  569.     merror1(seekpt);
  570.     if (inopen && CE)
  571.         vclreol();
  572.     if (SO && SE)
  573.         putpad(SO);
  574.     lprintf(mesg(linebuf), cp);
  575.     if (SO && SE)
  576.         putpad(SE);
  577. }
  578.  
  579. #define    std_nerrs (sizeof std_errlist / sizeof std_errlist[0])
  580.  
  581. #define    error(i)    i
  582.  
  583. #ifdef lint
  584. char    *std_errlist[] = {
  585. #else
  586. short    std_errlist[] = {
  587. #endif
  588.     error("Error 0"),
  589.     error("Not super-user"),
  590.     error("No such file or directory"),
  591.     error("No such process"),
  592.     error("Interrupted system call"),
  593.     error("Physical I/O error"),
  594.     error("No such device or address"),
  595.     error("Argument list too long"),
  596.     error("Exec format error"),
  597.     error("Bad file number"),
  598.     error("No children"),
  599.     error("No more processes"),
  600.     error("Not enough core"),
  601.     error("Permission denied"),
  602.     error("Bad address"),
  603.     error("Block device required"),
  604.     error("Mount device busy"),
  605.     error("File exists"),
  606.     error("Cross-device link"),
  607.     error("No such device"),
  608.     error("Not a directory"),
  609.     error("Is a directory"),
  610.     error("Invalid argument"),
  611.     error("File table overflow"),
  612.     error("Too many open files"),
  613.     error("Not a typewriter"),
  614.     error("Text file busy"),
  615.     error("File too large"),
  616.     error("No space left on device"),
  617.     error("Illegal seek"),
  618.     error("Read-only file system"),
  619.     error("Too many links"),
  620.     error("Broken pipe")
  621. #ifndef QUOTA
  622.     , error("Math argument")
  623.     , error("Result too large")
  624. #else
  625.     , error("Quota exceeded")
  626. #endif
  627. };
  628.  
  629. #undef    error
  630.  
  631. char *
  632. strend(cp)
  633.     register char *cp;
  634. {
  635.  
  636.     while (*cp)
  637.         cp++;
  638.     return (cp);
  639. }
  640.  
  641. strcLIN(dp)
  642.     char *dp;
  643. {
  644.  
  645.     CP(linebuf, dp);
  646. }
  647.  
  648. syserror()
  649. {
  650.     register int e = errno;
  651.  
  652.     dirtcnt = 0;
  653.     putchar(' ');
  654.     if (e >= 0 && errno <= std_nerrs)
  655.         error(std_errlist[e]);
  656.     else
  657.         error("System error %d", e);
  658. }
  659.  
  660. char *
  661. vfindcol(i)
  662.     int i;
  663. {
  664.     register char *cp;
  665.     register int (*OO)() = Outchar;
  666.  
  667.     Outchar = qcount;
  668.     ignore(qcolumn(linebuf - 1, NOSTR));
  669.     for (cp = linebuf; *cp && vcntcol < i; cp++)
  670.         putchar(*cp);
  671.     if (cp != linebuf)
  672.         cp--;
  673.     Outchar = OO;
  674.     return (cp);
  675. }
  676.  
  677. char *
  678. vskipwh(cp)
  679.     register char *cp;
  680. {
  681.  
  682.     while (iswhite(*cp) && cp[1])
  683.         cp++;
  684.     return (cp);
  685. }
  686.  
  687.  
  688. char *
  689. vpastwh(cp)
  690.     register char *cp;
  691. {
  692.  
  693.     while (iswhite(*cp))
  694.         cp++;
  695.     return (cp);
  696. }
  697.  
  698. whitecnt(cp)
  699.     register char *cp;
  700. {
  701.     register int i;
  702.  
  703.     i = 0;
  704.     for (;;)
  705.         switch (*cp++) {
  706.  
  707.         case '\t':
  708.             i += value(TABSTOP) - i % value(TABSTOP);
  709.             break;
  710.  
  711.         case ' ':
  712.             i++;
  713.             break;
  714.  
  715.         default:
  716.             return (i);
  717.         }
  718. }
  719.  
  720. #ifdef lint
  721. Ignore(a)
  722.     char *a;
  723. {
  724.  
  725.     a = a;
  726. }
  727.  
  728. Ignorf(a)
  729.     int (*a)();
  730. {
  731.  
  732.     a = a;
  733. }
  734. #endif
  735.  
  736. markit(addr)
  737.     line *addr;
  738. {
  739.  
  740.     if (addr != dot && addr >= one && addr <= dol)
  741.         markDOT();
  742. }
  743.  
  744.