Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / misc / config_file / cf_gramatical.ypp
blob578bf53bfbce1842760f3315dd429a81111e1d5d
1 %{\r
2 \r
3 /* Includes */\r
4 \r
5 #ifdef NL_OS_WINDOWS\r
6 #pragma warning (disable : 4786)\r
7 #endif // NL_OS_WINDOWS\r
8 #include "nel/misc/config_file.h"\r
9 #include "nel/misc/common.h"\r
10 #include "nel/misc/debug.h"\r
12 #include <stdio.h>\r
13 #include <vector>\r
14 #include <string>\r
16 using namespace std;\r
17 using namespace NLMISC;\r
19 /* Constantes */\r
21 #define YYPARSE_PARAM pvararray\r
23 // WARNING!!!! DEBUG_PRINTF are commented using // so IT MUST HAVE NO INSTRUCTION AFTER A DEBUG_PRINTF OR THEY LL BE COMMENTED\r
24 /*\r
25 #define DEBUG_PRINTF    InfoLog->displayRaw\r
26 #define DEBUG_PRINT(a)  InfoLog->displayRaw(a)\r
27 */\r
29 #define DEBUG_PRINT(a)\r
30 #ifdef __GNUC__\r
31 #define DEBUG_PRINTF(format, args...)\r
32 #else // __GNUC__\r
33 #define DEBUG_PRINTF    // InfoLog->displayRaw\r
34 #endif // __GNUC__\r
37 /* Types */\r
39 enum cf_operation { OP_PLUS, OP_MINUS, OP_MULT, OP_DIVIDE, OP_NEG };\r
41 struct cf_value\r
42 {\r
43         NLMISC::CConfigFile::CVar::TVarType     Type;\r
44         int                                             Int;\r
45         double                                  Real;\r
46         char                                    String[1024];\r
47 };\r
49 /* Externals */\r
51 extern bool cf_Ignore;\r
53 extern bool LoadRoot;\r
55 extern FILE *yyin;\r
57 /* Variables */\r
59 NLMISC::CConfigFile::CVar               cf_CurrentVar;\r
61 int             cf_CurrentLine;\r
62 char    *cf_CurrentFile;\r
64 bool    cf_OverwriteExistingVariable;   // setup in the config_file.cpp reparse()\r
68 /* Prototypes */\r
70 int yylex (void);\r
72 cf_value cf_op (cf_value a, cf_value b, cf_operation op);\r
74 void cf_print (cf_value Val);\r
76 void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val);\r
78 int yyerror (const char *);\r
80 %}\r
82 %start ROOT\r
84 %union  {\r
85                         cf_value Val;\r
86                 }\r
88 %token <Val> ADD_ASSIGN ASSIGN VARIABLE STRING SEMICOLON\r
89 %token <Val> PLUS MINUS MULT DIVIDE\r
90 %token <Val> RPAREN LPAREN RBRACE LBRACE\r
91 %token <Val> COMMA INTEGER REAL FILELINE\r
93 %type <Val> inst\r
94 %type <Val> expression\r
95 %type <Val> expr2\r
96 %type <Val> expr3\r
97 %type <Val> expr4\r
98 %type <Val> exprbrace\r
99 %type <Val> variable\r
101 %%\r
103 ROOT:           instlist | { }\r
104                         ;\r
106 instlist:       instlist inst { }\r
107                 |       inst { }\r
108                 ;\r
110 inst    :       FILELINE STRING INTEGER\r
111                         {\r
112                                 DEBUG_PRINTF("Forcing current file %s and line %u\n", $2.String, $3.Int-1);\r
114                                 if (cf_CurrentFile != NULL)\r
115                                         free(cf_CurrentFile);\r
116                                 // store the filename\r
117                                 cf_CurrentFile = strdup($2.String);\r
118                                 // store the current line minus 1 because the #fileline count for a line\r
119                                 cf_CurrentLine = $3.Int-1;\r
120                         }\r
122 inst:           VARIABLE ASSIGN expression SEMICOLON\r
123                         {\r
124                                 DEBUG_PRINTF("                                   (TYPE %d VARIABLE=", $1.Type);\r
125                                 cf_print ($1);\r
126                                 DEBUG_PRINTF("), (TYPE %d VALUE=", $3.Type);\r
127                                 cf_print ($3);\r
128                                 DEBUG_PRINT(")\n");\r
129                                 int i;\r
130                                 // on recherche l'existence de la variable\r
131                                 for(i = 0; i < (int)((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM))).size()); i++)\r
132                                 {\r
133                                         if ((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Name == $1.String)\r
134                                         {\r
135                                                 if (cf_OverwriteExistingVariable || (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Root || !strcmp($1.String,"RootConfigFilename"))\r
136                                                 {\r
137                                                         DEBUG_PRINTF("Variable '%s' existe deja, ecrasement\n", $1.String);\r
138                                                 }\r
139                                                 break;\r
140                                         }\r
141                                 }\r
142                                 NLMISC::CConfigFile::CVar Var;\r
143                                 Var.Comp = false;\r
144                                 Var.Callback = NULL;\r
145                                 if (cf_CurrentVar.Comp)\r
146                                 {\r
147                                         DEBUG_PRINTF ("yacc: new assign complex variable '%s'\n", $1.String);\r
148                                         Var = cf_CurrentVar;\r
149                                 }\r
150                                 else\r
151                                 {\r
152                                         DEBUG_PRINTF ("yacc: new assign normal variable '%s'\n", $1.String);\r
153                                         cf_setVar (Var, $3);\r
154                                 }\r
155                                 Var.Name = $1.String;\r
156                                 if (i == (int)((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM))).size ()))\r
157                                 {\r
158                                         // nouvelle variable\r
159                                         DEBUG_PRINTF ("yacc: new assign var '%s'\n", $1.String);\r
160                                         (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM))).push_back (Var);\r
161                                 }\r
162                                 else if (cf_OverwriteExistingVariable || (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Root || !strcmp($1.String,"RootConfigFilename"))\r
163                                 {\r
164                                         // reaffectation d'une variable\r
165                                         Var.Callback = (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Callback;\r
166                                         DEBUG_PRINTF ("yacc: reassign var name '%s' type %d\n", Var.Name.c_str(), Var.Type);\r
167                                         if (Var != (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i] && Var.Callback != NULL)\r
168                                                 (Var.Callback)(Var);\r
169                                         (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i] = Var;\r
170                                 }\r
171                                 else\r
172                                 {\r
173                                         DEBUG_PRINTF ("yacc: don't reassign var '%s' because the variable already exists\n", $1.String);\r
174                                 }\r
176                                 cf_CurrentVar.IntValues.clear ();\r
177                                 cf_CurrentVar.RealValues.clear ();\r
178                                 cf_CurrentVar.StrValues.clear ();\r
179                                 cf_CurrentVar.Comp = false;\r
180                                 cf_CurrentVar.Type = NLMISC::CConfigFile::CVar::T_UNKNOWN;\r
181                         }\r
182                         ;\r
184 inst:           VARIABLE ADD_ASSIGN expression SEMICOLON\r
185                         {\r
186                                 DEBUG_PRINT("                                   (VARIABLE+=");\r
187                                 cf_print ($1);\r
188                                 DEBUG_PRINT("), (VALUE=");\r
189                                 cf_print ($3);\r
190                                 DEBUG_PRINT(")\n");\r
191                                 int i;\r
192                                 // on recherche l'existence de la variable\r
193                                 for(i = 0; i < (int)((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM))).size()); i++)\r
194                                 {\r
195                                         if ((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Name == $1.String)\r
196                                         {\r
197                                                 DEBUG_PRINTF("Variable '%s' existe deja, ajout\n", $1.String);\r
198                                                 break;\r
199                                         }\r
200                                 }\r
201                                 NLMISC::CConfigFile::CVar Var;\r
202                                 Var.Comp = false;\r
203                                 Var.Callback = NULL;\r
204                                 if (cf_CurrentVar.Comp) Var = cf_CurrentVar;\r
205                                 else cf_setVar (Var, $3);\r
206                                 Var.Name = $1.String;\r
207                                 if (i == (int)((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM))).size ()))\r
208                                 {\r
209                                         // nouvelle variable\r
210                                         DEBUG_PRINTF ("yacc: new add assign var '%s'\n", $1.String);\r
211                                         (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM))).push_back (Var);\r
212                                 }\r
213                                 else\r
214                                 {\r
215                                         // reaffectation d'une variable\r
216                                         Var.Callback = (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Callback;\r
217                                         DEBUG_PRINTF ("yacc: add assign var '%s'\n", $1.String);\r
218                                         if ((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].FromLocalFile)\r
219                                         {\r
220                                                 // this var was created in the current cfg, append the new value at the end\r
221                                                 (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].add(Var);\r
223                                                 if (Var.size() > 0 && Var.Callback != NULL)\r
224                                                         (Var.Callback)((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i]);\r
225                                         }\r
226                                         else\r
227                                         {\r
228                                                 // this var has been created in a parent Cfg, append at the beginning of the array\r
229                                                 Var.add ((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i]);\r
230                                                 if (Var != (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i] && Var.Callback != NULL)\r
231                                                         (Var.Callback)(Var);\r
232                                                 (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i] = Var;\r
233                                         }\r
234                                 }\r
236                                 cf_CurrentVar.IntValues.clear ();\r
237                                 cf_CurrentVar.RealValues.clear ();\r
238                                 cf_CurrentVar.StrValues.clear ();\r
239                                 cf_CurrentVar.Comp = false;\r
240                                 cf_CurrentVar.Type = NLMISC::CConfigFile::CVar::T_UNKNOWN;\r
241                         }\r
242                         ;\r
244 expression:     expr2 { $$ = $1; cf_CurrentVar.Comp = false; DEBUG_PRINT("false\n"); }\r
245                         | LBRACE exprbrace RBRACE { $$ = $2; cf_CurrentVar.Comp = true; DEBUG_PRINT("true\n"); }\r
246                         | LBRACE exprbrace COMMA RBRACE { $$ = $2; cf_CurrentVar.Comp = true; DEBUG_PRINT("true\n"); }\r
247                         | LBRACE RBRACE { $$ = $2; cf_CurrentVar.Comp = true; DEBUG_PRINT("true\n"); }\r
248                         ;\r
250 exprbrace:      expr2                                   { $$ = $1; /*cf_CurrentVar.Type = $1.Type;*/ cf_setVar (cf_CurrentVar, $1); }\r
251                         | exprbrace COMMA expr2 { $$ = $3; /*cf_CurrentVar.Type = $3.Type;*/ cf_setVar (cf_CurrentVar, $3); }\r
252                         ;\r
254 expr2:          expr3 { $$ = $1; }\r
255                         | expr2 PLUS expr3 { $$ = cf_op($1, $3, OP_PLUS); }\r
256                         | expr2 MINUS expr3 { $$ = cf_op($1, $3, OP_MINUS); }\r
257                         ;\r
259 expr3:          expr4 { $$ = $1; }\r
260                         | expr3 MULT expr4 { $$ = cf_op($1, $3, OP_MULT); }\r
261                         | expr3 DIVIDE expr4 { $$ = cf_op ($1, $3, OP_DIVIDE); }\r
262                         ;\r
264 expr4:          PLUS expr4 { $$ = $2; }\r
265                         | MINUS expr4 { cf_value v; v.Type=NLMISC::CConfigFile::CVar::T_INT; /* just to avoid a warning, I affect 'v' with a dummy value */ $$ = cf_op($2,v,OP_NEG); }\r
266                         | LPAREN expression RPAREN { $$ = $2; }\r
267                         | INTEGER { $$ = yylval.Val; }\r
268                         | REAL { $$ = yylval.Val; }\r
269                         | STRING { $$ = yylval.Val; }\r
270                         | variable { $$ = $1; }\r
271                         ;\r
273 variable:       VARIABLE\r
274                         {\r
275                                 DEBUG_PRINT("yacc: cont\n");\r
276                                 bool ok=false;\r
277                                 int i;\r
278                                 for(i = 0; i < (int)((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM))).size()); i++)\r
279                                 {\r
280                                         if ((*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Name == $1.String)\r
281                                         {\r
282                                                 ok = true;\r
283                                                 break;\r
284                                         }\r
285                                 }\r
286                                 if (ok)\r
287                                 {\r
288                                         cf_value Var;\r
289                                         Var.Type = (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].Type;\r
290                                         DEBUG_PRINTF("vart %d\n", Var.Type);\r
291                                         switch (Var.Type)\r
292                                         {\r
293                                         case NLMISC::CConfigFile::CVar::T_INT: Var.Int = (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].IntValues[0]; break;\r
294                                         case NLMISC::CConfigFile::CVar::T_REAL: Var.Real = (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].RealValues[0]; break;\r
295                                         case NLMISC::CConfigFile::CVar::T_STRING: strcpy (Var.String, (*((vector<NLMISC::CConfigFile::CVar>*)(YYPARSE_PARAM)))[i].StrValues[0].c_str()); break;\r
296                                         default: DEBUG_PRINT("*** CAN T DO THAT!!!\n"); break;\r
297                                         }\r
298                                         $$ = Var;\r
299                                 }\r
300                                 else\r
301                                 {\r
302                                         DEBUG_PRINT("var existe pas\n");\r
303                                 }\r
304                         }\r
305                         ;\r
306 %%\r
308 /* compute the good operation with a, b and op */\r
309 cf_value cf_op (cf_value a, cf_value b, cf_operation op)\r
311         DEBUG_PRINTF("[OP:%d; ", op);\r
312         cf_print(a);\r
313         DEBUG_PRINT("; ");\r
314         cf_print(b);\r
315         DEBUG_PRINT("; ");\r
317         switch (op)\r
318         {\r
319         case OP_MULT:                                                                                                                           //  *********************\r
320                 switch (a.Type)\r
321                 {\r
322                 case NLMISC::CConfigFile::CVar::T_INT:\r
323                         switch (b.Type)\r
324                         {\r
325                         case NLMISC::CConfigFile::CVar::T_INT:          a.Int *= b.Int; break;\r
326                         case NLMISC::CConfigFile::CVar::T_REAL: a.Int *= (int)b.Real; break;\r
327                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: int*str\n"); break;\r
328                         default: break;\r
329                         }\r
330                         break;\r
331                 case NLMISC::CConfigFile::CVar::T_REAL:\r
332                         switch (b.Type)\r
333                         {\r
334                         case NLMISC::CConfigFile::CVar::T_INT:          a.Real *= (double)b.Int; break;\r
335                         case NLMISC::CConfigFile::CVar::T_REAL: a.Real *= b.Real; break;\r
336                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: real*str\n"); break;\r
337                         default: break;\r
338                         }\r
339                         break;\r
340                 case NLMISC::CConfigFile::CVar::T_STRING:\r
341                         switch (b.Type)\r
342                         {\r
343                         case NLMISC::CConfigFile::CVar::T_INT:          DEBUG_PRINT("ERROR: str*int\n");  break;\r
344                         case NLMISC::CConfigFile::CVar::T_REAL: DEBUG_PRINT("ERROR: str*real\n");  break;\r
345                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: str*str\n");  break;\r
346                         default: break;\r
347                         }\r
348                         break;\r
349                 default: break;\r
350                 }\r
351                 break;\r
352         case OP_DIVIDE:                                                                                                                         //  //////////////////////\r
353                 switch (a.Type)\r
354                 {\r
355                 case NLMISC::CConfigFile::CVar::T_INT:\r
356                         switch (b.Type)\r
357                         {\r
358                         case NLMISC::CConfigFile::CVar::T_INT:          a.Int /= b.Int; break;\r
359                         case NLMISC::CConfigFile::CVar::T_REAL: a.Int /= (int)b.Real; break;\r
360                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: int/str\n"); break;\r
361                         default: break;\r
362                         }\r
363                         break;\r
364                 case NLMISC::CConfigFile::CVar::T_REAL:\r
365                         switch (b.Type)\r
366                         {\r
367                         case NLMISC::CConfigFile::CVar::T_INT:          a.Real /= (double)b.Int; break;\r
368                         case NLMISC::CConfigFile::CVar::T_REAL: a.Real /= b.Real; break;\r
369                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: real/str\n"); break;\r
370                         default: break;\r
371                         }\r
372                         break;\r
373                 case NLMISC::CConfigFile::CVar::T_STRING:\r
374                         switch (b.Type)\r
375                         {\r
376                         case NLMISC::CConfigFile::CVar::T_INT:          DEBUG_PRINT("ERROR: str/int\n"); break;\r
377                         case NLMISC::CConfigFile::CVar::T_REAL: DEBUG_PRINT("ERROR: str/real\n"); break;\r
378                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: str/str\n"); break;\r
379                          default: break;\r
380                         }\r
381                         break;\r
382                 default: break;\r
383                 }\r
384                 break;\r
385         case OP_PLUS:                                                                                                                           //  ++++++++++++++++++++++++\r
386                 switch (a.Type)\r
387                 {\r
388                 case NLMISC::CConfigFile::CVar::T_INT:\r
389                         switch (b.Type)\r
390                         {\r
391                         case NLMISC::CConfigFile::CVar::T_INT:  a.Int += b.Int; break;\r
392                         case NLMISC::CConfigFile::CVar::T_REAL: a.Int += (int)b.Real; break;\r
393                         case NLMISC::CConfigFile::CVar::T_STRING:       a.Int += atoi(b.String); break;\r
394                         default: break;\r
395                         }\r
396                         break;\r
397                 case NLMISC::CConfigFile::CVar::T_REAL:\r
398                         switch (b.Type)\r
399                         {\r
400                         case NLMISC::CConfigFile::CVar::T_INT:  a.Real += (double)b.Int; break;\r
401                         case NLMISC::CConfigFile::CVar::T_REAL: a.Real += b.Real; break;\r
402                         case NLMISC::CConfigFile::CVar::T_STRING:       a.Real += atof (b.String); break;\r
403                         default: break;\r
404                         }\r
405                         break;\r
406                 case NLMISC::CConfigFile::CVar::T_STRING:\r
407                         switch (b.Type)\r
408                         {\r
409                         case NLMISC::CConfigFile::CVar::T_INT:  { char str2[60]; NLMISC::smprintf(str2, 60, "%d", b.Int); strcat(a.String, str2); break; }\r
410                         case NLMISC::CConfigFile::CVar::T_REAL: { char str2[60]; NLMISC::smprintf(str2, 60, "%f", b.Real); strcat(a.String, str2); break; }\r
411                         case NLMISC::CConfigFile::CVar::T_STRING:       strcat (a.String, b.String); break;\r
412                         default: break;\r
413                         }\r
414                         break;\r
415                 default: break;\r
416                 }\r
417                 break;\r
418         case OP_MINUS:                                                                                                                          //  -------------------------\r
419                 switch (a.Type)\r
420                 {\r
421                 case NLMISC::CConfigFile::CVar::T_INT:\r
422                         switch (b.Type)\r
423                         {\r
424                         case NLMISC::CConfigFile::CVar::T_INT:  a.Int -= b.Int; break;\r
425                         case NLMISC::CConfigFile::CVar::T_REAL: a.Int -= (int)b.Real; break;\r
426                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: int-str\n"); break;\r
427                         default: break;\r
428                         }\r
429                         break;\r
430                 case NLMISC::CConfigFile::CVar::T_REAL:\r
431                         switch (b.Type)\r
432                         {\r
433                         case NLMISC::CConfigFile::CVar::T_INT:  a.Real -= (double)b.Int; break;\r
434                         case NLMISC::CConfigFile::CVar::T_REAL: a.Real -= b.Real; break;\r
435                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: real-str\n"); break;\r
436                         default: break;\r
437                         }\r
438                         break;\r
439                 case NLMISC::CConfigFile::CVar::T_STRING:\r
440                         switch (b.Type)\r
441                         {\r
442                         case NLMISC::CConfigFile::CVar::T_INT:  DEBUG_PRINT("ERROR: str-int\n"); break;\r
443                         case NLMISC::CConfigFile::CVar::T_REAL: DEBUG_PRINT("ERROR: str-real\n"); break;\r
444                         case NLMISC::CConfigFile::CVar::T_STRING:       DEBUG_PRINT("ERROR: str-str\n"); break;\r
445                         default: break;\r
446                         }\r
447                         break;\r
448                 default: break;\r
449                 }\r
450                 break;\r
451         case OP_NEG:                                                                                                                            // neg\r
452                 switch (a.Type)\r
453                 {\r
454                 case NLMISC::CConfigFile::CVar::T_INT:          a.Int = -a.Int; break;\r
455                 case NLMISC::CConfigFile::CVar::T_REAL:         a.Real = -a.Real; break;\r
456                 case NLMISC::CConfigFile::CVar::T_STRING:               DEBUG_PRINT("ERROR: -str\n"); break;\r
457                 default: break;\r
458                 }\r
459                 break;\r
460         }\r
461         cf_print(a);\r
462         DEBUG_PRINT("]\n");\r
463         return a;\r
466 /* print a value, it's only for debug purpose */\r
467 void cf_print (cf_value Val)\r
469         switch (Val.Type)\r
470         {\r
471         case NLMISC::CConfigFile::CVar::T_INT:\r
472                 DEBUG_PRINTF("'%d'", Val.Int);\r
473                 break;\r
474         case NLMISC::CConfigFile::CVar::T_REAL:\r
475                 DEBUG_PRINTF("`%f`", Val.Real);\r
476                 break;\r
477         case NLMISC::CConfigFile::CVar::T_STRING:\r
478                 DEBUG_PRINTF("\"%s\"", Val.String);\r
479                 break;\r
480         default: break;\r
481         }\r
484 /* put a value into a var */\r
485 void cf_setVar (NLMISC::CConfigFile::CVar &Var, cf_value Val)\r
487         DEBUG_PRINTF("Set var (type %d var name '%s') with new var type %d with value : ", Var.Type, Var.Name.c_str(), Val.Type);\r
488         cf_print(Val);\r
489         DEBUG_PRINTF("\n");\r
490         Var.Root = LoadRoot;\r
491         if (Var.Type == NLMISC::CConfigFile::CVar::T_UNKNOWN || Var.Type == Val.Type)\r
492         {\r
493                 if (Var.Type == NLMISC::CConfigFile::CVar::T_UNKNOWN)\r
494                 {\r
495                         DEBUG_PRINTF("var type is unknown, set to the val type\n");\r
496                 }\r
497                 else\r
498                 {\r
499                         DEBUG_PRINTF("val type is same var type, just add\n");\r
500                 }\r
502                 Var.Type = Val.Type;\r
503                 switch (Val.Type)\r
504                 {\r
505                 case NLMISC::CConfigFile::CVar::T_INT: Var.IntValues.push_back (Val.Int); break;\r
506                 case NLMISC::CConfigFile::CVar::T_REAL: Var.RealValues.push_back (Val.Real); break;\r
507                 case NLMISC::CConfigFile::CVar::T_STRING: Var.StrValues.push_back(Val.String); break;\r
508                 default: break;\r
509                 }\r
510         }\r
511         else\r
512         {\r
513                 // need to convert the type\r
514                 switch (Var.Type)\r
515                 {\r
516                 case NLMISC::CConfigFile::CVar::T_INT:\r
517                         switch (Val.Type)\r
518                         {\r
519                         case NLMISC::CConfigFile::CVar::T_REAL:         Var.IntValues.push_back ((int)Val.Real); break;\r
520                         case NLMISC::CConfigFile::CVar::T_STRING:       { int val = 0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; }\r
521                         default: break;\r
522                         }\r
523                         break;\r
524                 case NLMISC::CConfigFile::CVar::T_REAL:\r
525                         switch (Val.Type)\r
526                         {\r
527                         case NLMISC::CConfigFile::CVar::T_INT:          Var.RealValues.push_back ((double)Val.Int); break;\r
528                         case NLMISC::CConfigFile::CVar::T_STRING:       { double val = 0.0; NLMISC::fromString(Val.String, val); Var.RealValues.push_back(val); break; }\r
529                         default: break;\r
530                         }\r
531                         break;\r
532                 case NLMISC::CConfigFile::CVar::T_STRING:\r
533                         switch (Val.Type)\r
534                         {\r
535                         case NLMISC::CConfigFile::CVar::T_INT:  Var.StrValues.push_back(toString(Val.Int)); break;\r
536                         case NLMISC::CConfigFile::CVar::T_REAL: Var.StrValues.push_back(toString(Val.Real)); break;\r
537                         default: break;\r
538                         }\r
539                         break;\r
540                 default: break;\r
541                 }\r
542         }\r
545 int yyerror (const char *s)\r
547         DEBUG_PRINTF("%s\n",s);\r
548         return 1;\r