]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/zwgc/eval.c
0bf8d1c78d5cfb1195142deed561eae7da4f85bf
[1ts-debian.git] / zephyr / zwgc / eval.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It is one of the source files comprising zwgc, the Zephyr WindowGram
3  * client.
4  *
5  *      Created by:     Marc Horowitz <marc@athena.mit.edu>
6  *
7  *      $Id$
8  *
9  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h".
12  */
13
14 #include <sysdep.h>
15
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_eval_c[] = "$Id$";
18 #endif
19
20 #include <zephyr/mit-copyright.h>
21
22 /****************************************************************************/
23 /*                                                                          */
24 /*                      Code to evaluate an expression:                     */
25 /*                                                                          */
26 /****************************************************************************/
27
28 #include <zephyr/zephyr.h>
29 #include "new_memory.h"
30 #include "node.h"
31 #include "eval.h"
32 #include "substitute.h"
33 #include "port.h"
34 #include "buffer.h"
35 #include "regexp.h"
36 #include "text_operations.h"
37 #include "zwgc.h"
38 #include "variables.h"
39
40 /****************************************************************************/
41 /*                                                                          */
42 /*                Code to deal with string/boolean conversion:              */
43 /*                                                                          */
44 /****************************************************************************/
45
46 /*
47  *  Internal Routine:
48  *
49  *    int string_to_bool(string str)
50  *       Effects: Returns true iff the string str represents true.
51  *                True is represented by any string which is equal to
52  *                "true" when case is disregraded.
53  */
54
55 #define  string_to_bool(str)      (!strcasecmp(str,"true"))
56
57 /*
58  *  Internal Routine:
59  *
60  *    string bool_to_string(int bool)
61  *       Effects: Returns a string representive for the C boolean bool.
62  *                (In C, true == non-zero)  I.e.,
63  *                string_to_bool(bool_to_string(x)) == !!x.
64  *                The string returned is on the heap & must be freed
65  *                eventually.
66  */
67
68 static string bool_to_string(bool)
69      int bool;
70 {
71     return(bool ? string_Copy("TRUE") : string_Copy("FALSE"));
72 }
73
74 /*
75  *    int eval_bool_expr(Node *expr)
76  *        Modifies: dict
77  *        Requires: expr is a proper expression or NULL.  (see node.c)
78  *        Effects: Evaluates expr to its boolean value which is returned.
79  *                 NULL is defined to have the boolean value true.
80  */
81
82 int eval_bool_expr(expr)
83      Node *expr;
84 {
85     string temp;
86     int result;
87
88     if (!expr)
89       return(1);
90
91     temp = eval_expr(expr);
92     result = string_to_bool(temp);
93     free(temp);
94
95     return(result);
96 }
97
98 /****************************************************************************/
99 /*                                                                          */
100 /*                      Code to evaluate an expression:                     */
101 /*                                                                          */
102 /****************************************************************************/
103
104 /*
105  *    string eval_expr(Node *expr)
106  *        Modifies: dict
107  *        Requires: expr is a proper expression (NOT NULL).  (see node.c)
108  *        Effects: Evaluates expr to its string value which is returned.
109  *                 The returned string is on the heap and must be freed
110  *                 eventually.
111  */
112
113 string eval_expr(expr)
114      Node *expr;
115 {
116     int opcode = expr->opcode;
117     int bool_result;
118     string first, second;
119     char *result;
120     string *text_ptr;
121     char *getenv();           /* UNIX get environment variable function */
122
123     /*
124      * Dispatch based on the opcode of the top node in the expression:
125      */
126     switch (opcode) {
127       case STRING_CONSTANT_OPCODE:
128         return(string_Copy(expr->d.string_constant));
129
130       case VARREF_OPCODE:
131         return(string_Copy(var_get_variable(expr->d.string_constant)));
132
133       case BUFFER_OPCODE:
134         return(string_Copy(buffer_to_string()));
135
136         /*
137          * Handle unary expressions:
138          */
139       case NOT_OPCODE:
140       case SUBSTITUTE_OPCODE:
141       case PROTECT_OPCODE:
142       case VERBATIM_OPCODE:
143       case STYLESTRIP_OPCODE:
144       case GETENV_OPCODE:
145       case UPCASE_OPCODE:
146       case DOWNCASE_OPCODE:
147       case ZVAR_OPCODE:
148       case GET_OPCODE:
149         first = eval_expr(expr->d.nodes.first);
150
151         switch (opcode) {
152           case NOT_OPCODE:
153             result = bool_to_string(! string_to_bool(first));
154             break;
155
156           case SUBSTITUTE_OPCODE:
157             result = substitute(var_get_variable, first);
158             break;
159
160           case PROTECT_OPCODE:
161             result=protect(first);
162             break;
163
164           case VERBATIM_OPCODE:
165             return(verbatim(first,0));
166
167           case STYLESTRIP_OPCODE:
168             return(stylestrip(first));
169
170           case GETENV_OPCODE:
171             result = getenv(first);
172             if (!result)
173               result = string_Copy("");
174             else
175               result = string_Copy(result);
176             break;
177
178           case UPCASE_OPCODE:
179             return(string_Upcase(first));
180
181           case DOWNCASE_OPCODE:
182             return(string_Downcase(first));
183
184           case ZVAR_OPCODE:
185             result = ZGetVariable(first);
186             if (!result)
187               result = string_Copy("");
188             else
189               result = string_Copy(result);
190             break;
191
192           case GET_OPCODE:
193             result = read_from_port(first);
194             break;
195         }
196         free(first);
197         break;
198
199         /*
200          * Handle binary operators:
201          */
202       case PLUS_OPCODE:
203       case AND_OPCODE:
204       case OR_OPCODE:
205       case EQ_OPCODE:
206       case NEQ_OPCODE:
207       case REGEQ_OPCODE:
208       case REGNEQ_OPCODE:
209         first = eval_expr(expr->d.nodes.first);
210         second = eval_expr(expr->d.nodes.second);
211
212         switch (opcode) {
213           case PLUS_OPCODE:
214             result = string_Concat(first, second);
215             free(first);
216             free(second);
217             return(result);
218
219           case AND_OPCODE:
220             bool_result = string_to_bool(first) && string_to_bool(second);
221             break;
222
223           case OR_OPCODE:
224             bool_result = string_to_bool(first) || string_to_bool(second);
225             break;
226
227           case EQ_OPCODE:
228             bool_result = string_Eq(first, second);
229             break;
230
231           case NEQ_OPCODE:
232             bool_result = string_Neq(first, second);
233             break;
234
235           case REGEQ_OPCODE:
236             bool_result = ed_regexp_match_p(first, second);
237             break;
238
239           case REGNEQ_OPCODE:
240             bool_result = !ed_regexp_match_p(first, second);
241             break;
242         }
243         free(first);
244         free(second);
245         result = bool_to_string(bool_result);
246         break;
247
248         /*
249          * Handle text-manipulation operators:
250          */
251       case LANY_OPCODE:    case RANY_OPCODE:  
252       case LBREAK_OPCODE:  case RBREAK_OPCODE:
253       case LSPAN_OPCODE:   case RSPAN_OPCODE:
254         first = eval_expr(expr->d.nodes.first);
255         second = eval_expr(expr->d.nodes.second);
256         text_ptr = &first;
257
258         switch (opcode) {
259           case LANY_OPCODE:
260             result = lany(text_ptr, second);
261             break;
262
263           case RANY_OPCODE:  
264             result = rany(text_ptr, second);
265             break;
266
267           case LBREAK_OPCODE:
268             result = lbreak(text_ptr, string_to_character_class(second));
269             break;
270
271           case RBREAK_OPCODE:
272             result = rbreak(text_ptr, string_to_character_class(second));
273             break;
274
275           case LSPAN_OPCODE:
276             result = lspan(text_ptr, string_to_character_class(second));
277             break;
278
279           case RSPAN_OPCODE:
280             result = rspan(text_ptr, string_to_character_class(second));
281             break;
282         }
283
284         if (expr->d.nodes.first->opcode == VARREF_OPCODE)
285           var_set_variable(expr->d.nodes.first->d.string_constant, first);
286         free(first);
287         free(second);
288         break;
289
290 #ifdef DEBUG
291       default:
292         printf("zwgc: internal error: attempt to evaluate the following non-expression:\n");  fflush(stdout);
293         node_display(expr);
294         printf("\n\n");
295         exit(2);
296 #endif
297     }
298
299     return(result);
300 }