Annotation of src/usr.bin/window/parser5.c, Revision 1.5
1.5 ! millert 1: /* $OpenBSD: parser5.c,v 1.4 2001/11/19 19:02:18 mpech Exp $ */
1.1 deraadt 2: /* $NetBSD: parser5.c,v 1.3 1995/09/28 10:34:35 tls Exp $ */
3:
4: /*
5: * Copyright (c) 1983, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Edward Wang at The University of California, Berkeley.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
1.5 ! millert 19: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
36: #ifndef lint
37: #if 0
38: static char sccsid[] = "@(#)parser5.c 8.1 (Berkeley) 6/6/93";
39: #else
1.5 ! millert 40: static char rcsid[] = "$OpenBSD: parser5.c,v 1.4 2001/11/19 19:02:18 mpech Exp $";
1.1 deraadt 41: #endif
42: #endif /* not lint */
43:
44: #include "parser.h"
45: #include "var.h"
46:
47: /*
48: * unary $ $? + - ! ~
49: */
50: p_expr11(v, flag)
1.4 mpech 51: struct value *v;
1.1 deraadt 52: char flag;
53: {
54: int op;
55: char *opname;
56:
57: switch (token) {
58: case T_DOLLAR:
59: opname = "$";
60: break;
61: case T_DQ:
62: opname = "$?";
63: break;
64: case T_PLUS:
65: opname = "unary +";
66: break;
67: case T_MINUS:
68: opname = "unary -";
69: break;
70: case T_NOT:
71: opname = "!";
72: break;
73: case T_COMP:
74: opname = "~";
75: break;
76: default:
77: return p_expr12(v, flag);
78: }
79: op = token;
80: (void) s_gettok();
81: if (p_expr11(v, flag) < 0)
82: return -1;
83: switch (v->v_type) {
84: case V_NUM:
85: break;
86: case V_STR:
87: switch (op) {
88: case T_MINUS:
89: case T_NOT:
90: case T_COMP:
91: p_error("%s: Numeric operand required.", opname);
92: str_free(v->v_str);
93: v->v_type = V_ERR;
94: return 0;
95: }
96: break;
97: case V_ERR:
98: return 0;
99: }
100: switch (op) {
101: case T_DOLLAR:
102: case T_DQ:
103: if (v->v_type == V_NUM) {
104: int tmp = cx.x_type == X_BUF && cx.x_arg != 0 &&
105: v->v_num > 0 && v->v_num <= cx.x_narg;
106: if (op == T_DQ)
107: v->v_num = tmp;
108: else if (tmp)
109: *v = cx.x_arg[v->v_num - 1];
110: else {
111: p_error("%d: No such argument.", v->v_num);
112: v->v_type = V_ERR;
113: }
114: } else {
115: char *name = v->v_str;
116: struct var *r = var_lookup(name);
117: if (op == T_DQ) {
118: v->v_type = V_NUM;
119: v->v_num = r != 0;
120: } else if (r != 0)
121: *v = r->r_val;
122: else {
123: p_error("%s: Undefined variable.", name);
124: v->v_type = V_ERR;
125: }
126: str_free(name);
127: }
128: if (v->v_type == V_STR && (v->v_str = str_cpy(v->v_str)) == 0) {
129: p_memerror();
130: return -1;
131: }
132: break;
133: case T_MINUS:
134: v->v_num = - v->v_num;
135: break;
136: case T_NOT:
137: v->v_num = ! v->v_num;
138: break;
139: case T_COMP:
140: v->v_num = ~ v->v_num;
141: break;
142: }
143: return 0;
144: }
145:
146: /*
147: * string, number, ( expr )
148: * Plus function calls.
149: *
150: * Always return v_type == V_ERR when flag == 0.
151: */
152: p_expr12(v, flag)
1.4 mpech 153: struct value *v;
1.1 deraadt 154: char flag;
155: {
156: v->v_type = V_ERR;
157: switch (token) {
158: case T_NUM:
159: if (flag) {
160: v->v_type = V_NUM;
161: v->v_num = token_num;
162: }
163: (void) s_gettok();
164: break;
165: case T_STR:
166: if (flag) {
167: v->v_type = V_STR;
168: v->v_str = token_str;
169: } else
170: str_free(token_str);
171: (void) s_gettok();
172: break;
173: case T_LP:
174: (void) s_gettok();
175: if (p_expr(v, flag) < 0) {
176: p_synerror();
177: return -1;
178: }
179: if (token != T_RP) {
180: p_synerror();
181: val_free(*v);
182: return -1;
183: }
184: (void) s_gettok();
185: break;
186: default:
187: return -1;
188: }
189: while (token == T_LP) {
190: char *cmd;
191:
192: if (p_convstr(v) < 0)
193: return -1;
194: cmd = v->v_type == V_STR ? v->v_str : 0;
195: if (p_function(cmd, v, flag) < 0) {
196: if (cmd)
197: str_free(cmd);
198: return -1;
199: }
200: if (cmd)
201: str_free(cmd);
202: }
203: return 0;
204: }