118754Sedward /* 2*33514Sbostic * Copyright (c) 1983 Regents of the University of California. 3*33514Sbostic * All rights reserved. 4*33514Sbostic * 5*33514Sbostic * Redistribution and use in source and binary forms are permitted 6*33514Sbostic * provided that this notice is preserved and that due credit is given 7*33514Sbostic * to the University of California at Berkeley. The name of the University 8*33514Sbostic * may not be used to endorse or promote products derived from this 9*33514Sbostic * software without specific prior written permission. This software 10*33514Sbostic * is provided ``as is'' without express or implied warranty. 1118754Sedward */ 1218754Sedward 13*33514Sbostic #ifndef lint 14*33514Sbostic static char sccsid[] = "@(#)parser5.c 3.10 (Berkeley) 02/21/88"; 15*33514Sbostic #endif /* not lint */ 16*33514Sbostic 1715853Sedward #include "parser.h" 1815864Sedward #include "var.h" 1915853Sedward 2015853Sedward /* 2116714Sedward * unary $ $? + - ! ~ 2215853Sedward */ 2315853Sedward p_expr11(v, flag) 2415853Sedward register struct value *v; 2515853Sedward char flag; 2615853Sedward { 2715853Sedward int op; 2815853Sedward char *opname; 2915853Sedward 3015853Sedward switch (token) { 3115853Sedward case T_DOLLAR: 3215853Sedward opname = "$"; 3315853Sedward break; 3416714Sedward case T_DQ: 3516714Sedward opname = "$?"; 3616714Sedward break; 3715853Sedward case T_PLUS: 3815853Sedward opname = "unary +"; 3915853Sedward break; 4015853Sedward case T_MINUS: 4115853Sedward opname = "unary -"; 4215853Sedward break; 4315853Sedward case T_NOT: 4415853Sedward opname = "!"; 4515853Sedward break; 4615853Sedward case T_COMP: 4715853Sedward opname = "~"; 4815853Sedward break; 4915853Sedward default: 5015853Sedward return p_expr12(v, flag); 5115853Sedward } 5215853Sedward op = token; 5315853Sedward (void) s_gettok(); 5415853Sedward if (p_expr11(v, flag) < 0) 5515853Sedward return -1; 5615853Sedward switch (v->v_type) { 5715853Sedward case V_NUM: 5815853Sedward break; 5915853Sedward case V_STR: 6015853Sedward switch (op) { 6115853Sedward case T_MINUS: 6215853Sedward case T_NOT: 6315853Sedward case T_COMP: 6416714Sedward p_error("%s: Numeric operand required.", opname); 6515853Sedward str_free(v->v_str); 6615853Sedward v->v_type = V_ERR; 6715853Sedward return 0; 6815853Sedward } 6915853Sedward break; 7015853Sedward case V_ERR: 7115853Sedward return 0; 7215853Sedward } 7315853Sedward switch (op) { 7416714Sedward case T_DOLLAR: 7516714Sedward case T_DQ: 7616449Sedward if (v->v_type == V_NUM) { 7716714Sedward int tmp = cx.x_type == X_BUF && cx.x_arg != 0 && 7816714Sedward v->v_num > 0 && v->v_num <= cx.x_narg; 7916714Sedward if (op == T_DQ) 8016714Sedward v->v_num = tmp; 8116714Sedward else if (tmp) 8216714Sedward *v = cx.x_arg[v->v_num - 1]; 8316714Sedward else { 8416449Sedward p_error("%d: No such argument.", v->v_num); 8516449Sedward v->v_type = V_ERR; 8616449Sedward } 8716449Sedward } else { 8816714Sedward char *name = v->v_str; 8916714Sedward struct var *r = var_lookup(name); 9016714Sedward if (op == T_DQ) { 9116714Sedward v->v_type = V_NUM; 9216714Sedward v->v_num = r != 0; 9316714Sedward } else if (r != 0) 9416714Sedward *v = r->r_val; 9516714Sedward else { 9616714Sedward p_error("%s: Undefined variable.", name); 9716449Sedward v->v_type = V_ERR; 9816449Sedward } 9916714Sedward str_free(name); 10015853Sedward } 10116714Sedward if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) { 10216449Sedward p_memerror(); 10316449Sedward return -1; 10415853Sedward } 10515853Sedward break; 10615853Sedward case T_MINUS: 10715853Sedward v->v_num = - v->v_num; 10815853Sedward break; 10915853Sedward case T_NOT: 11015853Sedward v->v_num = ! v->v_num; 11115853Sedward break; 11215853Sedward case T_COMP: 11315853Sedward v->v_num = ~ v->v_num; 11415853Sedward break; 11515853Sedward } 11615853Sedward return 0; 11715853Sedward } 11815853Sedward 11915853Sedward /* 12015853Sedward * string, number, ( expr ) 12115853Sedward * Plus function calls. 12215853Sedward * 12315853Sedward * Always return v_type == V_ERR when flag == 0. 12415853Sedward */ 12515853Sedward p_expr12(v, flag) 12615853Sedward register struct value *v; 12715853Sedward char flag; 12815853Sedward { 12915853Sedward v->v_type = V_ERR; 13015853Sedward switch (token) { 13115853Sedward case T_NUM: 13215853Sedward if (flag) { 13315853Sedward v->v_type = V_NUM; 13415853Sedward v->v_num = token_num; 13515853Sedward } 13615853Sedward (void) s_gettok(); 13715853Sedward break; 13815853Sedward case T_STR: 13915853Sedward if (flag) { 14015853Sedward v->v_type = V_STR; 14115853Sedward v->v_str = token_str; 14215853Sedward } else 14315853Sedward str_free(token_str); 14415853Sedward (void) s_gettok(); 14515853Sedward break; 14615853Sedward case T_LP: 14715853Sedward (void) s_gettok(); 14815853Sedward if (p_expr(v, flag) < 0) { 14915853Sedward p_synerror(); 15015853Sedward return -1; 15115853Sedward } 15215853Sedward if (token != T_RP) { 15315853Sedward p_synerror(); 15415853Sedward val_free(*v); 15515853Sedward return -1; 15615853Sedward } 15715853Sedward (void) s_gettok(); 15815853Sedward break; 15915853Sedward default: 16015853Sedward return -1; 16115853Sedward } 16215853Sedward while (token == T_LP) { 16315853Sedward char *cmd; 16415853Sedward 16516449Sedward if (p_convstr(v) < 0) 16616449Sedward return -1; 16716449Sedward cmd = v->v_type == V_STR ? v->v_str : 0; 16815853Sedward if (p_function(cmd, v, flag) < 0) { 16916298Sedward if (cmd) 17016298Sedward str_free(cmd); 17115853Sedward return -1; 17215853Sedward } 17316298Sedward if (cmd) 17416298Sedward str_free(cmd); 17515853Sedward } 17615853Sedward return 0; 17715853Sedward } 178