Annotation of src/usr.bin/window/parser1.c, Revision 1.5
1.5 ! millert 1: /* $OpenBSD: parser1.c,v 1.4 2001/11/19 19:02:18 mpech Exp $ */
1.1 deraadt 2: /* $NetBSD: parser1.c,v 1.3 1995/09/28 10:34:31 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[] = "@(#)parser1.c 8.1 (Berkeley) 6/6/93";
39: #else
1.5 ! millert 40: static char rcsid[] = "$OpenBSD: parser1.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:
46: p_start()
47: {
48: char flag = 1;
49:
50: (void) s_gettok();
51: for (;;) {
52: p_statementlist(flag);
53: if (token == T_EOF || p_abort())
54: break;
55: flag = 0;
56: p_synerror();
57: while (token != T_EOL && token != T_EOF) {
58: if (token == T_STR)
59: str_free(token_str);
60: (void) s_gettok();
61: }
62: if (token == T_EOL)
63: (void) s_gettok();
64: p_clearerr();
65: }
66: }
67:
68: p_statementlist(flag)
69: char flag;
70: {
71: for (; p_statement(flag) >= 0; p_clearerr())
72: ;
73: }
74:
75: p_statement(flag)
76: char flag;
77: {
78: switch (token) {
79: case T_EOL:
80: (void) s_gettok();
81: return 0;
82: case T_IF:
83: return p_if(flag);
84: default:
85: return p_expression(flag);
86: }
87: }
88:
89: p_if(flag)
90: char flag;
91: {
92: struct value t;
93: char true = 0;
94:
95: top:
96: (void) s_gettok();
97:
98: if (p_expr(&t, flag) < 0) {
99: p_synerror();
100: return -1;
101: }
102: switch (t.v_type) {
103: case V_NUM:
104: true = !true && t.v_num != 0;
105: break;
106: case V_STR:
107: p_error("if: Numeric value required.");
108: str_free(t.v_str);
109: case V_ERR:
110: flag = 0;
111: break;
112: }
113:
114: if (token != T_THEN) {
115: p_synerror();
116: return -1;
117: }
118:
119: (void) s_gettok();
120: p_statementlist(flag && true);
121: if (p_erred())
122: return -1;
123:
124: if (token == T_ELSIF)
125: goto top;
126:
127: if (token == T_ELSE) {
128: (void) s_gettok();
129: p_statementlist(flag && !true);
130: if (p_erred())
131: return -1;
132: }
133:
134: if (token == T_ENDIF) {
135: (void) s_gettok();
136: return 0;
137: }
138:
139: p_synerror();
140: return -1;
141: }
142:
143: p_expression(flag)
144: char flag;
145: {
146: struct value t;
147: char *cmd;
148: int p_function(), p_assign();
149:
150: switch (token) {
151: case T_NUM:
152: t.v_type = V_NUM;
153: t.v_num = token_num;
154: (void) s_gettok();
155: break;
156: case T_STR:
157: t.v_type = V_STR;
158: t.v_str = token_str;
159: (void) s_gettok();
160: break;
161: default:
162: if (p_expr(&t, flag) < 0)
163: return -1;
164: if (token == T_EOF) {
165: val_free(t);
166: return 0;
167: }
168: }
169: if (token != T_ASSIGN && p_convstr(&t) < 0)
170: return -1;
171: cmd = t.v_type == V_STR ? t.v_str : 0;
172: if ((*(token == T_ASSIGN ? p_assign : p_function))(cmd, &t, flag) < 0) {
173: if (cmd)
174: str_free(cmd);
175: return -1;
176: }
177: if (cmd)
178: str_free(cmd);
179: val_free(t);
180: if (token == T_EOL)
181: (void) s_gettok();
182: else if (token != T_EOF) {
183: p_synerror();
184: return -1;
185: }
186: return 0;
187: }
188:
189: p_convstr(v)
1.4 mpech 190: struct value *v;
1.1 deraadt 191: {
192: if (v->v_type != V_NUM)
193: return 0;
194: if ((v->v_str = str_itoa(v->v_num)) == 0) {
195: p_memerror();
196: v->v_type = V_ERR;
197: return -1;
198: }
199: v->v_type = V_STR;
200: return 0;
201: }
202:
203: p_synerror()
204: {
205: if (!cx.x_synerred) {
206: cx.x_synerred = cx.x_erred = 1;
207: error("Syntax error.");
208: }
209: }
210:
211: /*VARARGS1*/
212: p_error(msg, a, b, c)
213: char *msg;
214: {
215: if (!cx.x_erred) {
216: cx.x_erred = 1;
217: error(msg, a, b, c);
218: }
219: }
220:
221: p_memerror()
222: {
223: cx.x_erred = cx.x_abort = 1;
224: error("Out of memory.");
225: }