xref: /dragonfly/contrib/tcsh-6/sh.exp.c (revision d6ab524c)
17d8fb588SMatthias Schmidt /*
27d8fb588SMatthias Schmidt  * sh.exp.c: Expression evaluations
37d8fb588SMatthias Schmidt  */
47d8fb588SMatthias Schmidt /*-
57d8fb588SMatthias Schmidt  * Copyright (c) 1980, 1991 The Regents of the University of California.
67d8fb588SMatthias Schmidt  * All rights reserved.
77d8fb588SMatthias Schmidt  *
87d8fb588SMatthias Schmidt  * Redistribution and use in source and binary forms, with or without
97d8fb588SMatthias Schmidt  * modification, are permitted provided that the following conditions
107d8fb588SMatthias Schmidt  * are met:
117d8fb588SMatthias Schmidt  * 1. Redistributions of source code must retain the above copyright
127d8fb588SMatthias Schmidt  *    notice, this list of conditions and the following disclaimer.
137d8fb588SMatthias Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
147d8fb588SMatthias Schmidt  *    notice, this list of conditions and the following disclaimer in the
157d8fb588SMatthias Schmidt  *    documentation and/or other materials provided with the distribution.
167d8fb588SMatthias Schmidt  * 3. Neither the name of the University nor the names of its contributors
177d8fb588SMatthias Schmidt  *    may be used to endorse or promote products derived from this software
187d8fb588SMatthias Schmidt  *    without specific prior written permission.
197d8fb588SMatthias Schmidt  *
207d8fb588SMatthias Schmidt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
217d8fb588SMatthias Schmidt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
227d8fb588SMatthias Schmidt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
237d8fb588SMatthias Schmidt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
247d8fb588SMatthias Schmidt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
257d8fb588SMatthias Schmidt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
267d8fb588SMatthias Schmidt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
277d8fb588SMatthias Schmidt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
287d8fb588SMatthias Schmidt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
297d8fb588SMatthias Schmidt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
307d8fb588SMatthias Schmidt  * SUCH DAMAGE.
317d8fb588SMatthias Schmidt  */
327d8fb588SMatthias Schmidt #include "sh.h"
337d8fb588SMatthias Schmidt #include "tw.h"
347d8fb588SMatthias Schmidt 
357d8fb588SMatthias Schmidt /*
367d8fb588SMatthias Schmidt  * C shell
377d8fb588SMatthias Schmidt  */
387d8fb588SMatthias Schmidt 
397d8fb588SMatthias Schmidt #define	ADDOP	1
407d8fb588SMatthias Schmidt #define	MULOP	2
417d8fb588SMatthias Schmidt #define	EQOP	4
427d8fb588SMatthias Schmidt #define	RELOP	8
437d8fb588SMatthias Schmidt #define	RESTOP	16
447d8fb588SMatthias Schmidt #define	ANYOP	31
457d8fb588SMatthias Schmidt 
467d8fb588SMatthias Schmidt #define	EQEQ	1
477d8fb588SMatthias Schmidt #define	GTR	2
487d8fb588SMatthias Schmidt #define	LSS	4
497d8fb588SMatthias Schmidt #define	NOTEQ	6
507d8fb588SMatthias Schmidt #define EQMATCH 7
517d8fb588SMatthias Schmidt #define NOTEQMATCH 8
527d8fb588SMatthias Schmidt 
537d8fb588SMatthias Schmidt static	int	   sh_access	(const Char *, int);
5494afa86dSJohn Marino static	tcsh_number_t  exp1		(Char ***, int);
5594afa86dSJohn Marino static	tcsh_number_t  exp2x	(Char ***, int);
5694afa86dSJohn Marino static	tcsh_number_t  exp2a	(Char ***, int);
5794afa86dSJohn Marino static	tcsh_number_t  exp2b	(Char ***, int);
5894afa86dSJohn Marino static	tcsh_number_t  exp2c	(Char ***, int);
597d8fb588SMatthias Schmidt static	Char 	  *exp3		(Char ***, int);
607d8fb588SMatthias Schmidt static	Char 	  *exp3a	(Char ***, int);
617d8fb588SMatthias Schmidt static	Char 	  *exp4		(Char ***, int);
627d8fb588SMatthias Schmidt static	Char 	  *exp5		(Char ***, int);
637d8fb588SMatthias Schmidt static	Char 	  *exp6		(Char ***, int);
647d8fb588SMatthias Schmidt static	void	   evalav	(Char **);
657d8fb588SMatthias Schmidt static	int	   isa		(Char *, int);
6694afa86dSJohn Marino static	tcsh_number_t  egetn	(const Char *);
677d8fb588SMatthias Schmidt 
687d8fb588SMatthias Schmidt #ifdef EDEBUG
6957e3f2b5SSimon 'corecode' Schubert static	void	   etracc	(const char *, const Char *, Char ***);
7094afa86dSJohn Marino static	void	   etraci	(const char *, tcsh_number_t, Char ***);
717d8fb588SMatthias Schmidt #else /* !EDEBUG */
727d8fb588SMatthias Schmidt #define etracc(A, B, C) ((void)0)
737d8fb588SMatthias Schmidt #define etraci(A, B, C) ((void)0)
747d8fb588SMatthias Schmidt #endif /* !EDEBUG */
757d8fb588SMatthias Schmidt 
767d8fb588SMatthias Schmidt /*
777d8fb588SMatthias Schmidt  * shell access function according to POSIX and non POSIX
787d8fb588SMatthias Schmidt  * From Beto Appleton (beto@aixwiz.aix.ibm.com)
797d8fb588SMatthias Schmidt  */
807d8fb588SMatthias Schmidt static int
sh_access(const Char * fname,int mode)817d8fb588SMatthias Schmidt sh_access(const Char *fname, int mode)
827d8fb588SMatthias Schmidt {
837d8fb588SMatthias Schmidt #if defined(POSIX) && !defined(USE_ACCESS)
847d8fb588SMatthias Schmidt     struct stat     statb;
857d8fb588SMatthias Schmidt #endif /* POSIX */
867d8fb588SMatthias Schmidt     char *name = short2str(fname);
877d8fb588SMatthias Schmidt 
887d8fb588SMatthias Schmidt     if (*name == '\0')
897d8fb588SMatthias Schmidt 	return 1;
907d8fb588SMatthias Schmidt 
917d8fb588SMatthias Schmidt #if !defined(POSIX) || defined(USE_ACCESS)
927d8fb588SMatthias Schmidt     return access(name, mode);
937d8fb588SMatthias Schmidt #else /* POSIX */
947d8fb588SMatthias Schmidt 
957d8fb588SMatthias Schmidt     /*
967d8fb588SMatthias Schmidt      * POSIX 1003.2-d11.2
977d8fb588SMatthias Schmidt      *	-r file		True if file exists and is readable.
987d8fb588SMatthias Schmidt      *	-w file		True if file exists and is writable.
997d8fb588SMatthias Schmidt      *			True shall indicate only that the write flag is on.
1007d8fb588SMatthias Schmidt      *			The file shall not be writable on a read-only file
1017d8fb588SMatthias Schmidt      *			system even if this test indicates true.
1027d8fb588SMatthias Schmidt      *	-x file		True if file exists and is executable.
1037d8fb588SMatthias Schmidt      *			True shall indicate only that the execute flag is on.
1047d8fb588SMatthias Schmidt      *			If file is a directory, true indicates that the file
1057d8fb588SMatthias Schmidt      *			can be searched.
1067d8fb588SMatthias Schmidt      */
1077d8fb588SMatthias Schmidt     if (mode != W_OK && mode != X_OK)
1087d8fb588SMatthias Schmidt 	return access(name, mode);
1097d8fb588SMatthias Schmidt 
1107d8fb588SMatthias Schmidt     if (stat(name, &statb) == -1)
1117d8fb588SMatthias Schmidt 	return 1;
1127d8fb588SMatthias Schmidt 
1137d8fb588SMatthias Schmidt     if (access(name, mode) == 0) {
1147d8fb588SMatthias Schmidt #ifdef S_ISDIR
1157d8fb588SMatthias Schmidt 	if (S_ISDIR(statb.st_mode) && mode == X_OK)
1167d8fb588SMatthias Schmidt 	    return 0;
1177d8fb588SMatthias Schmidt #endif /* S_ISDIR */
1187d8fb588SMatthias Schmidt 
1197d8fb588SMatthias Schmidt 	/* root needs permission for someone */
1207d8fb588SMatthias Schmidt 	switch (mode) {
1217d8fb588SMatthias Schmidt 	case W_OK:
1227d8fb588SMatthias Schmidt 	    mode = S_IWUSR | S_IWGRP | S_IWOTH;
1237d8fb588SMatthias Schmidt 	    break;
1247d8fb588SMatthias Schmidt 	case X_OK:
1257d8fb588SMatthias Schmidt 	    mode = S_IXUSR | S_IXGRP | S_IXOTH;
1267d8fb588SMatthias Schmidt 	    break;
1277d8fb588SMatthias Schmidt 	default:
1287d8fb588SMatthias Schmidt 	    abort();
1297d8fb588SMatthias Schmidt 	    break;
1307d8fb588SMatthias Schmidt 	}
1317d8fb588SMatthias Schmidt 
1327d8fb588SMatthias Schmidt     }
1337d8fb588SMatthias Schmidt 
1347d8fb588SMatthias Schmidt     else if (euid == statb.st_uid)
1357d8fb588SMatthias Schmidt 	mode <<= 6;
1367d8fb588SMatthias Schmidt 
1377d8fb588SMatthias Schmidt     else if (egid == statb.st_gid)
1387d8fb588SMatthias Schmidt 	mode <<= 3;
1397d8fb588SMatthias Schmidt 
1407d8fb588SMatthias Schmidt # ifdef NGROUPS_MAX
1417d8fb588SMatthias Schmidt     else {
1427d8fb588SMatthias Schmidt 	/* you can be in several groups */
1437d8fb588SMatthias Schmidt 	long	n;
1447d8fb588SMatthias Schmidt 	GETGROUPS_T *groups;
1457d8fb588SMatthias Schmidt 
1467d8fb588SMatthias Schmidt 	/*
1477d8fb588SMatthias Schmidt 	 * Try these things to find a positive maximum groups value:
1487d8fb588SMatthias Schmidt 	 *   1) sysconf(_SC_NGROUPS_MAX)
1497d8fb588SMatthias Schmidt 	 *   2) NGROUPS_MAX
1507d8fb588SMatthias Schmidt 	 *   3) getgroups(0, unused)
1517d8fb588SMatthias Schmidt 	 * Then allocate and scan the groups array if one of these worked.
1527d8fb588SMatthias Schmidt 	 */
1537d8fb588SMatthias Schmidt #  if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX)
1547d8fb588SMatthias Schmidt 	if ((n = sysconf(_SC_NGROUPS_MAX)) == -1)
1557d8fb588SMatthias Schmidt #  endif /* _SC_NGROUPS_MAX */
1567d8fb588SMatthias Schmidt 	    n = NGROUPS_MAX;
1577d8fb588SMatthias Schmidt 	if (n <= 0)
1587d8fb588SMatthias Schmidt 	    n = getgroups(0, (GETGROUPS_T *) NULL);
1597d8fb588SMatthias Schmidt 
1607d8fb588SMatthias Schmidt 	if (n > 0) {
1617d8fb588SMatthias Schmidt 	    groups = xmalloc(n * sizeof(*groups));
1627d8fb588SMatthias Schmidt 	    n = getgroups((int) n, groups);
1637d8fb588SMatthias Schmidt 	    while (--n >= 0)
1647d8fb588SMatthias Schmidt 		if (groups[n] == statb.st_gid) {
1657d8fb588SMatthias Schmidt 		    mode <<= 3;
1667d8fb588SMatthias Schmidt 		    break;
1677d8fb588SMatthias Schmidt 		}
16860962bbcSJohn Marino 	    xfree(groups);
1697d8fb588SMatthias Schmidt 	}
1707d8fb588SMatthias Schmidt     }
1717d8fb588SMatthias Schmidt # endif /* NGROUPS_MAX */
1727d8fb588SMatthias Schmidt 
1737d8fb588SMatthias Schmidt     if (statb.st_mode & mode)
1747d8fb588SMatthias Schmidt 	return 0;
1757d8fb588SMatthias Schmidt     else
1767d8fb588SMatthias Schmidt 	return 1;
1777d8fb588SMatthias Schmidt #endif /* !POSIX */
1787d8fb588SMatthias Schmidt }
1797d8fb588SMatthias Schmidt 
18094afa86dSJohn Marino tcsh_number_t
expr(Char *** vp)1817d8fb588SMatthias Schmidt expr(Char ***vp)
1827d8fb588SMatthias Schmidt {
1837d8fb588SMatthias Schmidt     return (exp0(vp, 0));
1847d8fb588SMatthias Schmidt }
1857d8fb588SMatthias Schmidt 
18694afa86dSJohn Marino tcsh_number_t
exp0(Char *** vp,int ignore)1877d8fb588SMatthias Schmidt exp0(Char ***vp, int ignore)
1887d8fb588SMatthias Schmidt {
18994afa86dSJohn Marino     tcsh_number_t p1 = exp1(vp, ignore);
1907d8fb588SMatthias Schmidt 
1917d8fb588SMatthias Schmidt     etraci("exp0 p1", p1, vp);
19257e3f2b5SSimon 'corecode' Schubert     while (**vp && eq(**vp, STRor2)) {
1937d8fb588SMatthias Schmidt 	int p2;
1947d8fb588SMatthias Schmidt 
1957d8fb588SMatthias Schmidt 	(*vp)++;
19657e3f2b5SSimon 'corecode' Schubert 
19757e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
19857e3f2b5SSimon 'corecode' Schubert 	    exp0(vp, (ignore & TEXP_IGNORE) || p1) :
19957e3f2b5SSimon 'corecode' Schubert 	    exp1(vp, (ignore & TEXP_IGNORE) || p1);
20057e3f2b5SSimon 'corecode' Schubert 	if (compat_expr || !(ignore & TEXP_IGNORE))
20157e3f2b5SSimon 'corecode' Schubert 	    p1 = (p1 || p2);
20257e3f2b5SSimon 'corecode' Schubert 	etraci("exp0 p1", p1, vp);
20357e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
20457e3f2b5SSimon 'corecode' Schubert 	    break;
2057d8fb588SMatthias Schmidt     }
2067d8fb588SMatthias Schmidt     return (p1);
2077d8fb588SMatthias Schmidt }
2087d8fb588SMatthias Schmidt 
20994afa86dSJohn Marino static tcsh_number_t
exp1(Char *** vp,int ignore)2107d8fb588SMatthias Schmidt exp1(Char ***vp, int ignore)
2117d8fb588SMatthias Schmidt {
21294afa86dSJohn Marino     tcsh_number_t p1 = exp2x(vp, ignore);
2137d8fb588SMatthias Schmidt 
2147d8fb588SMatthias Schmidt     etraci("exp1 p1", p1, vp);
21557e3f2b5SSimon 'corecode' Schubert     while (**vp && eq(**vp, STRand2)) {
21694afa86dSJohn Marino 	tcsh_number_t p2;
2177d8fb588SMatthias Schmidt 
2187d8fb588SMatthias Schmidt 	(*vp)++;
21957e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
22057e3f2b5SSimon 'corecode' Schubert 	    exp1(vp, (ignore & TEXP_IGNORE) || !p1) :
22157e3f2b5SSimon 'corecode' Schubert 	    exp2x(vp, (ignore & TEXP_IGNORE) || !p1);
22257e3f2b5SSimon 'corecode' Schubert 
2237d8fb588SMatthias Schmidt 	etraci("exp1 p2", p2, vp);
22457e3f2b5SSimon 'corecode' Schubert 	if (compat_expr || !(ignore & TEXP_IGNORE))
22557e3f2b5SSimon 'corecode' Schubert 	    p1 = (p1 && p2);
22657e3f2b5SSimon 'corecode' Schubert 	etraci("exp1 p1", p1, vp);
22757e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
22857e3f2b5SSimon 'corecode' Schubert 	    break;
2297d8fb588SMatthias Schmidt     }
2307d8fb588SMatthias Schmidt     return (p1);
2317d8fb588SMatthias Schmidt }
2327d8fb588SMatthias Schmidt 
23394afa86dSJohn Marino static tcsh_number_t
exp2x(Char *** vp,int ignore)2347d8fb588SMatthias Schmidt exp2x(Char ***vp, int ignore)
2357d8fb588SMatthias Schmidt {
23694afa86dSJohn Marino     tcsh_number_t p1 = exp2a(vp, ignore);
2377d8fb588SMatthias Schmidt 
23857e3f2b5SSimon 'corecode' Schubert     etraci("exp2x p1", p1, vp);
23957e3f2b5SSimon 'corecode' Schubert     while (**vp && eq(**vp, STRor)) {
24094afa86dSJohn Marino 	tcsh_number_t p2;
2417d8fb588SMatthias Schmidt 
2427d8fb588SMatthias Schmidt 	(*vp)++;
24357e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
24457e3f2b5SSimon 'corecode' Schubert 	    exp2x(vp, ignore) :
24557e3f2b5SSimon 'corecode' Schubert 	    exp2a(vp, ignore);
24657e3f2b5SSimon 'corecode' Schubert 	etraci("exp2x p2", p2, vp);
24757e3f2b5SSimon 'corecode' Schubert 	if (compat_expr || !(ignore & TEXP_IGNORE))
24857e3f2b5SSimon 'corecode' Schubert 		p1 = (p1 | p2);
24957e3f2b5SSimon 'corecode' Schubert 	etraci("exp2x p1", p1, vp);
25057e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
25157e3f2b5SSimon 'corecode' Schubert 	    break;
2527d8fb588SMatthias Schmidt     }
2537d8fb588SMatthias Schmidt     return (p1);
2547d8fb588SMatthias Schmidt }
2557d8fb588SMatthias Schmidt 
25694afa86dSJohn Marino static tcsh_number_t
exp2a(Char *** vp,int ignore)2577d8fb588SMatthias Schmidt exp2a(Char ***vp, int ignore)
2587d8fb588SMatthias Schmidt {
25994afa86dSJohn Marino     tcsh_number_t p1 = exp2b(vp, ignore);
2607d8fb588SMatthias Schmidt 
2617d8fb588SMatthias Schmidt     etraci("exp2a p1", p1, vp);
26257e3f2b5SSimon 'corecode' Schubert     while (**vp && eq(**vp, STRcaret)) {
26394afa86dSJohn Marino 	tcsh_number_t p2;
2647d8fb588SMatthias Schmidt 
2657d8fb588SMatthias Schmidt 	(*vp)++;
26657e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
26757e3f2b5SSimon 'corecode' Schubert 	    exp2a(vp, ignore) :
26857e3f2b5SSimon 'corecode' Schubert 	    exp2b(vp, ignore);
2697d8fb588SMatthias Schmidt 	etraci("exp2a p2", p2, vp);
27057e3f2b5SSimon 'corecode' Schubert 	if (compat_expr || !(ignore & TEXP_IGNORE))
27157e3f2b5SSimon 'corecode' Schubert 	    p1 = (p1 ^ p2);
27257e3f2b5SSimon 'corecode' Schubert 	etraci("exp2a p1", p1, vp);
27357e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
27457e3f2b5SSimon 'corecode' Schubert 	    break;
2757d8fb588SMatthias Schmidt     }
2767d8fb588SMatthias Schmidt     return (p1);
2777d8fb588SMatthias Schmidt }
2787d8fb588SMatthias Schmidt 
27994afa86dSJohn Marino static tcsh_number_t
exp2b(Char *** vp,int ignore)2807d8fb588SMatthias Schmidt exp2b(Char ***vp, int ignore)
2817d8fb588SMatthias Schmidt {
28294afa86dSJohn Marino     tcsh_number_t p1 = exp2c(vp, ignore);
2837d8fb588SMatthias Schmidt 
2847d8fb588SMatthias Schmidt     etraci("exp2b p1", p1, vp);
28557e3f2b5SSimon 'corecode' Schubert     while (**vp && eq(**vp, STRand)) {
28694afa86dSJohn Marino 	tcsh_number_t p2;
2877d8fb588SMatthias Schmidt 
2887d8fb588SMatthias Schmidt 	(*vp)++;
28957e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
29057e3f2b5SSimon 'corecode' Schubert 	    exp2b(vp, ignore) :
29157e3f2b5SSimon 'corecode' Schubert 	    exp2c(vp, ignore);
2927d8fb588SMatthias Schmidt 	etraci("exp2b p2", p2, vp);
29357e3f2b5SSimon 'corecode' Schubert 	if (compat_expr || !(ignore & TEXP_IGNORE))
29457e3f2b5SSimon 'corecode' Schubert 	    p1 = (p1 & p2);
29557e3f2b5SSimon 'corecode' Schubert 	etraci("exp2b p1", p1, vp);
29657e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
29757e3f2b5SSimon 'corecode' Schubert 	    break;
2987d8fb588SMatthias Schmidt     }
2997d8fb588SMatthias Schmidt     return (p1);
3007d8fb588SMatthias Schmidt }
3017d8fb588SMatthias Schmidt 
30294afa86dSJohn Marino static tcsh_number_t
exp2c(Char *** vp,int ignore)3037d8fb588SMatthias Schmidt exp2c(Char ***vp, int ignore)
3047d8fb588SMatthias Schmidt {
3057d8fb588SMatthias Schmidt     Char *p1 = exp3(vp, ignore);
3067d8fb588SMatthias Schmidt     Char *p2;
30794afa86dSJohn Marino     tcsh_number_t i;
3087d8fb588SMatthias Schmidt 
3097d8fb588SMatthias Schmidt     cleanup_push(p1, xfree);
3107d8fb588SMatthias Schmidt     etracc("exp2c p1", p1, vp);
3117d8fb588SMatthias Schmidt     if ((i = isa(**vp, EQOP)) != 0) {
3127d8fb588SMatthias Schmidt 	(*vp)++;
3137d8fb588SMatthias Schmidt 	if (i == EQMATCH || i == NOTEQMATCH)
3147d8fb588SMatthias Schmidt 	    ignore |= TEXP_NOGLOB;
3157d8fb588SMatthias Schmidt 	p2 = exp3(vp, ignore);
3167d8fb588SMatthias Schmidt 	cleanup_push(p2, xfree);
3177d8fb588SMatthias Schmidt 	etracc("exp2c p2", p2, vp);
3187d8fb588SMatthias Schmidt 	if (!(ignore & TEXP_IGNORE))
31960962bbcSJohn Marino 	    switch ((int)i) {
3207d8fb588SMatthias Schmidt 
3217d8fb588SMatthias Schmidt 	    case EQEQ:
3227d8fb588SMatthias Schmidt 		i = eq(p1, p2);
3237d8fb588SMatthias Schmidt 		break;
3247d8fb588SMatthias Schmidt 
3257d8fb588SMatthias Schmidt 	    case NOTEQ:
3267d8fb588SMatthias Schmidt 		i = !eq(p1, p2);
3277d8fb588SMatthias Schmidt 		break;
3287d8fb588SMatthias Schmidt 
3297d8fb588SMatthias Schmidt 	    case EQMATCH:
3307d8fb588SMatthias Schmidt 		i = Gmatch(p1, p2);
3317d8fb588SMatthias Schmidt 		break;
3327d8fb588SMatthias Schmidt 
3337d8fb588SMatthias Schmidt 	    case NOTEQMATCH:
3347d8fb588SMatthias Schmidt 		i = !Gmatch(p1, p2);
3357d8fb588SMatthias Schmidt 		break;
3367d8fb588SMatthias Schmidt 	    }
3377d8fb588SMatthias Schmidt 	cleanup_until(p1);
3387d8fb588SMatthias Schmidt 	return (i);
3397d8fb588SMatthias Schmidt     }
3407d8fb588SMatthias Schmidt     i = egetn(p1);
3417d8fb588SMatthias Schmidt     cleanup_until(p1);
3427d8fb588SMatthias Schmidt     return (i);
3437d8fb588SMatthias Schmidt }
3447d8fb588SMatthias Schmidt 
3457d8fb588SMatthias Schmidt static Char *
exp3(Char *** vp,int ignore)3467d8fb588SMatthias Schmidt exp3(Char ***vp, int ignore)
3477d8fb588SMatthias Schmidt {
3487d8fb588SMatthias Schmidt     Char *p1, *p2;
34994afa86dSJohn Marino     tcsh_number_t i;
3507d8fb588SMatthias Schmidt 
3517d8fb588SMatthias Schmidt     p1 = exp3a(vp, ignore);
3527d8fb588SMatthias Schmidt     etracc("exp3 p1", p1, vp);
35357e3f2b5SSimon 'corecode' Schubert     while ((i = isa(**vp, RELOP)) != 0) {
3547d8fb588SMatthias Schmidt 	(*vp)++;
3557d8fb588SMatthias Schmidt 	if (**vp && eq(**vp, STRequal))
3567d8fb588SMatthias Schmidt 	    i |= 1, (*vp)++;
3577d8fb588SMatthias Schmidt 	cleanup_push(p1, xfree);
35857e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
35957e3f2b5SSimon 'corecode' Schubert 	    exp3(vp, ignore) :
36057e3f2b5SSimon 'corecode' Schubert 	    exp3a(vp, ignore);
3617d8fb588SMatthias Schmidt 	cleanup_push(p2, xfree);
3627d8fb588SMatthias Schmidt 	etracc("exp3 p2", p2, vp);
3637d8fb588SMatthias Schmidt 	if (!(ignore & TEXP_IGNORE))
36460962bbcSJohn Marino 	    switch ((int)i) {
3657d8fb588SMatthias Schmidt 
3667d8fb588SMatthias Schmidt 	    case GTR:
3677d8fb588SMatthias Schmidt 		i = egetn(p1) > egetn(p2);
3687d8fb588SMatthias Schmidt 		break;
3697d8fb588SMatthias Schmidt 
3707d8fb588SMatthias Schmidt 	    case GTR | 1:
3717d8fb588SMatthias Schmidt 		i = egetn(p1) >= egetn(p2);
3727d8fb588SMatthias Schmidt 		break;
3737d8fb588SMatthias Schmidt 
3747d8fb588SMatthias Schmidt 	    case LSS:
3757d8fb588SMatthias Schmidt 		i = egetn(p1) < egetn(p2);
3767d8fb588SMatthias Schmidt 		break;
3777d8fb588SMatthias Schmidt 
3787d8fb588SMatthias Schmidt 	    case LSS | 1:
3797d8fb588SMatthias Schmidt 		i = egetn(p1) <= egetn(p2);
3807d8fb588SMatthias Schmidt 		break;
3817d8fb588SMatthias Schmidt 	    }
3827d8fb588SMatthias Schmidt 	cleanup_until(p1);
38357e3f2b5SSimon 'corecode' Schubert 	p1 = putn(i);
38457e3f2b5SSimon 'corecode' Schubert 	etracc("exp3 p1", p1, vp);
38557e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
38657e3f2b5SSimon 'corecode' Schubert 	    break;
3877d8fb588SMatthias Schmidt     }
3887d8fb588SMatthias Schmidt     return (p1);
3897d8fb588SMatthias Schmidt }
3907d8fb588SMatthias Schmidt 
3917d8fb588SMatthias Schmidt static Char *
exp3a(Char *** vp,int ignore)3927d8fb588SMatthias Schmidt exp3a(Char ***vp, int ignore)
3937d8fb588SMatthias Schmidt {
3947d8fb588SMatthias Schmidt     Char *p1, *p2;
3957d8fb588SMatthias Schmidt     const Char *op;
39694afa86dSJohn Marino     tcsh_number_t i;
3977d8fb588SMatthias Schmidt 
3987d8fb588SMatthias Schmidt     p1 = exp4(vp, ignore);
3997d8fb588SMatthias Schmidt     etracc("exp3a p1", p1, vp);
4007d8fb588SMatthias Schmidt     op = **vp;
4017d8fb588SMatthias Schmidt     if (op && any("<>", op[0]) && op[0] == op[1]) {
4027d8fb588SMatthias Schmidt 	(*vp)++;
4037d8fb588SMatthias Schmidt 	cleanup_push(p1, xfree);
40457e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
40557e3f2b5SSimon 'corecode' Schubert 	    exp3a(vp, ignore) :
40657e3f2b5SSimon 'corecode' Schubert 	    exp4(vp, ignore);
4077d8fb588SMatthias Schmidt 	cleanup_push(p2, xfree);
4087d8fb588SMatthias Schmidt 	etracc("exp3a p2", p2, vp);
4097d8fb588SMatthias Schmidt 	if (op[0] == '<')
4107d8fb588SMatthias Schmidt 	    i = egetn(p1) << egetn(p2);
4117d8fb588SMatthias Schmidt 	else
4127d8fb588SMatthias Schmidt 	    i = egetn(p1) >> egetn(p2);
4137d8fb588SMatthias Schmidt 	cleanup_until(p1);
41457e3f2b5SSimon 'corecode' Schubert 	p1 = putn(i);
41557e3f2b5SSimon 'corecode' Schubert 	etracc("exp3a p1", p1, vp);
4167d8fb588SMatthias Schmidt     }
4177d8fb588SMatthias Schmidt     return (p1);
4187d8fb588SMatthias Schmidt }
4197d8fb588SMatthias Schmidt 
4207d8fb588SMatthias Schmidt static Char *
exp4(Char *** vp,int ignore)4217d8fb588SMatthias Schmidt exp4(Char ***vp, int ignore)
4227d8fb588SMatthias Schmidt {
4237d8fb588SMatthias Schmidt     Char *p1, *p2;
42494afa86dSJohn Marino     tcsh_number_t i = 0;
4257d8fb588SMatthias Schmidt 
4267d8fb588SMatthias Schmidt     p1 = exp5(vp, ignore);
4277d8fb588SMatthias Schmidt     etracc("exp4 p1", p1, vp);
42857e3f2b5SSimon 'corecode' Schubert     while (isa(**vp, ADDOP)) {
4297d8fb588SMatthias Schmidt 	const Char *op = *(*vp)++;
4307d8fb588SMatthias Schmidt 
4317d8fb588SMatthias Schmidt 	cleanup_push(p1, xfree);
43257e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
43357e3f2b5SSimon 'corecode' Schubert 	    exp4(vp, ignore) :
43457e3f2b5SSimon 'corecode' Schubert 	    exp5(vp, ignore);
4357d8fb588SMatthias Schmidt 	cleanup_push(p2, xfree);
4367d8fb588SMatthias Schmidt 	etracc("exp4 p2", p2, vp);
4377d8fb588SMatthias Schmidt 	if (!(ignore & TEXP_IGNORE))
4387d8fb588SMatthias Schmidt 	    switch (op[0]) {
4397d8fb588SMatthias Schmidt 
4407d8fb588SMatthias Schmidt 	    case '+':
4417d8fb588SMatthias Schmidt 		i = egetn(p1) + egetn(p2);
4427d8fb588SMatthias Schmidt 		break;
4437d8fb588SMatthias Schmidt 
4447d8fb588SMatthias Schmidt 	    case '-':
4457d8fb588SMatthias Schmidt 		i = egetn(p1) - egetn(p2);
4467d8fb588SMatthias Schmidt 		break;
4477d8fb588SMatthias Schmidt 	    }
4487d8fb588SMatthias Schmidt 	cleanup_until(p1);
44957e3f2b5SSimon 'corecode' Schubert 	p1 = putn(i);
45057e3f2b5SSimon 'corecode' Schubert 	etracc("exp4 p1", p1, vp);
45157e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
45257e3f2b5SSimon 'corecode' Schubert 	    break;
4537d8fb588SMatthias Schmidt     }
4547d8fb588SMatthias Schmidt     return (p1);
4557d8fb588SMatthias Schmidt }
4567d8fb588SMatthias Schmidt 
4577d8fb588SMatthias Schmidt static Char *
exp5(Char *** vp,int ignore)4587d8fb588SMatthias Schmidt exp5(Char ***vp, int ignore)
4597d8fb588SMatthias Schmidt {
4607d8fb588SMatthias Schmidt     Char *p1, *p2;
46194afa86dSJohn Marino     tcsh_number_t i = 0;
4627d8fb588SMatthias Schmidt 
4637d8fb588SMatthias Schmidt     p1 = exp6(vp, ignore);
4647d8fb588SMatthias Schmidt     etracc("exp5 p1", p1, vp);
4657d8fb588SMatthias Schmidt 
46657e3f2b5SSimon 'corecode' Schubert     while (isa(**vp, MULOP)) {
4677d8fb588SMatthias Schmidt 	const Char *op = *(*vp)++;
4687d8fb588SMatthias Schmidt 	if ((ignore & TEXP_NOGLOB) != 0) {
4697d8fb588SMatthias Schmidt 	    /*
4707d8fb588SMatthias Schmidt 	     * We are just trying to get the right side of
4717d8fb588SMatthias Schmidt 	     * a =~ or !~ operator
4727d8fb588SMatthias Schmidt 	     */
4737d8fb588SMatthias Schmidt 	    xfree(p1);
4747d8fb588SMatthias Schmidt 	    return Strsave(op);
4757d8fb588SMatthias Schmidt 	}
4767d8fb588SMatthias Schmidt 
4777d8fb588SMatthias Schmidt 	cleanup_push(p1, xfree);
47857e3f2b5SSimon 'corecode' Schubert 	p2 = compat_expr ?
47957e3f2b5SSimon 'corecode' Schubert 	    exp5(vp, ignore) :
48057e3f2b5SSimon 'corecode' Schubert 	    exp6(vp, ignore);
4817d8fb588SMatthias Schmidt 	cleanup_push(p2, xfree);
4827d8fb588SMatthias Schmidt 	etracc("exp5 p2", p2, vp);
4837d8fb588SMatthias Schmidt 	if (!(ignore & TEXP_IGNORE))
4847d8fb588SMatthias Schmidt 	    switch (op[0]) {
4857d8fb588SMatthias Schmidt 
4867d8fb588SMatthias Schmidt 	    case '*':
4877d8fb588SMatthias Schmidt 		i = egetn(p1) * egetn(p2);
4887d8fb588SMatthias Schmidt 		break;
4897d8fb588SMatthias Schmidt 
4907d8fb588SMatthias Schmidt 	    case '/':
4917d8fb588SMatthias Schmidt 		i = egetn(p2);
4927d8fb588SMatthias Schmidt 		if (i == 0)
4937d8fb588SMatthias Schmidt 		    stderror(ERR_DIV0);
4947d8fb588SMatthias Schmidt 		i = egetn(p1) / i;
4957d8fb588SMatthias Schmidt 		break;
4967d8fb588SMatthias Schmidt 
4977d8fb588SMatthias Schmidt 	    case '%':
4987d8fb588SMatthias Schmidt 		i = egetn(p2);
4997d8fb588SMatthias Schmidt 		if (i == 0)
5007d8fb588SMatthias Schmidt 		    stderror(ERR_MOD0);
5017d8fb588SMatthias Schmidt 		i = egetn(p1) % i;
5027d8fb588SMatthias Schmidt 		break;
5037d8fb588SMatthias Schmidt 	    }
5047d8fb588SMatthias Schmidt 	cleanup_until(p1);
50557e3f2b5SSimon 'corecode' Schubert 	p1 = putn(i);
50657e3f2b5SSimon 'corecode' Schubert 	etracc("exp5 p1", p1, vp);
50757e3f2b5SSimon 'corecode' Schubert 	if (compat_expr)
50857e3f2b5SSimon 'corecode' Schubert 	    break;
5097d8fb588SMatthias Schmidt     }
5107d8fb588SMatthias Schmidt     return (p1);
5117d8fb588SMatthias Schmidt }
5127d8fb588SMatthias Schmidt 
5137d8fb588SMatthias Schmidt static Char *
exp6(Char *** vp,int ignore)5147d8fb588SMatthias Schmidt exp6(Char ***vp, int ignore)
5157d8fb588SMatthias Schmidt {
51694afa86dSJohn Marino     tcsh_number_t ccode;
51794afa86dSJohn Marino     tcsh_number_t i = 0;
5187d8fb588SMatthias Schmidt     Char *cp;
5197d8fb588SMatthias Schmidt 
5207d8fb588SMatthias Schmidt     if (**vp == 0)
5217d8fb588SMatthias Schmidt 	stderror(ERR_NAME | ERR_EXPRESSION);
5227d8fb588SMatthias Schmidt     if (eq(**vp, STRbang)) {
5237d8fb588SMatthias Schmidt 	(*vp)++;
5247d8fb588SMatthias Schmidt 	cp = exp6(vp, ignore);
5257d8fb588SMatthias Schmidt 	cleanup_push(cp, xfree);
5267d8fb588SMatthias Schmidt 	etracc("exp6 ! cp", cp, vp);
5277d8fb588SMatthias Schmidt 	i = egetn(cp);
5287d8fb588SMatthias Schmidt 	cleanup_until(cp);
5297d8fb588SMatthias Schmidt 	return (putn(!i));
5307d8fb588SMatthias Schmidt     }
5317d8fb588SMatthias Schmidt     if (eq(**vp, STRtilde)) {
5327d8fb588SMatthias Schmidt 	(*vp)++;
5337d8fb588SMatthias Schmidt 	cp = exp6(vp, ignore);
5347d8fb588SMatthias Schmidt 	cleanup_push(cp, xfree);
5357d8fb588SMatthias Schmidt 	etracc("exp6 ~ cp", cp, vp);
5367d8fb588SMatthias Schmidt 	i = egetn(cp);
5377d8fb588SMatthias Schmidt 	cleanup_until(cp);
5387d8fb588SMatthias Schmidt 	return (putn(~i));
5397d8fb588SMatthias Schmidt     }
5407d8fb588SMatthias Schmidt     if (eq(**vp, STRLparen)) {
5417d8fb588SMatthias Schmidt 	(*vp)++;
5427d8fb588SMatthias Schmidt 	ccode = exp0(vp, ignore);
5437d8fb588SMatthias Schmidt 	etraci("exp6 () ccode", ccode, vp);
5447d8fb588SMatthias Schmidt 	if (**vp == 0 || ***vp != ')')
5457d8fb588SMatthias Schmidt 	    stderror(ERR_NAME | ERR_EXPRESSION);
5467d8fb588SMatthias Schmidt 	(*vp)++;
5477d8fb588SMatthias Schmidt 	return (putn(ccode));
5487d8fb588SMatthias Schmidt     }
5497d8fb588SMatthias Schmidt     if (eq(**vp, STRLbrace)) {
5507d8fb588SMatthias Schmidt 	Char **v;
5517d8fb588SMatthias Schmidt 	struct command faket;
5527d8fb588SMatthias Schmidt 	Char   *fakecom[2];
5537d8fb588SMatthias Schmidt 
5547d8fb588SMatthias Schmidt 	faket.t_dtyp = NODE_COMMAND;
5557d8fb588SMatthias Schmidt 	faket.t_dflg = F_BACKQ;
5567d8fb588SMatthias Schmidt 	faket.t_dcar = faket.t_dcdr = faket.t_dspr = NULL;
5577d8fb588SMatthias Schmidt 	faket.t_dcom = fakecom;
5587d8fb588SMatthias Schmidt 	fakecom[0] = STRfakecom;
5597d8fb588SMatthias Schmidt 	fakecom[1] = NULL;
5607d8fb588SMatthias Schmidt 	(*vp)++;
5617d8fb588SMatthias Schmidt 	v = *vp;
5627d8fb588SMatthias Schmidt 	for (;;) {
5637d8fb588SMatthias Schmidt 	    if (!**vp)
5647d8fb588SMatthias Schmidt 		stderror(ERR_NAME | ERR_MISSING, '}');
5657d8fb588SMatthias Schmidt 	    if (eq(*(*vp)++, STRRbrace))
5667d8fb588SMatthias Schmidt 		break;
5677d8fb588SMatthias Schmidt 	}
5687d8fb588SMatthias Schmidt 	if (ignore & TEXP_IGNORE)
5697d8fb588SMatthias Schmidt 	    return (Strsave(STRNULL));
5707d8fb588SMatthias Schmidt 	psavejob();
5717d8fb588SMatthias Schmidt 	cleanup_push(&faket, psavejob_cleanup); /* faket is only a marker */
5727d8fb588SMatthias Schmidt 	if (pfork(&faket, -1) == 0) {
5737d8fb588SMatthias Schmidt 	    *--(*vp) = 0;
5747d8fb588SMatthias Schmidt 	    evalav(v);
5757d8fb588SMatthias Schmidt 	    exitstat();
5767d8fb588SMatthias Schmidt 	}
5777d8fb588SMatthias Schmidt 	pwait();
5787d8fb588SMatthias Schmidt 	cleanup_until(&faket);
579*d6ab524cSAntonio Huete Jimenez 	etraci("exp6 {} status", getstatus(), vp);
580*d6ab524cSAntonio Huete Jimenez 	return putn(getstatus() == 0);
5817d8fb588SMatthias Schmidt     }
5827d8fb588SMatthias Schmidt     if (isa(**vp, ANYOP))
5837d8fb588SMatthias Schmidt 	return (Strsave(STRNULL));
5847d8fb588SMatthias Schmidt     cp = *(*vp)++;
5857d8fb588SMatthias Schmidt #ifdef convex
5867d8fb588SMatthias Schmidt # define FILETESTS "erwxfdzoplstSXLbcugkmKR"
5877d8fb588SMatthias Schmidt #else
5887d8fb588SMatthias Schmidt # define FILETESTS "erwxfdzoplstSXLbcugkmK"
5897d8fb588SMatthias Schmidt #endif /* convex */
5907d8fb588SMatthias Schmidt #define FILEVALS  "ZAMCDIUGNFPL"
5917d8fb588SMatthias Schmidt     if (*cp == '-' && (any(FILETESTS, cp[1]) || any(FILEVALS, cp[1])))
5927d8fb588SMatthias Schmidt         return(filetest(cp, vp, ignore));
5937d8fb588SMatthias Schmidt     etracc("exp6 default", cp, vp);
5947d8fb588SMatthias Schmidt     return (ignore & TEXP_NOGLOB ? Strsave(cp) : globone(cp, G_APPEND));
5957d8fb588SMatthias Schmidt }
5967d8fb588SMatthias Schmidt 
5977d8fb588SMatthias Schmidt 
5987d8fb588SMatthias Schmidt /*
5997d8fb588SMatthias Schmidt  * Extended file tests
6007d8fb588SMatthias Schmidt  * From: John Rowe <rowe@excc.exeter.ac.uk>
6017d8fb588SMatthias Schmidt  */
6027d8fb588SMatthias Schmidt Char *
filetest(Char * cp,Char *** vp,int ignore)6037d8fb588SMatthias Schmidt filetest(Char *cp, Char ***vp, int ignore)
6047d8fb588SMatthias Schmidt {
6057d8fb588SMatthias Schmidt #ifdef convex
6067d8fb588SMatthias Schmidt     struct cvxstat stb, *st = NULL;
6077d8fb588SMatthias Schmidt # define TCSH_STAT	stat64
6087d8fb588SMatthias Schmidt #else
6097d8fb588SMatthias Schmidt # define TCSH_STAT	stat
6107d8fb588SMatthias Schmidt     struct stat stb, *st = NULL;
6117d8fb588SMatthias Schmidt #endif /* convex */
6127d8fb588SMatthias Schmidt 
6137d8fb588SMatthias Schmidt #ifdef S_IFLNK
6147d8fb588SMatthias Schmidt # ifdef convex
6157d8fb588SMatthias Schmidt     struct cvxstat lstb, *lst = NULL;
6167d8fb588SMatthias Schmidt #  define TCSH_LSTAT lstat64
6177d8fb588SMatthias Schmidt # else
6187d8fb588SMatthias Schmidt #  define TCSH_LSTAT lstat
6197d8fb588SMatthias Schmidt     struct stat lstb, *lst = NULL;
6207d8fb588SMatthias Schmidt # endif /* convex */
6217d8fb588SMatthias Schmidt     char *filnam;
6227d8fb588SMatthias Schmidt #endif /* S_IFLNK */
6237d8fb588SMatthias Schmidt 
62494afa86dSJohn Marino     tcsh_number_t i = 0;
6257d8fb588SMatthias Schmidt     unsigned pmask = 0xffff;
6267d8fb588SMatthias Schmidt     int altout = 0;
6277d8fb588SMatthias Schmidt     Char *ft = cp, *dp, *ep, *strdev, *strino, *strF, *str, valtest = '\0',
6287d8fb588SMatthias Schmidt     *errval = STR0;
62960962bbcSJohn Marino     char *string, string0[22 + MB_LEN_MAX + 1];	/* space for 64 bit octal */
6307d8fb588SMatthias Schmidt     time_t footime;
6317d8fb588SMatthias Schmidt     struct passwd *pw;
6327d8fb588SMatthias Schmidt     struct group *gr;
6337d8fb588SMatthias Schmidt 
6347d8fb588SMatthias Schmidt     while (any(FILETESTS, *++ft))
6357d8fb588SMatthias Schmidt 	continue;
6367d8fb588SMatthias Schmidt 
6377d8fb588SMatthias Schmidt     if (!*ft && *(ft - 1) == 'L')
6387d8fb588SMatthias Schmidt 	--ft;
6397d8fb588SMatthias Schmidt 
6407d8fb588SMatthias Schmidt     if (any(FILEVALS, *ft)) {
6417d8fb588SMatthias Schmidt 	valtest = *ft++;
6427d8fb588SMatthias Schmidt 	/*
6437d8fb588SMatthias Schmidt 	 * Value tests return '-1' on failure as 0 is
6447d8fb588SMatthias Schmidt 	 * a legitimate value for many of them.
6457d8fb588SMatthias Schmidt 	 * 'F' returns ':' for compatibility.
6467d8fb588SMatthias Schmidt 	 */
6477d8fb588SMatthias Schmidt 	errval = valtest == 'F' ? STRcolon : STRminus1;
6487d8fb588SMatthias Schmidt 
6497d8fb588SMatthias Schmidt 	if (valtest == 'P' && *ft >= '0' && *ft <= '7') {
6507d8fb588SMatthias Schmidt 	    pmask = (char) *ft - '0';
6517d8fb588SMatthias Schmidt 	    while ( *++ft >= '0' && *ft <= '7' )
6527d8fb588SMatthias Schmidt 		pmask = 8 * pmask + ((char) *ft - '0');
6537d8fb588SMatthias Schmidt 	}
6547d8fb588SMatthias Schmidt 	if (Strcmp(ft, STRcolon) == 0 && any("AMCUGP", valtest)) {
6557d8fb588SMatthias Schmidt 	    altout = 1;
6567d8fb588SMatthias Schmidt 	    ++ft;
6577d8fb588SMatthias Schmidt 	}
6587d8fb588SMatthias Schmidt     }
6597d8fb588SMatthias Schmidt 
6607d8fb588SMatthias Schmidt     if (*ft || ft == cp + 1)
6617d8fb588SMatthias Schmidt 	stderror(ERR_NAME | ERR_FILEINQ);
6627d8fb588SMatthias Schmidt 
6637d8fb588SMatthias Schmidt     /*
6647d8fb588SMatthias Schmidt      * Detect missing file names by checking for operator in the file name
6657d8fb588SMatthias Schmidt      * position.  However, if an operator name appears there, we must make
6667d8fb588SMatthias Schmidt      * sure that there's no file by that name (e.g., "/") before announcing
6677d8fb588SMatthias Schmidt      * an error.  Even this check isn't quite right, since it doesn't take
6687d8fb588SMatthias Schmidt      * globbing into account.
6697d8fb588SMatthias Schmidt      */
6707d8fb588SMatthias Schmidt 
6717d8fb588SMatthias Schmidt     if (isa(**vp, ANYOP) && TCSH_STAT(short2str(**vp), &stb))
6727d8fb588SMatthias Schmidt 	stderror(ERR_NAME | ERR_FILENAME);
6737d8fb588SMatthias Schmidt 
6747d8fb588SMatthias Schmidt     dp = *(*vp)++;
6757d8fb588SMatthias Schmidt     if (ignore & TEXP_IGNORE)
6767d8fb588SMatthias Schmidt 	return (Strsave(STRNULL));
677*d6ab524cSAntonio Huete Jimenez     if ((ignore & TEXP_NOGLOB) == 0) {
6787d8fb588SMatthias Schmidt 	ep = globone(dp, G_APPEND);
679*d6ab524cSAntonio Huete Jimenez     } else {
680*d6ab524cSAntonio Huete Jimenez 	ep = Strsave(dp);
681*d6ab524cSAntonio Huete Jimenez     }
6827d8fb588SMatthias Schmidt     cleanup_push(ep, xfree);
6837d8fb588SMatthias Schmidt     ft = &cp[1];
6847d8fb588SMatthias Schmidt     do
6857d8fb588SMatthias Schmidt 	switch (*ft) {
6867d8fb588SMatthias Schmidt 
6877d8fb588SMatthias Schmidt 	case 'r':
6887d8fb588SMatthias Schmidt 	    i = !sh_access(ep, R_OK);
6897d8fb588SMatthias Schmidt 	    break;
6907d8fb588SMatthias Schmidt 
6917d8fb588SMatthias Schmidt 	case 'w':
6927d8fb588SMatthias Schmidt 	    i = !sh_access(ep, W_OK);
6937d8fb588SMatthias Schmidt 	    break;
6947d8fb588SMatthias Schmidt 
6957d8fb588SMatthias Schmidt 	case 'x':
6967d8fb588SMatthias Schmidt 	    i = !sh_access(ep, X_OK);
6977d8fb588SMatthias Schmidt 	    break;
6987d8fb588SMatthias Schmidt 
6997d8fb588SMatthias Schmidt 	case 'X':	/* tcsh extension, name is an executable in the path
7007d8fb588SMatthias Schmidt 			 * or a tcsh builtin command
7017d8fb588SMatthias Schmidt 			 */
7027d8fb588SMatthias Schmidt 	    i = find_cmd(ep, 0);
7037d8fb588SMatthias Schmidt 	    break;
7047d8fb588SMatthias Schmidt 
7057d8fb588SMatthias Schmidt 	case 't':	/* SGI extension, true when file is a tty */
7067d8fb588SMatthias Schmidt 	    i = isatty(atoi(short2str(ep)));
7077d8fb588SMatthias Schmidt 	    break;
7087d8fb588SMatthias Schmidt 
7097d8fb588SMatthias Schmidt 	default:
7107d8fb588SMatthias Schmidt 
7117d8fb588SMatthias Schmidt #ifdef S_IFLNK
7127d8fb588SMatthias Schmidt 	    if (tolower(*ft) == 'l') {
7137d8fb588SMatthias Schmidt 		/*
7147d8fb588SMatthias Schmidt 		 * avoid convex compiler bug.
7157d8fb588SMatthias Schmidt 		 */
7167d8fb588SMatthias Schmidt 		if (!lst) {
7177d8fb588SMatthias Schmidt 		    lst = &lstb;
7187d8fb588SMatthias Schmidt 		    if (TCSH_LSTAT(short2str(ep), lst) == -1) {
7197d8fb588SMatthias Schmidt 			cleanup_until(ep);
7207d8fb588SMatthias Schmidt 			return (Strsave(errval));
7217d8fb588SMatthias Schmidt 		    }
7227d8fb588SMatthias Schmidt 		}
7237d8fb588SMatthias Schmidt 		if (*ft == 'L')
7247d8fb588SMatthias Schmidt 		    st = lst;
7257d8fb588SMatthias Schmidt 	    }
7267d8fb588SMatthias Schmidt 	    else
7277d8fb588SMatthias Schmidt #endif /* S_IFLNK */
7287d8fb588SMatthias Schmidt 		/*
7297d8fb588SMatthias Schmidt 		 * avoid convex compiler bug.
7307d8fb588SMatthias Schmidt 		 */
7317d8fb588SMatthias Schmidt 		if (!st) {
7327d8fb588SMatthias Schmidt 		    st = &stb;
7337d8fb588SMatthias Schmidt 		    if (TCSH_STAT(short2str(ep), st) == -1) {
7347d8fb588SMatthias Schmidt 			cleanup_until(ep);
7357d8fb588SMatthias Schmidt 			return (Strsave(errval));
7367d8fb588SMatthias Schmidt 		    }
7377d8fb588SMatthias Schmidt 		}
7387d8fb588SMatthias Schmidt 
7397d8fb588SMatthias Schmidt 	    switch (*ft) {
7407d8fb588SMatthias Schmidt 
7417d8fb588SMatthias Schmidt 	    case 'f':
7427d8fb588SMatthias Schmidt #ifdef S_ISREG
7437d8fb588SMatthias Schmidt 		i = S_ISREG(st->st_mode);
7447d8fb588SMatthias Schmidt #else /* !S_ISREG */
7457d8fb588SMatthias Schmidt 		i = 0;
7467d8fb588SMatthias Schmidt #endif /* S_ISREG */
7477d8fb588SMatthias Schmidt 		break;
7487d8fb588SMatthias Schmidt 
7497d8fb588SMatthias Schmidt 	    case 'd':
7507d8fb588SMatthias Schmidt #ifdef S_ISDIR
7517d8fb588SMatthias Schmidt 		i = S_ISDIR(st->st_mode);
7527d8fb588SMatthias Schmidt #else /* !S_ISDIR */
7537d8fb588SMatthias Schmidt 		i = 0;
7547d8fb588SMatthias Schmidt #endif /* S_ISDIR */
7557d8fb588SMatthias Schmidt 		break;
7567d8fb588SMatthias Schmidt 
7577d8fb588SMatthias Schmidt 	    case 'p':
7587d8fb588SMatthias Schmidt #ifdef S_ISFIFO
7597d8fb588SMatthias Schmidt 		i = S_ISFIFO(st->st_mode);
7607d8fb588SMatthias Schmidt #else /* !S_ISFIFO */
7617d8fb588SMatthias Schmidt 		i = 0;
7627d8fb588SMatthias Schmidt #endif /* S_ISFIFO */
7637d8fb588SMatthias Schmidt 		break;
7647d8fb588SMatthias Schmidt 
7657d8fb588SMatthias Schmidt 	    case 'm' :
7667d8fb588SMatthias Schmidt #ifdef S_ISOFL
7677d8fb588SMatthias Schmidt 	      i = S_ISOFL(st->st_dm_mode);
7687d8fb588SMatthias Schmidt #else /* !S_ISOFL */
7697d8fb588SMatthias Schmidt 	      i = 0;
7707d8fb588SMatthias Schmidt #endif /* S_ISOFL */
7717d8fb588SMatthias Schmidt 	      break ;
7727d8fb588SMatthias Schmidt 
7737d8fb588SMatthias Schmidt 	    case 'K' :
7747d8fb588SMatthias Schmidt #ifdef S_ISOFL
7757d8fb588SMatthias Schmidt 	      i = stb.st_dm_key;
7767d8fb588SMatthias Schmidt #else /* !S_ISOFL */
7777d8fb588SMatthias Schmidt 	      i = 0;
7787d8fb588SMatthias Schmidt #endif /* S_ISOFL */
7797d8fb588SMatthias Schmidt 	      break ;
7807d8fb588SMatthias Schmidt 
7817d8fb588SMatthias Schmidt 
7827d8fb588SMatthias Schmidt 	    case 'l':
7837d8fb588SMatthias Schmidt #ifdef S_ISLNK
7847d8fb588SMatthias Schmidt 		i = S_ISLNK(lst->st_mode);
7857d8fb588SMatthias Schmidt #else /* !S_ISLNK */
7867d8fb588SMatthias Schmidt 		i = 0;
7877d8fb588SMatthias Schmidt #endif /* S_ISLNK */
7887d8fb588SMatthias Schmidt 		break;
7897d8fb588SMatthias Schmidt 
7907d8fb588SMatthias Schmidt 	    case 'S':
7917d8fb588SMatthias Schmidt # ifdef S_ISSOCK
7927d8fb588SMatthias Schmidt 		i = S_ISSOCK(st->st_mode);
7937d8fb588SMatthias Schmidt # else /* !S_ISSOCK */
7947d8fb588SMatthias Schmidt 		i = 0;
7957d8fb588SMatthias Schmidt # endif /* S_ISSOCK */
7967d8fb588SMatthias Schmidt 		break;
7977d8fb588SMatthias Schmidt 
7987d8fb588SMatthias Schmidt 	    case 'b':
7997d8fb588SMatthias Schmidt #ifdef S_ISBLK
8007d8fb588SMatthias Schmidt 		i = S_ISBLK(st->st_mode);
8017d8fb588SMatthias Schmidt #else /* !S_ISBLK */
8027d8fb588SMatthias Schmidt 		i = 0;
8037d8fb588SMatthias Schmidt #endif /* S_ISBLK */
8047d8fb588SMatthias Schmidt 		break;
8057d8fb588SMatthias Schmidt 
8067d8fb588SMatthias Schmidt 	    case 'c':
8077d8fb588SMatthias Schmidt #ifdef S_ISCHR
8087d8fb588SMatthias Schmidt 		i = S_ISCHR(st->st_mode);
8097d8fb588SMatthias Schmidt #else /* !S_ISCHR */
8107d8fb588SMatthias Schmidt 		i = 0;
8117d8fb588SMatthias Schmidt #endif /* S_ISCHR */
8127d8fb588SMatthias Schmidt 		break;
8137d8fb588SMatthias Schmidt 
8147d8fb588SMatthias Schmidt 	    case 'u':
8157d8fb588SMatthias Schmidt 		i = (S_ISUID & st->st_mode) != 0;
8167d8fb588SMatthias Schmidt 		break;
8177d8fb588SMatthias Schmidt 
8187d8fb588SMatthias Schmidt 	    case 'g':
8197d8fb588SMatthias Schmidt 		i = (S_ISGID & st->st_mode) != 0;
8207d8fb588SMatthias Schmidt 		break;
8217d8fb588SMatthias Schmidt 
8227d8fb588SMatthias Schmidt 	    case 'k':
8237d8fb588SMatthias Schmidt 		i = (S_ISVTX & st->st_mode) != 0;
8247d8fb588SMatthias Schmidt 		break;
8257d8fb588SMatthias Schmidt 
8267d8fb588SMatthias Schmidt 	    case 'z':
8277d8fb588SMatthias Schmidt 		i = st->st_size == 0;
8287d8fb588SMatthias Schmidt 		break;
8297d8fb588SMatthias Schmidt 
8307d8fb588SMatthias Schmidt #ifdef convex
8317d8fb588SMatthias Schmidt 	    case 'R':
8327d8fb588SMatthias Schmidt 		i = (stb.st_dmonflags & IMIGRATED) == IMIGRATED;
8337d8fb588SMatthias Schmidt 		break;
8347d8fb588SMatthias Schmidt #endif /* convex */
8357d8fb588SMatthias Schmidt 
8367d8fb588SMatthias Schmidt 	    case 's':
8377d8fb588SMatthias Schmidt 		i = stb.st_size != 0;
8387d8fb588SMatthias Schmidt 		break;
8397d8fb588SMatthias Schmidt 
8407d8fb588SMatthias Schmidt 	    case 'e':
8417d8fb588SMatthias Schmidt 		i = 1;
8427d8fb588SMatthias Schmidt 		break;
8437d8fb588SMatthias Schmidt 
8447d8fb588SMatthias Schmidt 	    case 'o':
8457d8fb588SMatthias Schmidt 		i = st->st_uid == uid;
8467d8fb588SMatthias Schmidt 		break;
8477d8fb588SMatthias Schmidt 
8487d8fb588SMatthias Schmidt 		/*
8497d8fb588SMatthias Schmidt 		 * Value operators are a tcsh extension.
8507d8fb588SMatthias Schmidt 		 */
8517d8fb588SMatthias Schmidt 
8527d8fb588SMatthias Schmidt 	    case 'D':
85394afa86dSJohn Marino 		i = (tcsh_number_t) st->st_dev;
8547d8fb588SMatthias Schmidt 		break;
8557d8fb588SMatthias Schmidt 
8567d8fb588SMatthias Schmidt 	    case 'I':
85794afa86dSJohn Marino 		i = (tcsh_number_t) st->st_ino;
8587d8fb588SMatthias Schmidt 		break;
8597d8fb588SMatthias Schmidt 
8607d8fb588SMatthias Schmidt 	    case 'F':
8617d8fb588SMatthias Schmidt 		strdev = putn( (int) st->st_dev);
8627d8fb588SMatthias Schmidt 		strino = putn( (int) st->st_ino);
8637d8fb588SMatthias Schmidt 		strF = xmalloc((2 + Strlen(strdev) + Strlen(strino))
8647d8fb588SMatthias Schmidt 			       * sizeof(Char));
8657d8fb588SMatthias Schmidt 		(void) Strcat(Strcat(Strcpy(strF, strdev), STRcolon), strino);
8667d8fb588SMatthias Schmidt 		xfree(strdev);
8677d8fb588SMatthias Schmidt 		xfree(strino);
8687d8fb588SMatthias Schmidt 		cleanup_until(ep);
8697d8fb588SMatthias Schmidt 		return(strF);
8707d8fb588SMatthias Schmidt 
8717d8fb588SMatthias Schmidt 	    case 'L':
8727d8fb588SMatthias Schmidt 		if ( *(ft + 1) ) {
8737d8fb588SMatthias Schmidt 		    i = 1;
8747d8fb588SMatthias Schmidt 		    break;
8757d8fb588SMatthias Schmidt 		}
8767d8fb588SMatthias Schmidt #ifdef S_ISLNK
8777d8fb588SMatthias Schmidt 		filnam = short2str(ep);
8787d8fb588SMatthias Schmidt 		string = areadlink(filnam);
8797d8fb588SMatthias Schmidt 		strF = string == NULL ? errval : str2short(string);
8807d8fb588SMatthias Schmidt 		xfree(string);
8817d8fb588SMatthias Schmidt 		cleanup_until(ep);
8827d8fb588SMatthias Schmidt 		return(Strsave(strF));
8837d8fb588SMatthias Schmidt 
8847d8fb588SMatthias Schmidt #else /* !S_ISLNK */
8857d8fb588SMatthias Schmidt 		i = 0;
8867d8fb588SMatthias Schmidt 		break;
8877d8fb588SMatthias Schmidt #endif /* S_ISLNK */
8887d8fb588SMatthias Schmidt 
8897d8fb588SMatthias Schmidt 
8907d8fb588SMatthias Schmidt 	    case 'N':
89194afa86dSJohn Marino 		i = (tcsh_number_t) st->st_nlink;
8927d8fb588SMatthias Schmidt 		break;
8937d8fb588SMatthias Schmidt 
8947d8fb588SMatthias Schmidt 	    case 'P':
8957d8fb588SMatthias Schmidt 		string = string0 + 1;
8967d8fb588SMatthias Schmidt 		(void) xsnprintf(string, sizeof(string0) - 1, "%o",
8977d8fb588SMatthias Schmidt 		    pmask & (unsigned int)
8987d8fb588SMatthias Schmidt 		    ((S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID) & st->st_mode));
8997d8fb588SMatthias Schmidt 		if (altout && *string != '0')
9007d8fb588SMatthias Schmidt 		    *--string = '0';
9017d8fb588SMatthias Schmidt 		cleanup_until(ep);
9027d8fb588SMatthias Schmidt 		return(Strsave(str2short(string)));
9037d8fb588SMatthias Schmidt 
9047d8fb588SMatthias Schmidt 	    case 'U':
9057d8fb588SMatthias Schmidt 		if (altout && (pw = xgetpwuid(st->st_uid))) {
9067d8fb588SMatthias Schmidt 		    cleanup_until(ep);
9077d8fb588SMatthias Schmidt 		    return(Strsave(str2short(pw->pw_name)));
9087d8fb588SMatthias Schmidt 		}
90994afa86dSJohn Marino 		i = (tcsh_number_t) st->st_uid;
9107d8fb588SMatthias Schmidt 		break;
9117d8fb588SMatthias Schmidt 
9127d8fb588SMatthias Schmidt 	    case 'G':
9137d8fb588SMatthias Schmidt 		if (altout && (gr = xgetgrgid(st->st_gid))) {
9147d8fb588SMatthias Schmidt 		    cleanup_until(ep);
9157d8fb588SMatthias Schmidt 		    return(Strsave(str2short(gr->gr_name)));
9167d8fb588SMatthias Schmidt 		}
91794afa86dSJohn Marino 		i = (tcsh_number_t) st->st_gid;
9187d8fb588SMatthias Schmidt 		break;
9197d8fb588SMatthias Schmidt 
9207d8fb588SMatthias Schmidt 	    case 'Z':
92194afa86dSJohn Marino 		i = (tcsh_number_t) st->st_size;
9227d8fb588SMatthias Schmidt 		break;
9237d8fb588SMatthias Schmidt 
9247d8fb588SMatthias Schmidt 	    case 'A': case 'M': case 'C':
9257d8fb588SMatthias Schmidt 		footime = *ft == 'A' ? st->st_atime :
9267d8fb588SMatthias Schmidt 		    *ft == 'M' ? st->st_mtime : st->st_ctime;
9277d8fb588SMatthias Schmidt 		if (altout) {
9287d8fb588SMatthias Schmidt 		    strF = str2short(ctime(&footime));
9297d8fb588SMatthias Schmidt 		    if ((str = Strchr(strF, '\n')) != NULL)
9307d8fb588SMatthias Schmidt 			*str = (Char) '\0';
9317d8fb588SMatthias Schmidt 		    cleanup_until(ep);
9327d8fb588SMatthias Schmidt 		    return(Strsave(strF));
9337d8fb588SMatthias Schmidt 		}
93494afa86dSJohn Marino 		i = (tcsh_number_t) footime;
9357d8fb588SMatthias Schmidt 		break;
9367d8fb588SMatthias Schmidt 
9377d8fb588SMatthias Schmidt 	    }
9387d8fb588SMatthias Schmidt 	}
9397d8fb588SMatthias Schmidt     while (*++ft && i);
9407d8fb588SMatthias Schmidt     etraci("exp6 -? i", i, vp);
9417d8fb588SMatthias Schmidt     cleanup_until(ep);
9427d8fb588SMatthias Schmidt     return (putn(i));
9437d8fb588SMatthias Schmidt }
9447d8fb588SMatthias Schmidt 
9457d8fb588SMatthias Schmidt 
9467d8fb588SMatthias Schmidt static void
evalav(Char ** v)9477d8fb588SMatthias Schmidt evalav(Char **v)
9487d8fb588SMatthias Schmidt {
9497d8fb588SMatthias Schmidt     struct wordent paraml1;
9507d8fb588SMatthias Schmidt     struct wordent *hp = &paraml1;
9517d8fb588SMatthias Schmidt     struct command *t;
9527d8fb588SMatthias Schmidt     struct wordent *wdp = hp;
9537d8fb588SMatthias Schmidt 
954*d6ab524cSAntonio Huete Jimenez     setstatus(0);
955653fab9eSSascha Wildner     initlex(hp);
9567d8fb588SMatthias Schmidt     while (*v) {
9577d8fb588SMatthias Schmidt 	struct wordent *new = xcalloc(1, sizeof *wdp);
9587d8fb588SMatthias Schmidt 
9597d8fb588SMatthias Schmidt 	new->prev = wdp;
9607d8fb588SMatthias Schmidt 	new->next = hp;
9617d8fb588SMatthias Schmidt 	wdp->next = new;
9627d8fb588SMatthias Schmidt 	wdp = new;
9637d8fb588SMatthias Schmidt 	wdp->word = Strsave(*v++);
9647d8fb588SMatthias Schmidt     }
9657d8fb588SMatthias Schmidt     hp->prev = wdp;
9667d8fb588SMatthias Schmidt     cleanup_push(&paraml1, lex_cleanup);
9677d8fb588SMatthias Schmidt     alias(&paraml1);
9687d8fb588SMatthias Schmidt     t = syntax(paraml1.next, &paraml1, 0);
9697d8fb588SMatthias Schmidt     cleanup_push(t, syntax_cleanup);
9707d8fb588SMatthias Schmidt     if (seterr)
9717d8fb588SMatthias Schmidt 	stderror(ERR_OLD);
9727d8fb588SMatthias Schmidt     execute(t, -1, NULL, NULL, TRUE);
9737d8fb588SMatthias Schmidt     cleanup_until(&paraml1);
9747d8fb588SMatthias Schmidt }
9757d8fb588SMatthias Schmidt 
9767d8fb588SMatthias Schmidt static int
isa(Char * cp,int what)9777d8fb588SMatthias Schmidt isa(Char *cp, int what)
9787d8fb588SMatthias Schmidt {
9797d8fb588SMatthias Schmidt     if (cp == 0)
9807d8fb588SMatthias Schmidt 	return ((what & RESTOP) != 0);
9817d8fb588SMatthias Schmidt     if (*cp == '\0')
9827d8fb588SMatthias Schmidt     	return 0;
9837d8fb588SMatthias Schmidt     if (cp[1] == 0) {
9847d8fb588SMatthias Schmidt 	if (what & ADDOP && (*cp == '+' || *cp == '-'))
9857d8fb588SMatthias Schmidt 	    return (1);
9867d8fb588SMatthias Schmidt 	if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))
9877d8fb588SMatthias Schmidt 	    return (1);
9887d8fb588SMatthias Schmidt 	if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||
9897d8fb588SMatthias Schmidt 			      *cp == '~' || *cp == '^' || *cp == '"'))
9907d8fb588SMatthias Schmidt 	    return (1);
9917d8fb588SMatthias Schmidt     }
9927d8fb588SMatthias Schmidt     else if (cp[2] == 0) {
9937d8fb588SMatthias Schmidt 	if (what & RESTOP) {
9947d8fb588SMatthias Schmidt 	    if (cp[0] == '|' && cp[1] == '&')
9957d8fb588SMatthias Schmidt 		return (1);
9967d8fb588SMatthias Schmidt 	    if (cp[0] == '<' && cp[1] == '<')
9977d8fb588SMatthias Schmidt 		return (1);
9987d8fb588SMatthias Schmidt 	    if (cp[0] == '>' && cp[1] == '>')
9997d8fb588SMatthias Schmidt 		return (1);
10007d8fb588SMatthias Schmidt 	}
10017d8fb588SMatthias Schmidt 	if (what & EQOP) {
10027d8fb588SMatthias Schmidt 	    if (cp[0] == '=') {
10037d8fb588SMatthias Schmidt 		if (cp[1] == '=')
10047d8fb588SMatthias Schmidt 		    return (EQEQ);
10057d8fb588SMatthias Schmidt 		if (cp[1] == '~')
10067d8fb588SMatthias Schmidt 		    return (EQMATCH);
10077d8fb588SMatthias Schmidt 	    }
10087d8fb588SMatthias Schmidt 	    else if (cp[0] == '!') {
10097d8fb588SMatthias Schmidt 		if (cp[1] == '=')
10107d8fb588SMatthias Schmidt 		    return (NOTEQ);
10117d8fb588SMatthias Schmidt 		if (cp[1] == '~')
10127d8fb588SMatthias Schmidt 		    return (NOTEQMATCH);
10137d8fb588SMatthias Schmidt 	    }
10147d8fb588SMatthias Schmidt 	}
10157d8fb588SMatthias Schmidt     }
10167d8fb588SMatthias Schmidt     if (what & RELOP) {
10177d8fb588SMatthias Schmidt 	if (*cp == '<')
10187d8fb588SMatthias Schmidt 	    return (LSS);
10197d8fb588SMatthias Schmidt 	if (*cp == '>')
10207d8fb588SMatthias Schmidt 	    return (GTR);
10217d8fb588SMatthias Schmidt     }
10227d8fb588SMatthias Schmidt     return (0);
10237d8fb588SMatthias Schmidt }
10247d8fb588SMatthias Schmidt 
102594afa86dSJohn Marino static tcsh_number_t
egetn(const Char * cp)102694afa86dSJohn Marino egetn(const Char *cp)
10277d8fb588SMatthias Schmidt {
10287d8fb588SMatthias Schmidt     if (*cp && *cp != '-' && !Isdigit(*cp))
10297d8fb588SMatthias Schmidt 	stderror(ERR_NAME | ERR_EXPRESSION);
10307d8fb588SMatthias Schmidt     return (getn(cp));
10317d8fb588SMatthias Schmidt }
10327d8fb588SMatthias Schmidt 
10337d8fb588SMatthias Schmidt /* Phew! */
10347d8fb588SMatthias Schmidt 
10357d8fb588SMatthias Schmidt #ifdef EDEBUG
10367d8fb588SMatthias Schmidt static void
etraci(const char * str,tcsh_number_t i,Char *** vp)103794afa86dSJohn Marino etraci(const char *str, tcsh_number_t i, Char ***vp)
10387d8fb588SMatthias Schmidt {
103994afa86dSJohn Marino #ifdef HAVE_LONG_LONG
104094afa86dSJohn Marino     xprintf("%s=%lld\t", str, i);
104194afa86dSJohn Marino #else
104294afa86dSJohn Marino     xprintf("%s=%ld\t", str, i);
104394afa86dSJohn Marino #endif
10447d8fb588SMatthias Schmidt     blkpr(*vp);
10457d8fb588SMatthias Schmidt     xputchar('\n');
10467d8fb588SMatthias Schmidt }
10477d8fb588SMatthias Schmidt static void
etracc(const char * str,const Char * cp,Char *** vp)104857e3f2b5SSimon 'corecode' Schubert etracc(const char *str, const Char *cp, Char ***vp)
10497d8fb588SMatthias Schmidt {
105057e3f2b5SSimon 'corecode' Schubert     xprintf("%s=%S\t", str, cp);
10517d8fb588SMatthias Schmidt     blkpr(*vp);
10527d8fb588SMatthias Schmidt     xputchar('\n');
10537d8fb588SMatthias Schmidt }
10547d8fb588SMatthias Schmidt #endif /* EDEBUG */
1055