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 "datadesc_private.h"
13 #include "ddt_parse.yy.h"
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ddt_parse, xbt_ddt,
16 "Parsing C data structures to build XBT data description");
18 typedef struct s_type_modifier {
31 } s_type_modifier_t, *type_modifier_t;
33 typedef struct s_field {
34 xbt_datadesc_type_t type;
40 extern char *xbt_ddt_parse_text; /* text being considered in the parser */
43 static void parse_type_modifier(type_modifier_t type_modifier)
47 if (xbt_ddt_parse_tok_num == XBT_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(xbt_ddt_parse_text, "unsigned")) {
53 XBT_DEBUG("This is an unsigned");
54 type_modifier->is_unsigned = 1;
56 } else if (!strcmp(xbt_ddt_parse_text, "short")) {
57 XBT_DEBUG("This is short");
58 type_modifier->is_short = 1;
60 } else if (!strcmp(xbt_ddt_parse_text, "long")) {
61 XBT_DEBUG("This is long");
62 type_modifier->is_long++; /* handle "long long" */
64 } else if (!strcmp(xbt_ddt_parse_text, "struct")) {
65 XBT_DEBUG("This is a struct");
66 type_modifier->is_struct = 1;
68 } else if (!strcmp(xbt_ddt_parse_text, "union")) {
69 XBT_DEBUG("This is an union");
70 type_modifier->is_union = 1;
72 } else if (!strcmp(xbt_ddt_parse_text, "enum")) {
73 XBT_DEBUG("This is an enum");
74 type_modifier->is_enum = 1;
76 } else if (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_EMPTY) {
77 XBT_DEBUG("Pass space");
80 XBT_DEBUG("Done with modifiers (got %s)", xbt_ddt_parse_text);
84 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
85 if ((xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_WORD) &&
86 (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_STAR)) {
87 XBT_DEBUG("Done with modifiers (got %s,%d)", xbt_ddt_parse_text,
88 xbt_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 = xbt_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 = xbt_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 = xbt_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 xbt_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 = xbt_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 xbt_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 = xbt_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 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
241 if (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_RA) {
243 THROWF(mismatch_error, 0, "End of the englobing structure or union");
246 if (XBT_LOG_ISENABLED(xbt_ddt_parse, xbt_log_priority_debug)) {
248 for (colon_pos = xbt_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 + xbt_ddt_parse_col_pos, xbt_ddt_parse_col_pos);
254 definition[colon_pos] = ';';
257 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_WORD)
259 ("Unparsable symbol: found a typeless statement (got '%s' instead)",
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: XBT_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(xbt_ddt_parse_text, "char")
277 && strcmp(xbt_ddt_parse_text, "float")
278 && strcmp(xbt_ddt_parse_text, "double")
279 && strcmp(xbt_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(xbt_ddt_parse_text);
286 XBT_DEBUG("the base type is '%s'", identifier.type_name);
287 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
290 /**** build the base type for latter use ****/
291 if (identifier.tm.is_union) {
293 ("Unimplemented feature: XBT_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
295 } else if (identifier.tm.is_enum) {
297 ("Unimplemented feature: XBT_DEFINE_TYPE cannot handle enum yet");
299 } else if (identifier.tm.is_struct) {
300 sprintf(buffname, "struct %s", identifier.type_name);
301 identifier.type = xbt_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 = xbt_datadesc_by_name("unsigned long long int");
307 } else if (identifier.tm.is_long) {
308 identifier.type = xbt_datadesc_by_name("unsigned long int");
309 } else if (identifier.tm.is_short) {
310 identifier.type = xbt_datadesc_by_name("unsigned short int");
312 identifier.type = xbt_datadesc_by_name("unsigned int");
315 } else if (!strcmp(identifier.type_name, "char")) {
316 identifier.type = xbt_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 = xbt_datadesc_by_name("float");
326 } else if (!strcmp(identifier.type_name, "double")) {
327 if (identifier.tm.is_long)
328 PARSE_ERROR("long double not portable and thus not handled");
330 identifier.type = xbt_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 = xbt_datadesc_by_name("signed long long int");
336 } else if (identifier.tm.is_long) {
337 identifier.type = xbt_datadesc_by_name("signed long int");
338 } else if (identifier.tm.is_short) {
339 identifier.type = xbt_datadesc_by_name("signed short int");
341 identifier.type = xbt_datadesc_by_name("int");
344 } else if (!strcmp(identifier.type_name, "char")) {
345 identifier.type = xbt_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 = xbt_datadesc_by_name(identifier.type_name);
355 if (!identifier.type)
356 PARSE_ERROR("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; ( /*(xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_EMPTY) && FIXME */
369 (xbt_ddt_parse_tok_num !=
370 XBT_DDT_PARSE_TOKEN_SEMI_COLON));
371 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump()) {
373 if (expect_id_separator) {
374 if (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_COLON) {
375 expect_id_separator = 0;
378 } else if (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_LB) {
379 /* Handle fixed size arrays */
380 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
381 if (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_RB) {
383 ("Unimplemented feature: XBT_DEFINE_TYPE cannot deal with [] constructs (yet)");
385 } else if (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_WORD) {
387 long int size = strtol(xbt_ddt_parse_text, &end, 10);
389 if (end == xbt_ddt_parse_text || *end != '\0') {
390 /* Not a number. Get the constant value, if any */
391 int *storage = xbt_dict_get_or_null(xbt_dd_constants,
397 ("Unparsable size of array. Found '%s', expected number or known constant. Need to use xbt_datadesc_set_const(), huh?",
402 /* replace the previously pushed type to an array of it */
403 change_to_fixed_array(identifiers, size);
405 /* eat the closing bracket */
406 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
407 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_RB)
408 PARSE_ERROR("Unparsable size of array");
409 XBT_DEBUG("Fixed size array, size=%ld", size);
412 PARSE_ERROR("Unparsable size of array");
414 /* End of fixed size arrays handling */
416 } else if (xbt_ddt_parse_tok_num == XBT_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(xbt_ddt_parse_text, "XBT_ANNOTE"))
424 ("Unparsable symbol: Expected 'XBT_ANNOTE', got '%s'",
427 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
428 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_LP)
430 ("Unparsable annotation: Expected parenthesis, got '%s'",
433 while ((xbt_ddt_parse_tok_num =
434 xbt_ddt_parse_lex_n_dump()) ==
435 XBT_DDT_PARSE_TOKEN_EMPTY);
437 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_WORD)
439 ("Unparsable annotation: Expected key name, got '%s'",
441 keyname = (char *) strdup(xbt_ddt_parse_text);
443 while ((xbt_ddt_parse_tok_num =
444 xbt_ddt_parse_lex_n_dump()) ==
445 XBT_DDT_PARSE_TOKEN_EMPTY);
447 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_COLON)
449 ("Unparsable annotation: expected ',' after the key name, got '%s'",
452 while ((xbt_ddt_parse_tok_num =
453 xbt_ddt_parse_lex_n_dump()) ==
454 XBT_DDT_PARSE_TOKEN_EMPTY);
458 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_WORD)
460 ("Unparsable annotation: Expected key value, got '%s'",
462 keyval = (char *) strdup(xbt_ddt_parse_text);
464 while ((xbt_ddt_parse_tok_num =
465 xbt_ddt_parse_lex_n_dump()) ==
466 XBT_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 xbt_datadesc_type_t subtype = xbt_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(xbt_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_ERROR("Unknown annotation type: '%s'", keyname);
534 /* Get all the multipliers */
535 while (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_STAR) {
537 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
539 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_WORD)
541 ("Unparsable annotation: Expected field name after '*', got '%s'",
544 keyval = xbt_malloc(strlen(xbt_ddt_parse_text) + 2);
545 sprintf(keyval, "*%s", xbt_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 ((xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump())
552 == XBT_DDT_PARSE_TOKEN_EMPTY);
555 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_RP)
557 ("Unparsable annotation: Expected parenthesis, got '%s'",
562 /* End of annotation handling */
565 ("Unparsable symbol: Got '%s' instead of expected comma (',')",
568 } else if (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_COLON) {
569 PARSE_ERROR("Unparsable symbol: Unexpected comma (',')");
572 if (xbt_ddt_parse_tok_num == XBT_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 (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_WORD) {
580 identifier.name = (char *) strdup(xbt_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_ERROR("xbt_matrix_t field without 'subtype' annotation");
595 if (identifier.tm.is_dynar > 0)
596 PARSE_ERROR("xbt_dynar_t field without 'subtype' annotation");
601 static xbt_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 volatile xbt_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 (xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_WORD) {
625 struct_type = xbt_datadesc_struct(xbt_ddt_parse_text);
626 XBT_VERB("Parse the struct '%s'", xbt_ddt_parse_text);
627 xbt_ddt_parse_tok_num = xbt_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 = xbt_datadesc_struct(buffname);
634 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_LA)
636 ("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
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 XBT_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
659 field.name, (int)field.tm.is_ref);
661 XBT_VERB("Append field '%s' to %p", field.name, (void *) struct_type);
662 xbt_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 xbt_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 xbt_datadesc_cb_field_push(struct_type, name);
684 xbt_dynar_reset(fields_to_push);
686 xbt_datadesc_struct_close(struct_type);
689 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_RA)
691 ("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
694 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
696 xbt_dynar_free(&identifiers);
697 xbt_dynar_free(&fields_to_push);
702 static xbt_datadesc_type_t parse_typedef(char *definition)
705 s_type_modifier_t tm;
707 xbt_datadesc_type_t typedef_desc = NULL;
710 memset(&tm, 0, sizeof(tm));
712 /* get the aliased type */
713 parse_type_modifier(&tm);
716 parse_struct(definition);
719 parse_type_modifier(&tm);
723 ("XBT_DEFINE_TYPE cannot handle reference without annotation");
725 /* get the aliasing name */
726 if (xbt_ddt_parse_tok_num != XBT_DDT_PARSE_TOKEN_WORD)
728 ("Unparsable typedef: Expected the alias name, and got '%s'",
731 /* (FIXME: should) build the alias */
733 ("Unimplemented feature: XBT_DEFINE_TYPE cannot handle typedef yet");
741 * xbt_datadesc_parse:
743 * Create a datadescription from the result of parsing the C type description
746 xbt_datadesc_parse(const char *name, const char *C_statement)
749 xbt_datadesc_type_t res = NULL;
751 int semicolon_count = 0;
752 int def_count, C_count;
755 /* reput the \n in place for debug */
756 for (C_count = 0; C_statement[C_count] != '\0'; C_count++)
757 if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
759 definition = (char *) xbt_malloc(C_count + semicolon_count + 1);
760 for (C_count = 0, def_count = 0; C_statement[C_count] != '\0'; C_count++) {
761 definition[def_count++] = C_statement[C_count];
762 if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
763 definition[def_count++] = '\n';
766 definition[def_count] = '\0';
769 XBT_VERB("_xbt_ddt_type_parse(%s) -> %d chars", definition, def_count);
770 xbt_ddt_parse_pointer_string_init(definition);
772 /* Do I have a typedef, or a raw struct ? */
773 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
775 if ((xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_WORD)
776 && (!strcmp(xbt_ddt_parse_text, "struct"))) {
777 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
778 res = parse_struct(definition);
780 } else if ((xbt_ddt_parse_tok_num == XBT_DDT_PARSE_TOKEN_WORD)
781 && (!strcmp(xbt_ddt_parse_text, "typedef"))) {
782 xbt_ddt_parse_tok_num = xbt_ddt_parse_lex_n_dump();
783 res = parse_typedef(definition);
787 ("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",
792 xbt_ddt_parse_pointer_string_close();
793 XBT_VERB("end of _xbt_ddt_type_parse()");
795 /* register it under the name provided as symbol */
796 if (strcmp(res->name, name)) {
798 ("In XBT_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
802 xbt_ddt_parse_lex_destroy();
807 xbt_dict_t xbt_dd_constants;
808 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
809 void xbt_datadesc_set_const(const char *name, int value)
811 int *stored = xbt_new(int, 1);
814 xbt_dict_set(xbt_dd_constants, name, stored, NULL);