115853Sedward #ifndef lint 2*18754Sedward static char sccsid[] = "@(#)parser5.c 3.9 04/24/85"; 315853Sedward #endif 415853Sedward 5*18754Sedward /* 6*18754Sedward * Copyright (c) 1983 Regents of the University of California, 7*18754Sedward * All rights reserved. Redistribution permitted subject to 8*18754Sedward * the terms of the Berkeley Software License Agreement. 9*18754Sedward */ 10*18754Sedward 1115853Sedward #include "parser.h" 1215864Sedward #include "var.h" 1315853Sedward 1415853Sedward /* 1516714Sedward * unary $ $? + - ! ~ 1615853Sedward */ 1715853Sedward p_expr11(v, flag) 1815853Sedward register struct value *v; 1915853Sedward char flag; 2015853Sedward { 2115853Sedward int op; 2215853Sedward char *opname; 2315853Sedward 2415853Sedward switch (token) { 2515853Sedward case T_DOLLAR: 2615853Sedward opname = "$"; 2715853Sedward break; 2816714Sedward case T_DQ: 2916714Sedward opname = "$?"; 3016714Sedward break; 3115853Sedward case T_PLUS: 3215853Sedward opname = "unary +"; 3315853Sedward break; 3415853Sedward case T_MINUS: 3515853Sedward opname = "unary -"; 3615853Sedward break; 3715853Sedward case T_NOT: 3815853Sedward opname = "!"; 3915853Sedward break; 4015853Sedward case T_COMP: 4115853Sedward opname = "~"; 4215853Sedward break; 4315853Sedward default: 4415853Sedward return p_expr12(v, flag); 4515853Sedward } 4615853Sedward op = token; 4715853Sedward (void) s_gettok(); 4815853Sedward if (p_expr11(v, flag) < 0) 4915853Sedward return -1; 5015853Sedward switch (v->v_type) { 5115853Sedward case V_NUM: 5215853Sedward break; 5315853Sedward case V_STR: 5415853Sedward switch (op) { 5515853Sedward case T_MINUS: 5615853Sedward case T_NOT: 5715853Sedward case T_COMP: 5816714Sedward p_error("%s: Numeric operand required.", opname); 5915853Sedward str_free(v->v_str); 6015853Sedward v->v_type = V_ERR; 6115853Sedward return 0; 6215853Sedward } 6315853Sedward break; 6415853Sedward case V_ERR: 6515853Sedward return 0; 6615853Sedward } 6715853Sedward switch (op) { 6816714Sedward case T_DOLLAR: 6916714Sedward case T_DQ: 7016449Sedward if (v->v_type == V_NUM) { 7116714Sedward int tmp = cx.x_type == X_BUF && cx.x_arg != 0 && 7216714Sedward v->v_num > 0 && v->v_num <= cx.x_narg; 7316714Sedward if (op == T_DQ) 7416714Sedward v->v_num = tmp; 7516714Sedward else if (tmp) 7616714Sedward *v = cx.x_arg[v->v_num - 1]; 7716714Sedward else { 7816449Sedward p_error("%d: No such argument.", v->v_num); 7916449Sedward v->v_type = V_ERR; 8016449Sedward } 8116449Sedward } else { 8216714Sedward char *name = v->v_str; 8316714Sedward struct var *r = var_lookup(name); 8416714Sedward if (op == T_DQ) { 8516714Sedward v->v_type = V_NUM; 8616714Sedward v->v_num = r != 0; 8716714Sedward } else if (r != 0) 8816714Sedward *v = r->r_val; 8916714Sedward else { 9016714Sedward p_error("%s: Undefined variable.", name); 9116449Sedward v->v_type = V_ERR; 9216449Sedward } 9316714Sedward str_free(name); 9415853Sedward } 9516714Sedward if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) { 9616449Sedward p_memerror(); 9716449Sedward return -1; 9815853Sedward } 9915853Sedward break; 10015853Sedward case T_MINUS: 10115853Sedward v->v_num = - v->v_num; 10215853Sedward break; 10315853Sedward case T_NOT: 10415853Sedward v->v_num = ! v->v_num; 10515853Sedward break; 10615853Sedward case T_COMP: 10715853Sedward v->v_num = ~ v->v_num; 10815853Sedward break; 10915853Sedward } 11015853Sedward return 0; 11115853Sedward } 11215853Sedward 11315853Sedward /* 11415853Sedward * string, number, ( expr ) 11515853Sedward * Plus function calls. 11615853Sedward * 11715853Sedward * Always return v_type == V_ERR when flag == 0. 11815853Sedward */ 11915853Sedward p_expr12(v, flag) 12015853Sedward register struct value *v; 12115853Sedward char flag; 12215853Sedward { 12315853Sedward v->v_type = V_ERR; 12415853Sedward switch (token) { 12515853Sedward case T_NUM: 12615853Sedward if (flag) { 12715853Sedward v->v_type = V_NUM; 12815853Sedward v->v_num = token_num; 12915853Sedward } 13015853Sedward (void) s_gettok(); 13115853Sedward break; 13215853Sedward case T_STR: 13315853Sedward if (flag) { 13415853Sedward v->v_type = V_STR; 13515853Sedward v->v_str = token_str; 13615853Sedward } else 13715853Sedward str_free(token_str); 13815853Sedward (void) s_gettok(); 13915853Sedward break; 14015853Sedward case T_LP: 14115853Sedward (void) s_gettok(); 14215853Sedward if (p_expr(v, flag) < 0) { 14315853Sedward p_synerror(); 14415853Sedward return -1; 14515853Sedward } 14615853Sedward if (token != T_RP) { 14715853Sedward p_synerror(); 14815853Sedward val_free(*v); 14915853Sedward return -1; 15015853Sedward } 15115853Sedward (void) s_gettok(); 15215853Sedward break; 15315853Sedward default: 15415853Sedward return -1; 15515853Sedward } 15615853Sedward while (token == T_LP) { 15715853Sedward char *cmd; 15815853Sedward 15916449Sedward if (p_convstr(v) < 0) 16016449Sedward return -1; 16116449Sedward cmd = v->v_type == V_STR ? v->v_str : 0; 16215853Sedward if (p_function(cmd, v, flag) < 0) { 16316298Sedward if (cmd) 16416298Sedward str_free(cmd); 16515853Sedward return -1; 16615853Sedward } 16716298Sedward if (cmd) 16816298Sedward str_free(cmd); 16915853Sedward } 17015853Sedward return 0; 17115853Sedward } 172