118754Sedward /*
2*62461Sbostic * Copyright (c) 1983, 1993
3*62461Sbostic * The Regents of the University of California. All rights reserved.
433514Sbostic *
542954Sbostic * This code is derived from software contributed to Berkeley by
642954Sbostic * Edward Wang at The University of California, Berkeley.
742954Sbostic *
842835Sbostic * %sccs.include.redist.c%
918754Sedward */
1018754Sedward
1133514Sbostic #ifndef lint
12*62461Sbostic static char sccsid[] = "@(#)parser5.c 8.1 (Berkeley) 06/06/93";
1333514Sbostic #endif /* not lint */
1433514Sbostic
1515853Sedward #include "parser.h"
1615864Sedward #include "var.h"
1715853Sedward
1815853Sedward /*
1916714Sedward * unary $ $? + - ! ~
2015853Sedward */
p_expr11(v,flag)2115853Sedward p_expr11(v, flag)
2215853Sedward register struct value *v;
2315853Sedward char flag;
2415853Sedward {
2515853Sedward int op;
2615853Sedward char *opname;
2715853Sedward
2815853Sedward switch (token) {
2915853Sedward case T_DOLLAR:
3015853Sedward opname = "$";
3115853Sedward break;
3216714Sedward case T_DQ:
3316714Sedward opname = "$?";
3416714Sedward break;
3515853Sedward case T_PLUS:
3615853Sedward opname = "unary +";
3715853Sedward break;
3815853Sedward case T_MINUS:
3915853Sedward opname = "unary -";
4015853Sedward break;
4115853Sedward case T_NOT:
4215853Sedward opname = "!";
4315853Sedward break;
4415853Sedward case T_COMP:
4515853Sedward opname = "~";
4615853Sedward break;
4715853Sedward default:
4815853Sedward return p_expr12(v, flag);
4915853Sedward }
5015853Sedward op = token;
5115853Sedward (void) s_gettok();
5215853Sedward if (p_expr11(v, flag) < 0)
5315853Sedward return -1;
5415853Sedward switch (v->v_type) {
5515853Sedward case V_NUM:
5615853Sedward break;
5715853Sedward case V_STR:
5815853Sedward switch (op) {
5915853Sedward case T_MINUS:
6015853Sedward case T_NOT:
6115853Sedward case T_COMP:
6216714Sedward p_error("%s: Numeric operand required.", opname);
6315853Sedward str_free(v->v_str);
6415853Sedward v->v_type = V_ERR;
6515853Sedward return 0;
6615853Sedward }
6715853Sedward break;
6815853Sedward case V_ERR:
6915853Sedward return 0;
7015853Sedward }
7115853Sedward switch (op) {
7216714Sedward case T_DOLLAR:
7316714Sedward case T_DQ:
7416449Sedward if (v->v_type == V_NUM) {
7516714Sedward int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
7616714Sedward v->v_num > 0 && v->v_num <= cx.x_narg;
7716714Sedward if (op == T_DQ)
7816714Sedward v->v_num = tmp;
7916714Sedward else if (tmp)
8016714Sedward *v = cx.x_arg[v->v_num - 1];
8116714Sedward else {
8216449Sedward p_error("%d: No such argument.", v->v_num);
8316449Sedward v->v_type = V_ERR;
8416449Sedward }
8516449Sedward } else {
8616714Sedward char *name = v->v_str;
8716714Sedward struct var *r = var_lookup(name);
8816714Sedward if (op == T_DQ) {
8916714Sedward v->v_type = V_NUM;
9016714Sedward v->v_num = r != 0;
9116714Sedward } else if (r != 0)
9216714Sedward *v = r->r_val;
9316714Sedward else {
9416714Sedward p_error("%s: Undefined variable.", name);
9516449Sedward v->v_type = V_ERR;
9616449Sedward }
9716714Sedward str_free(name);
9815853Sedward }
9916714Sedward if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
10016449Sedward p_memerror();
10116449Sedward return -1;
10215853Sedward }
10315853Sedward break;
10415853Sedward case T_MINUS:
10515853Sedward v->v_num = - v->v_num;
10615853Sedward break;
10715853Sedward case T_NOT:
10815853Sedward v->v_num = ! v->v_num;
10915853Sedward break;
11015853Sedward case T_COMP:
11115853Sedward v->v_num = ~ v->v_num;
11215853Sedward break;
11315853Sedward }
11415853Sedward return 0;
11515853Sedward }
11615853Sedward
11715853Sedward /*
11815853Sedward * string, number, ( expr )
11915853Sedward * Plus function calls.
12015853Sedward *
12115853Sedward * Always return v_type == V_ERR when flag == 0.
12215853Sedward */
p_expr12(v,flag)12315853Sedward p_expr12(v, flag)
12415853Sedward register struct value *v;
12515853Sedward char flag;
12615853Sedward {
12715853Sedward v->v_type = V_ERR;
12815853Sedward switch (token) {
12915853Sedward case T_NUM:
13015853Sedward if (flag) {
13115853Sedward v->v_type = V_NUM;
13215853Sedward v->v_num = token_num;
13315853Sedward }
13415853Sedward (void) s_gettok();
13515853Sedward break;
13615853Sedward case T_STR:
13715853Sedward if (flag) {
13815853Sedward v->v_type = V_STR;
13915853Sedward v->v_str = token_str;
14015853Sedward } else
14115853Sedward str_free(token_str);
14215853Sedward (void) s_gettok();
14315853Sedward break;
14415853Sedward case T_LP:
14515853Sedward (void) s_gettok();
14615853Sedward if (p_expr(v, flag) < 0) {
14715853Sedward p_synerror();
14815853Sedward return -1;
14915853Sedward }
15015853Sedward if (token != T_RP) {
15115853Sedward p_synerror();
15215853Sedward val_free(*v);
15315853Sedward return -1;
15415853Sedward }
15515853Sedward (void) s_gettok();
15615853Sedward break;
15715853Sedward default:
15815853Sedward return -1;
15915853Sedward }
16015853Sedward while (token == T_LP) {
16115853Sedward char *cmd;
16215853Sedward
16316449Sedward if (p_convstr(v) < 0)
16416449Sedward return -1;
16516449Sedward cmd = v->v_type == V_STR ? v->v_str : 0;
16615853Sedward if (p_function(cmd, v, flag) < 0) {
16716298Sedward if (cmd)
16816298Sedward str_free(cmd);
16915853Sedward return -1;
17015853Sedward }
17116298Sedward if (cmd)
17216298Sedward str_free(cmd);
17315853Sedward }
17415853Sedward return 0;
17515853Sedward }
176