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