|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Edward Wang at The University of California, Berkeley. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: static char sccsid[] = "@(#)parser5.c 3.13 (Berkeley) 6/6/90"; ! 25: #endif /* not lint */ ! 26: ! 27: #include "parser.h" ! 28: #include "var.h" ! 29: ! 30: /* ! 31: * unary $ $? + - ! ~ ! 32: */ ! 33: p_expr11(v, flag) ! 34: register struct value *v; ! 35: char flag; ! 36: { ! 37: int op; ! 38: char *opname; ! 39: ! 40: switch (token) { ! 41: case T_DOLLAR: ! 42: opname = "$"; ! 43: break; ! 44: case T_DQ: ! 45: opname = "$?"; ! 46: break; ! 47: case T_PLUS: ! 48: opname = "unary +"; ! 49: break; ! 50: case T_MINUS: ! 51: opname = "unary -"; ! 52: break; ! 53: case T_NOT: ! 54: opname = "!"; ! 55: break; ! 56: case T_COMP: ! 57: opname = "~"; ! 58: break; ! 59: default: ! 60: return p_expr12(v, flag); ! 61: } ! 62: op = token; ! 63: (void) s_gettok(); ! 64: if (p_expr11(v, flag) < 0) ! 65: return -1; ! 66: switch (v->v_type) { ! 67: case V_NUM: ! 68: break; ! 69: case V_STR: ! 70: switch (op) { ! 71: case T_MINUS: ! 72: case T_NOT: ! 73: case T_COMP: ! 74: p_error("%s: Numeric operand required.", opname); ! 75: str_free(v->v_str); ! 76: v->v_type = V_ERR; ! 77: return 0; ! 78: } ! 79: break; ! 80: case V_ERR: ! 81: return 0; ! 82: } ! 83: switch (op) { ! 84: case T_DOLLAR: ! 85: case T_DQ: ! 86: if (v->v_type == V_NUM) { ! 87: int tmp = cx.x_type == X_BUF && cx.x_arg != 0 && ! 88: v->v_num > 0 && v->v_num <= cx.x_narg; ! 89: if (op == T_DQ) ! 90: v->v_num = tmp; ! 91: else if (tmp) ! 92: *v = cx.x_arg[v->v_num - 1]; ! 93: else { ! 94: p_error("%d: No such argument.", v->v_num); ! 95: v->v_type = V_ERR; ! 96: } ! 97: } else { ! 98: char *name = v->v_str; ! 99: struct var *r = var_lookup(name); ! 100: if (op == T_DQ) { ! 101: v->v_type = V_NUM; ! 102: v->v_num = r != 0; ! 103: } else if (r != 0) ! 104: *v = r->r_val; ! 105: else { ! 106: p_error("%s: Undefined variable.", name); ! 107: v->v_type = V_ERR; ! 108: } ! 109: str_free(name); ! 110: } ! 111: if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) { ! 112: p_memerror(); ! 113: return -1; ! 114: } ! 115: break; ! 116: case T_MINUS: ! 117: v->v_num = - v->v_num; ! 118: break; ! 119: case T_NOT: ! 120: v->v_num = ! v->v_num; ! 121: break; ! 122: case T_COMP: ! 123: v->v_num = ~ v->v_num; ! 124: break; ! 125: } ! 126: return 0; ! 127: } ! 128: ! 129: /* ! 130: * string, number, ( expr ) ! 131: * Plus function calls. ! 132: * ! 133: * Always return v_type == V_ERR when flag == 0. ! 134: */ ! 135: p_expr12(v, flag) ! 136: register struct value *v; ! 137: char flag; ! 138: { ! 139: v->v_type = V_ERR; ! 140: switch (token) { ! 141: case T_NUM: ! 142: if (flag) { ! 143: v->v_type = V_NUM; ! 144: v->v_num = token_num; ! 145: } ! 146: (void) s_gettok(); ! 147: break; ! 148: case T_STR: ! 149: if (flag) { ! 150: v->v_type = V_STR; ! 151: v->v_str = token_str; ! 152: } else ! 153: str_free(token_str); ! 154: (void) s_gettok(); ! 155: break; ! 156: case T_LP: ! 157: (void) s_gettok(); ! 158: if (p_expr(v, flag) < 0) { ! 159: p_synerror(); ! 160: return -1; ! 161: } ! 162: if (token != T_RP) { ! 163: p_synerror(); ! 164: val_free(*v); ! 165: return -1; ! 166: } ! 167: (void) s_gettok(); ! 168: break; ! 169: default: ! 170: return -1; ! 171: } ! 172: while (token == T_LP) { ! 173: char *cmd; ! 174: ! 175: if (p_convstr(v) < 0) ! 176: return -1; ! 177: cmd = v->v_type == V_STR ? v->v_str : 0; ! 178: if (p_function(cmd, v, flag) < 0) { ! 179: if (cmd) ! 180: str_free(cmd); ! 181: return -1; ! 182: } ! 183: if (cmd) ! 184: str_free(cmd); ! 185: } ! 186: return 0; ! 187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.