Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
allow the size of multidimentional objects to be given thru annotations in parsing...
[simgrid.git] / src / gras / DataDesc / ddt_parse.c
index b2a42e7..341767e 100644 (file)
@@ -90,7 +90,6 @@ static void parse_type_modifier(type_modifier_t type_modifier)  {
   XBT_OUT;
 }
 
-static void print_type_modifier(s_type_modifier_t tm) __attribute__((unused));
 static void print_type_modifier(s_type_modifier_t tm) {
   int i;
 
@@ -164,9 +163,9 @@ static void change_to_ref_pop_array(xbt_dynar_t dynar) {
   XBT_OUT;
 }
 
-static xbt_error_t parse_statement(char         *definition,
-                                   xbt_dynar_t  identifiers,
-                                   xbt_dynar_t  fields_to_push) {
+static void parse_statement(char        *definition,
+                           xbt_dynar_t  identifiers,
+                           xbt_dynar_t  fields_to_push) {
   char buffname[512];
 
   s_identifier_t identifier;
@@ -179,7 +178,7 @@ static xbt_error_t parse_statement(char      *definition,
   gras_ddt_parse_tok_num = gras_ddt_parse_lex_n_dump();
   if(gras_ddt_parse_tok_num == GRAS_DDT_PARSE_TOKEN_RA) {
     XBT_OUT;
-    return old_mismatch_error; /* end of the englobing structure or union */
+    THROW0(mismatch_error,0,"End of the englobing structure or union");
   }
   
   if (XBT_LOG_ISENABLED(ddt_parse,xbt_log_priority_debug)) {
@@ -359,15 +358,14 @@ static xbt_error_t parse_statement(char    *definition,
 
        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 );
 
-       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);
@@ -380,7 +378,6 @@ static xbt_error_t parse_statement(char      *definition,
          if (!strcmp(keyval,"1")) {
            change_to_ref(identifiers);
            free(keyval);
-           continue;
          } else {
            char *p;
            int fixed = 1;
@@ -391,19 +388,39 @@ static xbt_error_t parse_statement(char    *definition,
              change_to_fixed_array(identifiers,atoi(keyval));
              change_to_ref(identifiers);
              free(keyval);
-             continue;
 
            } else {
              change_to_ref_pop_array(identifiers);
              xbt_dynar_push(fields_to_push,&keyval);
-             continue;
            }
          }
-         THROW_IMPOSSIBLE;
-
        } else {
          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 */
@@ -435,18 +452,19 @@ static xbt_error_t parse_statement(char    *definition,
   }
 
   XBT_OUT;
-  return no_error;
 }
 
 static gras_datadesc_type_t parse_struct(char *definition) {
 
-  xbt_error_t errcode;
+  xbt_ex_t e;
+
   char buffname[32];
   static int anonymous_struct=0;
 
   xbt_dynar_t identifiers;
   s_identifier_t field;
   int i;
+  int done;
 
   xbt_dynar_t fields_to_push;
   char *name;
@@ -473,9 +491,16 @@ static gras_datadesc_type_t parse_struct(char *definition) {
                 gras_ddt_parse_text);
 
   /* Parse the identifiers */
-  for (errcode=parse_statement(definition,identifiers,fields_to_push);
-       errcode == no_error                            ;
-       errcode=parse_statement(definition,identifiers,fields_to_push)) {
+  done = 0;
+  do {
+    TRY {
+      parse_statement(definition,identifiers,fields_to_push);
+    } CATCH(e) {
+      if (e.category != mismatch_error)
+       RETHROW;
+      xbt_ex_free(e);
+      done = 1;
+    }
     
     DEBUG1("This statement contained %lu identifiers",xbt_dynar_length(identifiers));
     /* append the identifiers we've found */
@@ -496,17 +521,20 @@ static gras_datadesc_type_t parse_struct(char *definition) {
     /* Make sure that all fields declaring a size push it into the cbps */
     xbt_dynar_foreach(fields_to_push,i, name) {
       DEBUG1("struct_type=%p",(void*)struct_type);
-      VERB2("Push field '%s' into size stack of %p", name, (void*)struct_type);
-      gras_datadesc_cb_field_push(struct_type, name);
+      if (name[0] == '*') {
+       VERB2("Push field '%s' as a multiplier into size stack of %p",
+             name+1, (void*)struct_type);
+       gras_datadesc_cb_field_push_multiplier(struct_type, name+1);
+      } else {
+       VERB2("Push field '%s' into size stack of %p",
+             name, (void*)struct_type);
+       gras_datadesc_cb_field_push(struct_type, name);
+      }
       free(name);
     }
     xbt_dynar_reset(fields_to_push);
-  }
+  } while (!done);
   gras_datadesc_struct_close(struct_type);
-  if (errcode != mismatch_error) {
-    XBT_OUT;
-    return NULL; /* FIXME: LEAK! */
-  }
 
   /* terminates */
   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_RA)