00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00034 #include <stdarg.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038
00039 #include "lcmaps_log.h"
00040 #include "pdl_variable.h"
00041 #include "pdl_rule.h"
00042
00043 static var_t *top_var=0, *last_var=0;
00044
00045 BOOL _add_variable(const record_t* name, const record_t* value);
00046 void free_vars(void);
00047 var_t* find_variable(const char* name);
00048 var_t* detect_loop(const char* name, const char* value);
00049 void show_vars(void);
00050
00051
00064 void add_variable(record_t* name, record_t* value)
00065 {
00066 if (!_add_variable(name, value)) {
00067 free(name->string);
00068 free(value->string);
00069 }
00070
00071 free(name);
00072 free(value);
00073 }
00074
00075
00089 BOOL _add_variable(const record_t* name, const record_t* value)
00090 {
00091 var_t *var;
00092
00093 if ((var = find_variable(name->string))) {
00094 warning(PDL_ERROR, "variable '%s' already defined at line %d; ", var->name, var->lineno);
00095 warning(PDL_SAME, "pervious value: '%s'.", var->value);
00096 return FALSE;
00097 }
00098
00099 if ((var = detect_loop(name->string, value->string))) {
00100 warning(PDL_ERROR, "loop detected on variable '%s'; %s = %s", name->string, name->string, value->string);
00101 while (var) {
00102 var_t* tmp = var;
00103 warning(PDL_SAME, "see also line: %d %s = %s", var->lineno, var->name, var->value);
00104 var = var->next;
00105
00106
00107
00108
00109
00110
00111 free(tmp);
00112 }
00113 return FALSE;
00114 }
00115
00116 if (!(var = (var_t *)malloc(sizeof(var_t)))) {
00117 warning(PDL_ERROR, "Out of memory; cannot add variable '%s'.\n", name->string);
00118 return FALSE;
00119 }
00120
00121 var->name = name->string;
00122 var->value = value->string;
00123 var->okay = FALSE;
00124 var->lineno = name->lineno;
00125 var->next = 0;
00126
00127 if (top_var)
00128 last_var->next = var;
00129 else
00130 top_var = var;
00131
00132 last_var = var;
00133
00134 return TRUE;
00135 }
00136
00137
00142 void free_variables(void)
00143 {
00144 var_t* var = top_var;
00145
00146 while (var) {
00147 var_t* t = var->next;
00148
00149 free((char *)var->name);
00150 free((char *)var->value);
00151 free(var);
00152
00153 var = t;
00154 }
00155
00156 top_var = 0;
00157 }
00158
00159
00168 var_t* find_variable(const char* name)
00169 {
00170 var_t* var = top_var;
00171
00172 if (!name)
00173 return 0;
00174
00175 while (var && strcmp(name, var->name)!=0) {
00176 var = var->next;
00177 }
00178
00179 return var;
00180 }
00181
00182
00193 var_t* detect_loop(const char* name, const char* value)
00194 {
00195 var_t *loop=0, *top_loop=0, *var = find_variable(value);
00196
00197 while (var) {
00198 var_t* tmp = (var_t *)malloc(sizeof(var_t));
00199
00200 if (loop)
00201 loop->next = tmp;
00202 else
00203 top_loop = tmp;
00204
00205 loop = tmp;
00206 memcpy(loop, var, sizeof(var_t));
00207 loop->next = 0;
00208
00209 tmp = top_loop;
00210 while (tmp && strcmp(name, tmp->value)!=0) {
00211 tmp = tmp->next;
00212 }
00213
00214 if (tmp) return top_loop;
00215
00216 var = find_variable(var->value);
00217 }
00218
00219
00220 while (top_loop) {
00221 var_t* tmp = top_loop;
00222 free(top_loop);
00223 top_loop = tmp->next;
00224 }
00225
00226 return 0;
00227 }
00228
00229
00239 void reduce_to_var(const char** name, rule_type_t rule_type)
00240 {
00241 var_t *var=0, *tmp;
00242 const char* n = *name;
00243
00244 while ((tmp = find_variable(n))) {
00245 var = tmp;
00246 n = var->value;
00247 }
00248
00249 if (var) {
00250 const rule_t* t;
00251 if (var->okay || !(t = get_rule(n, rule_type==STATE ? right_side : left_side))) {
00252 var->okay = TRUE;
00253 free((char *)*name);
00254 *name = (const char*)strdup(n);
00255 } else {
00256 lineno = var->lineno;
00257 warning(PDL_WARNING, "Variable %s points to state %s. This is considered dangerous.", var->name, n);
00258 }
00259 }
00260 }
00261
00262
00269 var_t* get_variables(void)
00270 {
00271 return top_var;
00272 }
00273
00274
00280 void show_variables(void)
00281 {
00282 var_t* var = top_var;
00283
00284 while (var) {
00285 lcmaps_log_debug(1, "var: %s = %s\n", var->name, var->value);
00286 var = var->next;
00287 }
00288 }