Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Kill malek's leftovers
[simgrid.git] / src / gras / DataDesc / ddt_parse.c
index df88228..e06a297 100644 (file)
@@ -19,15 +19,18 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_ddt_parse,gras_ddt,
   "Parsing C data structures to build GRAS data description");
 
 typedef struct s_type_modifier{
-  short is_unsigned;
-  short is_short;
   short is_long;
+  int is_unsigned:1;
+  int is_short:1;
 
-  short is_struct;
-  short is_union;
-  short is_enum;
+  int is_struct:1;
+  int is_union:1;
+  int is_enum:1;
 
-  short is_ref;
+  int is_ref:1;
+   
+  int is_dynar:2;
+  int is_matrix:2;
 } s_type_modifier_t,*type_modifier_t;
 
 typedef struct s_field {
@@ -163,6 +166,49 @@ static void change_to_ref_pop_array(xbt_dynar_t dynar) {
   XBT_OUT;
 }
 
+static void change_to_dynar_of(xbt_dynar_t dynar,gras_datadesc_type_t subtype) {
+  s_identifier_t former,ref;
+  memset(&ref,0,sizeof(ref));
+
+  XBT_IN;
+  xbt_dynar_pop(dynar,&former);
+  ref.type = gras_datadesc_dynar(subtype,NULL); /* redeclaration are ignored */
+  ref.type_name = (char*)strdup(ref.type->name);
+  ref.name = former.name;
+
+  free(former.type_name);
+
+  xbt_dynar_push(dynar,&ref);
+  XBT_OUT;
+}
+
+static void change_to_matrix_of(xbt_dynar_t dynar,gras_datadesc_type_t subtype) {
+  s_identifier_t former,ref;
+  memset(&ref,0,sizeof(ref));
+
+  XBT_IN;
+  xbt_dynar_pop(dynar,&former);
+  ref.type = gras_datadesc_matrix(subtype,NULL); /* redeclaration are ignored */
+  ref.type_name = (char*)strdup(ref.type->name);
+  ref.name = former.name;
+
+  free(former.type_name);
+
+  xbt_dynar_push(dynar,&ref);
+  XBT_OUT;
+}
+
+static void add_free_f(xbt_dynar_t dynar,void_f_pvoid_t* free_f) {
+  s_identifier_t former,ref;
+  memset(&ref,0,sizeof(ref));
+
+  XBT_IN;
+  xbt_dynar_pop(dynar,&former);
+  memcpy(former.type->extra,free_f, sizeof(free_f));
+  xbt_dynar_push(dynar,&former);
+  XBT_OUT;
+}
+
 static void parse_statement(char        *definition,
                            xbt_dynar_t  identifiers,
                            xbt_dynar_t  fields_to_push) {
@@ -203,7 +249,7 @@ static void parse_statement(char     *definition,
 
   /*  FIXME: This does not detect recursive definitions at all? */
   if (identifier.tm.is_union || identifier.tm.is_enum || identifier.tm.is_struct)
-    PARSE_ERROR0("Cannot handle recursive type definition yet");
+    PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle recursive type definition yet");
 
   /**** get the base type, giving "short a" the needed love ****/
   if (!identifier.tm.is_union &&
@@ -228,10 +274,10 @@ static void parse_statement(char   *definition,
 
   /**** build the base type for latter use ****/
   if (identifier.tm.is_union) {
-    PARSE_ERROR0("Cannot handle union yet (get callback from annotation?)");
+    PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle union yet (get callback from annotation?)");
 
   } else if (identifier.tm.is_enum) {
-    PARSE_ERROR0("Cannot handle enum yet");
+    PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle enum yet");
 
   } else if (identifier.tm.is_struct) {
     sprintf(buffname,"struct %s",identifier.type_name);
@@ -283,14 +329,23 @@ static void parse_statement(char   *definition,
 
     } else { 
       DEBUG1("Base type is a constructed one (%s)",identifier.type_name);
-      identifier.type = gras_datadesc_by_name(identifier.type_name);
-      if (!identifier.type)
-       PARSE_ERROR1("Unknown base type '%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 */
+     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;
@@ -309,7 +364,7 @@ static void parse_statement(char     *definition,
        /* 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("Cannot deal with [] constructs (yet)");
+         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;
@@ -402,7 +457,35 @@ static void parse_statement(char    *definition,
              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);
        }
 
@@ -459,6 +542,11 @@ static void parse_statement(char    *definition,
     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;
 }
 
@@ -577,7 +665,7 @@ static gras_datadesc_type_t parse_typedef(char *definition) {
   parse_type_modifier(&tm);
 
   if (tm.is_ref) 
-    PARSE_ERROR0("Cannot handle reference without annotation");
+    PARSE_ERROR0("GRAS_DEFINE_TYPE cannot handle reference without annotation");
 
   /* get the aliasing name */
   if (gras_ddt_parse_tok_num != GRAS_DDT_PARSE_TOKEN_WORD)
@@ -585,7 +673,7 @@ static gras_datadesc_type_t parse_typedef(char *definition) {
                 gras_ddt_parse_text);
   
   /* (FIXME: should) build the alias */
-  PARSE_ERROR0("Cannot handle typedef yet");
+  PARSE_ERROR0("Unimplemented feature: GRAS_DEFINE_TYPE cannot handle typedef yet");
 
   XBT_OUT;
   return typedef_desc;
@@ -660,5 +748,5 @@ void gras_datadesc_set_const(const char*name, int value) {
   int *stored = xbt_new(int, 1);
   *stored=value;
 
-  xbt_dict_set(gras_dd_constants,name, stored, free); 
+  xbt_dict_set(gras_dd_constants,name, stored, xbt_free_f); 
 }