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)
50 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
51 /* This only used when parsing 'short *' since this function returns when int, float, double,... is encountered */
52 DEBUG0("This is a reference");
53 type_modifier->is_ref++;
55 } else if (!strcmp(gras_ddt_parse_text, "unsigned")) {
56 DEBUG0("This is an unsigned");
57 type_modifier->is_unsigned = 1;
59 } else if (!strcmp(gras_ddt_parse_text, "short")) {
60 DEBUG0("This is short");
61 type_modifier->is_short = 1;
63 } else if (!strcmp(gras_ddt_parse_text, "long")) {
64 DEBUG0("This is long");
65 type_modifier->is_long++; /* handle "long long" */
67 } else if (!strcmp(gras_ddt_parse_text, "struct")) {
68 DEBUG0("This is a struct");
69 type_modifier->is_struct = 1;
71 } else if (!strcmp(gras_ddt_parse_text, "union")) {
72 DEBUG0("This is an union");
73 type_modifier->is_union = 1;
75 } else if (!strcmp(gras_ddt_parse_text, "enum")) {
76 DEBUG0("This is an enum");
77 type_modifier->is_enum = 1;
79 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_EMPTY) {
83 DEBUG1("Done with modifiers (got %s)", gras_ddt_parse_text);
87 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
88 if ((gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD) &&
89 (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_STAR)) {
90 DEBUG2("Done with modifiers (got %s,%d)", gras_ddt_parse_text,
91 gras_ddt_parse_tok_num);
98 static void print_type_modifier(s_type_modifier_t tm)
104 printf("(unsigned) ");
107 for (i = 0; i < tm.is_long; i++)
117 for (i = 0; i < tm.is_ref; i++)
122 static void change_to_fixed_array(xbt_dynar_t dynar, long int size)
124 s_identifier_t former, array;
125 memset(&array, 0, sizeof(array));
128 xbt_dynar_pop(dynar, &former);
129 array.type_name = (char *) xbt_malloc(strlen(former.type->name) + 48);
130 DEBUG2("Array specification (size=%ld, elm='%s'), change pushed type",
131 size, former.type_name);
132 sprintf(array.type_name, "%s%s%s%s[%ld]",
133 (former.tm.is_unsigned ? "u " : ""),
134 (former.tm.is_short ? "s " : ""),
135 (former.tm.is_long ? "l " : ""), former.type_name, size);
136 free(former.type_name);
138 array.type = gras_datadesc_array_fixed(array.type_name, former.type, size); /* redeclaration are ignored */
139 array.name = former.name;
141 xbt_dynar_push(dynar, &array);
145 static void change_to_ref(xbt_dynar_t dynar)
147 s_identifier_t former, ref;
148 memset(&ref, 0, sizeof(ref));
151 xbt_dynar_pop(dynar, &former);
152 ref.type_name = (char *) xbt_malloc(strlen(former.type->name) + 2);
153 DEBUG1("Ref specification (elm='%s'), change pushed type",
155 sprintf(ref.type_name, "%s*", former.type_name);
156 free(former.type_name);
158 ref.type = gras_datadesc_ref(ref.type_name, former.type); /* redeclaration are ignored */
159 ref.name = former.name;
161 xbt_dynar_push(dynar, &ref);
165 static void change_to_ref_pop_array(xbt_dynar_t dynar)
167 s_identifier_t former, ref;
168 memset(&ref, 0, sizeof(ref));
171 xbt_dynar_pop(dynar, &former);
172 ref.type = gras_datadesc_ref_pop_arr(former.type); /* redeclaration are ignored */
173 ref.type_name = (char *) strdup(ref.type->name);
174 ref.name = former.name;
176 free(former.type_name);
178 xbt_dynar_push(dynar, &ref);
182 static void change_to_dynar_of(xbt_dynar_t dynar,
183 gras_datadesc_type_t subtype)
185 s_identifier_t former, ref;
186 memset(&ref, 0, sizeof(ref));
189 xbt_dynar_pop(dynar, &former);
190 ref.type = gras_datadesc_dynar(subtype, NULL); /* redeclaration are ignored */
191 ref.type_name = (char *) strdup(ref.type->name);
192 ref.name = former.name;
194 free(former.type_name);
196 xbt_dynar_push(dynar, &ref);
200 static void change_to_matrix_of(xbt_dynar_t dynar,
201 gras_datadesc_type_t subtype)
203 s_identifier_t former, ref;
204 memset(&ref, 0, sizeof(ref));
207 xbt_dynar_pop(dynar, &former);
208 ref.type = gras_datadesc_matrix(subtype, NULL); /* redeclaration are ignored */
209 ref.type_name = (char *) strdup(ref.type->name);
210 ref.name = former.name;
212 free(former.type_name);
214 xbt_dynar_push(dynar, &ref);
218 static void add_free_f(xbt_dynar_t dynar, void_f_pvoid_t free_f)
220 s_identifier_t former, ref;
221 memset(&ref, 0, sizeof(ref));
224 xbt_dynar_pop(dynar, &former);
225 memcpy(former.type->extra, free_f, sizeof(free_f));
226 xbt_dynar_push(dynar, &former);
230 static void parse_statement(char *definition,
231 xbt_dynar_t identifiers,
232 xbt_dynar_t fields_to_push)
236 s_identifier_t identifier;
238 int expect_id_separator = 0;
241 memset(&identifier, 0, sizeof(identifier));
243 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
244 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RA) {
246 THROW0(mismatch_error, 0, "End of the englobing structure or union");
249 if (XBT_LOG_ISENABLED(gras_ddt_parse, xbt_log_priority_debug)) {
251 for (colon_pos = gras_ddt_parse_col_pos;
252 definition[colon_pos] != ';'; colon_pos++);
253 definition[colon_pos] = '\0';
254 DEBUG3("Parse the statement \"%s%s;\" (col_pos=%d)",
256 definition + gras_ddt_parse_col_pos, gras_ddt_parse_col_pos);
257 definition[colon_pos] = ';';
260 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
262 ("Unparsable symbol: found a typeless statement (got '%s' instead)",
263 gras_ddt_parse_text);
265 /**** get the type modifier of this statement ****/
266 parse_type_modifier(&identifier.tm);
268 /* FIXME: This does not detect recursive definitions at all? */
269 if (identifier.tm.is_union || identifier.tm.is_enum
270 || identifier.tm.is_struct)
272 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle recursive type definition yet");
274 /**** get the base type, giving "short a" the needed love ****/
275 if (!identifier.tm.is_union &&
276 !identifier.tm.is_enum &&
277 !identifier.tm.is_struct &&
278 (identifier.tm.is_short || identifier.tm.is_long
279 || identifier.tm.is_unsigned) && strcmp(gras_ddt_parse_text, "char")
280 && strcmp(gras_ddt_parse_text, "float")
281 && strcmp(gras_ddt_parse_text, "double")
282 && strcmp(gras_ddt_parse_text, "int")) {
284 /* bastard user, they omited "int" ! */
285 identifier.type_name = (char *) strdup("int");
286 DEBUG0("the base type is 'int', which were omited (you vicious user)");
288 identifier.type_name = (char *) strdup(gras_ddt_parse_text);
289 DEBUG1("the base type is '%s'", identifier.type_name);
290 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
293 /**** build the base type for latter use ****/
294 if (identifier.tm.is_union) {
296 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
298 } else if (identifier.tm.is_enum) {
300 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle enum yet");
302 } else if (identifier.tm.is_struct) {
303 sprintf(buffname, "struct %s", identifier.type_name);
304 identifier.type = gras_datadesc_struct(buffname); /* Get created when does not exist */
306 } else if (identifier.tm.is_unsigned) {
307 if (!strcmp(identifier.type_name, "int")) {
308 if (identifier.tm.is_long == 2) {
309 identifier.type = gras_datadesc_by_name("unsigned long long int");
310 } else if (identifier.tm.is_long) {
311 identifier.type = gras_datadesc_by_name("unsigned long int");
312 } else if (identifier.tm.is_short) {
313 identifier.type = gras_datadesc_by_name("unsigned short int");
315 identifier.type = gras_datadesc_by_name("unsigned int");
318 } else if (!strcmp(identifier.type_name, "char")) {
319 identifier.type = gras_datadesc_by_name("unsigned char");
321 } else { /* impossible, gcc parses this shit before us */
325 } else if (!strcmp(identifier.type_name, "float")) {
326 /* no modificator allowed by gcc */
327 identifier.type = gras_datadesc_by_name("float");
329 } else if (!strcmp(identifier.type_name, "double")) {
330 if (identifier.tm.is_long)
331 PARSE_ERROR0("long double not portable and thus not handled");
333 identifier.type = gras_datadesc_by_name("double");
335 } else { /* signed integer elemental */
336 if (!strcmp(identifier.type_name, "int")) {
337 if (identifier.tm.is_long == 2) {
338 identifier.type = gras_datadesc_by_name("signed long long int");
339 } else if (identifier.tm.is_long) {
340 identifier.type = gras_datadesc_by_name("signed long int");
341 } else if (identifier.tm.is_short) {
342 identifier.type = gras_datadesc_by_name("signed short int");
344 identifier.type = gras_datadesc_by_name("int");
347 } else if (!strcmp(identifier.type_name, "char")) {
348 identifier.type = gras_datadesc_by_name("char");
351 DEBUG1("Base type is a constructed one (%s)", identifier.type_name);
352 if (!strcmp(identifier.type_name, "xbt_matrix_t")) {
353 identifier.tm.is_matrix = 1;
354 } else if (!strcmp(identifier.type_name, "xbt_dynar_t")) {
355 identifier.tm.is_dynar = 1;
357 identifier.type = gras_datadesc_by_name(identifier.type_name);
358 if (!identifier.type)
359 PARSE_ERROR1("Unknown base type '%s'", identifier.type_name);
363 /* Now identifier.type and identifier.name speak about the base type.
364 Stars are not eaten unless 'int' was omitted.
365 We will have to enhance it if we are in fact asked for array or reference.
367 Dynars and matrices also need some extra love (prodiged as annotations)
370 /**** look for the symbols of this type ****/
371 for (expect_id_separator = 0; ( /*(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_EMPTY) && FIXME */
372 (gras_ddt_parse_tok_num !=
373 GRAS_DDT_PARSE_TOKEN_SEMI_COLON));
374 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) {
376 if (expect_id_separator) {
377 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
378 expect_id_separator = 0;
381 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_LB) {
382 /* Handle fixed size arrays */
383 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
384 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RB) {
386 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot deal with [] constructs (yet)");
388 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
390 long int size = strtol(gras_ddt_parse_text, &end, 10);
392 if (end == gras_ddt_parse_text || *end != '\0') {
393 /* Not a number. Get the constant value, if any */
395 xbt_dict_get_or_null(gras_dd_constants, gras_ddt_parse_text);
400 ("Unparsable size of array. Found '%s', expected number or known constant. Need to use gras_datadesc_set_const(), huh?",
401 gras_ddt_parse_text);
405 /* replace the previously pushed type to an array of it */
406 change_to_fixed_array(identifiers, size);
408 /* eat the closing bracket */
409 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
410 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RB)
411 PARSE_ERROR0("Unparsable size of array");
412 DEBUG1("Fixed size array, size=%ld", size);
415 PARSE_ERROR0("Unparsable size of array");
417 /* End of fixed size arrays handling */
419 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
420 /* Handle annotation */
421 s_identifier_t array;
422 char *keyname = NULL;
424 memset(&array, 0, sizeof(array));
425 if (strcmp(gras_ddt_parse_text, "GRAS_ANNOTE"))
426 PARSE_ERROR1("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",
427 gras_ddt_parse_text);
429 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
430 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP)
432 ("Unparsable annotation: Expected parenthesis, got '%s'",
433 gras_ddt_parse_text);
435 while ((gras_ddt_parse_tok_num =
436 gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
438 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
439 PARSE_ERROR1("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()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
446 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON)
448 ("Unparsable annotation: expected ',' after the key name, got '%s'",
449 gras_ddt_parse_text);
451 while ((gras_ddt_parse_tok_num =
452 gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
456 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
457 PARSE_ERROR1("Unparsable annotation: Expected key value, got '%s'",
458 gras_ddt_parse_text);
459 keyval = (char *) strdup(gras_ddt_parse_text);
461 while ((gras_ddt_parse_tok_num =
462 gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY);
464 /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
466 DEBUG2("Anotation: %s=%s", keyname, keyval);
467 if (!strcmp(keyname, "size")) {
469 if (!identifier.tm.is_ref)
470 PARSE_ERROR0("Size annotation for a field not being a reference");
471 identifier.tm.is_ref--;
473 if (!strcmp(keyval, "1")) {
474 change_to_ref(identifiers);
479 for (p = keyval; *p != '\0'; p++)
483 change_to_fixed_array(identifiers, atoi(keyval));
484 change_to_ref(identifiers);
488 change_to_ref_pop_array(identifiers);
489 xbt_dynar_push(fields_to_push, &keyval);
492 } else if (!strcmp(keyname, "subtype")) {
493 gras_datadesc_type_t subtype = gras_datadesc_by_name(keyval);
494 if (identifier.tm.is_matrix) {
495 change_to_matrix_of(identifiers, subtype);
496 identifier.tm.is_matrix = -1;
497 } else if (identifier.tm.is_dynar) {
498 change_to_dynar_of(identifiers, subtype);
499 identifier.tm.is_dynar = -1;
502 ("subtype annotation only accepted for dynars and matrices, but passed to '%s'",
503 identifier.type_name);
506 } else if (!strcmp(keyname, "free_f")) {
507 int *storage = xbt_dict_get_or_null(gras_dd_constants, keyval);
510 ("value for free_f annotation of field %s is not a known constant",
512 if (identifier.tm.is_matrix == -1) {
513 add_free_f(identifiers, *(void_f_pvoid_t *) storage);
514 identifier.tm.is_matrix = 0;
515 } else if (identifier.tm.is_dynar == -1) {
516 add_free_f(identifiers, *(void_f_pvoid_t *) storage);
517 identifier.tm.is_dynar = 0;
520 ("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
526 PARSE_ERROR1("Unknown annotation type: '%s'", keyname);
529 /* Get all the multipliers */
530 while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
532 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
534 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
536 ("Unparsable annotation: Expected field name after '*', got '%s'",
537 gras_ddt_parse_text);
539 keyval = xbt_malloc(strlen(gras_ddt_parse_text) + 2);
540 sprintf(keyval, "*%s", gras_ddt_parse_text);
542 /* ask caller to push field as a multiplier */
543 xbt_dynar_push(fields_to_push, &keyval);
545 /* skip blanks after this block */
546 while ((gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump())
547 == GRAS_DDT_PARSE_TOKEN_EMPTY);
550 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
552 ("Unparsable annotation: Expected parenthesis, got '%s'",
553 gras_ddt_parse_text);
557 /* End of annotation handling */
560 ("Unparsable symbol: Got '%s' instead of expected comma (',')",
561 gras_ddt_parse_text);
563 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
564 PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
567 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
568 identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
572 /* found a symbol name. Build the type and push it to dynar */
573 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
575 identifier.name = (char *) strdup(gras_ddt_parse_text);
576 DEBUG1("Found the identifier \"%s\"", identifier.name);
578 xbt_dynar_push(identifiers, &identifier);
579 DEBUG1("Dynar_len=%lu", xbt_dynar_length(identifiers));
580 expect_id_separator = 1;
585 ("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
588 if (identifier.tm.is_matrix > 0)
589 PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
590 if (identifier.tm.is_dynar > 0)
591 PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
596 static gras_datadesc_type_t parse_struct(char *definition)
602 static int anonymous_struct = 0;
604 xbt_dynar_t identifiers;
605 s_identifier_t field;
609 xbt_dynar_t fields_to_push;
612 gras_datadesc_type_t struct_type;
615 identifiers = xbt_dynar_new(sizeof(s_identifier_t), NULL);
616 fields_to_push = xbt_dynar_new(sizeof(char *), NULL);
618 /* Create the struct descriptor */
619 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
620 struct_type = gras_datadesc_struct(gras_ddt_parse_text);
621 VERB1("Parse the struct '%s'", gras_ddt_parse_text);
622 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
624 sprintf(buffname, "anonymous struct %d", anonymous_struct++);
625 VERB1("Parse the anonymous struct nb %d", anonymous_struct);
626 struct_type = gras_datadesc_struct(buffname);
629 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
631 ("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
632 gras_ddt_parse_text);
634 /* Parse the identifiers */
638 parse_statement(definition, identifiers, fields_to_push);
641 if (e.category != mismatch_error)
647 DEBUG1("This statement contained %lu identifiers",
648 xbt_dynar_length(identifiers));
649 /* append the identifiers we've found */
650 xbt_dynar_foreach(identifiers, iter, field) {
653 ("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
654 field.name, field.tm.is_ref);
656 VERB2("Append field '%s' to %p", field.name, (void *) struct_type);
657 gras_datadesc_struct_append(struct_type, field.name, field.type);
659 free(field.type_name);
662 xbt_dynar_reset(identifiers);
663 DEBUG1("struct_type=%p", (void *) struct_type);
665 /* Make sure that all fields declaring a size push it into the cbps */
666 xbt_dynar_foreach(fields_to_push, iter, name) {
667 DEBUG1("struct_type=%p", (void *) struct_type);
668 if (name[0] == '*') {
669 VERB2("Push field '%s' as a multiplier into size stack of %p",
670 name + 1, (void *) struct_type);
671 gras_datadesc_cb_field_push_multiplier(struct_type, name + 1);
673 VERB2("Push field '%s' into size stack of %p",
674 name, (void *) struct_type);
675 gras_datadesc_cb_field_push(struct_type, name);
679 xbt_dynar_reset(fields_to_push);
681 gras_datadesc_struct_close(struct_type);
684 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
686 ("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
687 gras_ddt_parse_text);
689 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
691 xbt_dynar_free(&identifiers);
692 xbt_dynar_free(&fields_to_push);
697 static gras_datadesc_type_t parse_typedef(char *definition)
700 s_type_modifier_t tm;
702 gras_datadesc_type_t struct_desc = NULL;
703 gras_datadesc_type_t typedef_desc = NULL;
706 memset(&tm, 0, sizeof(tm));
708 /* get the aliased type */
709 parse_type_modifier(&tm);
712 struct_desc = parse_struct(definition);
715 parse_type_modifier(&tm);
719 ("GRAS_DEFINE_TYPE cannot handle reference without annotation");
721 /* get the aliasing name */
722 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
723 PARSE_ERROR1("Unparsable typedef: Expected the alias name, and got '%s'",
724 gras_ddt_parse_text);
726 /* (FIXME: should) build the alias */
728 ("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle typedef yet");
736 * gras_datadesc_parse:
738 * Create a datadescription from the result of parsing the C type description
741 gras_datadesc_parse(const char *name, const char *C_statement)
744 gras_datadesc_type_t res = NULL;
746 int semicolon_count = 0;
747 int def_count, C_count;
750 /* reput the \n in place for debug */
751 for (C_count = 0; C_statement[C_count] != '\0'; C_count++)
752 if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
754 definition = (char *) xbt_malloc(C_count + semicolon_count + 1);
755 for (C_count = 0, def_count = 0; C_statement[C_count] != '\0'; C_count++) {
756 definition[def_count++] = C_statement[C_count];
757 if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
758 definition[def_count++] = '\n';
761 definition[def_count] = '\0';
764 VERB2("_gras_ddt_type_parse(%s) -> %d chars", definition, def_count);
765 gras_ddt_parse_pointer_string_init(definition);
767 /* Do I have a typedef, or a raw struct ? */
768 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
770 if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD)
771 && (!strcmp(gras_ddt_parse_text, "struct"))) {
772 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
773 res = parse_struct(definition);
775 } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD)
776 && (!strcmp(gras_ddt_parse_text, "typedef"))) {
777 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
778 res = parse_typedef(definition);
782 ("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",
787 gras_ddt_parse_pointer_string_close();
788 VERB0("end of _gras_ddt_type_parse()");
790 /* register it under the name provided as symbol */
791 if (strcmp(res->name, name)) {
793 ("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
797 gras_ddt_parse_lex_destroy();
802 xbt_dict_t gras_dd_constants;
803 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
804 void gras_datadesc_set_const(const char *name, int value)
806 int *stored = xbt_new(int, 1);
809 xbt_dict_set(gras_dd_constants, name, stored, xbt_free_f);