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