Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Added round trip time contraint to the SDP program, this parameter
[simgrid.git] / src / gras / DataDesc / ddt_parse.c
1 /* $Id$ */
2
3 /* DataDesc/ddt_parse.c -- automatic parsing of data structures             */
4
5 /* Copyright (c) 2003 Arnaud Legrand.                                       */
6 /* Copyright (c) 2003, 2004 Martin Quinson.                                 */
7 /* All rights reserved.                                                     */
8
9 /* This program is free software; you can redistribute it and/or modify it
10  * under the terms of the license (GNU LGPL) which comes with this package. */
11
12 #include <ctype.h> /* isdigit */
13
14 #include "xbt/ex.h"
15 #include "gras/DataDesc/datadesc_private.h"
16 #include "gras/DataDesc/ddt_parse.yy.h"
17
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_ddt_parse,gras_ddt,
19   "Parsing C data structures to build GRAS data description");
20
21 typedef struct s_type_modifier{
22   short is_long;
23   int is_unsigned:1;
24   int is_short:1;
25
26   int is_struct:1;
27   int is_union:1;
28   int is_enum:1;
29
30   int is_ref:1;
31    
32   int is_dynar:2;
33   int is_matrix:2;
34 } s_type_modifier_t,*type_modifier_t;
35
36 typedef struct s_field {
37   gras_datadesc_type_t type;
38   char *type_name;
39   char *name;
40   s_type_modifier_t tm;
41 } s_identifier_t;
42  
43 extern char *gras_ddt_parse_text; /* text being considered in the parser */
44
45 /* local functions */
46 static void parse_type_modifier(type_modifier_t type_modifier)  {
47   XBT_IN;
48   do {
49     if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
50       /* This only used when parsing 'short *' since this function returns when int, float, double,... is encountered */
51       DEBUG0("This is a reference"); 
52       type_modifier->is_ref++;
53       
54     } else if (!strcmp(gras_ddt_parse_text,"unsigned")) {
55       DEBUG0("This is an unsigned");
56       type_modifier->is_unsigned = 1;
57       
58     } else if (!strcmp(gras_ddt_parse_text,"short")) {
59       DEBUG0("This is short");
60       type_modifier->is_short = 1;
61       
62     } else if (!strcmp(gras_ddt_parse_text,"long")) {
63       DEBUG0("This is long");
64       type_modifier->is_long++; /* handle "long long" */
65       
66     } else if (!strcmp(gras_ddt_parse_text,"struct")) {
67       DEBUG0("This is a struct");
68       type_modifier->is_struct = 1;
69       
70     } else if (!strcmp(gras_ddt_parse_text,"union")) {
71       DEBUG0("This is an union");
72       type_modifier->is_union = 1;
73       
74     } else if (!strcmp(gras_ddt_parse_text,"enum")) {
75       DEBUG0("This is an enum");
76       type_modifier->is_enum = 1;
77       
78     } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_EMPTY) {
79       DEBUG0("Pass space");
80
81     } else {
82       DEBUG1("Done with modifiers (got %s)",gras_ddt_parse_text);
83       break;
84     }
85
86     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
87     if((gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) && 
88        (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_STAR)) {
89       DEBUG2("Done with modifiers (got %s,%d)",gras_ddt_parse_text,gras_ddt_parse_tok_num);      
90       break;
91     }
92   } while(1);
93   XBT_OUT;
94 }
95
96 static void print_type_modifier(s_type_modifier_t tm) {
97   int i;
98
99   XBT_IN;
100   if (tm.is_unsigned)             printf("(unsigned) ");
101   if (tm.is_short)                printf("(short) ");
102   for (i=0 ; i<tm.is_long ; i++)  printf("(long) ");
103
104   if(tm.is_struct)                printf("(struct) ");
105   if(tm.is_enum)                  printf("(enum) ");
106   if(tm.is_union)                 printf("(union) ");
107
108   for (i=0 ; i<tm.is_ref ; i++)   printf("(ref) ");
109   XBT_OUT;
110 }
111
112 static void change_to_fixed_array(xbt_dynar_t dynar, long int size) {
113   s_identifier_t former,array;
114   memset(&array,0,sizeof(array));
115
116   XBT_IN;
117   xbt_dynar_pop(dynar,&former);
118   array.type_name=(char*)xbt_malloc(strlen(former.type->name)+48);
119   DEBUG2("Array specification (size=%ld, elm='%s'), change pushed type",
120          size,former.type_name);
121   sprintf(array.type_name,"%s%s%s%s[%ld]",
122           (former.tm.is_unsigned?"u ":""),
123           (former.tm.is_short?"s ":""),
124           (former.tm.is_long?"l ":""),
125           former.type_name,
126           size);
127   free(former.type_name);
128
129   array.type = gras_datadesc_array_fixed(array.type_name, former.type, size); /* redeclaration are ignored */
130   array.name = former.name;
131
132   xbt_dynar_push(dynar,&array);
133   XBT_OUT;
134 }
135 static void change_to_ref(xbt_dynar_t dynar) {
136   s_identifier_t former,ref;
137   memset(&ref,0,sizeof(ref));
138
139   XBT_IN;
140   xbt_dynar_pop(dynar,&former);
141   ref.type_name=(char*)xbt_malloc(strlen(former.type->name)+2);
142   DEBUG1("Ref specification (elm='%s'), change pushed type", former.type_name);
143   sprintf(ref.type_name,"%s*",former.type_name);
144   free(former.type_name);
145
146   ref.type = gras_datadesc_ref(ref.type_name, former.type); /* redeclaration are ignored */
147   ref.name = former.name;
148
149   xbt_dynar_push(dynar,&ref);
150   XBT_OUT;
151 }
152
153 static void change_to_ref_pop_array(xbt_dynar_t dynar) {
154   s_identifier_t former,ref;
155   memset(&ref,0,sizeof(ref));
156
157   XBT_IN;
158   xbt_dynar_pop(dynar,&former);
159   ref.type = gras_datadesc_ref_pop_arr(former.type); /* redeclaration are ignored */
160   ref.type_name = (char*)strdup(ref.type->name);
161   ref.name = former.name;
162
163   free(former.type_name);
164
165   xbt_dynar_push(dynar,&ref);
166   XBT_OUT;
167 }
168
169 static void change_to_dynar_of(xbt_dynar_t dynar,gras_datadesc_type_t subtype) {
170   s_identifier_t former,ref;
171   memset(&ref,0,sizeof(ref));
172
173   XBT_IN;
174   xbt_dynar_pop(dynar,&former);
175   ref.type = gras_datadesc_dynar(subtype,NULL); /* redeclaration are ignored */
176   ref.type_name = (char*)strdup(ref.type->name);
177   ref.name = former.name;
178
179   free(former.type_name);
180
181   xbt_dynar_push(dynar,&ref);
182   XBT_OUT;
183 }
184
185 static void change_to_matrix_of(xbt_dynar_t dynar,gras_datadesc_type_t subtype) {
186   s_identifier_t former,ref;
187   memset(&ref,0,sizeof(ref));
188
189   XBT_IN;
190   xbt_dynar_pop(dynar,&former);
191   ref.type = gras_datadesc_matrix(subtype,NULL); /* redeclaration are ignored */
192   ref.type_name = (char*)strdup(ref.type->name);
193   ref.name = former.name;
194
195   free(former.type_name);
196
197   xbt_dynar_push(dynar,&ref);
198   XBT_OUT;
199 }
200
201 static void add_free_f(xbt_dynar_t dynar,void_f_pvoid_t free_f) {
202   s_identifier_t former,ref;
203   memset(&ref,0,sizeof(ref));
204
205   XBT_IN;
206   xbt_dynar_pop(dynar,&former);
207   memcpy(former.type->extra,&free_f, sizeof(free_f));
208   xbt_dynar_push(dynar,&former);
209   XBT_OUT;
210 }
211
212 static void parse_statement(char         *definition,
213                             xbt_dynar_t  identifiers,
214                             xbt_dynar_t  fields_to_push) {
215   char buffname[512];
216
217   s_identifier_t identifier;
218
219   int expect_id_separator = 0;
220
221   XBT_IN;
222   memset(&identifier,0,sizeof(identifier));
223
224   gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
225   if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RA) {
226     XBT_OUT;
227     THROW0(mismatch_error,0,"End of the englobing structure or union");
228   }
229   
230   if (XBT_LOG_ISENABLED(gras_ddt_parse,xbt_log_priority_debug)) {
231     int colon_pos;
232     for (colon_pos = gras_ddt_parse_col_pos;
233          definition[colon_pos] != ';';
234          colon_pos++);
235     definition[colon_pos] = '\0';
236     DEBUG3("Parse the statement \"%s%s;\" (col_pos=%d)",
237            gras_ddt_parse_text,
238            definition+gras_ddt_parse_col_pos,
239            gras_ddt_parse_col_pos);
240     definition[colon_pos] = ';';
241   }
242
243   if(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
244     PARSE_ERROR1("Unparsable symbol: found a typeless statement (got '%s' instead)",
245                  gras_ddt_parse_text);
246
247   /**** get the type modifier of this statement ****/
248   parse_type_modifier(&identifier.tm);
249
250   /*  FIXME: This does not detect recursive definitions at all? */
251   if (identifier.tm.is_union || identifier.tm.is_enum || identifier.tm.is_struct)
252     PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle recursive type definition yet");
253
254   /**** get the base type, giving "short a" the needed love ****/
255   if (!identifier.tm.is_union &&
256       !identifier.tm.is_enum  && 
257       !identifier.tm.is_struct &&
258
259       (identifier.tm.is_short || identifier.tm.is_long || identifier.tm.is_unsigned) &&
260
261       strcmp(gras_ddt_parse_text,"char") && 
262       strcmp(gras_ddt_parse_text,"float") && 
263       strcmp(gras_ddt_parse_text,"double") && 
264       strcmp(gras_ddt_parse_text,"int") ) {
265
266     /* bastard user, they omited "int" ! */
267     identifier.type_name=(char*)strdup("int");
268     DEBUG0("the base type is 'int', which were omited (you vicious user)");
269   } else {
270     identifier.type_name=(char*)strdup(gras_ddt_parse_text);
271     DEBUG1("the base type is '%s'",identifier.type_name);
272     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump(); 
273   }
274
275   /**** build the base type for latter use ****/
276   if (identifier.tm.is_union) {
277     PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
278
279   } else if (identifier.tm.is_enum) {
280     PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle enum yet");
281
282   } else if (identifier.tm.is_struct) {
283     sprintf(buffname,"struct %s",identifier.type_name);
284     identifier.type = gras_datadesc_struct(buffname); /* Get created when does not exist */
285
286   } else if (identifier.tm.is_unsigned) {
287     if (!strcmp(identifier.type_name,"int")) {
288       if (identifier.tm.is_long == 2) {
289         identifier.type = gras_datadesc_by_name("unsigned long long int");
290       } else if (identifier.tm.is_long) {
291         identifier.type = gras_datadesc_by_name("unsigned long int");
292       } else if (identifier.tm.is_short) {
293         identifier.type = gras_datadesc_by_name("unsigned short int");
294       } else {
295         identifier.type = gras_datadesc_by_name("unsigned int");
296       }
297
298     } else if (!strcmp(identifier.type_name, "char")) {
299       identifier.type = gras_datadesc_by_name("unsigned char");
300
301     } else { /* impossible, gcc parses this shit before us */
302       THROW_IMPOSSIBLE;
303     }
304     
305   } else if (!strcmp(identifier.type_name, "float")) {
306     /* no modificator allowed by gcc */
307     identifier.type = gras_datadesc_by_name("float");
308
309   } else if (!strcmp(identifier.type_name, "double")) {
310     if (identifier.tm.is_long)
311       PARSE_ERROR0("long double not portable and thus not handled");
312
313     identifier.type = gras_datadesc_by_name("double");
314
315   } else { /* signed integer elemental */
316     if (!strcmp(identifier.type_name,"int")) {
317       if (identifier.tm.is_long == 2) {
318         identifier.type = gras_datadesc_by_name("signed long long int");
319       } else if (identifier.tm.is_long) {
320         identifier.type = gras_datadesc_by_name("signed long int");
321       } else if (identifier.tm.is_short) {
322         identifier.type = gras_datadesc_by_name("signed short int");
323       } else {
324         identifier.type = gras_datadesc_by_name("int");
325       }
326
327     } else if (!strcmp(identifier.type_name, "char")) {
328       identifier.type = gras_datadesc_by_name("char");
329
330     } else { 
331       DEBUG1("Base type is a constructed one (%s)",identifier.type_name);
332       if (!strcmp(identifier.type_name,"xbt_matrix_t")) {
333          identifier.tm.is_matrix = 1;
334       } else if (!strcmp(identifier.type_name,"xbt_dynar_t")) {
335          identifier.tm.is_dynar = 1;
336       } else {       
337          identifier.type = gras_datadesc_by_name(identifier.type_name);
338          if (!identifier.type)
339            PARSE_ERROR1("Unknown base type '%s'",identifier.type_name);
340       }
341     }
342   } 
343   /* Now identifier.type and identifier.name speak about the base type.
344      Stars are not eaten unless 'int' was omitted.
345      We will have to enhance it if we are in fact asked for array or reference.
346    
347      Dynars and matrices also need some extra love (prodiged as annotations)
348    */
349
350   /**** look for the symbols of this type ****/
351   for(expect_id_separator = 0;
352
353       (/*(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_EMPTY) && FIXME*/
354        (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_SEMI_COLON)) ; 
355
356       gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()          ) {   
357
358     if(expect_id_separator) {
359       if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
360         expect_id_separator = 0;
361         continue;
362
363       } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_LB) {
364         /* Handle fixed size arrays */
365         gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
366         if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RB) {
367           PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot deal with [] constructs (yet)");
368
369         } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
370           char *end;
371           long int size=strtol(gras_ddt_parse_text, &end, 10);
372
373           if (end == gras_ddt_parse_text || *end != '\0') {
374             /* Not a number. Get the constant value, if any */
375             int *storage=xbt_dict_get_or_null(gras_dd_constants,gras_ddt_parse_text);
376             if (storage) {
377               size = *storage;
378             } else {
379               PARSE_ERROR1("Unparsable size of array. Found '%s', expected number or known constant. Need to use gras_datadesc_set_const(), huh?",
380                            gras_ddt_parse_text);
381             }
382           }
383
384           /* replace the previously pushed type to an array of it */
385           change_to_fixed_array(identifiers,size);
386
387           /* eat the closing bracket */
388           gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
389           if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RB)
390             PARSE_ERROR0("Unparsable size of array");
391         DEBUG1("Fixed size array, size=%ld",size);
392         continue;
393         } else {
394           PARSE_ERROR0("Unparsable size of array");
395         }
396         /* End of fixed size arrays handling */
397
398       } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
399         /* Handle annotation */
400         s_identifier_t array;
401         char *keyname = NULL;
402         char *keyval  = NULL;
403         memset(&array,0,sizeof(array));
404         if (strcmp(gras_ddt_parse_text,"GRAS_ANNOTE"))
405           PARSE_ERROR1("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",gras_ddt_parse_text);
406         
407         gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
408         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP) 
409           PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",gras_ddt_parse_text);
410
411         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
412
413         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) 
414           PARSE_ERROR1("Unparsable annotation: Expected key name, got '%s'",gras_ddt_parse_text);
415         keyname = (char*)strdup(gras_ddt_parse_text);
416
417         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
418
419         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON) 
420           PARSE_ERROR1("Unparsable annotation: expected ',' after the key name, got '%s'",gras_ddt_parse_text);
421
422         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
423
424         /* get the value */
425
426         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) 
427           PARSE_ERROR1("Unparsable annotation: Expected key value, got '%s'",gras_ddt_parse_text);
428         keyval = (char*)strdup(gras_ddt_parse_text);
429
430         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
431
432         /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
433
434         DEBUG2("Anotation: %s=%s",keyname,keyval);
435         if (!strcmp(keyname,"size")) {
436           free(keyname);
437           if (!identifier.tm.is_ref)
438             PARSE_ERROR0("Size annotation for a field not being a reference");
439           identifier.tm.is_ref--;
440
441           if (!strcmp(keyval,"1")) {
442             change_to_ref(identifiers);
443             free(keyval);
444           } else {
445             char *p;
446             int fixed = 1;
447             for (p = keyval; *p != '\0'; p++) 
448               if (! isdigit(*p) )
449                 fixed = 0;
450             if (fixed) {
451               change_to_fixed_array(identifiers,atoi(keyval));
452               change_to_ref(identifiers);
453               free(keyval);
454
455             } else {
456               change_to_ref_pop_array(identifiers);
457               xbt_dynar_push(fields_to_push,&keyval);
458             }
459           }
460         } else if (!strcmp(keyname,"subtype")) {
461            gras_datadesc_type_t subtype = gras_datadesc_by_name(keyval);
462            if (identifier.tm.is_matrix) {
463               change_to_matrix_of(identifiers,subtype);
464               identifier.tm.is_matrix = -1;
465            } else if (identifier.tm.is_dynar) {
466               change_to_dynar_of(identifiers,subtype);
467               identifier.tm.is_dynar = -1;
468            } else {       
469              PARSE_ERROR1("subtype annotation only accepted for dynars and matrices, but passed to '%s'",identifier.type_name);
470            }
471            free(keyval);
472         } else if (!strcmp(keyname,"free_f")) {
473            int *storage=xbt_dict_get_or_null(gras_dd_constants,keyval);
474            if (!storage)
475              PARSE_ERROR1("value for free_f annotation of field %s is not a known constant",identifier.name);
476            if (identifier.tm.is_matrix == -1) {
477               add_free_f(identifiers,*(void_f_pvoid_t**)storage);
478               identifier.tm.is_matrix = 0;
479            } else if (identifier.tm.is_dynar == -1) {
480               add_free_f(identifiers,*(void_f_pvoid_t**)storage);
481               identifier.tm.is_dynar = 0;
482            } else {       
483              PARSE_ERROR1("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
484                           identifier.name);
485            }
486            free(keyval);
487         } else {
488           free(keyval);
489           PARSE_ERROR1("Unknown annotation type: '%s'",keyname);
490         }
491
492         /* Get all the multipliers */
493         while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
494
495           gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
496
497           if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) 
498             PARSE_ERROR1("Unparsable annotation: Expected field name after '*', got '%s'",gras_ddt_parse_text);
499           
500           keyval = xbt_malloc(strlen(gras_ddt_parse_text)+2);
501           sprintf(keyval,"*%s",gras_ddt_parse_text);
502
503           /* ask caller to push field as a multiplier */
504           xbt_dynar_push(fields_to_push,&keyval);
505
506           /* skip blanks after this block*/
507           while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) 
508                   == GRAS_DDT_PARSE_TOKEN_EMPTY );
509         }
510
511         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP) 
512           PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",
513                        gras_ddt_parse_text);
514
515         continue;
516
517         /* End of annotation handling */
518       } else {
519         PARSE_ERROR1("Unparsable symbol: Got '%s' instead of expected comma (',')",gras_ddt_parse_text);
520       }
521     } else if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
522       PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
523     }
524
525     if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
526       identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
527       continue;
528     }
529
530     /* found a symbol name. Build the type and push it to dynar */
531     if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
532
533       identifier.name=(char*)strdup(gras_ddt_parse_text);
534       DEBUG1("Found the identifier \"%s\"",identifier.name);
535       
536       xbt_dynar_push(identifiers, &identifier);
537       DEBUG1("Dynar_len=%lu",xbt_dynar_length(identifiers));
538       expect_id_separator = 1;
539       continue;
540     }
541
542     PARSE_ERROR0("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
543   }
544
545   if (identifier.tm.is_matrix>0) 
546      PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
547   if (identifier.tm.is_dynar>0)
548      PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
549    
550   XBT_OUT;
551 }
552
553 static gras_datadesc_type_t parse_struct(char *definition) {
554
555   xbt_ex_t e;
556
557   char buffname[32];
558   static int anonymous_struct=0;
559
560   xbt_dynar_t identifiers;
561   s_identifier_t field;
562   int i;
563   int done;
564
565   xbt_dynar_t fields_to_push;
566   char *name;
567
568   gras_datadesc_type_t struct_type;
569
570   XBT_IN;
571   identifiers = xbt_dynar_new(sizeof(s_identifier_t),NULL);
572   fields_to_push = xbt_dynar_new(sizeof(char*),NULL);
573
574   /* Create the struct descriptor */
575   if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
576     struct_type = gras_datadesc_struct(gras_ddt_parse_text);
577     VERB1("Parse the struct '%s'", gras_ddt_parse_text);
578     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
579   } else {
580     sprintf(buffname,"anonymous struct %d",anonymous_struct++); 
581     VERB1("Parse the anonymous struct nb %d", anonymous_struct);
582     struct_type = gras_datadesc_struct(buffname);
583   }
584
585   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
586     PARSE_ERROR1("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
587                  gras_ddt_parse_text);
588
589   /* Parse the identifiers */
590   done = 0;
591   do {
592     TRY {
593       parse_statement(definition,identifiers,fields_to_push);
594     } CATCH(e) {
595       if (e.category != mismatch_error)
596         RETHROW;
597       xbt_ex_free(e);
598       done = 1;
599     }
600     
601     DEBUG1("This statement contained %lu identifiers",xbt_dynar_length(identifiers));
602     /* append the identifiers we've found */
603     xbt_dynar_foreach(identifiers,i, field) {
604       if (field.tm.is_ref)
605         PARSE_ERROR2("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
606                      field.name,field.tm.is_ref);
607
608       VERB2("Append field '%s' to %p",field.name, (void*)struct_type);      
609       gras_datadesc_struct_append(struct_type, field.name, field.type);
610       free(field.name);
611       free(field.type_name);
612
613     }
614     xbt_dynar_reset(identifiers);
615     DEBUG1("struct_type=%p",(void*)struct_type);
616     
617     /* Make sure that all fields declaring a size push it into the cbps */
618     xbt_dynar_foreach(fields_to_push,i, name) {
619       DEBUG1("struct_type=%p",(void*)struct_type);
620       if (name[0] == '*') {
621         VERB2("Push field '%s' as a multiplier into size stack of %p",
622               name+1, (void*)struct_type);
623         gras_datadesc_cb_field_push_multiplier(struct_type, name+1);
624       } else {
625         VERB2("Push field '%s' into size stack of %p",
626               name, (void*)struct_type);
627         gras_datadesc_cb_field_push(struct_type, name);
628       }
629       free(name);
630     }
631     xbt_dynar_reset(fields_to_push);
632   } while (!done);
633   gras_datadesc_struct_close(struct_type);
634
635   /* terminates */
636   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
637     PARSE_ERROR1("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
638                  gras_ddt_parse_text);
639
640   gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
641
642   xbt_dynar_free(&identifiers);
643   xbt_dynar_free(&fields_to_push);
644   XBT_OUT;
645   return struct_type;
646 }
647
648 static gras_datadesc_type_t parse_typedef(char *definition) {
649
650   s_type_modifier_t tm;
651
652   gras_datadesc_type_t struct_desc=NULL;
653   gras_datadesc_type_t typedef_desc=NULL;
654
655   XBT_IN;
656   memset(&tm,0,sizeof(tm));
657
658   /* get the aliased type */
659   parse_type_modifier(&tm);
660
661   if (tm.is_struct) {
662     struct_desc = parse_struct(definition);
663   }
664
665   parse_type_modifier(&tm);
666
667   if (tm.is_ref) 
668     PARSE_ERROR0("GRAS_DEFINE_TYPE cannot handle reference without annotation");
669
670   /* get the aliasing name */
671   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
672     PARSE_ERROR1("Unparsable typedef: Expected the alias name, and got '%s'",
673                  gras_ddt_parse_text);
674   
675   /* (FIXME: should) build the alias */
676   PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle typedef yet");
677
678   XBT_OUT;
679   return typedef_desc;
680 }
681
682
683 /**
684  * gras_datadesc_parse:
685  *
686  * Create a datadescription from the result of parsing the C type description
687  */
688 gras_datadesc_type_t 
689 gras_datadesc_parse(const char            *name,
690                     const char            *C_statement) {
691
692   gras_datadesc_type_t res=NULL;
693   char *definition;
694   int semicolon_count=0;
695   int def_count,C_count;
696
697   XBT_IN;
698   /* reput the \n in place for debug */
699   for (C_count=0; C_statement[C_count] != '\0'; C_count++)
700     if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
701       semicolon_count++;
702   definition = (char*)xbt_malloc(C_count + semicolon_count + 1);
703   for (C_count=0,def_count=0; C_statement[C_count] != '\0'; C_count++) {
704     definition[def_count++] = C_statement[C_count];
705     if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
706       definition[def_count++] = '\n';
707     }
708   }
709   definition[def_count] = '\0';
710
711   /* init */ 
712   VERB2("_gras_ddt_type_parse(%s) -> %d chars",definition, def_count);
713   gras_ddt_parse_pointer_string_init(definition);
714
715   /* Do I have a typedef, or a raw struct ?*/
716   gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
717   
718   if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"struct"))) {
719     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
720     res = parse_struct(definition);
721       
722   } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"typedef"))) {
723     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
724     res = parse_typedef(definition);
725
726   } else {
727     ERROR1("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",definition);    
728     xbt_abort();
729   }
730
731   gras_ddt_parse_pointer_string_close();
732   VERB0("end of _gras_ddt_type_parse()");
733   free(definition);
734   /* register it under the name provided as symbol */
735   if (strcmp(res->name,name)) {
736     ERROR2("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
737            name,res->name);
738     xbt_abort();
739   }    
740   gras_ddt_parse_lex_destroy();
741   XBT_OUT;
742   return res;
743 }
744
745 xbt_dict_t gras_dd_constants;
746 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
747 void gras_datadesc_set_const(const char*name, int value) {
748   int *stored = xbt_new(int, 1);
749   *stored=value;
750
751   xbt_dict_set(gras_dd_constants,name, stored, xbt_free_f); 
752 }