00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00041 #include <stdarg.h>
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045
00046 #include "lcmaps_log.h"
00047 #include "pdl_variable.h"
00048 #include "pdl_rule.h"
00049
00050 static var_t *top_var=0, *last_var=0;
00051
00052 BOOL _add_variable(const record_t* name, const record_t* value);
00053 void free_vars(void);
00054 var_t* find_variable(const char* name);
00055 var_t* detect_loop(const char* name, const char* value);
00056 void show_vars(void);
00057
00058
00071 void add_variable(record_t* name, record_t* value)
00072 {
00073 if (!_add_variable(name, value)) {
00074 free(name->string); name->string = NULL;
00075 free(value->string); name->string = NULL;
00076 }
00077
00078 free(name); name = NULL;
00079 free(value); value = NULL;
00080 }
00081
00082
00096 BOOL _add_variable(const record_t* name, const record_t* value)
00097 {
00098 var_t *var;
00099
00100 if ((var = find_variable(name->string))) {
00101 warning(PDL_ERROR, "variable '%s' already defined at line %d; ", var->name, var->lineno);
00102 warning(PDL_SAME, "pervious value: '%s'.", var->value);
00103 return FALSE;
00104 }
00105
00106 if ((var = detect_loop(name->string, value->string))) {
00107 warning(PDL_ERROR, "loop detected on variable '%s'; %s = %s", name->string, name->string, value->string);
00108 while (var) {
00109 var_t* tmp = var;
00110 warning(PDL_SAME, "see also line: %d %s = %s", var->lineno, var->name, var->value);
00111 var = var->next;
00112
00113
00114
00115
00116
00117
00118 free(tmp);
00119 }
00120 return FALSE;
00121 }
00122
00123 if (!(var = (var_t *)malloc(sizeof(var_t)))) {
00124 warning(PDL_ERROR, "Out of memory; cannot add variable '%s'.\n", name->string);
00125 return FALSE;
00126 }
00127
00128 var->name = name->string;
00129 var->value = value->string;
00130 var->okay = FALSE;
00131 var->lineno = name->lineno;
00132 var->next = 0;
00133
00134 if (top_var)
00135 last_var->next = var;
00136 else
00137 top_var = var;
00138
00139 last_var = var;
00140
00141 return TRUE;
00142 }
00143
00144
00149 void free_variables(void)
00150 {
00151 var_t* var = top_var;
00152
00153 while (var) {
00154 var_t* t = var->next;
00155
00156 free((char *)var->name); var->name = NULL;
00157 free((char *)var->value); var->value = NULL;
00158 free(var);
00159
00160 var = t;
00161 }
00162
00163 top_var = 0;
00164 }
00165
00166
00175 var_t* find_variable(const char* name)
00176 {
00177 var_t* var = top_var;
00178
00179 if (!name)
00180 return 0;
00181
00182 while (var && strcmp(name, var->name)!=0) {
00183 var = var->next;
00184 }
00185
00186 return var;
00187 }
00188
00189
00200 var_t* detect_loop(const char* name, const char* value)
00201 {
00202 var_t *loop=0, *top_loop=0, *var = find_variable(value);
00203
00204 while (var) {
00205 var_t* tmp = (var_t *)malloc(sizeof(var_t));
00206
00207 if (loop)
00208 loop->next = tmp;
00209 else
00210 top_loop = tmp;
00211
00212 loop = tmp;
00213 memcpy(loop, var, sizeof(var_t));
00214 loop->next = 0;
00215
00216 tmp = top_loop;
00217 while (tmp && strcmp(name, tmp->value)!=0) {
00218 tmp = tmp->next;
00219 }
00220
00221 if (tmp) return top_loop;
00222
00223 var = find_variable(var->value);
00224 }
00225
00226
00227 while (top_loop) {
00228 var_t* tmp = top_loop;
00229 free(top_loop);
00230 top_loop = tmp->next;
00231 }
00232
00233 return 0;
00234 }
00235
00236
00247 void reduce_to_var(const char** name, rule_type_t rule_type)
00248 {
00249 var_t *var=0, *tmp;
00250 const char* n = *name;
00251
00252 while ((tmp = find_variable(n))) {
00253 var = tmp;
00254 n = var->value;
00255 }
00256
00257 if (var) {
00258 const rule_t* t;
00259 if (var->okay || !(t = get_rule(n, rule_type==STATE ? right_side : left_side))) {
00260 var->okay = TRUE;
00261 free((char *)*name);
00262 *name = (const char*)strdup(n);
00263 } else {
00264 lineno = var->lineno;
00265 warning(PDL_WARNING, "Variable %s points to state %s. This is considered dangerous.", var->name, n);
00266 }
00267 }
00268 }
00269
00270
00277 var_t* get_variables(void)
00278 {
00279 return top_var;
00280 }
00281
00282
00288 void show_variables(void)
00289 {
00290 var_t* var = top_var;
00291
00292 while (var) {
00293 lcmaps_log_debug(1, "var: %s = %s\n", var->name, var->value);
00294 var = var->next;
00295 }
00296 }