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 add_free_f(xbt_dynar_t dynar,void_f_pvoid_t* free_f) {
213 s_identifier_t former,ref;
214 memset(&ref,0,sizeof(ref));
217 xbt_dynar_pop(dynar,&former);
218 memcpy(former.type->extra,free_f, sizeof(free_f));
219 xbt_dynar_push(dynar,&former);
223 static void parse_statement(char *definition,
224 xbt_dynar_t identifiers,
225 xbt_dynar_t fields_to_push) {
228 s_identifier_t identifier;
230 int expect_id_separator = 0;
233 memset(&identifier,0,sizeof(identifier));
235 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
236 if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RA) {
238 THROW0(mismatch_error,0,"End of the englobing structure or union");
241 if (XBT_LOG_ISENABLED(gras_ddt_parse,xbt_log_priority_debug)) {
243 for (colon_pos = gras_ddt_parse_col_pos;
244 definition[colon_pos] != ';';
246 definition[colon_pos] = '\0';
247 DEBUG3("Parse the statement \"%s%s;\" (col_pos=%d)",
249 definition+gras_ddt_parse_col_pos,
250 gras_ddt_parse_col_pos);
251 definition[colon_pos] = ';';
254 if(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
255 PARSE_ERROR1("Unparsable symbol: found a typeless statement (got '%s' instead)",
256 gras_ddt_parse_text);
258 /**** get the type modifier of this statement ****/
259 parse_type_modifier(&identifier.tm);
261 /* FIXME: This does not detect recursive definitions at all? */
262 if (identifier.tm.is_union || identifier.tm.is_enum || identifier.tm.is_struct)
263 PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle recursive type definition yet");
265 /**** get the base type, giving "short a" the needed love ****/
266 if (!identifier.tm.is_union &&
267 !identifier.tm.is_enum &&
268 !identifier.tm.is_struct &&
270 (identifier.tm.is_short || identifier.tm.is_long || identifier.tm.is_unsigned) &&
272 strcmp(gras_ddt_parse_text,"char") &&
273 strcmp(gras_ddt_parse_text,"float") &&
274 strcmp(gras_ddt_parse_text,"double") &&
275 strcmp(gras_ddt_parse_text,"int") ) {
277 /* bastard user, they omited "int" ! */
278 identifier.type_name=(char*)strdup("int");
279 DEBUG0("the base type is 'int', which were omited (you vicious user)");
281 identifier.type_name=(char*)strdup(gras_ddt_parse_text);
282 DEBUG1("the base type is '%s'",identifier.type_name);
283 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
286 /**** build the base type for latter use ****/
287 if (identifier.tm.is_union) {
288 PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
290 } else if (identifier.tm.is_enum) {
291 PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle enum yet");
293 } else if (identifier.tm.is_struct) {
294 sprintf(buffname,"struct %s",identifier.type_name);
295 identifier.type = gras_datadesc_struct(buffname); /* Get created when does not exist */
297 } else if (identifier.tm.is_unsigned) {
298 if (!strcmp(identifier.type_name,"int")) {
299 if (identifier.tm.is_long == 2) {
300 identifier.type = gras_datadesc_by_name("unsigned long long int");
301 } else if (identifier.tm.is_long) {
302 identifier.type = gras_datadesc_by_name("unsigned long int");
303 } else if (identifier.tm.is_short) {
304 identifier.type = gras_datadesc_by_name("unsigned short int");
306 identifier.type = gras_datadesc_by_name("unsigned int");
309 } else if (!strcmp(identifier.type_name, "char")) {
310 identifier.type = gras_datadesc_by_name("unsigned char");
312 } else { /* impossible, gcc parses this shit before us */
316 } else if (!strcmp(identifier.type_name, "float")) {
317 /* no modificator allowed by gcc */
318 identifier.type = gras_datadesc_by_name("float");
320 } else if (!strcmp(identifier.type_name, "double")) {
321 if (identifier.tm.is_long)
322 PARSE_ERROR0("long double not portable and thus not handled");
324 identifier.type = gras_datadesc_by_name("double");
326 } else { /* signed integer elemental */
327 if (!strcmp(identifier.type_name,"int")) {
328 if (identifier.tm.is_long == 2) {
329 identifier.type = gras_datadesc_by_name("signed long long int");
330 } else if (identifier.tm.is_long) {
331 identifier.type = gras_datadesc_by_name("signed long int");
332 } else if (identifier.tm.is_short) {
333 identifier.type = gras_datadesc_by_name("signed short int");
335 identifier.type = gras_datadesc_by_name("int");
338 } else if (!strcmp(identifier.type_name, "char")) {
339 identifier.type = gras_datadesc_by_name("char");
342 DEBUG1("Base type is a constructed one (%s)",identifier.type_name);
343 if (!strcmp(identifier.type_name,"xbt_matrix_t")) {
344 identifier.tm.is_matrix = 1;
345 } else if (!strcmp(identifier.type_name,"xbt_dynar_t")) {
346 identifier.tm.is_dynar = 1;
348 identifier.type = gras_datadesc_by_name(identifier.type_name);
349 if (!identifier.type)
350 PARSE_ERROR1("Unknown base type '%s'",identifier.type_name);
354 /* Now identifier.type and identifier.name speak about the base type.
355 Stars are not eaten unless 'int' was omitted.
356 We will have to enhance it if we are in fact asked for array or reference.
358 Dynars and matrices also need some extra love (prodiged as annotations)
361 /**** look for the symbols of this type ****/
362 for(expect_id_separator = 0;
364 (/*(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_EMPTY) && FIXME*/
365 (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_SEMI_COLON)) ;
367 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump() ) {
369 if(expect_id_separator) {
370 if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
371 expect_id_separator = 0;
374 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_LB) {
375 /* Handle fixed size arrays */
376 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
377 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RB) {
378 PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot deal with [] constructs (yet)");
380 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
382 long int size=strtol(gras_ddt_parse_text, &end, 10);
384 if (end == gras_ddt_parse_text || *end != '\0') {
385 /* Not a number. Get the constant value, if any */
386 int *storage=xbt_dict_get_or_null(gras_dd_constants,gras_ddt_parse_text);
390 PARSE_ERROR1("Unparsable size of array. Found '%s', expected number or known constant. Need to use gras_datadesc_set_const(), huh?",
391 gras_ddt_parse_text);
395 /* replace the previously pushed type to an array of it */
396 change_to_fixed_array(identifiers,size);
398 /* eat the closing bracket */
399 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
400 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RB)
401 PARSE_ERROR0("Unparsable size of array");
402 DEBUG1("Fixed size array, size=%ld",size);
405 PARSE_ERROR0("Unparsable size of array");
407 /* End of fixed size arrays handling */
409 } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
410 /* Handle annotation */
411 s_identifier_t array;
412 char *keyname = NULL;
414 memset(&array,0,sizeof(array));
415 if (strcmp(gras_ddt_parse_text,"GRAS_ANNOTE"))
416 PARSE_ERROR1("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",gras_ddt_parse_text);
418 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
419 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP)
420 PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",gras_ddt_parse_text);
422 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
424 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
425 PARSE_ERROR1("Unparsable annotation: Expected key name, got '%s'",gras_ddt_parse_text);
426 keyname = (char*)strdup(gras_ddt_parse_text);
428 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
430 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON)
431 PARSE_ERROR1("Unparsable annotation: expected ',' after the key name, got '%s'",gras_ddt_parse_text);
433 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
437 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
438 PARSE_ERROR1("Unparsable annotation: Expected key value, got '%s'",gras_ddt_parse_text);
439 keyval = (char*)strdup(gras_ddt_parse_text);
441 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
443 /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
445 DEBUG2("Anotation: %s=%s",keyname,keyval);
446 if (!strcmp(keyname,"size")) {
448 if (!identifier.tm.is_ref)
449 PARSE_ERROR0("Size annotation for a field not being a reference");
450 identifier.tm.is_ref--;
452 if (!strcmp(keyval,"1")) {
453 change_to_ref(identifiers);
458 for (p = keyval; *p != '\0'; p++)
462 change_to_fixed_array(identifiers,atoi(keyval));
463 change_to_ref(identifiers);
467 change_to_ref_pop_array(identifiers);
468 xbt_dynar_push(fields_to_push,&keyval);
471 } else if (!strcmp(keyname,"subtype")) {
472 gras_datadesc_type_t subtype = gras_datadesc_by_name(keyval);
473 if (identifier.tm.is_matrix) {
474 change_to_matrix_of(identifiers,subtype);
475 identifier.tm.is_matrix = -1;
476 } else if (identifier.tm.is_dynar) {
477 change_to_dynar_of(identifiers,subtype);
478 identifier.tm.is_dynar = -1;
480 PARSE_ERROR1("subtype annotation only accepted for dynars and matrices, but passed to '%s'",identifier.type_name);
483 } else if (!strcmp(keyname,"free_f")) {
484 int *storage=xbt_dict_get_or_null(gras_dd_constants,keyval);
486 PARSE_ERROR1("value for free_f annotation of field %s is not a known constant",identifier.name);
487 if (identifier.tm.is_matrix == -1) {
488 add_free_f(identifiers,*(void_f_pvoid_t**)storage);
489 identifier.tm.is_matrix = 0;
490 } else if (identifier.tm.is_dynar == -1) {
491 add_free_f(identifiers,*(void_f_pvoid_t**)storage);
492 identifier.tm.is_dynar = 0;
494 PARSE_ERROR1("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
500 PARSE_ERROR1("Unknown annotation type: '%s'",keyname);
503 /* Get all the multipliers */
504 while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
506 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
508 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
509 PARSE_ERROR1("Unparsable annotation: Expected field name after '*', got '%s'",gras_ddt_parse_text);
511 keyval = xbt_malloc(strlen(gras_ddt_parse_text)+2);
512 sprintf(keyval,"*%s",gras_ddt_parse_text);
514 /* ask caller to push field as a multiplier */
515 xbt_dynar_push(fields_to_push,&keyval);
517 /* skip blanks after this block*/
518 while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump())
519 == GRAS_DDT_PARSE_TOKEN_EMPTY );
522 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
523 PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",
524 gras_ddt_parse_text);
528 /* End of annotation handling */
530 PARSE_ERROR1("Unparsable symbol: Got '%s' instead of expected comma (',')",gras_ddt_parse_text);
532 } else if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
533 PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
536 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
537 identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
541 /* found a symbol name. Build the type and push it to dynar */
542 if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
544 identifier.name=(char*)strdup(gras_ddt_parse_text);
545 DEBUG1("Found the identifier \"%s\"",identifier.name);
547 xbt_dynar_push(identifiers, &identifier);
548 DEBUG1("Dynar_len=%lu",xbt_dynar_length(identifiers));
549 expect_id_separator = 1;
553 PARSE_ERROR0("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
556 if (identifier.tm.is_matrix>0)
557 PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
558 if (identifier.tm.is_dynar>0)
559 PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
564 static gras_datadesc_type_t parse_struct(char *definition) {
569 static int anonymous_struct=0;
571 xbt_dynar_t identifiers;
572 s_identifier_t field;
576 xbt_dynar_t fields_to_push;
579 gras_datadesc_type_t struct_type;
582 identifiers = xbt_dynar_new(sizeof(s_identifier_t),NULL);
583 fields_to_push = xbt_dynar_new(sizeof(char*),NULL);
585 /* Create the struct descriptor */
586 if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
587 struct_type = gras_datadesc_struct(gras_ddt_parse_text);
588 VERB1("Parse the struct '%s'", gras_ddt_parse_text);
589 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
591 sprintf(buffname,"anonymous struct %d",anonymous_struct++);
592 VERB1("Parse the anonymous struct nb %d", anonymous_struct);
593 struct_type = gras_datadesc_struct(buffname);
596 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LA)
597 PARSE_ERROR1("Unparasable symbol: Expecting struct definition, but got %s instead of '{'",
598 gras_ddt_parse_text);
600 /* Parse the identifiers */
604 parse_statement(definition,identifiers,fields_to_push);
606 if (e.category != mismatch_error)
612 DEBUG1("This statement contained %lu identifiers",xbt_dynar_length(identifiers));
613 /* append the identifiers we've found */
614 xbt_dynar_foreach(identifiers,i, field) {
616 PARSE_ERROR2("Not enough GRAS_ANNOTATE to deal with all dereferencing levels of %s (%d '*' left)",
617 field.name,field.tm.is_ref);
619 VERB2("Append field '%s' to %p",field.name, (void*)struct_type);
620 gras_datadesc_struct_append(struct_type, field.name, field.type);
622 free(field.type_name);
625 xbt_dynar_reset(identifiers);
626 DEBUG1("struct_type=%p",(void*)struct_type);
628 /* Make sure that all fields declaring a size push it into the cbps */
629 xbt_dynar_foreach(fields_to_push,i, name) {
630 DEBUG1("struct_type=%p",(void*)struct_type);
631 if (name[0] == '*') {
632 VERB2("Push field '%s' as a multiplier into size stack of %p",
633 name+1, (void*)struct_type);
634 gras_datadesc_cb_field_push_multiplier(struct_type, name+1);
636 VERB2("Push field '%s' into size stack of %p",
637 name, (void*)struct_type);
638 gras_datadesc_cb_field_push(struct_type, name);
642 xbt_dynar_reset(fields_to_push);
644 gras_datadesc_struct_close(struct_type);
647 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)
648 PARSE_ERROR1("Unparasable symbol: Expected '}' at the end of struct definition, got '%s'",
649 gras_ddt_parse_text);
651 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
653 xbt_dynar_free(&identifiers);
654 xbt_dynar_free(&fields_to_push);
659 static gras_datadesc_type_t parse_typedef(char *definition) {
661 s_type_modifier_t tm;
663 gras_datadesc_type_t struct_desc=NULL;
664 gras_datadesc_type_t typedef_desc=NULL;
667 memset(&tm,0,sizeof(tm));
669 /* get the aliased type */
670 parse_type_modifier(&tm);
673 struct_desc = parse_struct(definition);
676 parse_type_modifier(&tm);
679 PARSE_ERROR0("GRAS_DEFINE_TYPE cannot handle reference without annotation");
681 /* get the aliasing name */
682 if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
683 PARSE_ERROR1("Unparsable typedef: Expected the alias name, and got '%s'",
684 gras_ddt_parse_text);
686 /* (FIXME: should) build the alias */
687 PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle typedef yet");
695 * gras_datadesc_parse:
697 * Create a datadescription from the result of parsing the C type description
700 gras_datadesc_parse(const char *name,
701 const char *C_statement) {
703 gras_datadesc_type_t res=NULL;
705 int semicolon_count=0;
706 int def_count,C_count;
709 /* reput the \n in place for debug */
710 for (C_count=0; C_statement[C_count] != '\0'; C_count++)
711 if (C_statement[C_count] == ';' || C_statement[C_count] == '{')
713 definition = (char*)xbt_malloc(C_count + semicolon_count + 1);
714 for (C_count=0,def_count=0; C_statement[C_count] != '\0'; C_count++) {
715 definition[def_count++] = C_statement[C_count];
716 if (C_statement[C_count] == ';' || C_statement[C_count] == '{') {
717 definition[def_count++] = '\n';
720 definition[def_count] = '\0';
723 VERB2("_gras_ddt_type_parse(%s) -> %d chars",definition, def_count);
724 gras_ddt_parse_pointer_string_init(definition);
726 /* Do I have a typedef, or a raw struct ?*/
727 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
729 if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"struct"))) {
730 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
731 res = parse_struct(definition);
733 } else if ((gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) && (!strcmp(gras_ddt_parse_text,"typedef"))) {
734 gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
735 res = parse_typedef(definition);
738 ERROR1("Failed to parse the following symbol (not a struct neither a typedef) :\n%s",definition);
742 gras_ddt_parse_pointer_string_close();
743 VERB0("end of _gras_ddt_type_parse()");
745 /* register it under the name provided as symbol */
746 if (strcmp(res->name,name)) {
747 ERROR2("In GRAS_DEFINE_TYPE, the provided symbol (here %s) must be the C type name (here %s)",
751 gras_ddt_parse_lex_destroy();
756 xbt_dict_t gras_dd_constants;
757 /** \brief Declare a constant to the parsing mecanism. See the "\#define and fixed size array" section */
758 void gras_datadesc_set_const(const char*name, int value) {
759 int *stored = xbt_new(int, 1);
762 xbt_dict_set(gras_dd_constants,name, stored, xbt_free_f);