- } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
- /* Handle annotation */
- identifier_t array;
- char *keyname = NULL;
- char *keyval = NULL;
- memset(&array,0,sizeof(array));
- if (strcmp(gras_ddt_parse_text,"GRAS_ANNOTE"))
- PARSE_ERROR1("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",gras_ddt_parse_text);
-
- gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
- if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP)
- PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",gras_ddt_parse_text);
-
- while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
-
- if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
- PARSE_ERROR1("Unparsable annotation: Expected key name, got '%s'",gras_ddt_parse_text);
- keyname = strdup(gras_ddt_parse_text);
-
- while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
-
- if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON)
- PARSE_ERROR1("Unparsable annotation: expected ',' after the key name, got '%s'",gras_ddt_parse_text);
-
- while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
-
- if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
- PARSE_ERROR1("Unparsable annotation: Expected key value, got '%s'",gras_ddt_parse_text);
- keyval = strdup(gras_ddt_parse_text);
-
- while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
-
- if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
- PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",gras_ddt_parse_text);
-
- /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
-
- DEBUG2("Anotation: %s=%s",keyname,keyval);
- if (!strcmp(keyname,"size")) {
- free(keyname);
- if (!identifier.tm.is_ref)
- PARSE_ERROR0("Size annotation for a field not being a reference");
- identifier.tm.is_ref--;
-
- if (!strcmp(keyval,"1")) {
- TRY(change_to_ref(identifiers));
- free(keyval);
- continue;
- } else {
- char *p;
- int fixed = 1;
- for (p = keyval; *p != '\0'; p++)
- if (! isdigit(*p) )
- fixed = 0;
- if (fixed) {
- TRY(change_to_fixed_array(identifiers,atoi(keyval)));
- TRY(change_to_ref(identifiers));
- free(keyval);
- continue;
-
- } else {
- TRY(change_to_ref_pop_array(identifiers));
- TRY(gras_dynar_push(fields_to_push,&keyval));
- continue;
- }
- }
- RAISE_IMPOSSIBLE;
+ /**** build the base type for latter use ****/
+ if (identifier.tm.is_union) {
+ PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
+
+ } else if (identifier.tm.is_enum) {
+ PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle enum yet");
+
+ } else if (identifier.tm.is_struct) {
+ sprintf(buffname,"struct %s",identifier.type_name);
+ identifier.type = gras_datadesc_struct(buffname); /* Get created when does not exist */
+
+ } else if (identifier.tm.is_unsigned) {
+ if (!strcmp(identifier.type_name,"int")) {
+ if (identifier.tm.is_long == 2) {
+ identifier.type = gras_datadesc_by_name("unsigned long long int");
+ } else if (identifier.tm.is_long) {
+ identifier.type = gras_datadesc_by_name("unsigned long int");
+ } else if (identifier.tm.is_short) {
+ identifier.type = gras_datadesc_by_name("unsigned short int");
+ } else {
+ identifier.type = gras_datadesc_by_name("unsigned int");
+ }
+
+ } else if (!strcmp(identifier.type_name, "char")) {
+ identifier.type = gras_datadesc_by_name("unsigned char");
+
+ } else { /* impossible, gcc parses this shit before us */
+ THROW_IMPOSSIBLE;
+ }
+
+ } else if (!strcmp(identifier.type_name, "float")) {
+ /* no modificator allowed by gcc */
+ identifier.type = gras_datadesc_by_name("float");
+
+ } else if (!strcmp(identifier.type_name, "double")) {
+ if (identifier.tm.is_long)
+ PARSE_ERROR0("long double not portable and thus not handled");
+
+ identifier.type = gras_datadesc_by_name("double");
+
+ } else { /* signed integer elemental */
+ if (!strcmp(identifier.type_name,"int")) {
+ if (identifier.tm.is_long == 2) {
+ identifier.type = gras_datadesc_by_name("signed long long int");
+ } else if (identifier.tm.is_long) {
+ identifier.type = gras_datadesc_by_name("signed long int");
+ } else if (identifier.tm.is_short) {
+ identifier.type = gras_datadesc_by_name("signed short int");
+ } else {
+ identifier.type = gras_datadesc_by_name("int");
+ }
+
+ } else if (!strcmp(identifier.type_name, "char")) {
+ identifier.type = gras_datadesc_by_name("char");
+
+ } else {
+ DEBUG1("Base type is a constructed one (%s)",identifier.type_name);
+ if (!strcmp(identifier.type_name,"xbt_matrix_t")) {
+ identifier.tm.is_matrix = 1;
+ } else if (!strcmp(identifier.type_name,"xbt_dynar_t")) {
+ identifier.tm.is_dynar = 1;
+ } else {
+ identifier.type = gras_datadesc_by_name(identifier.type_name);
+ if (!identifier.type)
+ PARSE_ERROR1("Unknown base type '%s'",identifier.type_name);
+ }
+ }
+ }
+ /* Now identifier.type and identifier.name speak about the base type.
+ Stars are not eaten unless 'int' was omitted.
+ We will have to enhance it if we are in fact asked for array or reference.
+
+ Dynars and matrices also need some extra love (prodiged as annotations)
+ */
+
+ /**** look for the symbols of this type ****/
+ for(expect_id_separator = 0;
+
+ (/*(gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_EMPTY) && FIXME*/
+ (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_SEMI_COLON)) ;
+
+ gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump() ) {
+
+ if(expect_id_separator) {
+ if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
+ expect_id_separator = 0;
+ continue;
+
+ } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_LB) {
+ /* Handle fixed size arrays */
+ gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
+ if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RB) {
+ PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot deal with [] constructs (yet)");
+
+ } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
+ char *end;
+ long int size=strtol(gras_ddt_parse_text, &end, 10);
+
+ if (end == gras_ddt_parse_text || *end != '\0') {
+ /* Not a number. Get the constant value, if any */
+ int *storage=xbt_dict_get_or_null(gras_dd_constants,gras_ddt_parse_text);
+ if (storage) {
+ size = *storage;
+ } else {
+ PARSE_ERROR1("Unparsable size of array. Found '%s', expected number or known constant. Need to use gras_datadesc_set_const(), huh?",
+ gras_ddt_parse_text);
+ }
+ }
+
+ /* replace the previously pushed type to an array of it */
+ change_to_fixed_array(identifiers,size);
+
+ /* eat the closing bracket */
+ gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
+ if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RB)
+ PARSE_ERROR0("Unparsable size of array");
+ DEBUG1("Fixed size array, size=%ld",size);
+ continue;
+ } else {
+ PARSE_ERROR0("Unparsable size of array");
+ }
+ /* End of fixed size arrays handling */
+
+ } else if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
+ /* Handle annotation */
+ s_identifier_t array;
+ char *keyname = NULL;
+ char *keyval = NULL;
+ memset(&array,0,sizeof(array));
+ if (strcmp(gras_ddt_parse_text,"GRAS_ANNOTE"))
+ PARSE_ERROR1("Unparsable symbol: Expected 'GRAS_ANNOTE', got '%s'",gras_ddt_parse_text);
+
+ gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
+ if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_LP)
+ PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",gras_ddt_parse_text);
+
+ while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
+
+ if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
+ PARSE_ERROR1("Unparsable annotation: Expected key name, got '%s'",gras_ddt_parse_text);
+ keyname = (char*)strdup(gras_ddt_parse_text);
+
+ while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
+
+ if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_COLON)
+ PARSE_ERROR1("Unparsable annotation: expected ',' after the key name, got '%s'",gras_ddt_parse_text);
+
+ while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
+
+ /* get the value */
+
+ if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
+ PARSE_ERROR1("Unparsable annotation: Expected key value, got '%s'",gras_ddt_parse_text);
+ keyval = (char*)strdup(gras_ddt_parse_text);
+
+ while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump()) == GRAS_DDT_PARSE_TOKEN_EMPTY );
+
+ /* Done with parsing the annotation. Now deal with it by replacing previously pushed type with the right one */
+
+ DEBUG2("Anotation: %s=%s",keyname,keyval);
+ if (!strcmp(keyname,"size")) {
+ free(keyname);
+ if (!identifier.tm.is_ref)
+ PARSE_ERROR0("Size annotation for a field not being a reference");
+ identifier.tm.is_ref--;
+
+ if (!strcmp(keyval,"1")) {
+ change_to_ref(identifiers);
+ free(keyval);
+ } else {
+ char *p;
+ int fixed = 1;
+ for (p = keyval; *p != '\0'; p++)
+ if (! isdigit(*p) )
+ fixed = 0;
+ if (fixed) {
+ change_to_fixed_array(identifiers,atoi(keyval));
+ change_to_ref(identifiers);
+ free(keyval);
+
+ } else {
+ change_to_ref_pop_array(identifiers);
+ xbt_dynar_push(fields_to_push,&keyval);
+ }
+ }
+ } else if (!strcmp(keyname,"subtype")) {
+ gras_datadesc_type_t subtype = gras_datadesc_by_name(keyval);
+ if (identifier.tm.is_matrix) {
+ change_to_matrix_of(identifiers,subtype);
+ identifier.tm.is_matrix = -1;
+ } else if (identifier.tm.is_dynar) {
+ change_to_dynar_of(identifiers,subtype);
+ identifier.tm.is_dynar = -1;
+ } else {
+ PARSE_ERROR1("subtype annotation only accepted for dynars and matrices, but passed to '%s'",identifier.type_name);
+ }
+ free(keyval);
+ } else if (!strcmp(keyname,"free_f")) {
+ int *storage=xbt_dict_get_or_null(gras_dd_constants,keyval);
+ if (!storage)
+ PARSE_ERROR1("value for free_f annotation of field %s is not a known constant",identifier.name);
+ if (identifier.tm.is_matrix == -1) {
+ add_free_f(identifiers,*(void_f_pvoid_t*)storage);
+ identifier.tm.is_matrix = 0;
+ } else if (identifier.tm.is_dynar == -1) {
+ add_free_f(identifiers,*(void_f_pvoid_t*)storage);
+ identifier.tm.is_dynar = 0;
+ } else {
+ PARSE_ERROR1("free_f annotation only accepted for dynars and matrices which subtype is already declared (field %s)",
+ identifier.name);
+ }
+ free(keyval);
+ } else {
+ free(keyval);
+ PARSE_ERROR1("Unknown annotation type: '%s'",keyname);
+ }
+
+ /* Get all the multipliers */
+ while (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
+
+ gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
+
+ if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
+ PARSE_ERROR1("Unparsable annotation: Expected field name after '*', got '%s'",gras_ddt_parse_text);
+
+ keyval = xbt_malloc(strlen(gras_ddt_parse_text)+2);
+ sprintf(keyval,"*%s",gras_ddt_parse_text);
+
+ /* ask caller to push field as a multiplier */
+ xbt_dynar_push(fields_to_push,&keyval);
+
+ /* skip blanks after this block*/
+ while ( (gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump())
+ == GRAS_DDT_PARSE_TOKEN_EMPTY );
+ }
+
+ if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RP)
+ PARSE_ERROR1("Unparsable annotation: Expected parenthesis, got '%s'",
+ gras_ddt_parse_text);
+
+ continue;
+
+ /* End of annotation handling */
+ } else {
+ PARSE_ERROR1("Unparsable symbol: Got '%s' instead of expected comma (',')",gras_ddt_parse_text);
+ }
+ } else if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_COLON) {
+ PARSE_ERROR0("Unparsable symbol: Unexpected comma (',')");
+ }
+
+ if (gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_STAR) {
+ identifier.tm.is_ref++; /* We indeed deal with multiple references with multiple annotations */
+ continue;
+ }
+
+ /* found a symbol name. Build the type and push it to dynar */
+ if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_WORD) {
+
+ identifier.name=(char*)strdup(gras_ddt_parse_text);
+ DEBUG1("Found the identifier \"%s\"",identifier.name);
+
+ xbt_dynar_push(identifiers, &identifier);
+ DEBUG1("Dynar_len=%lu",xbt_dynar_length(identifiers));
+ expect_id_separator = 1;
+ continue;
+ }
+
+ PARSE_ERROR0("Unparasable symbol (maybe a def struct in a def struct or a parser bug ;)");
+ }
+
+ if (identifier.tm.is_matrix>0)
+ PARSE_ERROR0("xbt_matrix_t field without 'subtype' annotation");
+ if (identifier.tm.is_dynar>0)
+ PARSE_ERROR0("xbt_dynar_t field without 'subtype' annotation");
+
+ XBT_OUT;
+}
+
+static gras_datadesc_type_t parse_struct(char *definition) {