Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

pdl_variable.c

Go to the documentation of this file.
00001 /*
00002  *   Copyright (c) 2003 EU DataGrid        http://www.eu-datagrid.org/
00003  *
00004  *   $Id: pdl_variable.c,v 1.9 2003/07/30 14:37:09 venekamp Exp $
00005  *
00006  *   Copyright (c) 2003 by
00007  *      G.M. Venekamp <venekamp@nikhef.nl>
00008  *      NIKHEF Amsterdam, the Netherlands
00009  *
00010  *   This software is distributed under a BSD-style open source
00011  *   licence. For a complete description of the licence take a look
00012  *   at: http://eu-datagrid.web.cern.ch/eu-datagrid/license.html
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        *  A list is created during the detect_loop call. This list must be
00107        *  freed. However, the elements of the structure are direct copies
00108        *  of existing elements. Therefore, only the list elements need be
00109        *  freed and not any of the structure elements!
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   /*  No loop was detected, free the allocated memory.  */
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 }

Generated at Thu Mar 4 17:39:03 2004 for edg-lcmaps by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001