home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Shells / tcsh / Source / sh.misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  8.1 KB  |  467 lines

  1. /* $Header: /u/christos/src/tcsh-6.03/RCS/sh.misc.c,v 3.17 1992/10/18 00:43:08 christos Exp $ */
  2. /*
  3.  * sh.misc.c: Miscelaneous functions
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "sh.h"
  38.  
  39. RCSID("$Id: sh.misc.c,v 3.17 1992/10/18 00:43:08 christos Exp $")
  40.  
  41. static    int    renum    __P((int, int));
  42. static  Char  **blkend    __P((Char **));
  43. static  Char  **blkcat    __P((Char **, Char **));
  44.  
  45. /*
  46.  * C Shell
  47.  */
  48.  
  49. int
  50. any(s, c)
  51.     register char *s;
  52.     register int c;
  53. {
  54.     if (!s)
  55.     return (0);        /* Check for nil pointer */
  56.     while (*s)
  57.     if (*s++ == c)
  58.         return (1);
  59.     return (0);
  60. }
  61.  
  62. void
  63. setzero(cp, i)
  64.     char   *cp;
  65.     int     i;
  66. {
  67.     if (i != 0)
  68.     do
  69.         *cp++ = 0;
  70.     while (--i);
  71. }
  72.  
  73. char   *
  74. strsave(s)
  75.     register const char *s;
  76. {
  77.     char   *n;
  78.     register char *p;
  79.  
  80.     if (s == NULL)
  81.     s = (const char *) "";
  82.     for (p = (char *) s; *p++;)
  83.     continue;
  84.     n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char)));
  85.     while ((*p++ = *s++) != '\0')
  86.     continue;
  87.     return (n);
  88. }
  89.  
  90. static Char  **
  91. blkend(up)
  92.     register Char **up;
  93. {
  94.  
  95.     while (*up)
  96.     up++;
  97.     return (up);
  98. }
  99.  
  100.  
  101. void
  102. blkpr(av)
  103.     register Char **av;
  104. {
  105.  
  106.     for (; *av; av++) {
  107.     xprintf("%S", *av);
  108.     if (av[1])
  109.         xprintf(" ");
  110.     }
  111. }
  112.  
  113. int
  114. blklen(av)
  115.     register Char **av;
  116. {
  117.     register int i = 0;
  118.  
  119.     while (*av++)
  120.     i++;
  121.     return (i);
  122. }
  123.  
  124. Char  **
  125. blkcpy(oav, bv)
  126.     Char  **oav;
  127.     register Char **bv;
  128. {
  129.     register Char **av = oav;
  130.  
  131.     while ((*av++ = *bv++) != NULL)
  132.     continue;
  133.     return (oav);
  134. }
  135.  
  136. static Char  **
  137. blkcat(up, vp)
  138.     Char  **up, **vp;
  139. {
  140.  
  141.     (void) blkcpy(blkend(up), vp);
  142.     return (up);
  143. }
  144.  
  145. void
  146. blkfree(av0)
  147.     Char  **av0;
  148. {
  149.     register Char **av = av0;
  150.  
  151.     if (!av0)
  152.     return;
  153.     for (; *av; av++)
  154.     xfree((ptr_t) * av);
  155.     xfree((ptr_t) av0);
  156. }
  157.  
  158. Char  **
  159. saveblk(v)
  160.     register Char **v;
  161. {
  162.     register Char **newv =
  163.     (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
  164.     Char  **onewv = newv;
  165.  
  166.     while (*v)
  167.     *newv++ = Strsave(*v++);
  168.     return (onewv);
  169. }
  170.  
  171. #ifndef POSIX
  172. char   *
  173. strstr(s, t)
  174.     register const char *s, *t;
  175. {
  176.     do {
  177.     register const char *ss = s;
  178.     register const char *tt = t;
  179.  
  180.     do
  181.         if (*tt == '\0')
  182.         return ((char *) s);
  183.     while (*ss++ == *tt++);
  184.     } while (*s++ != '\0');
  185.     return (NULL);
  186. }
  187.  
  188. #endif /* POSIX */
  189.  
  190. #ifndef SHORT_STRINGS
  191. char   *
  192. strspl(cp, dp)
  193.     char   *cp, *dp;
  194. {
  195.     char   *ep;
  196.     register char *p, *q;
  197.  
  198.     if (!cp)
  199.     cp = "";
  200.     if (!dp)
  201.     dp = "";
  202.     for (p = cp; *p++;);
  203.     for (q = dp; *q++;);
  204.     ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
  205.     for (p = ep, q = cp; *p++ = *q++;);
  206.     for (p--, q = dp; *p++ = *q++;);
  207.     return (ep);
  208. }
  209.  
  210. #endif
  211.  
  212. Char  **
  213. blkspl(up, vp)
  214.     register Char **up, **vp;
  215. {
  216.     register Char **wp =
  217.     (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
  218.               sizeof(Char **));
  219.  
  220.     (void) blkcpy(wp, up);
  221.     return (blkcat(wp, vp));
  222. }
  223.  
  224. Char
  225. lastchr(cp)
  226.     register Char *cp;
  227. {
  228.  
  229.     if (!cp)
  230.     return (0);
  231.     if (!*cp)
  232.     return (0);
  233.     while (cp[1])
  234.     cp++;
  235.     return (*cp);
  236. }
  237.  
  238. /*
  239.  * This routine is called after an error to close up
  240.  * any units which may have been left open accidentally.
  241.  */
  242. void
  243. closem()
  244. {
  245.     register int f;
  246.  
  247. #ifdef YPBUGS
  248.     /* suggested by Justin Bur; thanks to Karl Kleinpaste */
  249.     fix_yp_bugs();
  250. #endif
  251.     for (f = 0; f < NOFILE; f++)
  252.     if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
  253.         f != FSHTTY 
  254. #ifdef MALLOC_TRACE
  255.         && f != 25
  256. #endif /* MALLOC_TRACE */
  257.         )
  258.         (void) close(f);
  259. }
  260.  
  261. #ifndef CLOSE_ON_EXEC
  262. /*
  263.  * Close files before executing a file.
  264.  * We could be MUCH more intelligent, since (on a version 7 system)
  265.  * we need only close files here during a source, the other
  266.  * shell fd's being in units 16-19 which are closed automatically!
  267.  */
  268. void
  269. closech()
  270. {
  271.     register int f;
  272.  
  273.     if (didcch)
  274.     return;
  275.     didcch = 1;
  276.     SHIN = 0;
  277.     SHOUT = 1;
  278.     SHDIAG = 2;
  279.     OLDSTD = 0;
  280.     isoutatty = isatty(SHOUT);
  281.     isdiagatty = isatty(SHDIAG);
  282.     for (f = 3; f < NOFILE; f++)
  283.     (void) close(f);
  284. }
  285.  
  286. #endif /* CLOSE_ON_EXEC */
  287.  
  288. void
  289. donefds()
  290. {
  291.  
  292.     (void) close(0);
  293.     (void) close(1);
  294.     (void) close(2);
  295.     didfds = 0;
  296. }
  297.  
  298. /*
  299.  * Move descriptor i to j.
  300.  * If j is -1 then we just want to get i to a safe place,
  301.  * i.e. to a unit > 2.  This also happens in dcopy.
  302.  */
  303. int
  304. dmove(i, j)
  305.     register int i, j;
  306. {
  307.  
  308.     if (i == j || i < 0)
  309.     return (i);
  310. #ifdef HAVEDUP2
  311.     if (j >= 0) {
  312.     (void) dup2(i, j);
  313.     if (j != i)
  314.         (void) close(i);
  315.     return (j);
  316.     }
  317. #endif
  318.     j = dcopy(i, j);
  319.     if (j != i)
  320.     (void) close(i);
  321.     return (j);
  322. }
  323.  
  324. int
  325. dcopy(i, j)
  326.     register int i, j;
  327. {
  328.  
  329.     if (i == j || i < 0 || (j < 0 && i > 2))
  330.     return (i);
  331.     if (j >= 0) {
  332. #ifdef HAVEDUP2
  333.     (void) dup2(i, j);
  334.     return (j);
  335. #else
  336.     (void) close(j);
  337. #endif
  338.     }
  339.     return (renum(i, j));
  340. }
  341.  
  342. static int
  343. renum(i, j)
  344.     register int i, j;
  345. {
  346.     register int k = dup(i);
  347.  
  348.     if (k < 0)
  349.     return (-1);
  350.     if (j == -1 && k > 2)
  351.     return (k);
  352.     if (k != j) {
  353.     j = renum(k, j);
  354.     (void) close(k);
  355.     return (j);
  356.     }
  357.     return (k);
  358. }
  359.  
  360. /*
  361.  * Left shift a command argument list, discarding
  362.  * the first c arguments.  Used in "shift" commands
  363.  * as well as by commands like "repeat".
  364.  */
  365. void
  366. lshift(v, c)
  367.     register Char **v;
  368.     register int c;
  369. {
  370.     register Char **u;
  371.  
  372.     for (u = v; *u && --c >= 0; u++)
  373.     xfree((ptr_t) *u);
  374.     (void) blkcpy(v, u);
  375. }
  376.  
  377. int
  378. number(cp)
  379.     Char   *cp;
  380. {
  381.     if (!cp)
  382.     return (0);
  383.     if (*cp == '-') {
  384.     cp++;
  385.     if (!Isdigit(*cp))
  386.         return (0);
  387.     cp++;
  388.     }
  389.     while (*cp && Isdigit(*cp))
  390.     cp++;
  391.     return (*cp == 0);
  392. }
  393.  
  394. Char  **
  395. copyblk(v)
  396.     register Char **v;
  397. {
  398.     register Char **nv =
  399.     (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
  400.  
  401.     return (blkcpy(nv, v));
  402. }
  403.  
  404. #ifndef SHORT_STRINGS
  405. char   *
  406. strend(cp)
  407.     register char *cp;
  408. {
  409.     if (!cp)
  410.     return (cp);
  411.     while (*cp)
  412.     cp++;
  413.     return (cp);
  414. }
  415.  
  416. #endif /* SHORT_STRINGS */
  417.  
  418. Char   *
  419. strip(cp)
  420.     Char   *cp;
  421. {
  422.     register Char *dp = cp;
  423.  
  424.     if (!cp)
  425.     return (cp);
  426.     while (*dp++ &= TRIM)
  427.     continue;
  428.     return (cp);
  429. }
  430.  
  431. Char   *
  432. quote(cp)
  433.     Char   *cp;
  434. {
  435.     register Char *dp = cp;
  436.  
  437.     if (!cp)
  438.     return (cp);
  439.     while (*dp != '\0')
  440.     *dp++ |= QUOTE;
  441.     return (cp);
  442. }
  443.  
  444. void
  445. udvar(name)
  446.     Char   *name;
  447. {
  448.  
  449.     setname(short2str(name));
  450.     stderror(ERR_NAME | ERR_UNDVAR);
  451. }
  452.  
  453. int
  454. prefix(sub, str)
  455.     register Char *sub, *str;
  456. {
  457.  
  458.     for (;;) {
  459.     if (*sub == 0)
  460.         return (1);
  461.     if (*str == 0)
  462.         return (0);
  463.     if ((*sub++ & TRIM) != (*str++ & TRIM))
  464.         return (0);
  465.     }
  466. }
  467.