* Copyright (c) 1980, 1991 The Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)exp.c 5.16 (Berkeley) %G%";
#endif /* SHORT_STRINGS */
#define IGNORE 1 /* in ignore, it means to ignore value, just parse */
#define NOGLOB 2 /* in ignore, it means not to globone */
static int exp1
__P((Char
***, bool));
static int exp2
__P((Char
***, bool));
static int exp2a
__P((Char
***, bool));
static int exp2b
__P((Char
***, bool));
static int exp2c
__P((Char
***, bool));
static Char
* exp3
__P((Char
***, bool));
static Char
* exp3a
__P((Char
***, bool));
static Char
* exp4
__P((Char
***, bool));
static Char
* exp5
__P((Char
***, bool));
static Char
* exp6
__P((Char
***, bool));
static void evalav
__P((Char
**));
static int isa
__P((Char
*, int));
static int egetn
__P((Char
*));
static void etracc
__P((char *, Char
*, Char
***));
static void etraci
__P((char *, int, Char
***));
register int p1
= exp1(vp
, ignore
);
etraci("exp0 p1", p1
, vp
);
if (**vp
&& eq(**vp
, STRor2
)) {
p2
= exp0(vp
, (ignore
& IGNORE
) || p1
);
etraci("exp0 p2", p2
, vp
);
register int p1
= exp2(vp
, ignore
);
etraci("exp1 p1", p1
, vp
);
if (**vp
&& eq(**vp
, STRand2
)) {
p2
= exp1(vp
, (ignore
& IGNORE
) || !p1
);
etraci("exp1 p2", p2
, vp
);
register int p1
= exp2a(vp
, ignore
);
etraci("exp3 p1", p1
, vp
);
if (**vp
&& eq(**vp
, STRor
)) {
etraci("exp3 p2", p2
, vp
);
register int p1
= exp2b(vp
, ignore
);
etraci("exp2a p1", p1
, vp
);
if (**vp
&& eq(**vp
, STRcaret
)) {
etraci("exp2a p2", p2
, vp
);
register int p1
= exp2c(vp
, ignore
);
etraci("exp2b p1", p1
, vp
);
if (**vp
&& eq(**vp
, STRand
)) {
etraci("exp2b p2", p2
, vp
);
register Char
*p1
= exp3(vp
, ignore
);
etracc("exp2c p1", p1
, vp
);
if ((i
= isa(**vp
, EQOP
)) != 0) {
if (i
== EQMATCH
|| i
== NOTEQMATCH
)
etracc("exp2c p2", p2
, vp
);
etracc("exp3 p1", p1
, vp
);
if ((i
= isa(**vp
, RELOP
)) != 0) {
if (**vp
&& eq(**vp
, STRequal
))
etracc("exp3 p2", p2
, vp
);
i
= egetn(p1
) > egetn(p2
);
i
= egetn(p1
) >= egetn(p2
);
i
= egetn(p1
) < egetn(p2
);
i
= egetn(p1
) <= egetn(p2
);
register Char
*p1
, *p2
, *op
;
etracc("exp3a p1", p1
, vp
);
if (op
&& any("<>", op
[0]) && op
[0] == op
[1]) {
etracc("exp3a p2", p2
, vp
);
i
= egetn(p1
) << egetn(p2
);
i
= egetn(p1
) >> egetn(p2
);
etracc("exp4 p1", p1
, vp
);
register Char
*op
= *(*vp
)++;
etracc("exp4 p2", p2
, vp
);
i
= egetn(p1
) + egetn(p2
);
i
= egetn(p1
) - egetn(p2
);
etracc("exp5 p1", p1
, vp
);
register Char
*op
= *(*vp
)++;
etracc("exp5 p2", p2
, vp
);
i
= egetn(p1
) * egetn(p2
);
register Char
*cp
, *dp
, *ep
;
stderror(ERR_NAME
| ERR_EXPRESSION
);
etracc("exp6 ! cp", cp
, vp
);
if (eq(**vp
, STRtilde
)) {
etracc("exp6 ~ cp", cp
, vp
);
if (eq(**vp
, STRLparen
)) {
ccode
= exp0(vp
, ignore
);
etraci("exp6 () ccode", ccode
, vp
);
if (*vp
== 0 || **vp
== 0 || ***vp
!= ')')
stderror(ERR_NAME
| ERR_EXPRESSION
);
if (eq(**vp
, STRLbrace
)) {
faket
.t_dtyp
= NODE_COMMAND
;
faket
.t_dcar
= faket
.t_dcdr
= faket
.t_dspr
= NULL
;
stderror(ERR_NAME
| ERR_MISSING
, '}');
if (eq(*(*vp
)++, STRRbrace
))
return (Strsave(STRNULL
));
if (pfork(&faket
, -1) == 0) {
etraci("exp6 {} status", egetn(value(STRstatus
)), vp
);
return (putn(egetn(value(STRstatus
)) == 0));
return (Strsave(STRNULL
));
if (*cp
== '-' && any("erwxfdzopls", cp
[1])) {
stderror(ERR_NAME
| ERR_FILEINQ
);
* Detect missing file names by checking for operator in the file name
* position. However, if an operator name appears there, we must make
* sure that there's no file by that name (e.g., "/") before announcing
* an error. Even this check isn't quite right, since it doesn't take
if (isa(**vp
, ANYOP
) && stat(short2str(**vp
), &stb
))
stderror(ERR_NAME
| ERR_FILENAME
);
return (Strsave(STRNULL
));
ep
= globone(dp
, G_ERROR
);
i
= !access(short2str(ep
), R_OK
);
i
= !access(short2str(ep
), W_OK
);
i
= !access(short2str(ep
), X_OK
);
cp
[1] == 'l' ? lstat(short2str(ep
), &stb
) :
stat(short2str(ep
), &stb
)) {
i
= S_ISREG(stb
.st_mode
);
i
= S_ISDIR(stb
.st_mode
);
i
= S_ISFIFO(stb
.st_mode
);
i
= S_ISLNK(stb
.st_mode
);
i
= S_ISSOCK(stb
.st_mode
);
etraci("exp6 -? i", i
, vp
);
etracc("exp6 default", cp
, vp
);
return (ignore
& NOGLOB
? Strsave(cp
) : globone(cp
, G_ERROR
));
register struct wordent
*hp
= ¶ml1
;
register struct wordent
*wdp
= hp
;
set(STRstatus
, Strsave(STR0
));
hp
->prev
= hp
->next
= hp
;
register struct wordent
*new =
(struct wordent
*) xcalloc(1, sizeof *wdp
);
wdp
->word
= Strsave(*v
++);
t
= syntax(paraml1
.next
, ¶ml1
, 0);
execute(t
, -1, NULL
, NULL
);
freelex(¶ml1
), freesyn(t
);
return ((what
& RESTOP
) != 0);
if (what
& ADDOP
&& (*cp
== '+' || *cp
== '-'))
if (what
& MULOP
&& (*cp
== '*' || *cp
== '/' || *cp
== '%'))
if (what
& RESTOP
&& (*cp
== '(' || *cp
== ')' || *cp
== '!' ||
*cp
== '~' || *cp
== '^' || *cp
== '"'))
if (cp
[0] == '|' && cp
[1] == '&')
if (cp
[0] == '<' && cp
[1] == '<')
if (cp
[0] == '>' && cp
[1] == '>')
if (*cp
&& *cp
!= '-' && !Isdigit(*cp
))
stderror(ERR_NAME
| ERR_EXPRESSION
);
(void) fprintf(csherr
, "%s=%d\t", str
, i
);
(void) fprintf(csherr
, "\n");
(void) fprintf(csherr
, "%s=%s\t", str
, vis_str(cp
));
(void) fprintf(csherr
, "\n");