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

Revision 22036, 8.5 KB checked in by ghudson, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22035, 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.3 2005-06-03 14:35:17 ghudson 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. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33#include "sh.h"
34
35RCSID("$Id: sh.misc.c,v 1.1.1.3 2005-06-03 14:35:17 ghudson Exp $")
36
37static  int     renum   __P((int, int));
38static  Char  **blkend  __P((Char **));
39static  Char  **blkcat  __P((Char **, Char **));
40
41/*
42 * C Shell
43 */
44
45int
46any(s, c)
47    const char *s;
48    Char c;
49{
50    if (!s)
51        return (0);             /* Check for nil pointer */
52    while (*s)
53        if ((Char)*s++ == c)
54            return (1);
55    return (0);
56}
57
58void
59setzero(cp, i)
60    char   *cp;
61    int     i;
62{
63    if (i != 0)
64        do
65            *cp++ = 0;
66        while (--i);
67}
68
69char   *
70strsave(s)
71    const char *s;
72{
73    char   *n, *r;
74    const char *p;
75
76    if (s == NULL)
77        s = "";
78    for (p = s; *p++ != '\0';)
79        continue;
80    r = n = (char *) xmalloc((size_t)((((const char *) p) - s) * sizeof(char)));
81    while ((*n++ = *s++) != '\0')
82        continue;
83    return (r);
84}
85
86static Char  **
87blkend(up)
88    Char **up;
89{
90
91    while (*up)
92        up++;
93    return (up);
94}
95
96
97void
98blkpr(av)
99    Char **av;
100{
101
102    for (; *av; av++) {
103        xprintf("%S", *av);
104        if (av[1])
105            xprintf(" ");
106    }
107}
108
109void
110blkexpand(av, str)
111    Char **av;
112    Char *str;
113{
114    *str = '\0';
115    for (; *av; av++) {
116        (void) Strcat(str, *av);
117        if (av[1])
118            (void) Strcat(str, STRspace);
119    }
120}
121
122int
123blklen(av)
124    Char **av;
125{
126    int i = 0;
127
128    while (*av++)
129        i++;
130    return (i);
131}
132
133Char  **
134blkcpy(oav, bv)
135    Char  **oav;
136    Char **bv;
137{
138    Char **av = oav;
139
140    while ((*av++ = *bv++) != NULL)
141        continue;
142    return (oav);
143}
144
145static Char  **
146blkcat(up, vp)
147    Char  **up, **vp;
148{
149
150    (void) blkcpy(blkend(up), vp);
151    return (up);
152}
153
154void
155blkfree(av0)
156    Char  **av0;
157{
158    Char **av = av0;
159
160    if (!av0)
161        return;
162    for (; *av; av++)
163        xfree((ptr_t) * av);
164    xfree((ptr_t) av0);
165}
166
167Char  **
168saveblk(v)
169    Char **v;
170{
171    Char **newv =
172    (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
173    Char  **onewv = newv;
174
175    while (*v)
176        *newv++ = Strsave(*v++);
177    return (onewv);
178}
179
180#ifndef HAVE_STRSTR
181char   *
182strstr(s, t)
183    const char *s, *t;
184{
185    do {
186        const char *ss = s;
187        const char *tt = t;
188
189        do
190            if (*tt == '\0')
191                return ((char *) s);
192        while (*ss++ == *tt++);
193    } while (*s++ != '\0');
194    return (NULL);
195}
196#endif /* !HAVE_STRSTR */
197
198#ifndef SHORT_STRINGS
199char   *
200strspl(cp, dp)
201    const char *cp, *dp;
202{
203    char   *ep;
204    size_t cl, dl;
205
206    if (!cp)
207        cp = "";
208    if (!dp)
209        dp = "";
210    cl = strlen(cp);
211    dl = strlen(dp);
212    ep = (char *) xmalloc((cl + dl + 1) * sizeof(char));
213    memcpy(ep, cp, cl);
214    memcpy(ep + cl, dp, dl + 1);
215    return (ep);
216}
217
218#endif /* !SHORT_STRINGS */
219
220Char  **
221blkspl(up, vp)
222    Char **up, **vp;
223{
224    Char **wp =
225    (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
226                      sizeof(Char **));
227
228    (void) blkcpy(wp, up);
229    return (blkcat(wp, vp));
230}
231
232Char
233lastchr(cp)
234    Char *cp;
235{
236
237    if (!cp)
238        return (0);
239    if (!*cp)
240        return (0);
241    while (cp[1])
242        cp++;
243    return (*cp);
244}
245
246/*
247 * This routine is called after an error to close up
248 * any units which may have been left open accidentally.
249 */
250void
251closem()
252{
253    int f;
254
255#ifdef NLS_BUGS
256#ifdef NLS_CATALOGS
257    nlsclose();
258#endif /* NLS_CATALOGS */
259#endif /* NLS_BUGS */
260#ifdef YPBUGS
261    /* suggested by Justin Bur; thanks to Karl Kleinpaste */
262    fix_yp_bugs();
263#endif /* YPBUGS */
264    for (f = 0; f < NOFILE; f++)
265        if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
266            f != FSHTTY
267#ifdef MALLOC_TRACE
268            && f != 25
269#endif /* MALLOC_TRACE */
270            )
271          {
272            (void) close(f);
273#ifdef NISPLUS
274            if(f < 3)
275                (void) open(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE);
276#endif /* NISPLUS */
277          }
278#ifdef NLS_BUGS
279#ifdef NLS_CATALOGS
280    nlsinit();
281#endif /* NLS_CATALOGS */
282#endif /* NLS_BUGS */
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    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|O_LARGEFILE);
323        (void)dcopy(fd, 1);
324        (void)dcopy(fd, 2);
325        (void)dmove(fd, 0);
326    }
327#endif /*NISPLUS*/   
328}
329
330/*
331 * Move descriptor i to j.
332 * If j is -1 then we just want to get i to a safe place,
333 * i.e. to a unit > FSAFE.  This also happens in dcopy.
334 */
335int
336dmove(i, j)
337    int i, j;
338{
339
340    if (i == j || i < 0)
341        return (i);
342#ifdef HAVE_DUP2
343    if (j >= 0) {
344        (void) dup2(i, j);
345        if (j != i)
346            (void) close(i);
347        return (j);
348    }
349#endif
350    j = dcopy(i, j);
351    if (j != i)
352        (void) close(i);
353    return (j);
354}
355
356int
357dcopy(i, j)
358    int i, j;
359{
360
361    if (i == j || i < 0 || (j < 0 && i > FSAFE))
362        return (i);
363    if (j >= 0) {
364#ifdef HAVE_DUP2
365        (void) dup2(i, j);
366        return (j);
367#else
368        (void) close(j);
369#endif
370    }
371    return (renum(i, j));
372}
373
374static int
375renum(i, j)
376    int i, j;
377{
378    int k = dup(i);
379
380    if (k < 0)
381        return (-1);
382    if (j == -1 && k > FSAFE)
383        return (k);
384    if (k != j) {
385        j = renum(k, j);
386        (void) close(k);
387        return (j);
388    }
389    return (k);
390}
391
392/*
393 * Left shift a command argument list, discarding
394 * the first c arguments.  Used in "shift" commands
395 * as well as by commands like "repeat".
396 */
397void
398lshift(v, c)
399    Char **v;
400    int c;
401{
402    Char **u;
403
404    for (u = v; *u && --c >= 0; u++)
405        xfree((ptr_t) *u);
406    (void) blkcpy(v, u);
407}
408
409int
410number(cp)
411    Char   *cp;
412{
413    if (!cp)
414        return (0);
415    if (*cp == '-') {
416        cp++;
417        if (!Isdigit(*cp))
418            return (0);
419        cp++;
420    }
421    while (*cp && Isdigit(*cp))
422        cp++;
423    return (*cp == 0);
424}
425
426Char  **
427copyblk(v)
428    Char **v;
429{
430    Char **nv =
431    (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
432
433    return (blkcpy(nv, v));
434}
435
436#ifndef SHORT_STRINGS
437char   *
438strend(cp)
439    char *cp;
440{
441    if (!cp)
442        return (cp);
443    while (*cp)
444        cp++;
445    return (cp);
446}
447
448#endif /* SHORT_STRINGS */
449
450Char   *
451strip(cp)
452    Char   *cp;
453{
454    Char *dp = cp;
455
456    if (!cp)
457        return (cp);
458    while ((*dp++ &= TRIM) != '\0')
459        continue;
460    return (cp);
461}
462
463Char   *
464quote(cp)
465    Char   *cp;
466{
467    Char *dp = cp;
468
469    if (!cp)
470        return (cp);
471    while (*dp != '\0')
472        *dp++ |= QUOTE;
473    return (cp);
474}
475
476Char   *
477quote_meta(d, s)
478    Char   *d;
479    const Char   *s;
480{
481    Char *r = d;
482    while (*s != '\0') {
483        if (cmap(*s, _META | _DOL | _QF | _QB | _ESC | _GLOB))
484                *d++ = '\\';
485        *d++ = *s++;
486    }
487    *d = '\0';
488    return r;
489}
490
491void
492udvar(name)
493    Char   *name;
494{
495
496    setname(short2str(name));
497    stderror(ERR_NAME | ERR_UNDVAR);
498}
499
500int
501prefix(sub, str)
502    const Char *sub, *str;
503{
504
505    for (;;) {
506        if (*sub == 0)
507            return (1);
508        if (*str == 0)
509            return (0);
510        if ((*sub++ & TRIM) != (*str++ & TRIM))
511            return (0);
512    }
513}
Note: See TracBrowser for help on using the repository browser.