Logo AND Algorithmique Numérique Distribuée

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