Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
b2a42e7b1726a4bbaad21b7c5df94e7220143e65
[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(ddt_parse,datadesc,
19   "Parsing C data structures to build GRAS data description");
20
21 typedef struct s_type_modifier{
22   short is_unsigned;
23   short is_short;
24   short is_long;
25
26   short is_struct;
27   short is_union;
28   short is_enum;
29
30   short is_ref;
31 } s_type_modifier_t,*type_modifier_t;
32
33 typedef struct s_field {
34   gras_datadesc_type_t type;
35   char *type_name;
36   char *name;
37   s_type_modifier_t tm;
38 } s_identifier_t;
39  
40 extern char *gras_ddt_parse_text; /* text being considered in the parser */
41
42 /* local functions */
43 static void parse_type_modifier(type_modifier_t type_modifier)  {
44   XBT_IN;
45   do {
46     if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
47       /* This only used when parsing 'short *' since this function returns when int, float, double,... is encountered */
48       DEBUG0("This is a reference"); 
49       type_modifier->is_ref++;
50       
51     } else if (!strcmp(gras_ddt_parse_text,"unsigned")) {
52       DEBUG0("This is an unsigned");
53       type_modifier->is_unsigned = 1;
54       
55     } else if (!strcmp(gras_ddt_parse_text,"short")) {
56       DEBUG0("This is short");
57       type_modifier->is_short = 1;
58       
59     } else if (!strcmp(gras_ddt_parse_text,"long")) {
60       DEBUG0("This is long");
61       type_modifier->is_long++; /* handle "long long" */
62       
63     } else if (!strcmp(gras_ddt_parse_text,"struct")) {
64       DEBUG0("This is a struct");
65       type_modifier->is_struct = 1;
66       
67     } else if (!strcmp(gras_ddt_parse_text,"union")) {
68       DEBUG0("This is an union");
69       type_modifier->is_union = 1;
70       
71     } else if (!strcmp(gras_ddt_parse_text,"enum")) {
72       DEBUG0("This is an enum");
73       type_modifier->is_enum = 1;
74       
75     } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_EMPTY) {
76       DEBUG0("Pass space");
77
78     } else {
79       DEBUG1("Done with modifiers (got %s)",gras_ddt_parse_text);
80       break;
81     }
82
83     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
84     if((gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) && 
85        (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_STAR)) {
86       DEBUG2("Done with modifiers (got %s,%d)",gras_ddt_parse_text,gras_ddt_parse_tok_num);      
87       break;
88     }
89   } while(1);
90   XBT_OUT;
91 }
92
93 static void print_type_modifier(s_type_modifier_t tm) __attribute__((unused));
94 static void print_type_modifier(s_type_modifier_t tm) {
95   int i;
96
97   XBT_IN;
98   if (tm.is_unsigned)             printf("(unsigned) ");
99   if (tm.is_short)                printf("(short) ");
100   for (i=0 ; i<tm.is_long ; i++)  printf("(long) ");
101
102   if(tm.is_struct)                printf("(struct) ");
103   if(tm.is_enum)                  printf("(enum) ");
104   if(tm.is_union)                 printf("(union) ");
105
106   for (i=0 ; i<tm.is_ref ; i++)   printf("(ref) ");
107   XBT_OUT;
108 }
109
110 static void change_to_fixed_array(xbt_dynar_t dynar, long int size) {
111   s_identifier_t former,array;
112   memset(&array,0,sizeof(array));
113
114   XBT_IN;
115   xbt_dynar_pop(dynar,&former);
116   array.type_name=(char*)xbt_malloc(strlen(former.type->name)+48);
117   DEBUG2("Array specification (size=%ld, elm='%s'), change pushed type",
118          size,former.type_name);
119   sprintf(array.type_name,"%s%s%s%s[%ld]",
120           (former.tm.is_unsigned?"u ":""),
121           (former.tm.is_short?"s ":""),
122           (former.tm.is_long?"l ":""),
123           former.type_name,
124           size);
125   free(former.type_name);
126
127   array.type = gras_datadesc_array_fixed(array.type_name, former.type, size); /* redeclaration are ignored */
128   array.name = former.name;
129
130   xbt_dynar_push(dynar,&array);
131   XBT_OUT;
132 }
133 static void change_to_ref(xbt_dynar_t dynar) {
134   s_identifier_t former,ref;
135   memset(&ref,0,sizeof(ref));
136
137   XBT_IN;
138   xbt_dynar_pop(dynar,&former);
139   ref.type_name=(char*)xbt_malloc(strlen(former.type->name)+2);
140   DEBUG1("Ref specification (elm='%s'), change pushed type", former.type_name);
141   sprintf(ref.type_name,"%s*",former.type_name);
142   free(former.type_name);
143
144   ref.type = gras_datadesc_ref(ref.type_name, former.type); /* redeclaration are ignored */
145   ref.name = former.name;
146
147   xbt_dynar_push(dynar,&ref);
148   XBT_OUT;
149 }
150
151 static void change_to_ref_pop_array(xbt_dynar_t dynar) {
152   s_identifier_t former,ref;
153   memset(&ref,0,sizeof(ref));
154
155   XBT_IN;
156   xbt_dynar_pop(dynar,&former);
157   ref.type = gras_datadesc_ref_pop_arr(former.type); /* redeclaration are ignored */
158   ref.type_name = (char*)strdup(ref.type->name);
159   ref.name = former.name;
160
161   free(former.type_name);
162
163   xbt_dynar_push(dynar,&ref);
164   XBT_OUT;
165 }
166
167 static xbt_error_t parse_statement(char  *definition,
168                                     xbt_dynar_t  identifiers,
169                                     xbt_dynar_t  fields_to_push) {
170   char buffname[512];
171
172   s_identifier_t identifier;
173
174   int expect_id_separator = 0;
175
176   XBT_IN;
177   memset(&identifier,0,sizeof(identifier));
178
179   gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
180   if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RA) {
181     XBT_OUT;
182     return old_mismatch_error; /* end of the englobing structure or union */
183   }
184   
185   if (XBT_LOG_ISENABLED(ddt_parse,xbt_log_priority_debug)) {
186     int colon_pos;
187     for (colon_pos = gras_ddt_parse_col_pos;
188          definition[colon_pos] != ';';
189          colon_pos++);
190     definition[colon_pos] = '\0';
191     DEBUG3("Parse the statement \"%s%s;\" (col_pos=%d)",
192            gras_ddt_parse_text,
193            definition+gras_ddt_parse_col_pos,
194            gras_ddt_parse_col_pos);
195     definition[colon_pos] = ';';
196   }
197
198   if(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
199     PARSE_ERROR1("Unparsable symbol: found a typeless statement (got '%s' instead)",
200                  gras_ddt_parse_text);
201
202   /**** get the type modifier of this statement ****/
203   parse_type_modifier(&identifier.tm);
204
205   /*  FIXME: This does not detect recursive definitions at all? */
206   if (identifier.tm.is_union || identifier.tm.is_enum || identifier.tm.is_struct)
207     PARSE_ERROR0("Cannot handle recursive type definition yet");
208
209   /**** get the base type, giving "short a" the needed love ****/
210   if (!identifier.tm.is_union &&
211       !identifier.tm.is_enum  && 
212       !identifier.tm.is_struct &&
213
214       (identifier.tm.is_short || identifier.tm.is_long || identifier.tm.is_unsigned) &&
215
216       strcmp(gras_ddt_parse_text,"char") && 
217       strcmp(gras_ddt_parse_text,"float") && 
218       strcmp(gras_ddt_parse_text,"double") && 
219       strcmp(gras_ddt_parse_text,"int") ) {
220
221     /* bastard user, they omited "int" ! */
222     identifier.type_name=(char*)strdup("int");
223     DEBUG0("the base type is 'int', which were omited (you vicious user)");
224   } else {
225     identifier.type_name=(char*)strdup(gras_ddt_parse_text);
226     DEBUG1("the base type is '%s'",identifier.type_name);
227     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump(); 
228   }
229
230   /**** build the base type for latter use ****/
231   if (identifier.tm.is_union) {
232     PARSE_ERROR0("Cannot handle union yet (get callback from annotation?)");
233
234   } else if (identifier.tm.is_enum) {
235     PARSE_ERROR0("Cannot handle enum yet");
236
237   } else if (identifier.tm.is_struct) {
238     sprintf(buffname,"struct %s",identifier.type_name);
239     identifier.type = gras_datadesc_struct(buffname); /* Get created when does not exist */
240
241   } else if (identifier.tm.is_unsigned) {
242     if (!strcmp(identifier.type_name,"int")) {
243       if (identifier.tm.is_long == 2) {
244         identifier.type = gras_datadesc_by_name("unsigned long long int");
245       } else if (identifier.tm.is_long) {
246         identifier.type = gras_datadesc_by_name("unsigned long int");
247       } else if (identifier.tm.is_short) {
248         identifier.type = gras_datadesc_by_name("unsigned short int");
249       } else {
250         identifier.type = gras_datadesc_by_name("unsigned int");
251       }
252
253     } else if (!strcmp(identifier.type_name, "char")) {
254       identifier.type = gras_datadesc_by_name("unsigned char");
255
256     } else { /* impossible, gcc parses this shit before us */
257       THROW_IMPOSSIBLE;
258     }
259     
260   } else if (!strcmp(identifier.type_name, "float")) {
261     /* no modificator allowed by gcc */
262     identifier.type = gras_datadesc_by_name("float");
263
264   } else if (!strcmp(identifier.type_name, "double")) {
265     if (identifier.tm.is_long)
266       PARSE_ERROR0("long double not portable and thus not handled");
267
268     identifier.type = gras_datadesc_by_name("double");
269
270   } else { /* signed integer elemental */
271     if (!strcmp(identifier.type_name,"int")) {
272       if (identifier.tm.is_long == 2) {
273         identifier.type = gras_datadesc_by_name("signed long long int");
274       } else if (identifier.tm.is_long) {
275         identifier.type = gras_datadesc_by_name("signed long int");
276       } else if (identifier.tm.is_short) {
277         identifier.type = gras_datadesc_by_name("signed short int");
278       } else {
279         identifier.type = gras_datadesc_by_name("int");
280       }
281
282     } else if (!strcmp(identifier.type_name, "char")) {
283       identifier.type = gras_datadesc_by_name("char");
284
285     } else { 
286       DEBUG1("Base type is a constructed one (%s)",identifier.type_name);
287       identifier.type = gras_datadesc_by_name(identifier.type_name);
288       if (!identifier.type)
289         PARSE_ERROR1("Unknown base type '%s'",identifier.type_name);
290     }
291   } 
292   /* Now identifier.type and identifier.name speak about the base type.
293      Stars are not eaten unless 'int' was omitted.
294      We will have to enhance it if we are in fact asked for array or reference */
295
296   /**** look for the symbols of this type ****/
297   for(expect_id_separator = 0;
298
299       (/*(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_EMPTY) && FIXME*/
300        (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_SEMI_COLON)) ; 
301
302       gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()          ) {   
303
304     if(expect_id_separator) {
305       if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
306         expect_id_separator = 0;
307         continue;
308
309       } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_LB) {
310         /* Handle fixed size arrays */
311         gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
312         if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RB) {
313           PARSE_ERROR0("Cannot deal with [] constructs (yet)");
314
315         } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
316           char *end;
317           long int size=strtol(gras_ddt_parse_text, &end, 10);
318
319           if (end == gras_ddt_parse_text || *end != '\0')
320             PARSE_ERROR1("Unparsable size of array (found '%c', expected number)",*end);
321
322           /* replace the previously pushed type to an array of it */
323           change_to_fixed_array(identifiers,size);
324
325           /* eat the closing bracket */
326           gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
327           if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RB)
328             PARSE_ERROR0("Unparsable size of array");
329         DEBUG1("Fixed size array, size=%ld",size);
330         continue;
331         } else {
332           PARSE_ERROR0("Unparsable size of array");
333         }
334         /* End of fixed size arrays handling */
335
336       } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
337         /* Handle annotation */
338         s_identifier_t array;
339         char *keyname = NULL;
340         char *keyval  = NULL;
341         memset(&array,0,sizeof(array));
342         if (strcmp(gras_ddt_parse_text,"GRAS_ANNOTE"))
343           PARSE_ERROR1("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",gras_ddt_parse_text);
344         
345         gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
346         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP) 
347           PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",gras_ddt_parse_text);
348
349         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
350
351         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) 
352           PARSE_ERROR1("Unparsable annotation: Expected key name, got '%s'",gras_ddt_parse_text);
353         keyname = (char*)strdup(gras_ddt_parse_text);
354
355         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
356
357         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON) 
358           PARSE_ERROR1("Unparsable annotation: expected ',' after the key name, got '%s'",gras_ddt_parse_text);
359
360         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
361
362         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) 
363           PARSE_ERROR1("Unparsable annotation: Expected key value, got '%s'",gras_ddt_parse_text);
364         keyval = (char*)strdup(gras_ddt_parse_text);
365
366         while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
367
368         if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP) 
369           PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",gras_ddt_parse_text);
370
371         /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
372
373         DEBUG2("Anotation: %s=%s",keyname,keyval);
374         if (!strcmp(keyname,"size")) {
375           free(keyname);
376           if (!identifier.tm.is_ref)
377             PARSE_ERROR0("Size annotation for a field not being a reference");
378           identifier.tm.is_ref--;
379
380           if (!strcmp(keyval,"1")) {
381             change_to_ref(identifiers);
382             free(keyval);
383             continue;
384           } else {
385             char *p;
386             int fixed = 1;
387             for (p = keyval; *p != '\0'; p++) 
388               if (! isdigit(*p) )
389                 fixed = 0;
390             if (fixed) {
391               change_to_fixed_array(identifiers,atoi(keyval));
392               change_to_ref(identifiers);
393               free(keyval);
394               continue;
395
396             } else {
397               change_to_ref_pop_array(identifiers);
398               xbt_dynar_push(fields_to_push,&keyval);
399               continue;
400             }
401           }
402           THROW_IMPOSSIBLE;
403
404         } else {
405           PARSE_ERROR1("Unknown annotation type: '%s'",keyname);
406         }
407         continue;
408
409         /* End of annotation handling */
410       } else {
411         PARSE_ERROR1("Unparsable symbol: Got '%s' instead of expected comma (',')",gras_ddt_parse_text);
412       }
413     } else if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
414       PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
415     }
416
417     if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
418       identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
419       continue;
420     }
421
422     /* found a symbol name. Build the type and push it to dynar */
423     if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
424
425       identifier.name=(char*)strdup(gras_ddt_parse_text);
426       DEBUG1("Found the identifier \"%s\"",identifier.name);
427       
428       xbt_dynar_push(identifiers, &identifier);
429       DEBUG1("Dynar_len=%lu",xbt_dynar_length(identifiers));
430       expect_id_separator = 1;
431       continue;
432     }
433
434     PARSE_ERROR0("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
435   }
436
437   XBT_OUT;
438   return no_error;
439 }
440
441 static gras_datadesc_type_t parse_struct(char *definition) {
442
443   xbt_error_t errcode;
444   char buffname[32];
445   static int anonymous_struct=0;
446
447   xbt_dynar_t identifiers;
448   s_identifier_t field;
449   int i;
450
451   xbt_dynar_t fields_to_push;
452   char *name;
453
454   gras_datadesc_type_t struct_type;
455
456   XBT_IN;
457   identifiers = xbt_dynar_new(sizeof(s_identifier_t),NULL);
458   fields_to_push = xbt_dynar_new(sizeof(char*),NULL);
459
460   /* Create the struct descriptor */
461   if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
462     struct_type = gras_datadesc_struct(gras_ddt_parse_text);
463     VERB1("Parse the struct '%s'", gras_ddt_parse_text);
464     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
465   } else {
466     sprintf(buffname,"anonymous struct %d",anonymous_struct++); 
467     VERB1("Parse the anonymous struct nb %d", anonymous_struct);
468     struct_type = gras_datadesc_struct(buffname);
469   }
470
471   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
472     PARSE_ERROR1("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
473                  gras_ddt_parse_text);
474
475   /* Parse the identifiers */
476   for (errcode=parse_statement(definition,identifiers,fields_to_push);
477        errcode == no_error                            ;
478        errcode=parse_statement(definition,identifiers,fields_to_push)) {
479     
480     DEBUG1("This statement contained %lu identifiers",xbt_dynar_length(identifiers));
481     /* append the identifiers we've found */
482     xbt_dynar_foreach(identifiers,i, field) {
483       if (field.tm.is_ref)
484         PARSE_ERROR2("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
485                      field.name,field.tm.is_ref);
486
487       VERB2("Append field '%s' to %p",field.name, (void*)struct_type);      
488       gras_datadesc_struct_append(struct_type, field.name, field.type);
489       free(field.name);
490       free(field.type_name);
491
492     }
493     xbt_dynar_reset(identifiers);
494     DEBUG1("struct_type=%p",(void*)struct_type);
495     
496     /* Make sure that all fields declaring a size push it into the cbps */
497     xbt_dynar_foreach(fields_to_push,i, name) {
498       DEBUG1("struct_type=%p",(void*)struct_type);
499       VERB2("Push field '%s' into size stack of %p", name, (void*)struct_type);
500       gras_datadesc_cb_field_push(struct_type, name);
501       free(name);
502     }
503     xbt_dynar_reset(fields_to_push);
504   }
505   gras_datadesc_struct_close(struct_type);
506   if (errcode != mismatch_error) {
507     XBT_OUT;
508     return NULL; /* FIXME: LEAK! */
509   }
510
511   /* terminates */
512   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
513     PARSE_ERROR1("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
514                  gras_ddt_parse_text);
515
516   gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
517
518   xbt_dynar_free(&identifiers);
519   xbt_dynar_free(&fields_to_push);
520   XBT_OUT;
521   return struct_type;
522 }
523
524 static gras_datadesc_type_t parse_typedef(char *definition) {
525
526   s_type_modifier_t tm;
527
528   gras_datadesc_type_t struct_desc=NULL;
529   gras_datadesc_type_t typedef_desc=NULL;
530
531   XBT_IN;
532   memset(&tm,0,sizeof(tm));
533
534   /* get the aliased type */
535   parse_type_modifier(&tm);
536
537   if (tm.is_struct) {
538     struct_desc = parse_struct(definition);
539   }
540
541   parse_type_modifier(&tm);
542
543   if (tm.is_ref) 
544     PARSE_ERROR0("Cannot handle reference without annotation");
545
546   /* get the aliasing name */
547   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
548     PARSE_ERROR1("Unparsable typedef: Expected the alias name, and got '%s'",
549                  gras_ddt_parse_text);
550   
551   /* (FIXME: should) build the alias */
552   PARSE_ERROR0("Cannot handle typedef yet");
553
554   XBT_OUT;
555   return typedef_desc;
556 }
557
558
559 /**
560  * gras_datadesc_parse:
561  *
562  * Create a datadescription from the result of parsing the C type description
563  */
564 gras_datadesc_type_t 
565 gras_datadesc_parse(const char            *name,
566                     const char            *C_statement) {
567
568   gras_datadesc_type_t res=NULL;
569   char *definition;
570   int semicolon_count=0;
571   int def_count,C_count;
572
573   XBT_IN;
574   /* reput the \n in place for debug */
575   for (C_count=0; C_statement[C_count] != '\0'; C_count++)
576     if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
577       semicolon_count++;
578   definition = (char*)xbt_malloc(C_count + semicolon_count + 1);
579   for (C_count=0,def_count=0; C_statement[C_count] != '\0'; C_count++) {
580     definition[def_count++] = C_statement[C_count];
581     if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
582       definition[def_count++] = '\n';
583     }
584   }
585   definition[def_count] = '\0';
586
587   /* init */ 
588   VERB2("_gras_ddt_type_parse(%s) -> %d chars",definition, def_count);
589   gras_ddt_parse_pointer_string_init(definition);
590
591   /* Do I have a typedef, or a raw struct ?*/
592   gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
593   
594   if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"struct"))) {
595     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
596     res = parse_struct(definition);
597       
598   } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"typedef"))) {
599     gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
600     res = parse_typedef(definition);
601
602   } else {
603     ERROR1("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",definition);    
604     xbt_abort();
605   }
606
607   gras_ddt_parse_pointer_string_close();
608   VERB0("end of _gras_ddt_type_parse()");
609   free(definition);
610   /* register it under the name provided as symbol */
611   if (strcmp(res->name,name)) {
612     ERROR2("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
613            name,res->name);
614     xbt_abort();
615   }    
616   gras_ddt_parse_lex_destroy();
617   XBT_OUT;
618   return res;
619 }