|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)parser5.c 3.9 4/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.