Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Catch up with the lastest API breakage
[simgrid.git] / src / gras / DataDesc / ddt_parse.c
index c034d63..193c6f1 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <ctype.h> /* isdigit */
 
+#include "xbt/ex.h"
 #include "gras/DataDesc/datadesc_private.h"
 #include "gras/DataDesc/ddt_parse.yy.h"
 
@@ -111,10 +112,15 @@ static void change_to_fixed_array(xbt_dynar_t dynar, long int size) {
 
   XBT_IN;
   xbt_dynar_pop(dynar,&former);
-  array.type_name=(char*)xbt_malloc(strlen(former.type->name)+20);
+  array.type_name=(char*)xbt_malloc(strlen(former.type->name)+48);
   DEBUG2("Array specification (size=%ld, elm='%s'), change pushed type",
         size,former.type_name);
-  sprintf(array.type_name,"%s[%ld]",former.type_name,size);
+  sprintf(array.type_name,"%s%s%s%s[%ld]",
+         (former.tm.is_unsigned?"u ":""),
+         (former.tm.is_short?"s ":""),
+         (former.tm.is_long?"l ":""),
+         former.type_name,
+         size);
   free(former.type_name);
 
   array.type = gras_datadesc_array_fixed(array.type_name, former.type, size); /* redeclaration are ignored */
@@ -157,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;
@@ -172,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 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)) {
@@ -247,7 +253,7 @@ static xbt_error_t parse_statement(char      *definition,
       identifier.type = gras_datadesc_by_name("unsigned char");
 
     } else { /* impossible, gcc parses this shit before us */
-      RAISE_IMPOSSIBLE;
+      THROW_IMPOSSIBLE;
     }
     
   } else if (!strcmp(identifier.type_name, "float")) {
@@ -352,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);
@@ -373,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;
@@ -384,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;
            }
          }
-         RAISE_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 */
@@ -428,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;
@@ -466,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 */
@@ -489,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)
@@ -610,5 +645,3 @@ gras_datadesc_parse(const char            *name,
   XBT_OUT;
   return res;
 }
-
-