home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume14 / jove4.9 / part08 / util.c < prev   
C/C++ Source or Header  |  1988-04-25  |  16KB  |  1,046 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "ctype.h"
  10. #include "termcap.h"
  11. #include <signal.h>
  12.  
  13. #ifdef MAC
  14. #    include "mac.h"
  15. #else
  16. #    include <varargs.h>
  17. #endif
  18.  
  19. #ifdef MSDOS
  20. #include <time.h>
  21. #endif
  22.  
  23. struct cmd *
  24. FindCmd(proc)
  25. register void     (*proc)();
  26. {
  27.     register struct cmd    *cp;
  28.  
  29.       for (cp = commands; cp->Name; cp++)
  30.         if (cp->c_proc == proc)
  31.             return cp;
  32.     return 0;
  33. }
  34.  
  35. int    Interactive;    /* True when we invoke with the command handler? */
  36. data_obj    *LastCmd;
  37. char    *ProcFmt = ": %f ";
  38.  
  39. void
  40. ExecCmd(cp)
  41. data_obj    *cp;
  42. {
  43.     LastCmd = cp;
  44.     if (cp->Type & MAJOR_MODE)
  45.         SetMajor((cp->Type >> 8));
  46.     else if (cp->Type & MINOR_MODE)
  47.         TogMinor((cp->Type >> 8));
  48.     else    switch (cp->Type&TYPEMASK) {
  49.         case MACRO:
  50.             do_macro((struct macro *) cp);
  51.             break;
  52.  
  53.         case FUNCTION:
  54.             {
  55.                 struct cmd    *cmd = (struct cmd *) cp;
  56.  
  57.             if (cmd->c_proc)
  58.                 (*cmd->c_proc)();
  59.             }
  60.     }
  61. }
  62.  
  63. Line *
  64. lastline(lp)
  65. register Line    *lp;
  66. {
  67.     register Line    *next;
  68.  
  69.     while (next = lp->l_next)
  70.         lp = next;
  71.     return lp;
  72. }
  73.  
  74. private int    *slowp = 0;
  75.  
  76. char    key_strokes[100];
  77. private char    *key_p = key_strokes;
  78.  
  79. void
  80. init_strokes()
  81. {
  82.     key_strokes[0] = 0;
  83.     key_p = key_strokes;
  84. }
  85.  
  86. void
  87. add_stroke(c)
  88. {
  89.     if (key_p + 5 > &key_strokes[(sizeof key_strokes) - 1])
  90.         key_p = key_strokes;
  91.     sprintf(key_p, "%p ", c);
  92.     key_p += strlen(key_p);
  93. }
  94.  
  95. void
  96. slowpoke()
  97. {
  98.     if (slowp)
  99.         *slowp = YES;
  100.     f_mess(key_strokes);
  101. }
  102.  
  103. #ifdef UNIX
  104. #ifdef BSD4_2
  105. #    define N_SEC    1    /* will be precisely 1 second on 4.2 */
  106. #else
  107. #    define N_SEC    2    /* but from 1 to 2 seconds otherwise */
  108. #endif
  109. #else /* MSDOS or MAC */
  110. #define N_SEC    1
  111. int in_macro();
  112. #endif /* UNIX */
  113.  
  114. int
  115. waitchar(slow)
  116. int    *slow;
  117. {
  118. #ifdef UNIX
  119. #ifdef EUNICE
  120.     return getch();
  121. #endif
  122.     unsigned int    old_time;
  123.     int    c;
  124.     int    (*oldproc)();
  125. #else /* MSDOS or MAC */
  126.     long sw, time();
  127. #endif /* UNIX */
  128.  
  129.     slowp = slow;
  130.     if (slow)
  131.         *slow = NO;
  132. #ifdef UNIX
  133.     oldproc = signal(SIGALRM, slowpoke);
  134.  
  135.     if ((old_time = alarm((unsigned) N_SEC)) == 0)
  136.         old_time = UpdFreq;
  137.     c = getch();
  138.     (void) alarm(old_time);
  139.     (void) signal(SIGALRM, oldproc);
  140.  
  141.     return c;
  142. #else /* MSDOS or MAC */
  143. #ifdef MAC
  144.     Keyonly = 1;
  145.     if(charp() || in_macro()) return getch();    /* to avoid flicker */
  146. #endif
  147.     time(&sw);
  148.     sw += N_SEC;
  149.     while(time(NULL) <= sw)
  150.         if (charp() || in_macro())
  151.             return getch();
  152. #ifdef MAC
  153.     menus_off();
  154. #endif
  155.     slowpoke();
  156.     return getch();
  157. #endif /* UNIX */
  158. }
  159.  
  160. /* dir > 0 means forward; else means backward. */
  161.  
  162. char *
  163. StrIndex(dir, buf, charpos, what)
  164. char    *buf,
  165.     what;
  166. {
  167.     char    *cp = &buf[charpos],
  168.         c;
  169.  
  170.     if (dir > 0) {
  171.         while (c = *cp++)
  172.             if (c == what)
  173.                 return (cp - 1);
  174.     } else {
  175.         while (cp >= buf && (c = *cp--))
  176.             if (c == what)
  177.                 return (cp + 1);
  178.     }
  179.     return 0;
  180. }
  181.  
  182. int
  183. blnkp(buf)
  184. register char    *buf;
  185. {
  186.     register char    c;
  187.  
  188.     while ((c = *buf++) && (c == ' ' || c == '\t'))
  189.         ;
  190.     return c == 0;    /* It's zero if we got to the end of the Line */
  191. }
  192.  
  193. Line *
  194. next_line(line, num)
  195. register Line    *line;
  196. register int    num;
  197. {
  198.     if (num < 0)
  199.         return prev_line(line, -num);
  200.     if (line)
  201.         while (--num >= 0 && line->l_next != 0)
  202.             line = line->l_next;
  203.     return line;
  204. }
  205.  
  206. Line *
  207. prev_line(line, num)
  208. register Line    *line;
  209. register int    num;
  210. {
  211.     if (num < 0)
  212.         return next_line(line, -num);
  213.     if (line)
  214.         while (--num >= 0 && line->l_prev != 0)
  215.             line = line->l_prev;
  216.     return line;
  217. }
  218.  
  219. void
  220. DotTo(line, col)
  221. Line    *line;
  222. {
  223.     Bufpos    bp;
  224.  
  225.     bp.p_line = line;
  226.     bp.p_char = col;
  227.     SetDot(&bp);
  228. }
  229.  
  230. /* If bp->p_line is != current line, then save current line.  Then set dot
  231.    to bp->p_line, and if they weren't equal get that line into linebuf.  */
  232.  
  233. void
  234. SetDot(bp)
  235. register Bufpos    *bp;
  236. {
  237.     register int    notequal;
  238.  
  239.     if (bp == 0)
  240.         return;
  241.  
  242.     notequal = bp->p_line != curline;
  243.     if (notequal)
  244.         lsave();
  245.     if (bp->p_line)
  246.         curline = bp->p_line;
  247.     if (notequal)
  248.         getDOT();
  249.     curchar = bp->p_char;
  250.     if (curchar > length(curline))
  251.         curchar = length(curline);
  252. }
  253.  
  254. void
  255. ToLast()
  256. {
  257.     SetLine(curbuf->b_last);
  258.     Eol();
  259. }
  260.  
  261. int    MarkThresh = 22;    /* average screen size ... */
  262. static int    line_diff;
  263.  
  264. int
  265. LineDist(nextp, endp)
  266. register Line    *nextp,
  267.         *endp;
  268. {
  269.     (void) inorder(nextp, 0, endp, 0);
  270.     return line_diff;
  271. }
  272.  
  273. int
  274. inorder(nextp, char1, endp, char2)
  275. register Line    *nextp,
  276.         *endp;
  277. {
  278.     int    count = 0;
  279.     register Line    *prevp = nextp;
  280.  
  281.     line_diff = 0;
  282.     if (nextp == endp)
  283.         return char1 < char2;
  284.  
  285.     while (nextp || prevp) {
  286.         if (nextp == endp || prevp == endp)
  287.             break;
  288.         if (nextp)
  289.             nextp = nextp->l_next;
  290.         if (prevp)
  291.             prevp = prevp->l_prev;
  292.         count += 1;
  293.     }
  294.     if (nextp == 0 && prevp == 0)
  295.         return -1;
  296.     line_diff = count;
  297.  
  298.     return nextp == endp;
  299. }
  300.  
  301. void
  302. PushPntp(line)
  303. register Line    *line;
  304. {
  305.     if (LineDist(curline, line) >= MarkThresh)
  306.         set_mark();
  307. }
  308.  
  309. void
  310. ToFirst()
  311. {
  312.     SetLine(curbuf->b_first);
  313. }
  314.  
  315. int
  316. length(line)
  317. Line    *line;
  318. {
  319.     return strlen(lcontents(line));
  320. };
  321.  
  322. void
  323. to_word(dir)
  324. register int    dir;
  325. {
  326.     register char    c;
  327.  
  328.     if (dir == FORWARD) {
  329.         while ((c = linebuf[curchar]) != 0 && !isword(c))
  330.             curchar += 1;
  331.         if (eolp()) {
  332.             if (curline->l_next == 0)
  333.                 return;
  334.             SetLine(curline->l_next);
  335.             to_word(dir);
  336.             return;
  337.         }
  338.     } else {
  339.         while (!bolp() && (c = linebuf[curchar - 1], !isword(c)))
  340.             curchar -= 1;
  341.         if (bolp()) {
  342.             if (curline->l_prev == 0)
  343.                 return;
  344.             SetLine(curline->l_prev);
  345.             Eol();
  346.             to_word(dir);
  347.         }
  348.     }
  349. }
  350.  
  351. /* Are there any modified buffers?  Allp means include B_PROCESS
  352.    buffers in the check. */
  353.  
  354. int
  355. ModBufs(allp)
  356. {
  357.     register Buffer    *b;
  358.  
  359.     for (b = world; b != 0; b = b->b_next) {
  360.         if (b->b_type == B_SCRATCH)
  361.             continue;
  362.         if ((b->b_type == B_FILE || allp) && IsModified(b))
  363.             return 1;
  364.     }
  365.     return 0;
  366. }
  367.  
  368. char *
  369. filename(b)
  370. register Buffer    *b;
  371. {
  372.     return b->b_fname ? pr_name(b->b_fname, YES) : "[No file]";
  373. }
  374.  
  375. char *
  376. itoa(num)
  377. register int    num;
  378. {
  379.     static char    line[15];
  380.  
  381.     sprintf(line, "%d", num);
  382.     return line;
  383. }
  384.  
  385. int
  386. min(a, b)
  387. register int    a,
  388.         b;
  389. {
  390.     return (a < b) ? a : b;
  391. }
  392.  
  393. int
  394. max(a, b)
  395. register int    a,
  396.         b;
  397. {
  398.     return (a > b) ? a : b;
  399. }
  400.  
  401. void
  402. tiewind(w, bp)
  403. register Window    *w;
  404. register Buffer    *bp;
  405. {
  406.     int    not_tied = (w->w_bufp != bp);
  407.  
  408.     UpdModLine = YES;    /* kludge ... but speeds things up considerably */
  409.     w->w_line = bp->b_dot;
  410.     w->w_char = bp->b_char;
  411.     w->w_bufp = bp;
  412.     if (not_tied)
  413.         CalcWind(w);    /* ah, this has been missing since the
  414.                    beginning of time! */
  415. }
  416.  
  417. extern int    Jr_Len;
  418.  
  419. char *
  420. lcontents(line)
  421. register Line    *line;
  422. {
  423.     if (line == curline)
  424.         return linebuf;
  425.     else
  426.         return lbptr(line);
  427. }
  428.  
  429. char *
  430. ltobuf(line, buf)
  431. Line    *line;
  432. char    *buf;
  433. {
  434.     if (line == curline) {
  435.         if (buf != linebuf)
  436.             strcpy(buf, linebuf);
  437.         Jr_Len = strlen(linebuf);
  438.     } else
  439.         getline(line->l_dline, buf);
  440.     return buf;
  441. }
  442.  
  443. void
  444. DOTsave(buf)
  445. Bufpos *buf;
  446. {
  447.     buf->p_line = curline;
  448.     buf->p_char = curchar;
  449. }
  450.  
  451. /* Return none-zero if we had to rearrange the order. */
  452.  
  453. int
  454. fixorder(line1, char1, line2, char2)
  455. register Line    **line1,
  456.         **line2;
  457. register int    *char1,
  458.         *char2;
  459. {
  460.     Line    *tline;
  461.     int    tchar;
  462.  
  463.     if (inorder(*line1, *char1, *line2, *char2))
  464.         return 0;
  465.  
  466.     tline = *line1;
  467.     tchar = *char1;
  468.     *line1 = *line2;
  469.     *char1 = *char2;
  470.     *line2 = tline;
  471.     *char2 = tchar;
  472.  
  473.     return 1;
  474. }
  475.  
  476. int
  477. inlist(first, what)
  478. register Line    *first,
  479.         *what;
  480. {
  481.     while (first) {
  482.         if (first == what)
  483.             return 1;
  484.         first = first->l_next;
  485.     }
  486.     return 0;
  487. }
  488.  
  489. /* Make `buf' (un)modified and tell the redisplay code to update the modeline
  490.    if it will need to be changed. */
  491.  
  492. int    ModCount = 0;
  493.  
  494. void
  495. modify()
  496. {
  497.     extern int    DOLsave;
  498.  
  499.     if (!curbuf->b_modified) {
  500.         UpdModLine = YES;
  501.         curbuf->b_modified = YES;
  502.     }
  503.     DOLsave = YES;
  504.     if (!Asking)
  505.         ModCount += 1;
  506. }
  507.  
  508. void
  509. unmodify()
  510. {
  511.     if (curbuf->b_modified) {
  512.         UpdModLine = YES;
  513.         curbuf->b_modified = NO;
  514.     }
  515. }
  516.  
  517. int
  518. numcomp(s1, s2)
  519. register char    *s1,
  520.         *s2;
  521. {
  522.     register int    count = 0;
  523.  
  524.     while (*s1 != 0 && *s1++ == *s2++)
  525.         count += 1;
  526.     return count;
  527. }
  528.  
  529. char *
  530. copystr(str)
  531. char    *str;
  532. {
  533.     char    *val;
  534.  
  535.     if (str == 0)
  536.         return 0;
  537.     val = emalloc(strlen(str) + 1);
  538.  
  539.     strcpy(val, str);
  540.     return val;
  541. }
  542.  
  543. #ifndef byte_copy
  544. void
  545. byte_copy(from, to, count)
  546. register char    *from,
  547.         *to;
  548. register int    count;
  549. {
  550.     while (--count >= 0)
  551.         *to++ = *from++;
  552. }
  553. #endif
  554.  
  555. void
  556. len_error(flag)
  557. {
  558.     char    *mesg = "[line too long]";
  559.  
  560.     if (flag == COMPLAIN) complain(mesg);
  561.         else error(mesg);
  562. }
  563.  
  564. /* Insert num number of c's at offset atchar in a linebuf of LBSIZE */
  565.  
  566. void
  567. ins_c(c, buf, atchar, num, max)
  568. char    c, *buf;
  569. {
  570.     register char    *pp, *pp1;
  571.     register int    len;
  572.     int    numchars;    /* number of characters to copy forward */
  573.  
  574.     if (num <= 0)
  575.         return;
  576.     len = atchar + strlen(&buf[atchar]);
  577.     if (len + num >= max)
  578.         len_error(COMPLAIN);
  579.     pp = &buf[len + 1];        /* + 1 so we can --pp (not pp--) */
  580.     pp1 = &buf[len + num + 1];
  581.     numchars = len - atchar;
  582.     while (numchars-- >= 0)
  583.         *--pp1 = *--pp;
  584.     pp = &buf[atchar];
  585.     while (--num >= 0)
  586.         *pp++ = c;
  587. }
  588.  
  589. int
  590. TwoBlank()
  591. {
  592.     register Line    *next = curline->l_next;
  593.  
  594.     return ((next != 0) &&
  595.         (*(lcontents(next)) == '\0') &&
  596.         (next->l_next != 0) &&
  597.         (*(lcontents(next->l_next)) == '\0'));
  598. }
  599.  
  600. void
  601. linecopy(onto, atchar, from)
  602. register char    *onto,
  603.         *from;
  604. {
  605.     register char    *endp = &onto[LBSIZE - 2];
  606.  
  607.     onto += atchar;
  608.  
  609.     while (*onto = *from++)
  610.         if (onto++ >= endp)
  611.             len_error(ERROR);
  612. }
  613.  
  614. char *
  615. IOerr(err, file)
  616. char    *err, *file;
  617. {
  618.     return sprint("Couldn't %s \"%s\".", err, file);
  619. }
  620.  
  621. #ifdef UNIX
  622. void
  623. pclose(p)
  624. int    *p;
  625. {
  626.     (void) close(p[0]);
  627.     (void) close(p[1]);
  628. }
  629.  
  630. void
  631. dopipe(p)
  632. int    p[];
  633. {
  634.     if (pipe(p) == -1)
  635.         complain("[Pipe failed]");
  636. }
  637.  
  638. #endif /* UNIX */
  639. /* NOSTRICT */
  640.  
  641. char *
  642. emalloc(size)
  643. {
  644.     register char    *ptr;
  645.  
  646.     if (ptr = malloc((unsigned) size))
  647.         return ptr;
  648.     /* Try garbage collecting lines */
  649.     GCchunks();
  650.     if (ptr = malloc((unsigned) size))
  651.         return ptr;
  652.     /* Uh ... Oh screw it! */
  653.     error("[Out of memory] ");
  654.     /* NOTREACHED */
  655. }
  656.  
  657. /* Return the basename of file F. */
  658.  
  659. char *
  660. basename(f)
  661. register char    *f;
  662. {
  663.     register char    *cp;
  664.  
  665.     if (cp = rindex(f, '/'))
  666.         return cp + 1;
  667.     else
  668. #ifdef MSDOS
  669.         if (cp = rindex(f, '\\'))
  670.             return cp + 1;
  671.     else
  672.         if (cp = rindex(f, ':'))
  673.             return cp + 1;
  674. #endif /* MSDOS */
  675.         return f;
  676. }
  677.  
  678. void
  679. push_env(savejmp)
  680. jmp_buf    savejmp;
  681. {
  682.     byte_copy((char *) mainjmp, (char *) savejmp, sizeof (jmp_buf));
  683. }
  684.  
  685. void
  686. pop_env(savejmp)
  687. jmp_buf    savejmp;
  688. {
  689.     byte_copy((char *) savejmp, (char *) mainjmp, sizeof (jmp_buf));
  690. }
  691.  
  692. #ifdef LOAD_AV
  693. # if defined(BSD4_2) && !defined(BSD2_10)
  694. #   if defined(PURDUE_EE) && (defined(vax) || defined(gould))
  695.  
  696. void
  697. get_la(dp)
  698. double *dp;
  699. {
  700.     *dp = (double) loadav(0) / 100.0;
  701. }
  702.  
  703. #   else /* !PURDUE_EE || (!vax && !gould) */ 
  704.  
  705. #ifdef sun
  706. #   include <sys/param.h>
  707. #endif
  708. #include <nlist.h>
  709.  
  710. static struct    nlist nl[] = {
  711.     { "_avenrun" },
  712. #define    X_AVENRUN    0
  713.     { "" }
  714. };
  715.  
  716. void
  717. get_la(dp)
  718. double    *dp;
  719. {
  720. #ifdef sun
  721.     long    avenrun[3];
  722. #else
  723.     double    avenrun[3];
  724. #endif
  725.     static int    kmem = 0;
  726.  
  727.     if (kmem == -1) {
  728.         *dp = 4.0;    /* So shell commands will say "Chugging" */
  729.         return;
  730.     } else if (kmem == 0) {
  731.         if ((kmem = open("/dev/kmem", 0)) == -1) {
  732.             f_mess("Can't open kmem for load average.");
  733.             *dp = 4.0;
  734.             return;
  735.         }
  736.         nlist("/vmunix", nl);
  737.     }
  738.     lseek(kmem, (long) nl[X_AVENRUN].n_value, 0);
  739.     read(kmem, (char *) avenrun, sizeof(avenrun));
  740. #ifdef sun
  741.     *dp = (double) avenrun[0] / FSCALE;
  742. #else
  743.     *dp = avenrun[0];
  744. #endif
  745. }
  746.  
  747. #    endif
  748. #  else /* !BSD4_2 || BSD2_10 */
  749.  
  750. void
  751. get_la(dp)
  752. double    *dp;
  753. {
  754.     short    avg[3];
  755.  
  756.     gldav(avg);
  757.     *dp = (double) avg[0] / 256;
  758. }
  759.  
  760. #  endif
  761. #endif /* LOAD_AV */
  762.  
  763. /* get the time buf, designated by *timep, from FROM to TO. */
  764. char *
  765. get_time(timep, buf, from, to)
  766. char    *buf;
  767. time_t    *timep;
  768. {
  769.     time_t    now;
  770.     char    *cp;
  771.     extern char    *ctime();
  772.  
  773.     if (timep != 0)
  774.         now = *timep;
  775.     else
  776.         (void) time(&now);
  777.     cp = ctime(&now) + from;
  778. #ifndef MSDOS
  779.     if (to == -1)
  780. #else /* MSDOS */
  781.     if ((to == -1) && (cp[strlen(cp)-1] == '\n'))
  782. #endif /* MSDOS */
  783.         cp[strlen(cp) - 1] = '\0';        /* Get rid of \n */
  784.     else
  785.         cp[to - from] = '\0';
  786.     if (buf) {
  787.         strcpy(buf, cp);
  788.         return buf;
  789.     } else
  790.         return cp;
  791. }
  792.  
  793. #ifndef MSDOS
  794. #ifndef MAC
  795. int
  796. strlen(s)
  797. register char    *s;
  798. {
  799.     register char    *base = s;
  800.  
  801.     while (*s++)
  802.         ;
  803.     return (s - base) - 1;
  804. }
  805.  
  806. char *
  807. index(s, c)
  808. register char    *s;
  809. register int    c;
  810. {
  811.     register int    c1;
  812.  
  813.     if (c != 0)
  814.         while (c1 = *s++)
  815.             if (c == c1)
  816.                 return s - 1;
  817.     return 0;
  818. }
  819.  
  820. int
  821. strcmp(s1, s2)
  822. register char    *s1,
  823.         *s2;
  824. {
  825.     if (!s1 || !s2)
  826.         return 1;    /* which is not zero ... */
  827.     while (*s1 == *s2++)
  828.         if (*s1++ == '\0')
  829.             return 0;
  830.     return (*s1 - *--s2);
  831. }
  832.  
  833. #endif /* MAC */
  834. #endif /* MSDOS */
  835.  
  836. int
  837. casecmp(s1, s2)
  838. register char    *s1,
  839.         *s2;
  840. {
  841.     if (!s1 || !s2)
  842.         return 1;    /* which is not zero ... */
  843.     while (CharUpcase(*s1) == CharUpcase(*s2++))
  844.         if (*s1++ == '\0')
  845.             return 0;
  846.     return (*s1 - *--s2);
  847. }
  848.  
  849. int
  850. casencmp(s1, s2, n)
  851. register char    *s1,
  852.         *s2;
  853. register int    n;
  854. {
  855.     if (!s1 || !s2)
  856.         return 1;    /* which is not zero ... */
  857.     while (--n >= 0  && (CharUpcase(*s1) == CharUpcase(*s2++)))
  858.         if (*s1++ == '\0')
  859.             return 0;
  860.     return ((n < 0) ? 0 : *s1 - *--s2);
  861. }
  862.  
  863. void
  864. null_ncpy(to, from, n)
  865. char    *to,
  866.     *from;
  867. {
  868.     (void) strncpy(to, from, n);
  869.     to[n] = '\0';
  870. }
  871.  
  872. #ifndef MSDOS
  873. #ifndef MAC
  874. void
  875. strcpy(t, f)
  876. register char    *t,
  877.         *f;
  878. {
  879.     while (*t++ = *f++)
  880.         ;
  881. }
  882.  
  883. #endif /* MAC */
  884. #endif /* MSDOS */
  885.  
  886. /* Tries to pause for delay/10 seconds OR until a character is typed
  887.    at the keyboard.  This works well on BSD4_2 and not so well on the
  888.    rest.  Returns 1 if it returned because of keyboard input, or 0
  889.    otherwise. */
  890.  
  891. #ifdef MAC
  892. void
  893. SitFor(delay)
  894. unsigned int    delay;
  895. {
  896.     long    start,
  897.         end;
  898.  
  899. #define Ticks (long *) 0x16A    /* 1/60 sec */
  900.     Keyonly = 1;
  901.     redisplay();
  902.     start = *Ticks;
  903.  
  904.     end = start + delay * 6;
  905.     do
  906.         if (InputPending = charp())
  907.             break;
  908.     while (*Ticks < end);
  909. }
  910. #else    /* not MAC */
  911.  
  912. void
  913. SitFor(delay)
  914. unsigned int    delay;
  915. {
  916. #ifndef MSDOS
  917. #if defined(BSD4_2) && !defined(BSD2_10)
  918. #include <sys/time.h>
  919.  
  920.     struct timeval    timer;
  921.     long    readfds = 1;
  922.  
  923.     timer.tv_sec = (delay / 10);
  924.     timer.tv_usec = (delay % 10) * 100000;
  925.  
  926.     if (charp())
  927.         return;
  928.     /* gross that I had to snarf this from getch() */
  929.     if (!UpdMesg && !Asking) {    /* Don't erase if we are asking */
  930.         if (mesgbuf[0] && !errormsg)
  931.             message(NullStr);
  932.     }
  933.     redisplay();
  934.     select(1, &readfds, (long *)0, (long *)0, &timer);
  935. #else
  936.     static int cps[] = {
  937.         0,
  938.         5,
  939.         7,
  940.         11,
  941.         13,
  942.         15,
  943.         20,
  944.         30,
  945.         60,
  946.         120,
  947.         180,
  948.         240,
  949.         480,
  950.         960,
  951.         1920,
  952.         1920,
  953.     };
  954.     register int    nchars,
  955.             check_cnt;
  956.  
  957.     if (charp())
  958.         return;
  959.     nchars = (delay * cps[ospeed]) / 10;
  960.     check_cnt = BufSize;
  961.     redisplay();
  962.     while ((--nchars > 0) && !InputPending) {
  963.         putchar(0);
  964.         if (--check_cnt == 0) {
  965.             check_cnt = BufSize;
  966.             InputPending = charp();
  967.         }
  968.     }
  969. #endif
  970. #else /* MSDOS */
  971. #include <bios.h>
  972. #include <dos.h>
  973.  
  974.     long    start,
  975.         end;
  976. #ifndef IBMPC
  977.     struct dostime_t tc;
  978. #endif    
  979.  
  980.     redisplay();
  981. #ifdef IBMPC
  982.     _bios_timeofday(_TIME_GETCLOCK, &start);
  983. #else
  984.     _dos_gettime(&tc);
  985.     start = (long)(tc.hour*60L*60L*10L)+(long)(tc.minute*60L*10L)+
  986.             (long)(tc.second*10)+(long)(tc.hsecond/10);
  987. #endif
  988.     end = (start + delay);
  989.     do  {
  990.         if (InputPending = charp())
  991.             break;
  992. #ifdef IBMPC
  993.         if (_bios_timeofday(_TIME_GETCLOCK, &start))
  994.             break;    /* after midnight */
  995. #else
  996.         start = (long)(tc.hour*60L*60L*10L)+(long)(tc.minute*60L*10L)+
  997.                 (long)(tc.second*10)+(long)(tc.hsecond/10);
  998. #endif
  999.     }
  1000.     while (start < end);
  1001. #endif /* MSDOS */
  1002. }
  1003. #endif /* MAC */
  1004.  
  1005. int
  1006. sindex(pattern, string)
  1007. register char    *pattern,
  1008.         *string;
  1009. {
  1010.     register int    len = strlen(pattern);
  1011.  
  1012.     while (*string != '\0') {
  1013.         if (*pattern == *string && strncmp(pattern, string, len) == 0)
  1014.             return TRUE;
  1015.         string += 1;
  1016.     }
  1017.     return FALSE;
  1018. }
  1019.  
  1020. void
  1021. make_argv(argv, ap)
  1022. register char    *argv[];
  1023. va_list    ap;
  1024. {
  1025.     register char    *cp;
  1026.     register int    i = 0;
  1027.  
  1028.     argv[i++] = va_arg(ap, char *);
  1029.     argv[i++] = basename(argv[0]);
  1030.     while (cp = va_arg(ap, char *))
  1031.         argv[i++] = cp;
  1032.     argv[i] = 0;
  1033. }
  1034.  
  1035. int
  1036. pnt_line()
  1037. {
  1038.     register Line    *lp = curbuf->b_first;
  1039.     register int    i;
  1040.  
  1041.     for (i = 0; lp != 0; i++, lp = lp->l_next)
  1042.         if (lp == curline)
  1043.             break;
  1044.     return i + 1;
  1045. }
  1046.