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("Unimplemented feature: GRAS_DEFINE_TYPE 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("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
279 } else if (identifier.tm.is_enum) {
280 PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE 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("Unimplemented feature: GRAS_DEFINE_TYPE 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);
472 } else if (!strcmp(keyname,"free_f")) {
473 int *storage=xbt_dict_get_or_null(gras_dd_constants,keyval);
475 PARSE_ERROR1("value for free_f annotation of field %s is not a known constant",identifier.name);
476 if (identifier.tm.is_matrix == -1) {
477 add_free_f(identifiers,*(void_f_pvoid_t*)storage);
478 identifier.tm.is_matrix = 0;
479 } else if (identifier.tm.is_dynar == -1) {
480 add_free_f(identifiers,*(void_f_pvoid_t*)storage);
481 identifier.tm.is_dynar = 0;
483 PARSE_ERROR1("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
489 PARSE_ERROR1("Unknown annotation type: '%s'",keyname);
492 /* Get all the multipliers */
493 while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
495 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
497 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
498 PARSE_ERROR1("Unparsable annotation: Expected field name after '*', got '%s'",gras_ddt_parse_text);
500 keyval = xbt_malloc(strlen(gras_ddt_parse_text)+2);
501 sprintf(keyval,"*%s",gras_ddt_parse_text);
503 /* ask caller to push field as a multiplier */
504 xbt_dynar_push(fields_to_push,&keyval);
506 /* skip blanks after this block*/
507 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump())
508 == GRAS_DDT_PARSE_TOKEN_EMPTY );
511 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
512 PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",
513 gras_ddt_parse_text);
517 /* End of annotation handling */
519 PARSE_ERROR1("Unparsable symbol: Got '%s' instead of expected comma (',')",gras_ddt_parse_text);
521 } else if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
522 PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
525 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
526 identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
530 /* found a symbol name. Build the type and push it to dynar */
531 if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
533 identifier.name=(char*)strdup(gras_ddt_parse_text);
534 DEBUG1("Found the identifier \"%s\"",identifier.name);
536 xbt_dynar_push(identifiers, &identifier);
537 DEBUG1("Dynar_len=%lu",xbt_dynar_length(identifiers));
538 expect_id_separator = 1;
542 PARSE_ERROR0("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
545 if (identifier.tm.is_matrix>0)
546 PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
547 if (identifier.tm.is_dynar>0)
548 PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
553 static gras_datadesc_type_t parse_struct(char *definition) {
558 static int anonymous_struct=0;
560 xbt_dynar_t identifiers;
561 s_identifier_t field;
565 xbt_dynar_t fields_to_push;
568 gras_datadesc_type_t struct_type;
571 identifiers = xbt_dynar_new(sizeof(s_identifier_t),NULL);
572 fields_to_push = xbt_dynar_new(sizeof(char*),NULL);
574 /* Create the struct descriptor */
575 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
576 struct_type = gras_datadesc_struct(gras_ddt_parse_text);
577 VERB1("Parse the struct '%s'", gras_ddt_parse_text);
578 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
580 sprintf(buffname,"anonymous struct %d",anonymous_struct++);
581 VERB1("Parse the anonymous struct nb %d", anonymous_struct);
582 struct_type = gras_datadesc_struct(buffname);
585 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
586 PARSE_ERROR1("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
587 gras_ddt_parse_text);
589 /* Parse the identifiers */
593 parse_statement(definition,identifiers,fields_to_push);
595 if (e.category != mismatch_error)
601 DEBUG1("This statement contained %lu identifiers",xbt_dynar_length(identifiers));
602 /* append the identifiers we've found */
603 xbt_dynar_foreach(identifiers,iter, field) {
605 PARSE_ERROR2("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
606 field.name,field.tm.is_ref);
608 VERB2("Append field '%s' to %p",field.name, (void*)struct_type);
609 gras_datadesc_struct_append(struct_type, field.name, field.type);
611 free(field.type_name);
614 xbt_dynar_reset(identifiers);
615 DEBUG1("struct_type=%p",(void*)struct_type);
617 /* Make sure that all fields declaring a size push it into the cbps */
618 xbt_dynar_foreach(fields_to_push,iter, name) {
619 DEBUG1("struct_type=%p",(void*)struct_type);
620 if (name[0] == '*') {
621 VERB2("Push field '%s' as a multiplier into size stack of %p",
622 name+1, (void*)struct_type);
623 gras_datadesc_cb_field_push_multiplier(struct_type, name+1);
625 VERB2("Push field '%s' into size stack of %p",
626 name, (void*)struct_type);
627 gras_datadesc_cb_field_push(struct_type, name);
631 xbt_dynar_reset(fields_to_push);
633 gras_datadesc_struct_close(struct_type);
636 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
637 PARSE_ERROR1("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
638 gras_ddt_parse_text);
640 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
642 xbt_dynar_free(&identifiers);
643 xbt_dynar_free(&fields_to_push);
648 static gras_datadesc_type_t parse_typedef(char *definition) {
650 s_type_modifier_t tm;
652 gras_datadesc_type_t struct_desc=NULL;
653 gras_datadesc_type_t typedef_desc=NULL;
656 memset(&tm,0,sizeof(tm));
658 /* get the aliased type */
659 parse_type_modifier(&tm);
662 struct_desc = parse_struct(definition);
665 parse_type_modifier(&tm);
668 PARSE_ERROR0("GRAS_DEFINE_TYPE cannot handle reference without annotation");
670 /* get the aliasing name */
671 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
672 PARSE_ERROR1("Unparsable typedef: Expected the alias name, and got '%s'",
673 gras_ddt_parse_text);
675 /* (FIXME: should) build the alias */
676 PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle typedef yet");
684 * gras_datadesc_parse:
686 * Create a datadescription from the result of parsing the C type description
689 gras_datadesc_parse(const char *name,
690 const char *C_statement) {
692 gras_datadesc_type_t res=NULL;
694 int semicolon_count=0;
695 int def_count,C_count;
698 /* reput the \n in place for debug */
699 for (C_count=0; C_statement[C_count] != '\0'; C_count++)
700 if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
702 definition = (char*)xbt_malloc(C_count + semicolon_count + 1);
703 for (C_count=0,def_count=0; C_statement[C_count] != '\0'; C_count++) {
704 definition[def_count++] = C_statement[C_count];
705 if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
706 definition[def_count++] = '\n';
709 definition[def_count] = '\0';
712 VERB2("_gras_ddt_type_parse(%s) -> %d chars",definition, def_count);
713 gras_ddt_parse_pointer_string_init(definition);
715 /* Do I have a typedef, or a raw struct ?*/
716 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
718 if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"struct"))) {
719 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
720 res = parse_struct(definition);
722 } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"typedef"))) {
723 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
724 res = parse_typedef(definition);
727 ERROR1("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",definition);
731 gras_ddt_parse_pointer_string_close();
732 VERB0("end of _gras_ddt_type_parse()");
734 /* register it under the name provided as symbol */
735 if (strcmp(res->name,name)) {
736 ERROR2("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
740 gras_ddt_parse_lex_destroy();
745 xbt_dict_t gras_dd_constants;
746 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
747 void gras_datadesc_set_const(const char*name, int value) {
748 int *stored = xbt_new(int, 1);
751 xbt_dict_set(gras_dd_constants,name, stored, xbt_free_f);