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 DEBUG0("This is a reference");
50 type_modifier->is_ref++;
52 } else if (!strcmp(gras_ddt_parse_text, "unsigned")) {
53 DEBUG0("This is an unsigned");
54 type_modifier->is_unsigned = 1;
56 } else if (!strcmp(gras_ddt_parse_text, "short")) {
57 DEBUG0("This is short");
58 type_modifier->is_short = 1;
60 } else if (!strcmp(gras_ddt_parse_text, "long")) {
61 DEBUG0("This is long");
62 type_modifier->is_long++; /* handle "long long" */
64 } else if (!strcmp(gras_ddt_parse_text, "struct")) {
65 DEBUG0("This is a struct");
66 type_modifier->is_struct = 1;
68 } else if (!strcmp(gras_ddt_parse_text, "union")) {
69 DEBUG0("This is an union");
70 type_modifier->is_union = 1;
72 } else if (!strcmp(gras_ddt_parse_text, "enum")) {
73 DEBUG0("This is an enum");
74 type_modifier->is_enum = 1;
76 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_EMPTY) {
80 DEBUG1("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 DEBUG2("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 DEBUG2("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 DEBUG1("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 DEBUG3("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 DEBUG0("the base type is 'int', which were omited (you vicious user)");
285 identifier.type_name = (char *) strdup(gras_ddt_parse_text);
286 DEBUG1("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 DEBUG1("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 */
392 xbt_dict_get_or_null(gras_dd_constants, 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 DEBUG1("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"))
423 PARSE_ERROR1("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",
424 gras_ddt_parse_text);
426 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
427 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP)
429 ("Unparsable annotation: Expected parenthesis, got '%s'",
430 gras_ddt_parse_text);
432 while ((gras_ddt_parse_tok_num =
433 gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
435 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
436 PARSE_ERROR1("Unparsable annotation: Expected key name, got '%s'",
437 gras_ddt_parse_text);
438 keyname = (char *) strdup(gras_ddt_parse_text);
440 while ((gras_ddt_parse_tok_num =
441 gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
443 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON)
445 ("Unparsable annotation: expected ',' after the key name, got '%s'",
446 gras_ddt_parse_text);
448 while ((gras_ddt_parse_tok_num =
449 gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
453 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
454 PARSE_ERROR1("Unparsable annotation: Expected key value, got '%s'",
455 gras_ddt_parse_text);
456 keyval = (char *) strdup(gras_ddt_parse_text);
458 while ((gras_ddt_parse_tok_num =
459 gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
461 /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
463 DEBUG2("Anotation: %s=%s", keyname, keyval);
464 if (!strcmp(keyname, "size")) {
466 if (!identifier.tm.is_ref)
467 PARSE_ERROR0("Size annotation for a field not being a reference");
468 identifier.tm.is_ref--;
470 if (!strcmp(keyval, "1")) {
471 change_to_ref(identifiers);
476 for (p = keyval; *p != '\0'; p++)
480 change_to_fixed_array(identifiers, atoi(keyval));
481 change_to_ref(identifiers);
485 change_to_ref_pop_array(identifiers);
486 xbt_dynar_push(fields_to_push, &keyval);
489 } else if (!strcmp(keyname, "subtype")) {
490 gras_datadesc_type_t subtype = gras_datadesc_by_name(keyval);
491 if (identifier.tm.is_matrix) {
492 change_to_matrix_of(identifiers, subtype);
493 identifier.tm.is_matrix = -1;
494 } else if (identifier.tm.is_dynar) {
495 change_to_dynar_of(identifiers, subtype);
496 identifier.tm.is_dynar = -1;
499 ("subtype annotation only accepted for dynars and matrices, but passed to '%s'",
500 identifier.type_name);
503 } else if (!strcmp(keyname, "free_f")) {
504 int *storage = xbt_dict_get_or_null(gras_dd_constants, keyval);
507 ("value for free_f annotation of field %s is not a known constant",
509 if (identifier.tm.is_matrix == -1) {
510 add_free_f(identifiers, *(void_f_pvoid_t *) storage);
511 identifier.tm.is_matrix = 0;
512 } else if (identifier.tm.is_dynar == -1) {
513 add_free_f(identifiers, *(void_f_pvoid_t *) storage);
514 identifier.tm.is_dynar = 0;
517 ("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
523 PARSE_ERROR1("Unknown annotation type: '%s'", keyname);
526 /* Get all the multipliers */
527 while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
529 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
531 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
533 ("Unparsable annotation: Expected field name after '*', got '%s'",
534 gras_ddt_parse_text);
536 keyval = xbt_malloc(strlen(gras_ddt_parse_text) + 2);
537 sprintf(keyval, "*%s", gras_ddt_parse_text);
539 /* ask caller to push field as a multiplier */
540 xbt_dynar_push(fields_to_push, &keyval);
542 /* skip blanks after this block */
543 while ((gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump())
544 == GRAS_DDT_PARSE_TOKEN_EMPTY);
547 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
549 ("Unparsable annotation: Expected parenthesis, got '%s'",
550 gras_ddt_parse_text);
554 /* End of annotation handling */
557 ("Unparsable symbol: Got '%s' instead of expected comma (',')",
558 gras_ddt_parse_text);
560 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
561 PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
564 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
565 identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
569 /* found a symbol name. Build the type and push it to dynar */
570 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
572 identifier.name = (char *) strdup(gras_ddt_parse_text);
573 DEBUG1("Found the identifier \"%s\"", identifier.name);
575 xbt_dynar_push(identifiers, &identifier);
576 DEBUG1("Dynar_len=%lu", xbt_dynar_length(identifiers));
577 expect_id_separator = 1;
582 ("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
585 if (identifier.tm.is_matrix > 0)
586 PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
587 if (identifier.tm.is_dynar > 0)
588 PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
593 static gras_datadesc_type_t parse_struct(char *definition)
599 static int anonymous_struct = 0;
601 xbt_dynar_t identifiers;
602 s_identifier_t field;
606 xbt_dynar_t fields_to_push;
609 gras_datadesc_type_t struct_type;
612 identifiers = xbt_dynar_new(sizeof(s_identifier_t), NULL);
613 fields_to_push = xbt_dynar_new(sizeof(char *), NULL);
615 /* Create the struct descriptor */
616 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
617 struct_type = gras_datadesc_struct(gras_ddt_parse_text);
618 VERB1("Parse the struct '%s'", gras_ddt_parse_text);
619 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
621 sprintf(buffname, "anonymous struct %d", anonymous_struct++);
622 VERB1("Parse the anonymous struct nb %d", anonymous_struct);
623 struct_type = gras_datadesc_struct(buffname);
626 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
628 ("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
629 gras_ddt_parse_text);
631 /* Parse the identifiers */
635 parse_statement(definition, identifiers, fields_to_push);
638 if (e.category != mismatch_error)
644 DEBUG1("This statement contained %lu identifiers",
645 xbt_dynar_length(identifiers));
646 /* append the identifiers we've found */
647 xbt_dynar_foreach(identifiers, iter, field) {
650 ("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
651 field.name, field.tm.is_ref);
653 VERB2("Append field '%s' to %p", field.name, (void *) struct_type);
654 gras_datadesc_struct_append(struct_type, field.name, field.type);
656 free(field.type_name);
659 xbt_dynar_reset(identifiers);
660 DEBUG1("struct_type=%p", (void *) struct_type);
662 /* Make sure that all fields declaring a size push it into the cbps */
663 xbt_dynar_foreach(fields_to_push, iter, name) {
664 DEBUG1("struct_type=%p", (void *) struct_type);
665 if (name[0] == '*') {
666 VERB2("Push field '%s' as a multiplier into size stack of %p",
667 name + 1, (void *) struct_type);
668 gras_datadesc_cb_field_push_multiplier(struct_type, name + 1);
670 VERB2("Push field '%s' into size stack of %p",
671 name, (void *) struct_type);
672 gras_datadesc_cb_field_push(struct_type, name);
676 xbt_dynar_reset(fields_to_push);
678 gras_datadesc_struct_close(struct_type);
681 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
683 ("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
684 gras_ddt_parse_text);
686 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
688 xbt_dynar_free(&identifiers);
689 xbt_dynar_free(&fields_to_push);
694 static gras_datadesc_type_t parse_typedef(char *definition)
697 s_type_modifier_t tm;
699 gras_datadesc_type_t struct_desc = NULL;
700 gras_datadesc_type_t typedef_desc = NULL;
703 memset(&tm, 0, sizeof(tm));
705 /* get the aliased type */
706 parse_type_modifier(&tm);
709 struct_desc = parse_struct(definition);
712 parse_type_modifier(&tm);
716 ("GRAS_DEFINE_TYPE cannot handle reference without annotation");
718 /* get the aliasing name */
719 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
720 PARSE_ERROR1("Unparsable typedef: Expected the alias name, and got '%s'",
721 gras_ddt_parse_text);
723 /* (FIXME: should) build the alias */
725 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle typedef yet");
733 * gras_datadesc_parse:
735 * Create a datadescription from the result of parsing the C type description
738 gras_datadesc_parse(const char *name, const char *C_statement)
741 gras_datadesc_type_t res = NULL;
743 int semicolon_count = 0;
744 int def_count, C_count;
747 /* reput the \n in place for debug */
748 for (C_count = 0; C_statement[C_count] != '\0'; C_count++)
749 if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
751 definition = (char *) xbt_malloc(C_count + semicolon_count + 1);
752 for (C_count = 0, def_count = 0; C_statement[C_count] != '\0'; C_count++) {
753 definition[def_count++] = C_statement[C_count];
754 if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
755 definition[def_count++] = '\n';
758 definition[def_count] = '\0';
761 VERB2("_gras_ddt_type_parse(%s) -> %d chars", definition, def_count);
762 gras_ddt_parse_pointer_string_init(definition);
764 /* Do I have a typedef, or a raw struct ? */
765 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
767 if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD)
768 && (!strcmp(gras_ddt_parse_text, "struct"))) {
769 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
770 res = parse_struct(definition);
772 } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD)
773 && (!strcmp(gras_ddt_parse_text, "typedef"))) {
774 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
775 res = parse_typedef(definition);
779 ("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",
784 gras_ddt_parse_pointer_string_close();
785 VERB0("end of _gras_ddt_type_parse()");
787 /* register it under the name provided as symbol */
788 if (strcmp(res->name, name)) {
790 ("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
794 gras_ddt_parse_lex_destroy();
799 xbt_dict_t gras_dd_constants;
800 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
801 void gras_datadesc_set_const(const char *name, int value)
803 int *stored = xbt_new(int, 1);
806 xbt_dict_set(gras_dd_constants, name, stored, xbt_free_f);