00001
00012 #include <stdarg.h>
00013 #include "output.h"
00014 #include "globals.h"
00015 #include "module.h"
00016
00017 static GLOBALVAR *global_varlist = NULL, *lastvar = NULL;
00018
00019 static struct s_varmap {
00020 char *name;
00021 PROPERTYTYPE type;
00022 void *addr;
00023 PROPERTYACCESS access;
00024 char *init;
00025 } map[] = {
00027 {"version.major", PT_int32, &global_version_major, PA_REFERENCE},
00028 {"version.minor", PT_int32, &global_version_minor, PA_REFERENCE},
00029 {"command_line", PT_char1024, &global_command_line, PA_REFERENCE},
00030 {"environment", PT_char1024, &global_environment, PA_REFERENCE},
00031 {"quiet", PT_int32, &global_quiet_mode, PA_REFERENCE},
00032 {"warn", PT_int32, &global_warn_mode, PA_REFERENCE},
00033 {"debugger", PT_int32, &global_debug_mode, PA_REFERENCE},
00034 {"debug", PT_int32, &global_debug_output, PA_REFERENCE},
00035 {"test", PT_int32, &global_debug_mode, PA_REFERENCE},
00036 {"verbose", PT_int32, &global_verbose_mode, PA_REFERENCE},
00037 {"iteration_limit", PT_int32, &global_iteration_limit, PA_REFERENCE},
00038 {"workdir", PT_char1024, &global_workdir, PA_REFERENCE},
00039 {"dumpfile", PT_char1024, &global_dumpfile, PA_REFERENCE},
00040 {"savefile", PT_char1024, &global_savefile, PA_REFERENCE},
00041 {"dumpall", PT_int32, &global_dumpall, PA_REFERENCE},
00042 {"runchecks", PT_int32, &global_runchecks, PA_REFERENCE},
00043 {"threadcount", PT_int32, &global_threadcount, PA_REFERENCE},
00044 {"profiler", PT_int32, &global_profiler, PA_REFERENCE},
00045 {"pauseatexit", PT_int32, &global_pauseatexit, PA_REFERENCE},
00046 {"testoutputfile", PT_char1024, &global_testoutputfile, PA_REFERENCE},
00047 {"xml_encoding", PT_int32, &global_xml_encoding, PA_REFERENCE},
00048 {"clock", PT_timestamp, &global_clock, PA_REFERENCE},
00049 {"starttime", PT_timestamp, &global_starttime, PA_REFERENCE},
00050 {"stoptime", PT_timestamp, &global_stoptime, PA_REFERENCE},
00051 {"double_format", PT_char32, &global_double_format, PA_REFERENCE},
00052 {"complex_format", PT_char256, &global_complex_format, PA_REFERENCE},
00053 {"object_format", PT_char32, &global_object_format, PA_REFERENCE},
00054 {"object_scan", PT_char32, &global_object_scan, PA_REFERENCE},
00055 {"object_tree_balance", PT_bool, &global_no_balance, PA_REFERENCE},
00056 {"kmlfile", PT_char1024, &global_kmlfile, PA_REFERENCE},
00057 {"modelname", PT_char1024, &global_modelname, PA_REFERENCE},
00058 {"execdir",PT_char1024, &global_execdir, PA_REFERENCE},
00059
00060 };
00061
00065 STATUS global_init(void)
00066 {
00067 unsigned int i;
00068 for (i=0; i<sizeof(map)/sizeof(map[0]); i++)
00069 {
00070 struct s_varmap *p = &(map[i]);
00071 if (global_create(p->name,p->type,p->addr,PT_ACCESS,p->access,NULL)==NULL)
00072 output_error("global_init(): global variable '%s' registration failed", p->name);
00073 }
00074 return SUCCESS;
00075 }
00076
00080 GLOBALVAR *global_find(char *name)
00081 {
00082 GLOBALVAR *var;
00083 for (var=global_getnext(NULL); var!=NULL; var=global_getnext(var))
00084 {
00085 if (strcmp(var->name,name)==0)
00086 return var;
00087 }
00088 return NULL;
00089 }
00090
00099 GLOBALVAR *global_getnext(GLOBALVAR *previous)
00100 {
00101 return previous==NULL ? global_varlist : previous->next;
00102 }
00103
00116 GLOBALVAR *global_create(char *name, ...)
00117 {
00118 va_list arg;
00119 PROPERTY *property = NULL, *lastprop = NULL;
00120 PROPERTYTYPE proptype;
00121
00122
00123 GLOBALVAR *var = (GLOBALVAR*)malloc(sizeof(GLOBALVAR));
00124 if (var==NULL)
00125 {
00126 errno = ENOMEM;
00127 throw_exception("global_create(char *name='%s',...): unable to allocate memory for global variable", name);
00128 return NULL;
00129 }
00130 strncpy(var->name,name,sizeof(var->name));
00131 var->prop = NULL;
00132 var->next = NULL;
00133
00134
00135 va_start(arg,name);
00136 while ((proptype=va_arg(arg,PROPERTYTYPE))!=0)
00137 {
00138 if (proptype>_PT_LAST)
00139 {
00140 if (property==NULL)
00141 throw_exception("global_create(char *name='%s',...): property keyword not specified after an enumeration property definition", name);
00142 else if (proptype==PT_KEYWORD && property->ptype==PT_enumeration)
00143 {
00144 char *keyword = va_arg(arg,char*);
00145 long keyvalue = va_arg(arg,long);
00146 KEYWORD *key = (KEYWORD*)malloc(sizeof(KEYWORD));
00147 if (key==NULL)
00148 throw_exception("global_create(char *name='%s',...): property keyword could not be stored", name);
00149 key->next = property->keywords;
00150 strncpy(key->name,keyword,sizeof(key->name));
00151 key->value = keyvalue;
00152 property->keywords = key;
00153 }
00154 else if (proptype==PT_KEYWORD && property->ptype==PT_set)
00155 {
00156 char *keyword = va_arg(arg,char*);
00157 unsigned char keyvalue = va_arg(arg, int);
00158 KEYWORD *key = (KEYWORD*)malloc(sizeof(KEYWORD));
00159 if (keyvalue>63)
00160 throw_exception("global_create(char *name='%s',...): set '%s' keyword value '%d' may not exceed 64",name,keyword,keyvalue);
00161 if (key==NULL)
00162 throw_exception("global_create(char *name='%s',...): property keyword could not be stored", name);
00163 key->next = property->keywords;
00164 strncpy(key->name,keyword,sizeof(key->name));
00165 key->value = keyvalue;
00166 property->keywords = key;
00167 }
00168 else if (proptype==PT_ACCESS)
00169 {
00170 PROPERTYACCESS pa = va_arg(arg,PROPERTYACCESS);
00171 switch (pa) {
00172 case PA_PUBLIC:
00173 case PA_REFERENCE:
00174 case PA_PROTECTED:
00175 case PA_PRIVATE:
00176 property->access = pa;
00177 break;
00178 default:
00179 errno = EINVAL;
00180 throw_exception("global_create(char *name='%s',...): unrecognized property access code (PROPERTYACCESS=%d)", name, pa);
00181 break;
00182 }
00183 }
00184 else if (proptype==PT_SIZE)
00185 {
00186 property->size = va_arg(arg,unsigned long);
00187 if (property->addr==0)
00188 {
00189 if (property->size>0)
00190 property->addr = (PROPERTYADDR)malloc(property->size * property_size(property));
00191 else
00192 throw_exception("global_create(char *name='%s',...): property size must be greater than 0 to allocate memory", name);
00193 }
00194 }
00195 else
00196 throw_exception("global_create(char *name='%s',...): property extension code not recognized (PROPERTYTYPE=%d)", name, proptype);
00197 }
00198 else
00199 {
00200 DELEGATEDTYPE *delegation=(proptype==PT_delegated?va_arg(arg,DELEGATEDTYPE*):NULL);
00201 char unitspec[1024];
00202 if (strlen(name)>=sizeof(property->name))
00203 throw_exception("global_create(char *name='%s',...): property name '%s' is too big to store", name, name);
00204 property = (PROPERTY*)malloc(sizeof(PROPERTY));
00205 if (property==NULL)
00206 throw_exception("global_create(char *name='%s',...): property '%s' could not be stored", name, name);
00207 property->otype = 0;
00208 property->ptype = proptype;
00209 property->addr = va_arg(arg,PROPERTYADDR);
00210 property->size = 1;
00211 property->keywords = NULL;
00212 if (sscanf(name,"%[^[][%[A-Za-z0-9*/^]]",property->name,unitspec)==2)
00213 {
00214 property->unit = unit_find(unitspec);
00215 if (property->unit==NULL)
00216 throw_exception("global_create(char *name='%s',...): property %s unit '%s' is not recognized",name, property->name,unitspec);
00217 }
00218 else
00219 property->unit = NULL;
00220 property->delegation = delegation;
00221 property->next = NULL;
00222 if (var->prop==NULL)
00223 var->prop = property;
00224
00225
00226
00227 if (lastprop!=NULL)
00228 lastprop->next = property;
00229 else
00230 lastprop = property;
00231
00232
00233 if (property->ptype>_PT_LAST)
00234 property = NULL;
00235 }
00236 }
00237 va_end(arg);
00238
00239 if (lastvar==NULL)
00240
00241 global_varlist = lastvar = var;
00242 else
00243 {
00244 lastvar->next = var;
00245 lastvar = var;
00246 }
00247
00248 return var;
00249 }
00250
00260 STATUS global_setvar(char *def, ...)
00261 {
00262 char name[32]="", value[1024]="";
00263 if (sscanf(def,"%[^=]=%[^\n]",name,value)<2)
00264 {
00265 va_list ptr;
00266 char *v;
00267 va_start(ptr,def);
00268 v = va_arg(ptr,char*);
00269 va_end(ptr);
00270 strncpy(value,v,sizeof(value));
00271 if (strcmp(value,v)!=0)
00272 output_error("global_setvar(char *name='%s',...): value is too long to store");
00273 }
00274 if (strcmp(name,"")!=0)
00275 {
00276 GLOBALVAR *var = global_find(name);
00277 if (var==NULL)
00279 var = global_create(name,PT_char1024,NULL,PT_SIZE,1,PT_ACCESS,PA_PUBLIC,NULL);
00280 class_string_to_property(var->prop,(void*)var->prop->addr,value);
00281 return SUCCESS;
00282 }
00283 else
00284 {
00285 output_error("global variable definition '%s' not formatted correctedly", def);
00286 return FAILED;
00287 }
00288 }
00289
00290 #if 0
00291
00297 char *global_getvar(char *name)
00298 {
00299 static char result[1024];
00300 GLOBALVAR *var = global_find(name);
00301 if (var==NULL)
00302 return NULL;
00303 if (class_property_to_string(var->prop,(void*)var->prop->addr,result,sizeof(result))>0)
00304 return result;
00305 else
00306 return NULL;
00307 }
00308 #endif
00309
00316 char *global_getvar(char *name, char *buffer, int size){
00317 static char local_buff[1024];
00318 char temp[1024];
00319 int len = 0;
00320 GLOBALVAR *var = NULL;
00321 if(buffer == NULL){
00322 buffer = local_buff;
00323 size = 1024;
00324 }
00325 if(size < 1){
00326 return NULL;
00327 }
00328 var = global_find(name);
00329 if(var == NULL)
00330 return NULL;
00331 len = class_property_to_string(var->prop, (void *)var->prop->addr, temp, sizeof(temp));
00332 if(len < size){
00333 strncpy(buffer, temp, len+1);
00334 return buffer;
00335 }
00336 return NULL;
00337 }
00338
00339 void global_dump(void)
00340 {
00341 GLOBALVAR *var=NULL;
00342 while ((var=global_getnext(var))!=NULL)
00343 {
00344 char buffer[1024];
00345 if (class_property_to_string(var->prop, (void*)var->prop->addr,buffer,sizeof(buffer)))
00346 output_message("%s=%s;", var->name, buffer);
00347 }
00348 }
00349