1 #ifndef lint 2 static char sccsid[] = "@(#)parser5.c 3.9 04/24/85"; 3 #endif 4 5 /* 6 * Copyright (c) 1983 Regents of the University of California, 7 * All rights reserved. Redistribution permitted subject to 8 * the terms of the Berkeley Software License Agreement. 9 */ 10 11 #include "parser.h" 12 #include "var.h" 13 14 /* 15 * unary $ $? + - ! ~ 16 */ 17 p_expr11(v, flag) 18 register struct value *v; 19 char flag; 20 { 21 int op; 22 char *opname; 23 24 switch (token) { 25 case T_DOLLAR: 26 opname = "$"; 27 break; 28 case T_DQ: 29 opname = "$?"; 30 break; 31 case T_PLUS: 32 opname = "unary +"; 33 break; 34 case T_MINUS: 35 opname = "unary -"; 36 break; 37 case T_NOT: 38 opname = "!"; 39 break; 40 case T_COMP: 41 opname = "~"; 42 break; 43 default: 44 return p_expr12(v, flag); 45 } 46 op = token; 47 (void) s_gettok(); 48 if (p_expr11(v, flag) < 0) 49 return -1; 50 switch (v->v_type) { 51 case V_NUM: 52 break; 53 case V_STR: 54 switch (op) { 55 case T_MINUS: 56 case T_NOT: 57 case T_COMP: 58 p_error("%s: Numeric operand required.", opname); 59 str_free(v->v_str); 60 v->v_type = V_ERR; 61 return 0; 62 } 63 break; 64 case V_ERR: 65 return 0; 66 } 67 switch (op) { 68 case T_DOLLAR: 69 case T_DQ: 70 if (v->v_type == V_NUM) { 71 int tmp = cx.x_type == X_BUF && cx.x_arg != 0 && 72 v->v_num > 0 && v->v_num <= cx.x_narg; 73 if (op == T_DQ) 74 v->v_num = tmp; 75 else if (tmp) 76 *v = cx.x_arg[v->v_num - 1]; 77 else { 78 p_error("%d: No such argument.", v->v_num); 79 v->v_type = V_ERR; 80 } 81 } else { 82 char *name = v->v_str; 83 struct var *r = var_lookup(name); 84 if (op == T_DQ) { 85 v->v_type = V_NUM; 86 v->v_num = r != 0; 87 } else if (r != 0) 88 *v = r->r_val; 89 else { 90 p_error("%s: Undefined variable.", name); 91 v->v_type = V_ERR; 92 } 93 str_free(name); 94 } 95 if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) { 96 p_memerror(); 97 return -1; 98 } 99 break; 100 case T_MINUS: 101 v->v_num = - v->v_num; 102 break; 103 case T_NOT: 104 v->v_num = ! v->v_num; 105 break; 106 case T_COMP: 107 v->v_num = ~ v->v_num; 108 break; 109 } 110 return 0; 111 } 112 113 /* 114 * string, number, ( expr ) 115 * Plus function calls. 116 * 117 * Always return v_type == V_ERR when flag == 0. 118 */ 119 p_expr12(v, flag) 120 register struct value *v; 121 char flag; 122 { 123 v->v_type = V_ERR; 124 switch (token) { 125 case T_NUM: 126 if (flag) { 127 v->v_type = V_NUM; 128 v->v_num = token_num; 129 } 130 (void) s_gettok(); 131 break; 132 case T_STR: 133 if (flag) { 134 v->v_type = V_STR; 135 v->v_str = token_str; 136 } else 137 str_free(token_str); 138 (void) s_gettok(); 139 break; 140 case T_LP: 141 (void) s_gettok(); 142 if (p_expr(v, flag) < 0) { 143 p_synerror(); 144 return -1; 145 } 146 if (token != T_RP) { 147 p_synerror(); 148 val_free(*v); 149 return -1; 150 } 151 (void) s_gettok(); 152 break; 153 default: 154 return -1; 155 } 156 while (token == T_LP) { 157 char *cmd; 158 159 if (p_convstr(v) < 0) 160 return -1; 161 cmd = v->v_type == V_STR ? v->v_str : 0; 162 if (p_function(cmd, v, flag) < 0) { 163 if (cmd) 164 str_free(cmd); 165 return -1; 166 } 167 if (cmd) 168 str_free(cmd); 169 } 170 return 0; 171 } 172