1 /* DataDesc/ddt_parse.c -- automatic parsing of data structures */
3 /* Copyright (c) 2004, 2005, 2006, 2007, 2009, 2010. The SimGrid Team.
4 * All rights reserved. */
6 /* This program is free software; you can redistribute it and/or modify it
7 * under the terms of the license (GNU LGPL) which comes with this package. */
9 #include <ctype.h> /* isdigit */
12 #include "gras/DataDesc/datadesc_private.h"
13 #include "gras/DataDesc/ddt_parse.yy.h"
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_ddt_parse, gras_ddt,
16 "Parsing C data structures to build GRAS data description");
18 typedef struct s_type_modifier {
31 } s_type_modifier_t, *type_modifier_t;
33 typedef struct s_field {
34 gras_datadesc_type_t type;
40 extern char *gras_ddt_parse_text; /* text being considered in the parser */
43 static void parse_type_modifier(type_modifier_t type_modifier)
47 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
48 /* This only used when parsing 'short *' since this function returns when int, float, double,... is encountered */
49 XBT_DEBUG("This is a reference");
50 type_modifier->is_ref++;
52 } else if (!strcmp(gras_ddt_parse_text, "unsigned")) {
53 XBT_DEBUG("This is an unsigned");
54 type_modifier->is_unsigned = 1;
56 } else if (!strcmp(gras_ddt_parse_text, "short")) {
57 XBT_DEBUG("This is short");
58 type_modifier->is_short = 1;
60 } else if (!strcmp(gras_ddt_parse_text, "long")) {
61 XBT_DEBUG("This is long");
62 type_modifier->is_long++; /* handle "long long" */
64 } else if (!strcmp(gras_ddt_parse_text, "struct")) {
65 XBT_DEBUG("This is a struct");
66 type_modifier->is_struct = 1;
68 } else if (!strcmp(gras_ddt_parse_text, "union")) {
69 XBT_DEBUG("This is an union");
70 type_modifier->is_union = 1;
72 } else if (!strcmp(gras_ddt_parse_text, "enum")) {
73 XBT_DEBUG("This is an enum");
74 type_modifier->is_enum = 1;
76 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_EMPTY) {
77 XBT_DEBUG("Pass space");
80 XBT_DEBUG("Done with modifiers (got %s)", gras_ddt_parse_text);
84 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
85 if ((gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) &&
86 (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_STAR)) {
87 XBT_DEBUG("Done with modifiers (got %s,%d)", gras_ddt_parse_text,
88 gras_ddt_parse_tok_num);
95 static void print_type_modifier(s_type_modifier_t tm)
101 printf("(unsigned) ");
104 for (i = 0; i < tm.is_long; i++)
114 for (i = 0; i < tm.is_ref; i++)
119 static void change_to_fixed_array(xbt_dynar_t dynar, long int size)
121 s_identifier_t former, array;
122 memset(&array, 0, sizeof(array));
125 xbt_dynar_pop(dynar, &former);
126 array.type_name = (char *) xbt_malloc(strlen(former.type->name) + 48);
127 XBT_DEBUG("Array specification (size=%ld, elm='%s'), change pushed type",
128 size, former.type_name);
129 sprintf(array.type_name, "%s%s%s%s[%ld]",
130 (former.tm.is_unsigned ? "u " : ""),
131 (former.tm.is_short ? "s " : ""),
132 (former.tm.is_long ? "l " : ""), former.type_name, size);
133 free(former.type_name);
135 array.type = gras_datadesc_array_fixed(array.type_name, former.type, size); /* redeclaration are ignored */
136 array.name = former.name;
138 xbt_dynar_push(dynar, &array);
142 static void change_to_ref(xbt_dynar_t dynar)
144 s_identifier_t former, ref;
145 memset(&ref, 0, sizeof(ref));
148 xbt_dynar_pop(dynar, &former);
149 ref.type_name = (char *) xbt_malloc(strlen(former.type->name) + 2);
150 XBT_DEBUG("Ref specification (elm='%s'), change pushed type",
152 sprintf(ref.type_name, "%s*", former.type_name);
153 free(former.type_name);
155 ref.type = gras_datadesc_ref(ref.type_name, former.type); /* redeclaration are ignored */
156 ref.name = former.name;
158 xbt_dynar_push(dynar, &ref);
162 static void change_to_ref_pop_array(xbt_dynar_t dynar)
164 s_identifier_t former, ref;
165 memset(&ref, 0, sizeof(ref));
168 xbt_dynar_pop(dynar, &former);
169 ref.type = gras_datadesc_ref_pop_arr(former.type); /* redeclaration are ignored */
170 ref.type_name = (char *) strdup(ref.type->name);
171 ref.name = former.name;
173 free(former.type_name);
175 xbt_dynar_push(dynar, &ref);
179 static void change_to_dynar_of(xbt_dynar_t dynar,
180 gras_datadesc_type_t subtype)
182 s_identifier_t former, ref;
183 memset(&ref, 0, sizeof(ref));
186 xbt_dynar_pop(dynar, &former);
187 ref.type = gras_datadesc_dynar(subtype, NULL); /* redeclaration are ignored */
188 ref.type_name = (char *) strdup(ref.type->name);
189 ref.name = former.name;
191 free(former.type_name);
193 xbt_dynar_push(dynar, &ref);
197 static void change_to_matrix_of(xbt_dynar_t dynar,
198 gras_datadesc_type_t subtype)
200 s_identifier_t former, ref;
201 memset(&ref, 0, sizeof(ref));
204 xbt_dynar_pop(dynar, &former);
205 ref.type = gras_datadesc_matrix(subtype, NULL); /* redeclaration are ignored */
206 ref.type_name = (char *) strdup(ref.type->name);
207 ref.name = former.name;
209 free(former.type_name);
211 xbt_dynar_push(dynar, &ref);
215 static void add_free_f(xbt_dynar_t dynar, void_f_pvoid_t free_f)
217 s_identifier_t former, ref;
218 memset(&ref, 0, sizeof(ref));
221 xbt_dynar_pop(dynar, &former);
222 memcpy(former.type->extra, free_f, sizeof(free_f));
223 xbt_dynar_push(dynar, &former);
227 static void parse_statement(char *definition,
228 xbt_dynar_t identifiers,
229 xbt_dynar_t fields_to_push)
233 s_identifier_t identifier;
235 int expect_id_separator = 0;
238 memset(&identifier, 0, sizeof(identifier));
240 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
241 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RA) {
243 THROW0(mismatch_error, 0, "End of the englobing structure or union");
246 if (XBT_LOG_ISENABLED(gras_ddt_parse, xbt_log_priority_debug)) {
248 for (colon_pos = gras_ddt_parse_col_pos;
249 definition[colon_pos] != ';'; colon_pos++);
250 definition[colon_pos] = '\0';
251 XBT_DEBUG("Parse the statement \"%s%s;\" (col_pos=%d)",
253 definition + gras_ddt_parse_col_pos, gras_ddt_parse_col_pos);
254 definition[colon_pos] = ';';
257 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
259 ("Unparsable symbol: found a typeless statement (got '%s' instead)",
260 gras_ddt_parse_text);
262 /**** get the type modifier of this statement ****/
263 parse_type_modifier(&identifier.tm);
265 /* FIXME: This does not detect recursive definitions at all? */
266 if (identifier.tm.is_union || identifier.tm.is_enum
267 || identifier.tm.is_struct)
269 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle recursive type definition yet");
271 /**** get the base type, giving "short a" the needed love ****/
272 if (!identifier.tm.is_union &&
273 !identifier.tm.is_enum &&
274 !identifier.tm.is_struct &&
275 (identifier.tm.is_short || identifier.tm.is_long
276 || identifier.tm.is_unsigned) && strcmp(gras_ddt_parse_text, "char")
277 && strcmp(gras_ddt_parse_text, "float")
278 && strcmp(gras_ddt_parse_text, "double")
279 && strcmp(gras_ddt_parse_text, "int")) {
281 /* bastard user, they omited "int" ! */
282 identifier.type_name = (char *) strdup("int");
283 XBT_DEBUG("the base type is 'int', which were omited (you vicious user)");
285 identifier.type_name = (char *) strdup(gras_ddt_parse_text);
286 XBT_DEBUG("the base type is '%s'", identifier.type_name);
287 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
290 /**** build the base type for latter use ****/
291 if (identifier.tm.is_union) {
293 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
295 } else if (identifier.tm.is_enum) {
297 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle enum yet");
299 } else if (identifier.tm.is_struct) {
300 sprintf(buffname, "struct %s", identifier.type_name);
301 identifier.type = gras_datadesc_struct(buffname); /* Get created when does not exist */
303 } else if (identifier.tm.is_unsigned) {
304 if (!strcmp(identifier.type_name, "int")) {
305 if (identifier.tm.is_long == 2) {
306 identifier.type = gras_datadesc_by_name("unsigned long long int");
307 } else if (identifier.tm.is_long) {
308 identifier.type = gras_datadesc_by_name("unsigned long int");
309 } else if (identifier.tm.is_short) {
310 identifier.type = gras_datadesc_by_name("unsigned short int");
312 identifier.type = gras_datadesc_by_name("unsigned int");
315 } else if (!strcmp(identifier.type_name, "char")) {
316 identifier.type = gras_datadesc_by_name("unsigned char");
318 } else { /* impossible, gcc parses this shit before us */
322 } else if (!strcmp(identifier.type_name, "float")) {
323 /* no modificator allowed by gcc */
324 identifier.type = gras_datadesc_by_name("float");
326 } else if (!strcmp(identifier.type_name, "double")) {
327 if (identifier.tm.is_long)
328 PARSE_ERROR0("long double not portable and thus not handled");
330 identifier.type = gras_datadesc_by_name("double");
332 } else { /* signed integer elemental */
333 if (!strcmp(identifier.type_name, "int")) {
334 if (identifier.tm.is_long == 2) {
335 identifier.type = gras_datadesc_by_name("signed long long int");
336 } else if (identifier.tm.is_long) {
337 identifier.type = gras_datadesc_by_name("signed long int");
338 } else if (identifier.tm.is_short) {
339 identifier.type = gras_datadesc_by_name("signed short int");
341 identifier.type = gras_datadesc_by_name("int");
344 } else if (!strcmp(identifier.type_name, "char")) {
345 identifier.type = gras_datadesc_by_name("char");
348 XBT_DEBUG("Base type is a constructed one (%s)", identifier.type_name);
349 if (!strcmp(identifier.type_name, "xbt_matrix_t")) {
350 identifier.tm.is_matrix = 1;
351 } else if (!strcmp(identifier.type_name, "xbt_dynar_t")) {
352 identifier.tm.is_dynar = 1;
354 identifier.type = gras_datadesc_by_name(identifier.type_name);
355 if (!identifier.type)
356 PARSE_ERROR1("Unknown base type '%s'", identifier.type_name);
360 /* Now identifier.type and identifier.name speak about the base type.
361 Stars are not eaten unless 'int' was omitted.
362 We will have to enhance it if we are in fact asked for array or reference.
364 Dynars and matrices also need some extra love (prodiged as annotations)
367 /**** look for the symbols of this type ****/
368 for (expect_id_separator = 0; ( /*(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_EMPTY) && FIXME */
369 (gras_ddt_parse_tok_num !=
370 GRAS_DDT_PARSE_TOKEN_SEMI_COLON));
371 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) {
373 if (expect_id_separator) {
374 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
375 expect_id_separator = 0;
378 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_LB) {
379 /* Handle fixed size arrays */
380 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
381 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RB) {
383 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot deal with [] constructs (yet)");
385 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
387 long int size = strtol(gras_ddt_parse_text, &end, 10);
389 if (end == gras_ddt_parse_text || *end != '\0') {
390 /* Not a number. Get the constant value, if any */
391 int *storage = xbt_dict_get_or_null(gras_dd_constants,
392 gras_ddt_parse_text);
397 ("Unparsable size of array. Found '%s', expected number or known constant. Need to use gras_datadesc_set_const(), huh?",
398 gras_ddt_parse_text);
402 /* replace the previously pushed type to an array of it */
403 change_to_fixed_array(identifiers, size);
405 /* eat the closing bracket */
406 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
407 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RB)
408 PARSE_ERROR0("Unparsable size of array");
409 XBT_DEBUG("Fixed size array, size=%ld", size);
412 PARSE_ERROR0("Unparsable size of array");
414 /* End of fixed size arrays handling */
416 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
417 /* Handle annotation */
418 s_identifier_t array;
419 char *keyname = NULL;
421 memset(&array, 0, sizeof(array));
422 if (strcmp(gras_ddt_parse_text, "GRAS_ANNOTE"))
424 ("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",
425 gras_ddt_parse_text);
427 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
428 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP)
430 ("Unparsable annotation: Expected parenthesis, got '%s'",
431 gras_ddt_parse_text);
433 while ((gras_ddt_parse_tok_num =
434 gras_ddt_parse_lex_n_dump()) ==
435 GRAS_DDT_PARSE_TOKEN_EMPTY);
437 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
439 ("Unparsable annotation: Expected key name, got '%s'",
440 gras_ddt_parse_text);
441 keyname = (char *) strdup(gras_ddt_parse_text);
443 while ((gras_ddt_parse_tok_num =
444 gras_ddt_parse_lex_n_dump()) ==
445 GRAS_DDT_PARSE_TOKEN_EMPTY);
447 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON)
449 ("Unparsable annotation: expected ',' after the key name, got '%s'",
450 gras_ddt_parse_text);
452 while ((gras_ddt_parse_tok_num =
453 gras_ddt_parse_lex_n_dump()) ==
454 GRAS_DDT_PARSE_TOKEN_EMPTY);
458 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
460 ("Unparsable annotation: Expected key value, got '%s'",
461 gras_ddt_parse_text);
462 keyval = (char *) strdup(gras_ddt_parse_text);
464 while ((gras_ddt_parse_tok_num =
465 gras_ddt_parse_lex_n_dump()) ==
466 GRAS_DDT_PARSE_TOKEN_EMPTY);
468 /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
470 XBT_DEBUG("Anotation: %s=%s", keyname, keyval);
471 if (!strcmp(keyname, "size")) {
472 if (!identifier.tm.is_ref)
474 ("Size annotation for a field not being a reference");
475 identifier.tm.is_ref--;
477 if (!strcmp(keyval, "1")) {
478 change_to_ref(identifiers);
483 for (p = keyval; *p != '\0'; p++)
487 change_to_fixed_array(identifiers, atoi(keyval));
488 change_to_ref(identifiers);
492 change_to_ref_pop_array(identifiers);
493 xbt_dynar_push(fields_to_push, &keyval);
496 } else if (!strcmp(keyname, "subtype")) {
497 gras_datadesc_type_t subtype = gras_datadesc_by_name(keyval);
498 if (identifier.tm.is_matrix) {
499 change_to_matrix_of(identifiers, subtype);
500 identifier.tm.is_matrix = -1;
501 } else if (identifier.tm.is_dynar) {
502 change_to_dynar_of(identifiers, subtype);
503 identifier.tm.is_dynar = -1;
506 ("subtype annotation only accepted for dynars and matrices, but passed to '%s'",
507 identifier.type_name);
510 } else if (!strcmp(keyname, "free_f")) {
511 int *storage = xbt_dict_get_or_null(gras_dd_constants, keyval);
514 ("value for free_f annotation of field %s is not a known constant",
516 if (identifier.tm.is_matrix == -1) {
517 add_free_f(identifiers, *(void_f_pvoid_t *) storage);
518 identifier.tm.is_matrix = 0;
519 } else if (identifier.tm.is_dynar == -1) {
520 add_free_f(identifiers, *(void_f_pvoid_t *) storage);
521 identifier.tm.is_dynar = 0;
524 ("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
530 PARSE_ERROR1("Unknown annotation type: '%s'", keyname);
534 /* Get all the multipliers */
535 while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
537 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
539 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
541 ("Unparsable annotation: Expected field name after '*', got '%s'",
542 gras_ddt_parse_text);
544 keyval = xbt_malloc(strlen(gras_ddt_parse_text) + 2);
545 sprintf(keyval, "*%s", gras_ddt_parse_text);
547 /* ask caller to push field as a multiplier */
548 xbt_dynar_push(fields_to_push, &keyval);
550 /* skip blanks after this block */
551 while ((gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump())
552 == GRAS_DDT_PARSE_TOKEN_EMPTY);
555 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
557 ("Unparsable annotation: Expected parenthesis, got '%s'",
558 gras_ddt_parse_text);
562 /* End of annotation handling */
565 ("Unparsable symbol: Got '%s' instead of expected comma (',')",
566 gras_ddt_parse_text);
568 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
569 PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
572 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
573 identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
577 /* found a symbol name. Build the type and push it to dynar */
578 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
580 identifier.name = (char *) strdup(gras_ddt_parse_text);
581 XBT_DEBUG("Found the identifier \"%s\"", identifier.name);
583 xbt_dynar_push(identifiers, &identifier);
584 XBT_DEBUG("Dynar_len=%lu", xbt_dynar_length(identifiers));
585 expect_id_separator = 1;
590 ("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
593 if (identifier.tm.is_matrix > 0)
594 PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
595 if (identifier.tm.is_dynar > 0)
596 PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
601 static gras_datadesc_type_t parse_struct(char *definition)
607 static int anonymous_struct = 0;
609 xbt_dynar_t identifiers;
610 s_identifier_t field;
614 xbt_dynar_t fields_to_push;
617 gras_datadesc_type_t struct_type;
620 identifiers = xbt_dynar_new(sizeof(s_identifier_t), NULL);
621 fields_to_push = xbt_dynar_new(sizeof(char *), NULL);
623 /* Create the struct descriptor */
624 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
625 struct_type = gras_datadesc_struct(gras_ddt_parse_text);
626 XBT_VERB("Parse the struct '%s'", gras_ddt_parse_text);
627 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
629 sprintf(buffname, "anonymous struct %d", anonymous_struct++);
630 XBT_VERB("Parse the anonymous struct nb %d", anonymous_struct);
631 struct_type = gras_datadesc_struct(buffname);
634 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
636 ("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
637 gras_ddt_parse_text);
639 /* Parse the identifiers */
643 parse_statement(definition, identifiers, fields_to_push);
646 if (e.category != mismatch_error)
652 XBT_DEBUG("This statement contained %lu identifiers",
653 xbt_dynar_length(identifiers));
654 /* append the identifiers we've found */
655 xbt_dynar_foreach(identifiers, iter, field) {
658 ("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
659 field.name, field.tm.is_ref);
661 XBT_VERB("Append field '%s' to %p", field.name, (void *) struct_type);
662 gras_datadesc_struct_append(struct_type, field.name, field.type);
664 free(field.type_name);
667 xbt_dynar_reset(identifiers);
668 XBT_DEBUG("struct_type=%p", (void *) struct_type);
670 /* Make sure that all fields declaring a size push it into the cbps */
671 xbt_dynar_foreach(fields_to_push, iter, name) {
672 XBT_DEBUG("struct_type=%p", (void *) struct_type);
673 if (name[0] == '*') {
674 XBT_VERB("Push field '%s' as a multiplier into size stack of %p",
675 name + 1, (void *) struct_type);
676 gras_datadesc_cb_field_push_multiplier(struct_type, name + 1);
678 XBT_VERB("Push field '%s' into size stack of %p",
679 name, (void *) struct_type);
680 gras_datadesc_cb_field_push(struct_type, name);
684 xbt_dynar_reset(fields_to_push);
686 gras_datadesc_struct_close(struct_type);
689 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
691 ("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
692 gras_ddt_parse_text);
694 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
696 xbt_dynar_free(&identifiers);
697 xbt_dynar_free(&fields_to_push);
702 static gras_datadesc_type_t parse_typedef(char *definition)
705 s_type_modifier_t tm;
707 gras_datadesc_type_t struct_desc = NULL;
708 gras_datadesc_type_t typedef_desc = NULL;
711 memset(&tm, 0, sizeof(tm));
713 /* get the aliased type */
714 parse_type_modifier(&tm);
717 struct_desc = parse_struct(definition);
720 parse_type_modifier(&tm);
724 ("GRAS_DEFINE_TYPE cannot handle reference without annotation");
726 /* get the aliasing name */
727 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
729 ("Unparsable typedef: Expected the alias name, and got '%s'",
730 gras_ddt_parse_text);
732 /* (FIXME: should) build the alias */
734 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle typedef yet");
742 * gras_datadesc_parse:
744 * Create a datadescription from the result of parsing the C type description
747 gras_datadesc_parse(const char *name, const char *C_statement)
750 gras_datadesc_type_t res = NULL;
752 int semicolon_count = 0;
753 int def_count, C_count;
756 /* reput the \n in place for debug */
757 for (C_count = 0; C_statement[C_count] != '\0'; C_count++)
758 if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
760 definition = (char *) xbt_malloc(C_count + semicolon_count + 1);
761 for (C_count = 0, def_count = 0; C_statement[C_count] != '\0'; C_count++) {
762 definition[def_count++] = C_statement[C_count];
763 if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
764 definition[def_count++] = '\n';
767 definition[def_count] = '\0';
770 XBT_VERB("_gras_ddt_type_parse(%s) -> %d chars", definition, def_count);
771 gras_ddt_parse_pointer_string_init(definition);
773 /* Do I have a typedef, or a raw struct ? */
774 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
776 if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD)
777 && (!strcmp(gras_ddt_parse_text, "struct"))) {
778 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
779 res = parse_struct(definition);
781 } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD)
782 && (!strcmp(gras_ddt_parse_text, "typedef"))) {
783 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
784 res = parse_typedef(definition);
788 ("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",
793 gras_ddt_parse_pointer_string_close();
794 XBT_VERB("end of _gras_ddt_type_parse()");
796 /* register it under the name provided as symbol */
797 if (strcmp(res->name, name)) {
799 ("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
803 gras_ddt_parse_lex_destroy();
808 xbt_dict_t gras_dd_constants;
809 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
810 void gras_datadesc_set_const(const char *name, int value)
812 int *stored = xbt_new(int, 1);
815 xbt_dict_set(gras_dd_constants, name, stored, xbt_free_f);