source: trunk/emx/src/emxdoc/cond.c@ 2446

Last change on this file since 2446 was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 5.3 KB
Line 
1/* cond.c -- Conditional expressions
2 Copyright (c) 1993-1999 Eberhard Mattes
3
4This file is part of emxdoc.
5
6emxdoc is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11emxdoc is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with emxdoc; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <ctype.h>
26#include "emxdoc.h"
27#include "cond.h"
28
29enum ctok
30{
31 CTOK_END,
32 CTOK_LPAR,
33 CTOK_RPAR,
34 CTOK_OR,
35 CTOK_AND,
36 CTOK_NOT,
37 CTOK_CONST
38};
39
40struct cond_var
41{
42 struct cond_var *next;
43 uchar *name;
44 int value;
45};
46
47static const uchar *cond_ptr;
48static enum ctok ct_token;
49static int ct_value;
50static struct cond_var *cond_vars = NULL;
51
52
53static int cond_or (void);
54static void cond_fetch (void);
55static struct cond_var *cond_find (const uchar *name);
56
57
58int condition (const uchar *p)
59{
60 int result;
61
62 cond_ptr = p;
63 cond_fetch ();
64 result = cond_or ();
65 if (ct_token != CTOK_END)
66 fatal ("%s:%d: End of line expected after condition expression",
67 input_fname, line_no);
68 return result;
69}
70
71
72void cond_set (const uchar *name, int value)
73{
74 struct cond_var *v;
75
76 v = cond_find (name);
77 if (v == NULL)
78 {
79 v = xmalloc (sizeof (*v));
80 v->name = xstrdup (name);
81 v->next = cond_vars;
82 cond_vars = v;
83 }
84 v->value = value;
85}
86
87
88static struct cond_var *cond_find (const uchar *name)
89{
90 struct cond_var *v;
91
92 for (v = cond_vars; v != NULL; v = v->next)
93 if (strcmp (v->name, name) == 0)
94 return v;
95 return NULL;
96}
97
98
99static void cond_fetch (void)
100{
101 static uchar name[512];
102 int len;
103 struct cond_var *v;
104
105 while (isspace (*cond_ptr))
106 ++cond_ptr;
107 switch (*cond_ptr)
108 {
109 case 0:
110 ct_token = CTOK_END;
111 return;
112 case '!':
113 ct_token = CTOK_NOT; ++cond_ptr;
114 return;
115 case '&':
116 ct_token = CTOK_AND; ++cond_ptr;
117 return;
118 case '|':
119 ct_token = CTOK_OR; ++cond_ptr;
120 return;
121 case '(':
122 ct_token = CTOK_LPAR; ++cond_ptr;
123 return;
124 case ')':
125 ct_token = CTOK_RPAR; ++cond_ptr;
126 return;
127 case 'f':
128 if (strncmp (cond_ptr, "false", 5) == 0)
129 {
130 ct_token = CTOK_CONST; ct_value = FALSE;
131 cond_ptr += 5;
132 return;
133 }
134 break;
135 case 'h':
136 if (strncmp (cond_ptr, "html", 4) == 0)
137 {
138 ct_token = CTOK_CONST; ct_value = (mode == 'H');
139 cond_ptr += 4;
140 return;
141 }
142 break;
143 case 'i':
144 if (strncmp (cond_ptr, "ipf", 3) == 0)
145 {
146 ct_token = CTOK_CONST; ct_value = (mode == 'I');
147 cond_ptr += 3;
148 return;
149 }
150 break;
151 case 'l':
152 if (strncmp (cond_ptr, "latex", 5) == 0)
153 {
154 ct_token = CTOK_CONST; ct_value = (mode == 'L');
155 cond_ptr += 5;
156 return;
157 }
158 break;
159 case 't':
160 if (strncmp (cond_ptr, "text", 4) == 0)
161 {
162 ct_token = CTOK_CONST; ct_value = (mode == 'T');
163 cond_ptr += 4;
164 return;
165 }
166 else if (strncmp (cond_ptr, "true", 4) == 0)
167 {
168 ct_token = CTOK_CONST; ct_value = TRUE;
169 cond_ptr += 4;
170 return;
171 }
172 break;
173 }
174 if (isalpha (*cond_ptr))
175 {
176 len = 0;
177 name[len] = cond_ptr[len]; ++len;
178 while (isalnum (cond_ptr[len]) || cond_ptr[len] == '_')
179 name[len] = cond_ptr[len], ++len;
180 name[len] = 0;
181 v = cond_find (name);
182 if (v != NULL)
183 {
184 ct_token = CTOK_CONST; ct_value = v->value;
185 cond_ptr += len;
186 return;
187 }
188 }
189 fatal ("%s:%d: Invalid token in condition expression",
190 input_fname, line_no);
191}
192
193
194static int cond_factor (void)
195{
196 int result;
197
198 switch (ct_token)
199 {
200 case CTOK_LPAR:
201 cond_fetch ();
202 result = cond_or ();
203 if (ct_token != CTOK_RPAR)
204 fatal ("%s:%d: Missing right parenthesis in condition expression",
205 input_fname, line_no);
206 break;
207
208 case CTOK_END:
209 fatal ("%s:%d: Operand expected in condition expression",
210 input_fname, line_no);
211
212 case CTOK_CONST:
213 result = ct_value;
214 cond_fetch ();
215 break;
216
217 default:
218 fatal ("%s:%d: Invalid operand in condition expression",
219 input_fname, line_no);
220 }
221 return result;
222}
223
224
225static int cond_not (void)
226{
227 if (ct_token == CTOK_NOT)
228 {
229 cond_fetch ();
230 return !cond_not ();
231 }
232 else
233 return cond_factor ();
234}
235
236
237static int cond_and (void)
238{
239 int result;
240
241 result = cond_not ();
242 while (ct_token == CTOK_AND)
243 {
244 cond_fetch ();
245 if (!cond_not ())
246 result = FALSE;
247 }
248 return result;
249}
250
251
252static int cond_or (void)
253{
254 int result;
255
256 result = cond_and ();
257 while (ct_token == CTOK_OR)
258 {
259 cond_fetch ();
260 if (cond_and ())
261 result = TRUE;
262 }
263 return result;
264}
Note: See TracBrowser for help on using the repository browser.