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