|
funkalicious 0.1
|
#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 matdb * | read_matdb_dotcode (const GString *name, int *err) |
| struct matdb * | read_matdb_dotcode_gio (GFile *f, GError **error) |
| 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: