Logo AND Algorithmique Numérique Distribuée

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