62cd32dd9346c25af37d3ec959bae569b20dbf55
[bcm963xx.git] / userapps / opensource / atm2684 / atm / lane / load.c
1 /*
2  * Configuration file loader
3  *
4  * $Id: load.c,v 1.1.1.1 2006/04/12 06:26:44 michaelc Exp $
5  *
6  */
7
8 /* System includes */
9 #include <stdlib.h>
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <assert.h>
13 #include <syslog.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <errno.h>
17 #include <fcntl.h>
18
19 /* Local includes */
20 #include "load.h"
21 #include "lane.h"
22 #include "units.h"
23 #include "dump.h"
24 #include "mem.h"
25 #include "load_lex.h"
26
27 /* Type definitions */
28 typedef enum {
29   VT_INT, VT_STR, VT_BOOL, VT_ADDR, VT_PVC
30 } VarType_t;
31
32 typedef struct {
33   const Unit_t *unit;
34   const char *name;
35   VarType_t type;
36   union {
37     int intval;
38     const char *strval;
39     Bool_t boolval;
40     const AtmAddr_t *addrval;
41     const InitPvc_t *init;
42   } val_u;
43 } Var_t;
44
45 typedef struct _VarList_t {
46   Var_t *var;
47   struct _VarList_t *next;
48 } VarList_t;
49
50 /* Local function prototypes */
51 static void load_init0(void);
52 static void load_init1(void);
53 static void load_dump(void);
54 static void load_release(void);
55
56 static Var_t *find_var(const Unit_t *unit, const char *varname);
57 static void add_var(Var_t *var);
58 static void load_vars(const char *filename);
59
60
61 /* Data */
62 #define BUFLEN 256
63 static const char *rcsid = "$Id: load.c,v 1.1.1.1 2006/04/12 06:26:44 michaelc Exp $";
64
65 static VarList_t *varlist;
66 extern char *var_file;
67
68 const Unit_t load_unit = {
69   "load",
70   &load_init0,
71   &load_init1,
72   &load_dump,
73   &load_release
74 };
75
76 /* Functions */
77
78 /* Initialize local data */
79 static void
80 load_init0(void)
81 {
82   varlist = NULL;
83 }
84
85 /* Initialization for data that needs other units */
86 static void
87 load_init1(void)
88 {
89   set_var_str(&load_unit, "version", rcsid);
90   /*
91    * Load variables from file
92    * For example:
93    * [main]
94    * debug=True
95    * memdebug=True
96    * [conn]
97    * #S4, Join Timeout, s
98    * S4=60
99    */
100   load_vars(var_file);
101
102   Debug_unit(&load_unit, "Initialized.");
103 }
104
105 /* Dump status, local data etc. */
106 static void
107 load_dump(void)
108 {
109   dump_vars(NULL);
110 }
111
112 /* Release allocated memory, close files etc. */
113 static void
114 load_release(void)
115 {
116   VarList_t *tmp;
117   LaneDestList_t *ltmp, *ltmp2;
118
119   Debug_unit(&load_unit, "Releasing unit");
120   for (tmp = varlist; tmp != NULL;) {
121     Debug_unit(&load_unit, "Freeing var %s/%s", tmp->var->unit->name, tmp->var->name);
122     assert(tmp->var != NULL);
123     assert(tmp->var->name != NULL);
124     varlist = varlist->next;
125     if (tmp->var->type == VT_STR){
126       assert(tmp->var->val_u.strval != NULL);
127       mem_free(&load_unit, tmp->var->val_u.strval);
128     }
129     if (tmp->var->type == VT_ADDR){
130       assert(tmp->var->val_u.addrval != NULL);
131       mem_free(&load_unit, tmp->var->val_u.addrval);
132     }
133     if (tmp->var->type == VT_PVC){
134       assert(tmp->var->val_u.init != NULL);
135       assert(tmp->var->val_u.init->pvc != NULL);
136       mem_free(&load_unit, tmp->var->val_u.init->pvc);
137       assert(tmp->var->val_u.init->address != NULL);
138       mem_free(&load_unit, tmp->var->val_u.init->address);
139       ltmp = tmp->var->val_u.init->destinations;
140       while (ltmp != NULL) {
141         ltmp2 = ltmp->next;
142         assert(ltmp->addr != NULL);
143         mem_free(&load_unit, ltmp->addr);
144         mem_free(&load_unit, ltmp);
145         ltmp = ltmp2;
146       }
147       mem_free(&load_unit, tmp->var->val_u.init);
148     }
149     mem_free(&load_unit, tmp->var->name);
150     mem_free(&load_unit, tmp->var);
151     mem_free(&load_unit, tmp);
152     tmp = varlist;
153   }
154 }
155
156 static Var_t *
157 find_var(const Unit_t *unit, const char *varname)
158 {
159   VarList_t *tmp;
160
161   assert(unit != NULL);
162   assert(unit->name != NULL);
163   assert(varname != NULL);
164
165   for (tmp = varlist; tmp != NULL; tmp = tmp->next) {
166     assert(tmp->var != NULL);
167     assert(tmp->var->unit != NULL);
168     assert(tmp->var->unit->name != NULL);
169     assert(tmp->var->name != NULL);
170     if (strcmp(unit->name, tmp->var->unit->name) == 0 && strcmp(tmp->var->name, varname) == 0) {
171       break;
172     }
173   }
174   if (tmp) {
175     return tmp->var;
176   }
177   else {
178     return NULL;
179   }
180 }
181
182 /* Get or initialize variable */
183 int
184 get_var_int(const Unit_t *unit, const char *varname)
185 {
186   const Var_t *tmp;
187
188   tmp = find_var(unit, varname);
189   if (tmp) {
190     assert(tmp->type == VT_INT);
191     return tmp->val_u.intval;
192   }
193   else {
194     return 0;
195   }
196 }
197
198 const InitPvc_t *get_var_vcc(const Unit_t *unit, const char *varname)
199 {
200   const Var_t *tmp;
201
202   tmp=find_var(unit, varname);
203   if(tmp) {
204     assert(tmp->type == VT_PVC);
205     return tmp->val_u.init;
206   } else {
207     return NULL;
208   }
209 }
210
211 const char *
212 get_var_str(const Unit_t *unit, const char *varname)
213 {
214   const Var_t *tmp;
215
216   tmp=find_var(unit, varname);
217   if (tmp) {
218     assert(tmp->type == VT_STR);
219     return tmp->val_u.strval;
220   }
221   else {
222     return NULL;
223   }
224 }
225
226 Bool_t
227 get_var_bool(const Unit_t *unit, const char *varname)
228 {
229   const Var_t *tmp;
230
231   tmp = find_var(unit, varname);
232   if (tmp) {
233     assert(tmp->type == VT_BOOL);
234     return tmp->val_u.boolval;
235   }
236   else {
237     return BL_FALSE;
238   }
239 }
240
241 const AtmAddr_t *
242 get_var_addr(const Unit_t *unit, const char *varname)
243 {
244   const Var_t *tmp;
245
246   tmp = find_var(unit, varname);
247   if (tmp) {
248     assert(tmp->type == VT_ADDR);
249     return tmp->val_u.addrval;
250   }
251   else {
252     return NULL;
253   }
254 }
255
256 static void
257 add_var(Var_t *var)
258 {
259   VarList_t *tmpl;
260
261   tmpl = (VarList_t *)mem_alloc(&load_unit, sizeof(VarList_t));
262   tmpl->var = var;
263   tmpl->next = varlist;
264   varlist = tmpl;
265 }
266
267 /* Set or initialize variable */
268
269 void 
270 set_var_vcc(const Unit_t *unit, const char *varname, 
271             const InitPvc_t *vcc)
272 {
273   Var_t *tmp;
274   LaneDestList_t *ltmp, *ltmp2;
275
276   assert(unit != NULL && unit->name != NULL && varname != NULL);
277   tmp = find_var(unit, varname);
278   if (tmp == NULL) {
279     tmp = (Var_t *)mem_alloc(&load_unit, sizeof(Var_t));
280     tmp->unit = unit;
281     tmp->name = varname;
282     tmp->val_u.init = vcc;
283     tmp->type = VT_PVC;
284     add_var(tmp);
285   } else {
286     assert(tmp->type == VT_PVC);
287     mem_free(&load_unit, tmp->name);
288     tmp->name = varname;
289     assert(tmp->val_u.init->pvc != NULL);
290     mem_free(&load_unit, tmp->val_u.init->pvc);
291     assert(tmp->val_u.init->address != NULL);
292     mem_free(&load_unit, tmp->val_u.init->address);
293     ltmp = tmp->val_u.init->destinations;
294     while(ltmp != NULL) {
295       ltmp2 = ltmp->next;
296       assert(ltmp->addr != NULL);
297       mem_free(&load_unit, ltmp->addr);
298       mem_free(&load_unit, ltmp);
299       ltmp = ltmp2;
300     }
301     mem_free(&load_unit, tmp->val_u.init);
302     tmp->val_u.init = vcc;
303   }
304 }
305
306 void
307 set_var_int(const Unit_t *unit, const char *varname, int intval)
308 {
309   Var_t *tmp;
310
311   assert(unit != NULL && unit->name != NULL && varname != NULL);
312   tmp = find_var(unit, varname);
313   if (tmp == NULL) {
314     tmp = (Var_t *)mem_alloc(&load_unit, sizeof(Var_t));
315     tmp->unit = unit;
316     tmp->name = varname;
317     tmp->val_u.intval = intval;
318     tmp->type = VT_INT;
319     add_var(tmp);
320   }
321   else {
322     assert(tmp->type == VT_INT);
323     mem_free(&load_unit, tmp->name);
324     tmp->name = varname;
325     tmp->val_u.intval = intval;
326   }
327 }
328
329 void
330 set_var_str(const Unit_t *unit, const char *varname, const char *strval)
331 {
332   Var_t *tmp;
333
334   assert(unit != NULL && unit->name != NULL && varname != NULL);
335   tmp = find_var(unit, varname);
336   if (tmp == NULL) {
337     tmp = (Var_t *)mem_alloc(&load_unit, sizeof(Var_t));
338     tmp->unit = unit;
339     tmp->name = varname;
340     tmp->val_u.strval = strval;
341     tmp->type = VT_STR;
342     add_var(tmp);
343   } else {
344     assert(tmp->type == VT_STR);
345     mem_free(&load_unit, tmp->name);
346     tmp->name = varname;
347     mem_free(&load_unit, tmp->val_u.strval);
348     tmp->val_u.strval = strval;
349   }
350 }
351
352
353 void
354 set_var_addr(const Unit_t *unit, const char *varname, const AtmAddr_t *addr)
355 {
356   Var_t *tmp;
357
358   assert(unit != NULL && unit->name != NULL && varname != NULL);
359   tmp = find_var(unit, varname);
360   if (tmp == NULL) {
361     tmp = (Var_t *)mem_alloc(&load_unit, sizeof(Var_t));
362     tmp->unit = unit;
363     tmp->name = varname;
364     tmp->val_u.addrval = addr;
365     tmp->type = VT_ADDR;
366     add_var(tmp);
367   }
368   else {
369     assert(tmp->type == VT_ADDR);
370     mem_free(&load_unit, tmp->name);
371     tmp->name = varname;
372     mem_free(&load_unit, tmp->val_u.addrval);
373     tmp->val_u.addrval = addr;
374   }
375 }
376
377 void
378 set_var_bool(const Unit_t *unit, const char *varname, Bool_t boolval)
379 {
380   Var_t *tmp;
381
382   assert(unit != NULL && unit->name != NULL && varname != NULL);
383   tmp = find_var(unit, varname);
384   if (tmp == NULL) {
385     tmp = (Var_t *)mem_alloc(&load_unit, sizeof(Var_t));
386     tmp->unit = unit;
387     tmp->name = varname;
388     tmp->val_u.boolval = boolval;
389     tmp->type = VT_BOOL;
390     add_var(tmp);
391   }
392   else {
393     mem_free(&load_unit, tmp->name);
394     tmp->name = varname;
395     assert(tmp->type == VT_BOOL);
396     tmp->val_u.boolval = boolval;
397   }
398 }
399
400 void
401 dump_vars(const Unit_t *unit)
402 {
403   const VarList_t *tmp;
404   LaneDestList_t *ltmp;
405
406   Debug_unit(&load_unit, "Dumping variables");
407   for (tmp = varlist; tmp != NULL; tmp = tmp->next) {
408     assert(tmp->var != NULL);
409     assert(tmp->var->unit != NULL);
410     assert(tmp->var->unit->name != NULL);
411     assert(tmp->var->name != NULL);
412     if (unit == NULL || strcmp(unit->name, tmp->var->unit->name) == 0) {
413       switch (tmp->var->type) {
414       case VT_INT:
415         Debug_unit(&load_unit, "%s/%s = %d", tmp->var->unit->name, tmp->var->name, tmp->var->val_u.intval);
416         break;
417       case VT_STR:
418         Debug_unit(&load_unit, "%s/%s = \"%s\"", tmp->var->unit->name, tmp->var->name, tmp->var->val_u.strval);
419         break;
420       case VT_BOOL:
421         Debug_unit(&load_unit, "%s/%s = %s", tmp->var->unit->name, tmp->var->name, tmp->var->val_u.boolval == BL_TRUE? "True" : "False" );
422         break;
423       case VT_ADDR:
424         Debug_unit(&load_unit, "%s/%s =", tmp->var->unit->name, tmp->var->name);
425         dump_atmaddr(tmp->var->val_u.addrval);
426         break;
427       case VT_PVC:
428         Debug_unit(&load_unit,"%s/%s = %d,%d,%d with lecid:%d ",
429                    tmp->var->unit->name, 
430                    tmp->var->name, 
431                    tmp->var->val_u.init->pvc->port,
432                    tmp->var->val_u.init->pvc->vpi,
433                    tmp->var->val_u.init->pvc->vci,
434                    tmp->var->val_u.init->lecid);
435         dump_atmaddr(tmp->var->val_u.init->address);
436         ltmp = tmp->var->val_u.init->destinations;
437         while(ltmp) {
438           dump_printf(EL_CONT,"\t");
439           dump_addr(ltmp->addr);
440           dump_printf(EL_CONT,"\n");
441           ltmp = ltmp->next;
442         }
443         break;
444       }
445     }
446   }
447 }
448
449 void
450 load_vars(const char *file)
451 {
452   const Unit_t *curr_unit = NULL;
453
454   int ret = 0;   /* to silence gcc 2.7.2.1 */
455   char *varname;
456   InitPvc_t *pvc;
457   LaneDestList_t *ltmp;
458   int read_flag = 1;
459
460   assert(file != NULL);
461   Debug_unit(&load_unit, "Loading variables from file %s", file);
462   yyin = fopen(file, "r");
463   if (!yyin) {
464     Debug_unit(&load_unit, "Cannot open file %s: %s", file, strerror(errno));
465     return;
466   }
467   g_buf_index = 0;
468   do {
469     if (read_flag)
470       ret = yylex();
471     else
472       read_flag =1;
473     switch(ret) {
474     case END:
475       Debug_unit(&load_unit, "EOF");
476       break;
477     case UNIT:
478       Debug_unit(&load_unit, "Got unit %s", g_return.stringgi);
479       curr_unit = find_unit(g_return.stringgi);
480       if (curr_unit == NULL) {
481         Debug_unit(&load_unit, "Unknown unit %s", g_return.stringgi);
482       }
483       Debug_unit(&load_unit, "Got unit %s", g_return.stringgi);
484       mem_free(&load_unit,g_return.stringgi);
485       break;
486     case VARNAME:
487       varname = g_return.stringgi;
488       Debug_unit(&load_unit, "Got variable name %s", varname);
489       ret = yylex();
490       switch(ret) {
491       case STRING:
492         Debug_unit(&load_unit, "Variable is string: %s", g_return.stringgi);
493         set_var_str(curr_unit, varname, g_return.stringgi);
494         break;
495       case BOOLEAN:
496         Debug_unit(&load_unit, "Variable is boolean: %s", 
497                    g_return.bool==BL_TRUE?"True":"False");
498         set_var_bool(curr_unit, varname, g_return.bool);
499         break;
500       case INTEGER:
501         Debug_unit(&load_unit, "Variable is integer: %d", g_return.intti);
502         set_var_int(curr_unit, varname, g_return.intti);
503         break;
504       case ATMADDRESS:
505         Debug_unit(&load_unit, "Variable is atmaddress ");
506         dump_atmaddr(g_return.atmaddress);
507         set_var_addr(curr_unit, varname, g_return.atmaddress);
508         break;
509       case LANEDEST:
510         Debug_unit(&load_unit, "Invalid variable value for %s", varname);
511         mem_free(&load_unit, g_return.destaddr);
512         break;
513       case UNIT:
514         Debug_unit(&load_unit, "Invalid variable value for %s", varname);
515         mem_free(&load_unit, g_return.stringgi);
516         break;
517       case VCC:
518         Debug_unit(&load_unit, "Variable is vcc");
519         pvc = (InitPvc_t *)mem_alloc(curr_unit, sizeof(InitPvc_t));
520         pvc->pvc = (LaneVcc_t *)mem_alloc(curr_unit, sizeof(LaneVcc_t));
521         pvc->pvc->port = g_return.vcc.port;
522         pvc->pvc->vpi = g_return.vcc.vpi;
523         pvc->pvc->vci = g_return.vcc.vci;
524         pvc->address = NULL;
525         pvc->lecid = 0;
526         pvc->destinations = NULL;
527         ret = yylex();
528         if (ret != ATMADDRESS) {
529           Debug_unit(&load_unit, "Invalid atm_address for pvc %d,%d,%d",
530                      pvc->pvc->port, pvc->pvc->vpi, pvc->pvc->vci);
531           switch(ret) {
532           case UNIT:
533           case STRING:
534           case VARNAME:
535             mem_free(&load_unit, g_return.stringgi);
536             break;
537           case LANEDEST:
538             mem_free(&load_unit, g_return.destaddr);
539             break;
540           }
541         } else {
542           pvc->address = g_return.atmaddress;
543         }
544         ret = yylex();
545         if (ret != INTEGER) {
546           Debug_unit(&load_unit, "Invalid lecid for pvc %d,%d,%d\n",
547                      pvc->pvc->port,pvc->pvc->vpi,pvc->pvc->vci);
548           switch(ret) {
549           case UNIT:
550           case STRING:
551           case VARNAME:
552             mem_free(&load_unit, g_return.stringgi);
553             break;
554           case LANEDEST:
555             mem_free(&load_unit, g_return.destaddr);
556             break;
557           case ATMADDRESS:
558             mem_free(&load_unit, g_return.atmaddress);
559             break;
560           }
561         } else {
562           pvc->lecid = g_return.intti;
563         }
564         while((ret=yylex())==LANEDEST) {
565           ltmp=(LaneDestList_t *)mem_alloc(&load_unit, sizeof(LaneDestList_t));
566           ltmp->addr = g_return.destaddr;
567           ltmp->next = pvc->destinations;
568           pvc->destinations = ltmp;
569         }
570         read_flag=0;
571         set_var_vcc(curr_unit, varname, pvc);
572         break;  
573       default:
574         Debug_unit(&load_unit, "Invalid variable value for %s", varname);
575         break;
576       }
577       break;
578     case STRING:
579       Debug_unit(&load_unit,"Invalid string placement %s",g_return.stringgi);
580       mem_free(&load_unit, g_return.stringgi);
581       break;
582     case ATMADDRESS:
583       Debug_unit(&load_unit, "Invalid atm address placement");
584       mem_free(&load_unit, g_return.atmaddress);
585       break;
586     case LANEDEST:
587       Debug_unit(&load_unit, "Invalid lane destination placement");
588       mem_free(&load_unit, g_return.destaddr);
589       break;
590     case INTEGER:
591       Debug_unit(&load_unit, "Invalid integer placement");
592       break;
593     default:
594       Debug_unit(&load_unit, "Invalid input");
595       break;
596     }
597   } while (ret != END);
598   if (fclose(yyin) != 0) {
599     Debug_unit(&load_unit, "Cannot close file %s: %s", file, strerror(errno));
600   }
601 }
602