source: trunk/third/tcsh/sh.misc.c @ 12039

Revision 12039, 9.0 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12038, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/sh.misc.c,v 1.1.1.2 1998-10-03 21:10:04 danw 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
39RCSID("$Id: sh.misc.c,v 1.1.1.2 1998-10-03 21:10:04 danw Exp $")
40
41static  int     renum   __P((int, int));
42static  Char  **blkend  __P((Char **));
43static  Char  **blkcat  __P((Char **, Char **));
44
45/*
46 * C Shell
47 */
48
49int
50any(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
62void
63setzero(cp, i)
64    char   *cp;
65    int     i;
66{
67    if (i != 0)
68        do
69            *cp++ = 0;
70        while (--i);
71}
72
73char   *
74strsave(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++ != '\0';)
83        continue;
84    n = p = (char *) xmalloc((size_t)
85                             ((((const char *) p) - s) * sizeof(char)));
86    while ((*p++ = *s++) != '\0')
87        continue;
88    return (n);
89}
90
91static Char  **
92blkend(up)
93    register Char **up;
94{
95
96    while (*up)
97        up++;
98    return (up);
99}
100
101
102void
103blkpr(av)
104    register Char **av;
105{
106
107    for (; *av; av++) {
108        xprintf("%S", *av);
109        if (av[1])
110            xprintf(" ");
111    }
112}
113
114void
115blkexpand(av, str)
116    register Char **av;
117    Char *str;
118{
119    *str = '\0';
120    for (; *av; av++) {
121        (void) Strcat(str, *av);
122        if (av[1])
123            (void) Strcat(str, STRspace);
124    }
125}
126
127int
128blklen(av)
129    register Char **av;
130{
131    register int i = 0;
132
133    while (*av++)
134        i++;
135    return (i);
136}
137
138Char  **
139blkcpy(oav, bv)
140    Char  **oav;
141    register Char **bv;
142{
143    register Char **av = oav;
144
145    while ((*av++ = *bv++) != NULL)
146        continue;
147    return (oav);
148}
149
150static Char  **
151blkcat(up, vp)
152    Char  **up, **vp;
153{
154
155    (void) blkcpy(blkend(up), vp);
156    return (up);
157}
158
159void
160blkfree(av0)
161    Char  **av0;
162{
163    register Char **av = av0;
164
165    if (!av0)
166        return;
167    for (; *av; av++)
168        xfree((ptr_t) * av);
169    xfree((ptr_t) av0);
170}
171
172Char  **
173saveblk(v)
174    register Char **v;
175{
176    register Char **newv =
177    (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
178    Char  **onewv = newv;
179
180    while (*v)
181        *newv++ = Strsave(*v++);
182    return (onewv);
183}
184
185#if !defined(SHORT_STRINGS) && !defined(POSIX)
186char   *
187strstr(s, t)
188    register const char *s, *t;
189{
190    do {
191        register const char *ss = s;
192        register const char *tt = t;
193
194        do
195            if (*tt == '\0')
196                return ((char *) s);
197        while (*ss++ == *tt++);
198    } while (*s++ != '\0');
199    return (NULL);
200}
201
202#endif /* !SHORT_STRINGS && !POSIX */
203
204#ifndef SHORT_STRINGS
205char   *
206strspl(cp, dp)
207    char   *cp, *dp;
208{
209    char   *ep;
210    register char *p, *q;
211
212    if (!cp)
213        cp = "";
214    if (!dp)
215        dp = "";
216    for (p = cp; *p++ != '\0';)
217        continue;
218    for (q = dp; *q++ != '\0';)
219        continue;
220    ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
221    for (p = ep, q = cp; (*p++ = *q++) != '\0';)
222        continue;
223    for (p--, q = dp; (*p++ = *q++) != '\0';)
224        continue;
225    return (ep);
226}
227
228#endif /* !SHORT_STRINGS */
229
230Char  **
231blkspl(up, vp)
232    register Char **up, **vp;
233{
234    register Char **wp =
235    (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
236                      sizeof(Char **));
237
238    (void) blkcpy(wp, up);
239    return (blkcat(wp, vp));
240}
241
242Char
243lastchr(cp)
244    register Char *cp;
245{
246
247    if (!cp)
248        return (0);
249    if (!*cp)
250        return (0);
251    while (cp[1])
252        cp++;
253    return (*cp);
254}
255
256/*
257 * This routine is called after an error to close up
258 * any units which may have been left open accidentally.
259 */
260void
261closem()
262{
263    register int f;
264
265#ifdef YPBUGS
266    /* suggested by Justin Bur; thanks to Karl Kleinpaste */
267    fix_yp_bugs();
268#endif /* YPBUGS */
269    for (f = 0; f < NOFILE; f++)
270        if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
271            f != FSHTTY
272#ifdef MALLOC_TRACE
273            && f != 25
274#endif /* MALLOC_TRACE */
275            )
276          {
277            (void) close(f);
278#ifdef NISPLUS
279            if(f < 3)
280                (void) open(_PATH_DEVNULL, O_RDONLY);
281#endif /* NISPLUS */
282          }
283}
284
285#ifndef CLOSE_ON_EXEC
286/*
287 * Close files before executing a file.
288 * We could be MUCH more intelligent, since (on a version 7 system)
289 * we need only close files here during a source, the other
290 * shell fd's being in units 16-19 which are closed automatically!
291 */
292void
293closech()
294{
295    register int f;
296
297    if (didcch)
298        return;
299    didcch = 1;
300    SHIN = 0;
301    SHOUT = 1;
302    SHDIAG = 2;
303    OLDSTD = 0;
304    isoutatty = isatty(SHOUT);
305    isdiagatty = isatty(SHDIAG);
306    for (f = 3; f < NOFILE; f++)
307        (void) close(f);
308}
309
310#endif /* CLOSE_ON_EXEC */
311
312void
313donefds()
314{
315
316    (void) close(0);
317    (void) close(1);
318    (void) close(2);
319    didfds = 0;
320#ifdef NISPLUS
321    {
322        int fd = open(_PATH_DEVNULL, O_RDONLY);
323        (void) dup2(fd, 1);
324        (void) dup2(fd, 2);
325        if (fd != 0) {
326            (void) dup2(fd, 0);
327            (void) close(fd);
328        }
329    }
330#endif /*NISPLUS*/   
331}
332
333/*
334 * Move descriptor i to j.
335 * If j is -1 then we just want to get i to a safe place,
336 * i.e. to a unit > 2.  This also happens in dcopy.
337 */
338int
339dmove(i, j)
340    register int i, j;
341{
342
343    if (i == j || i < 0)
344        return (i);
345#ifdef HAVEDUP2
346    if (j >= 0) {
347        (void) dup2(i, j);
348        if (j != i)
349            (void) close(i);
350        return (j);
351    }
352#endif
353    j = dcopy(i, j);
354    if (j != i)
355        (void) close(i);
356    return (j);
357}
358
359int
360dcopy(i, j)
361    register int i, j;
362{
363
364    if (i == j || i < 0 || (j < 0 && i > 2))
365        return (i);
366    if (j >= 0) {
367#ifdef HAVEDUP2
368        (void) dup2(i, j);
369        return (j);
370#else
371        (void) close(j);
372#endif
373    }
374    return (renum(i, j));
375}
376
377static int
378renum(i, j)
379    register int i, j;
380{
381    register int k = dup(i);
382
383    if (k < 0)
384        return (-1);
385    if (j == -1 && k > 2)
386        return (k);
387    if (k != j) {
388        j = renum(k, j);
389        (void) close(k);
390        return (j);
391    }
392    return (k);
393}
394
395/*
396 * Left shift a command argument list, discarding
397 * the first c arguments.  Used in "shift" commands
398 * as well as by commands like "repeat".
399 */
400void
401lshift(v, c)
402    register Char **v;
403    register int c;
404{
405    register Char **u;
406
407    for (u = v; *u && --c >= 0; u++)
408        xfree((ptr_t) *u);
409    (void) blkcpy(v, u);
410}
411
412int
413number(cp)
414    Char   *cp;
415{
416    if (!cp)
417        return (0);
418    if (*cp == '-') {
419        cp++;
420        if (!Isdigit(*cp))
421            return (0);
422        cp++;
423    }
424    while (*cp && Isdigit(*cp))
425        cp++;
426    return (*cp == 0);
427}
428
429Char  **
430copyblk(v)
431    register Char **v;
432{
433    register Char **nv =
434    (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
435
436    return (blkcpy(nv, v));
437}
438
439#ifndef SHORT_STRINGS
440char   *
441strend(cp)
442    register char *cp;
443{
444    if (!cp)
445        return (cp);
446    while (*cp)
447        cp++;
448    return (cp);
449}
450
451#endif /* SHORT_STRINGS */
452
453Char   *
454strip(cp)
455    Char   *cp;
456{
457    register Char *dp = cp;
458
459    if (!cp)
460        return (cp);
461    while ((*dp++ &= TRIM) != '\0')
462        continue;
463    return (cp);
464}
465
466Char   *
467quote(cp)
468    Char   *cp;
469{
470    register Char *dp = cp;
471
472    if (!cp)
473        return (cp);
474    while (*dp != '\0')
475        *dp++ |= QUOTE;
476    return (cp);
477}
478
479Char   *
480quote_meta(d, s)
481    Char   *d;
482    const Char   *s;
483{
484    Char *r = d;
485    while (*s != '\0') {
486        if (cmap(*s, _META | _DOL | _QF | _QB | _ESC | _GLOB))
487                *d++ = '\\';
488        *d++ = *s++;
489    }
490    *d = '\0';
491    return r;
492}
493
494void
495udvar(name)
496    Char   *name;
497{
498
499    setname(short2str(name));
500    stderror(ERR_NAME | ERR_UNDVAR);
501}
502
503int
504prefix(sub, str)
505    register Char *sub, *str;
506{
507
508    for (;;) {
509        if (*sub == 0)
510            return (1);
511        if (*str == 0)
512            return (0);
513        if ((*sub++ & TRIM) != (*str++ & TRIM))
514            return (0);
515    }
516}
Note: See TracBrowser for help on using the repository browser.