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
5 * Created by: Marc Horowitz <marc@athena.mit.edu>
9 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_eval_c[] = "$Id$";
20 #include <zephyr/mit-copyright.h>
22 /****************************************************************************/
24 /* Code to evaluate an expression: */
26 /****************************************************************************/
28 #include <zephyr/zephyr.h>
29 #include "new_memory.h"
32 #include "substitute.h"
36 #include "text_operations.h"
38 #include "variables.h"
40 /****************************************************************************/
42 /* Code to deal with string/boolean conversion: */
44 /****************************************************************************/
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.
55 #define string_to_bool(str) (!strcasecmp(str,"true"))
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
68 static string bool_to_string(bool)
71 return(bool ? string_Copy("TRUE") : string_Copy("FALSE"));
75 * int eval_bool_expr(Node *expr)
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.
82 int eval_bool_expr(expr)
91 temp = eval_expr(expr);
92 result = string_to_bool(temp);
98 /****************************************************************************/
100 /* Code to evaluate an expression: */
102 /****************************************************************************/
105 * string eval_expr(Node *expr)
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
113 string eval_expr(expr)
116 int opcode = expr->opcode;
118 string first, second;
121 char *getenv(); /* UNIX get environment variable function */
124 * Dispatch based on the opcode of the top node in the expression:
127 case STRING_CONSTANT_OPCODE:
128 return(string_Copy(expr->d.string_constant));
131 return(string_Copy(var_get_variable(expr->d.string_constant)));
134 return(string_Copy(buffer_to_string()));
137 * Handle unary expressions:
140 case SUBSTITUTE_OPCODE:
142 case VERBATIM_OPCODE:
143 case STYLESTRIP_OPCODE:
146 case DOWNCASE_OPCODE:
149 first = eval_expr(expr->d.nodes.first);
153 result = bool_to_string(! string_to_bool(first));
156 case SUBSTITUTE_OPCODE:
157 result = substitute(var_get_variable, first);
161 result=protect(first);
164 case VERBATIM_OPCODE:
165 return(verbatim(first,0));
167 case STYLESTRIP_OPCODE:
168 return(stylestrip(first));
171 result = getenv(first);
173 result = string_Copy("");
175 result = string_Copy(result);
179 return(string_Upcase(first));
181 case DOWNCASE_OPCODE:
182 return(string_Downcase(first));
185 result = ZGetVariable(first);
187 result = string_Copy("");
189 result = string_Copy(result);
193 result = read_from_port(first);
200 * Handle binary operators:
209 first = eval_expr(expr->d.nodes.first);
210 second = eval_expr(expr->d.nodes.second);
214 result = string_Concat(first, second);
220 bool_result = string_to_bool(first) && string_to_bool(second);
224 bool_result = string_to_bool(first) || string_to_bool(second);
228 bool_result = string_Eq(first, second);
232 bool_result = string_Neq(first, second);
236 bool_result = ed_regexp_match_p(first, second);
240 bool_result = !ed_regexp_match_p(first, second);
245 result = bool_to_string(bool_result);
249 * Handle text-manipulation operators:
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);
260 result = lany(text_ptr, second);
264 result = rany(text_ptr, second);
268 result = lbreak(text_ptr, string_to_character_class(second));
272 result = rbreak(text_ptr, string_to_character_class(second));
276 result = lspan(text_ptr, string_to_character_class(second));
280 result = rspan(text_ptr, string_to_character_class(second));
284 if (expr->d.nodes.first->opcode == VARREF_OPCODE)
285 var_set_variable(expr->d.nodes.first->d.string_constant, first);
292 printf("zwgc: internal error: attempt to evaluate the following non-expression:\n"); fflush(stdout);