3 /* DataDesc/ddt_parse.c -- automatic parsing of data structures */
5 /* Copyright (c) 2003 Arnaud Legrand. */
6 /* Copyright (c) 2003, 2004 Martin Quinson. */
7 /* All rights reserved. */
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. */
12 #include <ctype.h> /* isdigit */
15 #include "gras/DataDesc/datadesc_private.h"
16 #include "gras/DataDesc/ddt_parse.yy.h"
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_ddt_parse,gras_ddt,
19 "Parsing C data structures to build GRAS data description");
21 typedef struct s_type_modifier{
34 } s_type_modifier_t,*type_modifier_t;
36 typedef struct s_field {
37 gras_datadesc_type_t type;
43 extern char *gras_ddt_parse_text; /* text being considered in the parser */
46 static void parse_type_modifier(type_modifier_t type_modifier) {
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++;
54 } else if (!strcmp(gras_ddt_parse_text,"unsigned")) {
55 DEBUG0("This is an unsigned");
56 type_modifier->is_unsigned = 1;
58 } else if (!strcmp(gras_ddt_parse_text,"short")) {
59 DEBUG0("This is short");
60 type_modifier->is_short = 1;
62 } else if (!strcmp(gras_ddt_parse_text,"long")) {
63 DEBUG0("This is long");
64 type_modifier->is_long++; /* handle "long long" */
66 } else if (!strcmp(gras_ddt_parse_text,"struct")) {
67 DEBUG0("This is a struct");
68 type_modifier->is_struct = 1;
70 } else if (!strcmp(gras_ddt_parse_text,"union")) {
71 DEBUG0("This is an union");
72 type_modifier->is_union = 1;
74 } else if (!strcmp(gras_ddt_parse_text,"enum")) {
75 DEBUG0("This is an enum");
76 type_modifier->is_enum = 1;
78 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_EMPTY) {
82 DEBUG1("Done with modifiers (got %s)",gras_ddt_parse_text);
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);
96 static void print_type_modifier(s_type_modifier_t tm) {
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) ");
104 if(tm.is_struct) printf("(struct) ");
105 if(tm.is_enum) printf("(enum) ");
106 if(tm.is_union) printf("(union) ");
108 for (i=0 ; i<tm.is_ref ; i++) printf("(ref) ");
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));
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 ":""),
127 free(former.type_name);
129 array.type = gras_datadesc_array_fixed(array.type_name, former.type, size); /* redeclaration are ignored */
130 array.name = former.name;
132 xbt_dynar_push(dynar,&array);
135 static void change_to_ref(xbt_dynar_t dynar) {
136 s_identifier_t former,ref;
137 memset(&ref,0,sizeof(ref));
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);
146 ref.type = gras_datadesc_ref(ref.type_name, former.type); /* redeclaration are ignored */
147 ref.name = former.name;
149 xbt_dynar_push(dynar,&ref);
153 static void change_to_ref_pop_array(xbt_dynar_t dynar) {
154 s_identifier_t former,ref;
155 memset(&ref,0,sizeof(ref));
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;
163 free(former.type_name);
165 xbt_dynar_push(dynar,&ref);
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));
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;
179 free(former.type_name);
181 xbt_dynar_push(dynar,&ref);
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));
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;
195 free(former.type_name);
197 xbt_dynar_push(dynar,&ref);
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));
206 xbt_dynar_pop(dynar,&former);
207 memcpy(former.type->extra,&free_f, sizeof(free_f));
208 xbt_dynar_push(dynar,&former);
212 static void parse_statement(char *definition,
213 xbt_dynar_t identifiers,
214 xbt_dynar_t fields_to_push) {
217 s_identifier_t identifier;
219 int expect_id_separator = 0;
222 memset(&identifier,0,sizeof(identifier));
224 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
225 if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RA) {
227 THROW0(mismatch_error,0,"End of the englobing structure or union");
230 if (XBT_LOG_ISENABLED(gras_ddt_parse,xbt_log_priority_debug)) {
232 for (colon_pos = gras_ddt_parse_col_pos;
233 definition[colon_pos] != ';';
235 definition[colon_pos] = '\0';
236 DEBUG3("Parse the statement \"%s%s;\" (col_pos=%d)",
238 definition+gras_ddt_parse_col_pos,
239 gras_ddt_parse_col_pos);
240 definition[colon_pos] = ';';
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);
247 /**** get the type modifier of this statement ****/
248 parse_type_modifier(&identifier.tm);
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("Cannot handle recursive type definition yet");
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 &&
259 (identifier.tm.is_short || identifier.tm.is_long || identifier.tm.is_unsigned) &&
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") ) {
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)");
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();
275 /**** build the base type for latter use ****/
276 if (identifier.tm.is_union) {
277 PARSE_ERROR0("Cannot handle union yet (get callback from annotation?)");
279 } else if (identifier.tm.is_enum) {
280 PARSE_ERROR0("Cannot handle enum yet");
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 */
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");
295 identifier.type = gras_datadesc_by_name("unsigned int");
298 } else if (!strcmp(identifier.type_name, "char")) {
299 identifier.type = gras_datadesc_by_name("unsigned char");
301 } else { /* impossible, gcc parses this shit before us */
305 } else if (!strcmp(identifier.type_name, "float")) {
306 /* no modificator allowed by gcc */
307 identifier.type = gras_datadesc_by_name("float");
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");
313 identifier.type = gras_datadesc_by_name("double");
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");
324 identifier.type = gras_datadesc_by_name("int");
327 } else if (!strcmp(identifier.type_name, "char")) {
328 identifier.type = gras_datadesc_by_name("char");
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;
337 identifier.type = gras_datadesc_by_name(identifier.type_name);
338 if (!identifier.type)
339 PARSE_ERROR1("Unknown base type '%s'",identifier.type_name);
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.
347 Dynars and matrices also need some extra love (prodiged as annotations)
350 /**** look for the symbols of this type ****/
351 for(expect_id_separator = 0;
353 (/*(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_EMPTY) && FIXME*/
354 (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_SEMI_COLON)) ;
356 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump() ) {
358 if(expect_id_separator) {
359 if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
360 expect_id_separator = 0;
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("Cannot deal with [] constructs (yet)");
369 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
371 long int size=strtol(gras_ddt_parse_text, &end, 10);
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);
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);
384 /* replace the previously pushed type to an array of it */
385 change_to_fixed_array(identifiers,size);
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);
394 PARSE_ERROR0("Unparsable size of array");
396 /* End of fixed size arrays handling */
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;
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);
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);
411 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
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);
417 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
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);
422 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
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);
430 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
432 /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
434 DEBUG2("Anotation: %s=%s",keyname,keyval);
435 if (!strcmp(keyname,"size")) {
437 if (!identifier.tm.is_ref)
438 PARSE_ERROR0("Size annotation for a field not being a reference");
439 identifier.tm.is_ref--;
441 if (!strcmp(keyval,"1")) {
442 change_to_ref(identifiers);
447 for (p = keyval; *p != '\0'; p++)
451 change_to_fixed_array(identifiers,atoi(keyval));
452 change_to_ref(identifiers);
456 change_to_ref_pop_array(identifiers);
457 xbt_dynar_push(fields_to_push,&keyval);
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;
469 PARSE_ERROR1("subtype annotation only accepted for dynars and matrices, but passed to '%s'",identifier.type_name);
471 } else if (!strcmp(keyname,"free_f")) {
472 int *storage=xbt_dict_get_or_null(gras_dd_constants,keyval);
474 PARSE_ERROR1("value for free_f annotation of field %s is not a known constant",identifier.name);
475 if (identifier.tm.is_matrix == -1) {
476 add_free_f(identifiers,*(void_f_pvoid_t**)storage);
477 identifier.tm.is_matrix = 0;
478 } else if (identifier.tm.is_dynar == -1) {
479 add_free_f(identifiers,*(void_f_pvoid_t**)storage);
480 identifier.tm.is_dynar = 0;
482 PARSE_ERROR1("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
486 PARSE_ERROR1("Unknown annotation type: '%s'",keyname);
489 /* Get all the multipliers */
490 while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
492 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
494 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
495 PARSE_ERROR1("Unparsable annotation: Expected field name after '*', got '%s'",gras_ddt_parse_text);
497 keyval = xbt_malloc(strlen(gras_ddt_parse_text)+2);
498 sprintf(keyval,"*%s",gras_ddt_parse_text);
500 /* ask caller to push field as a multiplier */
501 xbt_dynar_push(fields_to_push,&keyval);
503 /* skip blanks after this block*/
504 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump())
505 == GRAS_DDT_PARSE_TOKEN_EMPTY );
508 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
509 PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",
510 gras_ddt_parse_text);
514 /* End of annotation handling */
516 PARSE_ERROR1("Unparsable symbol: Got '%s' instead of expected comma (',')",gras_ddt_parse_text);
518 } else if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
519 PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
522 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
523 identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
527 /* found a symbol name. Build the type and push it to dynar */
528 if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
530 identifier.name=(char*)strdup(gras_ddt_parse_text);
531 DEBUG1("Found the identifier \"%s\"",identifier.name);
533 xbt_dynar_push(identifiers, &identifier);
534 DEBUG1("Dynar_len=%lu",xbt_dynar_length(identifiers));
535 expect_id_separator = 1;
539 PARSE_ERROR0("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
542 if (identifier.tm.is_matrix>0)
543 PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
544 if (identifier.tm.is_dynar>0)
545 PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
550 static gras_datadesc_type_t parse_struct(char *definition) {
555 static int anonymous_struct=0;
557 xbt_dynar_t identifiers;
558 s_identifier_t field;
562 xbt_dynar_t fields_to_push;
565 gras_datadesc_type_t struct_type;
568 identifiers = xbt_dynar_new(sizeof(s_identifier_t),NULL);
569 fields_to_push = xbt_dynar_new(sizeof(char*),NULL);
571 /* Create the struct descriptor */
572 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
573 struct_type = gras_datadesc_struct(gras_ddt_parse_text);
574 VERB1("Parse the struct '%s'", gras_ddt_parse_text);
575 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
577 sprintf(buffname,"anonymous struct %d",anonymous_struct++);
578 VERB1("Parse the anonymous struct nb %d", anonymous_struct);
579 struct_type = gras_datadesc_struct(buffname);
582 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
583 PARSE_ERROR1("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
584 gras_ddt_parse_text);
586 /* Parse the identifiers */
590 parse_statement(definition,identifiers,fields_to_push);
592 if (e.category != mismatch_error)
598 DEBUG1("This statement contained %lu identifiers",xbt_dynar_length(identifiers));
599 /* append the identifiers we've found */
600 xbt_dynar_foreach(identifiers,i, field) {
602 PARSE_ERROR2("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
603 field.name,field.tm.is_ref);
605 VERB2("Append field '%s' to %p",field.name, (void*)struct_type);
606 gras_datadesc_struct_append(struct_type, field.name, field.type);
608 free(field.type_name);
611 xbt_dynar_reset(identifiers);
612 DEBUG1("struct_type=%p",(void*)struct_type);
614 /* Make sure that all fields declaring a size push it into the cbps */
615 xbt_dynar_foreach(fields_to_push,i, name) {
616 DEBUG1("struct_type=%p",(void*)struct_type);
617 if (name[0] == '*') {
618 VERB2("Push field '%s' as a multiplier into size stack of %p",
619 name+1, (void*)struct_type);
620 gras_datadesc_cb_field_push_multiplier(struct_type, name+1);
622 VERB2("Push field '%s' into size stack of %p",
623 name, (void*)struct_type);
624 gras_datadesc_cb_field_push(struct_type, name);
628 xbt_dynar_reset(fields_to_push);
630 gras_datadesc_struct_close(struct_type);
633 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
634 PARSE_ERROR1("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
635 gras_ddt_parse_text);
637 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
639 xbt_dynar_free(&identifiers);
640 xbt_dynar_free(&fields_to_push);
645 static gras_datadesc_type_t parse_typedef(char *definition) {
647 s_type_modifier_t tm;
649 gras_datadesc_type_t struct_desc=NULL;
650 gras_datadesc_type_t typedef_desc=NULL;
653 memset(&tm,0,sizeof(tm));
655 /* get the aliased type */
656 parse_type_modifier(&tm);
659 struct_desc = parse_struct(definition);
662 parse_type_modifier(&tm);
665 PARSE_ERROR0("Cannot handle reference without annotation");
667 /* get the aliasing name */
668 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
669 PARSE_ERROR1("Unparsable typedef: Expected the alias name, and got '%s'",
670 gras_ddt_parse_text);
672 /* (FIXME: should) build the alias */
673 PARSE_ERROR0("Cannot handle typedef yet");
681 * gras_datadesc_parse:
683 * Create a datadescription from the result of parsing the C type description
686 gras_datadesc_parse(const char *name,
687 const char *C_statement) {
689 gras_datadesc_type_t res=NULL;
691 int semicolon_count=0;
692 int def_count,C_count;
695 /* reput the \n in place for debug */
696 for (C_count=0; C_statement[C_count] != '\0'; C_count++)
697 if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
699 definition = (char*)xbt_malloc(C_count + semicolon_count + 1);
700 for (C_count=0,def_count=0; C_statement[C_count] != '\0'; C_count++) {
701 definition[def_count++] = C_statement[C_count];
702 if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
703 definition[def_count++] = '\n';
706 definition[def_count] = '\0';
709 VERB2("_gras_ddt_type_parse(%s) -> %d chars",definition, def_count);
710 gras_ddt_parse_pointer_string_init(definition);
712 /* Do I have a typedef, or a raw struct ?*/
713 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
715 if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"struct"))) {
716 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
717 res = parse_struct(definition);
719 } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"typedef"))) {
720 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
721 res = parse_typedef(definition);
724 ERROR1("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",definition);
728 gras_ddt_parse_pointer_string_close();
729 VERB0("end of _gras_ddt_type_parse()");
731 /* register it under the name provided as symbol */
732 if (strcmp(res->name,name)) {
733 ERROR2("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
737 gras_ddt_parse_lex_destroy();
742 xbt_dict_t gras_dd_constants;
743 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
744 void gras_datadesc_set_const(const char*name, int value) {
745 int *stored = xbt_new(int, 1);
748 xbt_dict_set(gras_dd_constants,name, stored, free);