funkalicious 0.1

matdb-dotcode.h File Reference

#include <glib-2.0/glib.h>
#include <gio/gio.h>
#include <libdotcode/matdb.h>
Include dependency graph for matdb-dotcode.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

struct matdbread_matdb_dotcode (const GString *name, int *err)
struct matdbread_matdb_dotcode_gio (GFile *f, GError **error)

Function Documentation

struct matdb* read_matdb_dotcode ( const GString *  name,
int *  err 
) [read]

Definition at line 163 of file matdb-dotcode.c.

References matdb::bowings, destroy_bowing_gpointer(), destroy_double(), destroy_material_gpointer(), destroy_string(), matdb_bowing::from, getline(), insert_into_matdb(), matdb::materials, matdb_material::name, prettify_line(), and matdb_bowing::to.

                                                                {
#ifdef DEBUG_2
  fprintf(stderr, "in read_matdb_dotcode(%s, %d)\n", name->str, *err);
#endif
  *err=0;
  struct matdb *mdb = (struct matdb*)malloc(sizeof(struct matdb));
  if(mdb == NULL) {*err = 1; return NULL;}

  double *value;
  if((mdb->materials = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_material_gpointer)) == NULL) {
    *err = 1;
    free(mdb);
    return NULL;
  }
  if((mdb->bowings = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_bowing_gpointer)) == NULL) {
    *err = 1;
    g_hash_table_unref(mdb->materials);
    free(mdb);
    return NULL;
  }
  struct matdb_material *mat = NULL;
  struct matdb_bowing *bow = NULL;
  /*Valid sections:
   * 0 (no/global section)
   * 1 (material)
   * 2 (bow)
   */
  int section=0;
  size_t n;
  char *line;
  FILE *infile = fopen(name->str, "r");
  if(infile == NULL) {
    g_hash_table_unref(mdb->materials);
    g_hash_table_unref(mdb->bowings);
    free(mdb);
    *err=2;
    return NULL;
#ifdef DEBUG_2
  }else{
    fprintf(stderr, "infile=%x\n", (unsigned int)infile);
#endif
  }
  int val;
  while(!feof(infile)) {
#ifdef DEBUG_2
    fprintf(stderr, "mat=%p(%s), bow=%p(%s:%s)\n", (void*)mat, mat?mat->name->str:"", (void*)bow, bow?bow->from->str:"", bow?bow->to->str:"");
#endif
    line=NULL;
    if((val = getline(&line, &n, infile)) == -1) {
#ifdef DEBUG_2
      fprintf(stderr, "getline returned %d\n", val);
#endif
      if(!feof(infile)) *err = 4;
      //fclose(infile);
      break;
    }
#ifdef DEBUG_2
    fprintf(stderr, "line=(%s)\n", line);
#endif
    prettify_line(line);
#ifdef DEBUG_2
    fprintf(stderr, "%d: prettified line=(%s)\n", section, line);
#endif
    if(*line == '\0') {
      free(line);
      continue;
    }
    char *i = index(line, '\t');
    if(i == NULL) {
      *err &= 8;
    }
    *i++ = '\0';
    /*At this point, we have line which stores the first word on the
      line, and i which stores the second word on the line.
    */
    char *to;
    GHashTable *ht;
#ifdef DEBUG_2
    fprintf(stderr, "part_a=(%s) part_b=(%s)\n", line, i);
#endif
    /*If we have a material or bowing underway, save it off*/
    if(strcasecmp(line, "material") == 0) {
      insert_into_matdb(mdb, &mat, &bow);
      if((mat = (struct matdb_material*)malloc(sizeof(struct matdb_material))) == NULL) {
  *err &= 32;
      }
      if((mat->name = g_string_new(i)) == NULL) {
  *err &= 32;
  free(mat);
  section=0;
  continue;
      }
      if((mat->properties = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_double)) == NULL) {
  *err &= 32;
  g_string_free(mat->name, TRUE);
  free(bow);
  section=0;
  continue;
      }
#ifdef DEBUG_2
      fprintf(stderr, "new material (%s):\n", i);
#endif
      section=1;
    }else if(strcasecmp(line, "bow") == 0) {
      insert_into_matdb(mdb, &mat, &bow);
      if((bow = (struct matdb_bowing*)malloc(sizeof(struct matdb_bowing))) == NULL) {
  *err &= 128;
      }
      if((to = index(i, ':')) == NULL) {
  *err &= 1024;
  free(bow);
  section=0;
  continue;
      }
      *to++ = '\0';
      /*Same trick as before, but i now stores the from material,
  and to the to material
      */
      if((bow->from = g_string_new(i)) == NULL) {
  *err &= 128;
  free(bow);
  section=0;
  continue;
      }
      if((bow->to = g_string_new(to)) == NULL) {
  *err &= 128;
  g_string_free(bow->from, TRUE);
  free(bow);
  section=0;
  continue;
      }
      if((bow->properties = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_double)) == NULL) {
  *err &= 128;
  g_string_free(bow->to, TRUE);
  g_string_free(bow->from, TRUE);
  free(bow);
  section=0;
  continue;
      }
#ifdef DEBUG_2
      fprintf(stderr, "new bowing (%s:%s):\n", i, to);
#endif
      section=2;
    }else{
#ifdef DEBUG_2
      fprintf(stderr, "\t%d/%s\t", section, line);
#endif
      /*Process a property.*/
      switch(section) {
      case 1:
#ifdef DEBUG_2
  fprintf(stderr, "(1)\t");
#endif
  ht = mat->properties;
  break;
      case 2:
#ifdef DEBUG_2
  fprintf(stderr, "(2)\t");
#endif
  ht = bow->properties;
  break;
      default:
#ifdef DEBUG
  fprintf(stderr, "(default)\t");
#endif
  *err &= 16;
  section = 0;
      }
      if(section == 0) {
#ifdef DEBUG
  fprintf(stderr, "section was 0\n");
#endif
  continue;
      }
      if((value = (double*)malloc(sizeof(double))) == NULL) {
  *err &= 2048;
#ifdef DEBUG
  fprintf(stderr, "malloc of value failed\n");
#endif
  continue;
      }
      int num;
      if((num=sscanf(i, " %lg", value)) != 1) {
  *err &= 2048;
  free(value);
#ifdef DEBUG
  fprintf(stderr, "bad sscanf to get value (scanned \"%s\", returned %d)\n", i, num);
#endif
  continue;
      }
      g_hash_table_insert(ht, g_strdup(line), value);
#ifdef DEBUG_2
      fprintf(stderr, "%g(%s)\n", *value, line);
#endif
    }
    free(line);
    line=i=to=NULL;
    value=NULL;
  }
  fclose(infile);
  insert_into_matdb(mdb, &mat, &bow);
  return mdb;
}

Here is the call graph for this function:

struct matdb* read_matdb_dotcode_gio ( GFile *  f,
GError **  error 
) [read]

Definition at line 367 of file matdb-dotcode.c.

References matdb::bowings, destroy_bowing_gpointer(), destroy_double(), destroy_material_gpointer(), destroy_string(), e, matdb_bowing::from, GERROR_DOMAIN_MATDB_DOTCODE, insert_into_matdb(), matdb::materials, matdb_material::name, prettify_line(), str, and matdb_bowing::to.

Referenced by dotcode_displ_get_matdb(), and main().

                                                               {
  char* str;
#ifdef DEBUG_2
  fprintf(stderr, "in read_matdb_dotcode_gio(%s, %p)\n", str=g_file_get_uri(f), (void*)error);
  g_free(str);
#endif
  GError *e = NULL;
  struct matdb *mdb = (struct matdb*)malloc(sizeof(struct matdb));
  if(mdb == NULL) {
    *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 1, "ERROR: failed to allocate memory for matdb structure.");
    return NULL;
  }

  double *value;
  if((mdb->materials = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_material_gpointer)) == NULL) {
    *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 1, "ERROR: failed to allocate memory for matdb->materials hash table.");
    free(mdb);
    return NULL;
  }
  if((mdb->bowings = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_bowing_gpointer)) == NULL) {
    *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 1, "ERROR: failed to allocate memory for matdb->bowings hash table.");
    g_hash_table_unref(mdb->materials);
    free(mdb);
    return NULL;
  }
  struct matdb_material *mat = NULL;
  struct matdb_bowing *bow = NULL;
  /*Valid sections:
   * 0 (no/global section)
   * 1 (material)
   * 2 (bow)
   */
  int section=0;
  char *line;
  GFileInputStream *fis = g_file_read(f, NULL, &e);
  if((fis == NULL) || (e != NULL)) {
    g_propagate_prefixed_error(error, e, "Failed to open file (%s) for reading.", str=g_file_get_uri(f));
    g_free(str);
    g_hash_table_unref(mdb->bowings);
    g_hash_table_unref(mdb->materials);
    free(mdb);
    return NULL;
  }
  GDataInputStream *dis = g_data_input_stream_new((GInputStream*)fis);
  gsize amt_read = 1;
  /*Exit condition is line is NULL*/
  while(1) {
#ifdef DEBUG_2
    fprintf(stderr, "mat=%p(%s), bow=%p(%s:%s)\n", (void*)mat, mat?mat->name->str:"", (void*)bow, bow?bow->from->str:"", bow?bow->to->str:"");
#endif
    e=NULL;
    line = g_data_input_stream_read_line(dis, &amt_read, NULL, &e);
    if(e != NULL){
#ifdef DEBUG_2
      fprintf(stderr, "Error: getline returned %d chars\n", amt_read);
#endif
      g_propagate_prefixed_error(error, e, "Failed to read a line from file (%s)", str=g_file_get_uri(f));
      g_free(str);
      g_hash_table_unref(mdb->bowings);
      g_hash_table_unref(mdb->materials);
      free(mdb);
      return NULL;
    }
    if(line == NULL) break;
    if(amt_read == 0) {
#ifdef DEBUG
      fprintf(stderr, "read zero chars in that call; line=%s", line);
#endif
      continue;
    }
#ifdef DEBUG_2
    fprintf(stderr, "line=(%s)\n", line);
#endif
    prettify_line(line);
#ifdef DEBUG_2
    fprintf(stderr, "%d: prettified line=(%s)\n", section, line);
#endif
    if(*line == '\0') {
      free(line);
      continue;
    }
    char *i = index(line, '\t');
    if(i == NULL) {
      *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 8, "There was no tab on the line (line was \"%s\")", line);
      g_hash_table_unref(mdb->bowings);
      g_hash_table_unref(mdb->materials);
      free(mdb);
      return NULL;
    }
    *i++ = '\0';
    /*At this point, we have line which stores the first word on the
      line, and i which stores the second word on the line.
    */
    char *to;
    GHashTable *ht;
#ifdef DEBUG_2
    fprintf(stderr, "part_a=(%s) part_b=(%s)\n", line, i);
#endif
    /*If we have a material or bowing underway, save it off*/
    if(strcasecmp(line, "material") == 0) {
      insert_into_matdb(mdb, &mat, &bow);
      if((mat = (struct matdb_material*)malloc(sizeof(struct matdb_material))) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 32, "Failed to allocate memory for a new matdb material");
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
      if((mat->name = g_string_new(i)) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 32, "Failed to allocate string for material name");
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
      if((mat->properties = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_double)) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 32, "Failed to allocate new properties hash for material %s", i);
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
#ifdef DEBUG_2
      fprintf(stderr, "new material (%s):\n", i);
#endif
      section=1;
    }else if(strcasecmp(line, "bow") == 0) {
      insert_into_matdb(mdb, &mat, &bow);
      if((bow = (struct matdb_bowing*)malloc(sizeof(struct matdb_bowing))) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 32, "Failed to allocate new bowing");
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
      if((to = index(i, ':')) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 1024, "Failed to allocate new bowing");
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
      *to++ = '\0';
      /*Same trick as before, but i now stores the from material,
  and to the to material
      */
      if((bow->from = g_string_new(i)) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 128, "Failed to allocate new string (for \"%s\")", i);
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
      if((bow->to = g_string_new(to)) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 128, "Failed to allocate new string (for \"%s\")", to);
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
      if((bow->properties = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_double)) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 128, "Failed to allocate new bowing hash table for properties for material %s,%s", bow->from->str, bow->to->str);
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
#ifdef DEBUG_2
      fprintf(stderr, "new bowing (%s:%s):\n", i, to);
#endif
      section=2;
    }else{
#ifdef DEBUG_2
      fprintf(stderr, "\t%d/%s\t", section, line);
#endif
      /*Process a property.*/
      switch(section) {
      case 1:
#ifdef DEBUG_2
  fprintf(stderr, "(1)\t");
#endif
  ht = mat->properties;
  break;
      case 2:
#ifdef DEBUG_2
  fprintf(stderr, "(2)\t");
#endif
  ht = bow->properties;
  break;
      default:
#ifdef DEBUG
  fprintf(stderr, "(default)\t");
#endif
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 16, "Invalid section index (%d)\n", section);
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
      }
      if(section == 0) {
#ifdef DEBUG_2
  fprintf(stderr, "section was 0\n");
#endif
  continue;
      }
      if((value = (double*)malloc(sizeof(double))) == NULL) {
  *error = g_error_new(GERROR_DOMAIN_MATDB_DOTCODE, 2048, "Malloc of value failed");
  g_hash_table_unref(mdb->bowings);
  g_hash_table_unref(mdb->materials);
  free(mdb);
  return NULL;
#ifdef DEBUG
  fprintf(stderr, "malloc of value failed\n");
#endif
  continue;
      }
      int num;
      if((num=sscanf(i, " %lg", value)) != 1) {
  /*Invalid values are used to insert NaNs*/
  num=nan("NaN");
#ifdef DEBUG
  fprintf(stderr, "bad sscanf to get value (scanned \"%s\", returned %d; using NaN)\n", i, num);
#endif
      }
      g_hash_table_insert(ht, g_strdup(line), value);
#ifdef DEBUG_2
      fprintf(stderr, "%g(%s)\n", *value, line);
#endif
    }
    free(line);
    line=i=to=NULL;
    value=NULL;
  }
#ifdef DEBUG_2
  fprintf(stderr, "amt_read=%lu", (long unsigned int)amt_read);
#endif
  g_input_stream_close((GInputStream*)fis, NULL, &e);
  if(e != NULL) {
    g_propagate_prefixed_error(error, e, "Error closing file (%s):", str=g_file_get_uri(f));
    g_free(str);
  }
  insert_into_matdb(mdb, &mat, &bow);
  return mdb;
}

Here is the call graph for this function:

Here is the caller graph for this function:

 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines