|
funkalicious 0.1
|
#include <stdio.h>#include <math.h>#include <strings.h>#include <stdlib.h>#include <glib-2.0/glib.h>#include "config.h"#include <libdotcode/matdb.h>#include <libdotcode/matdb-dotcode.h>
Include dependency graph for matdb-dotcode.c:Go to the source code of this file.
Defines | |
| #define | GERROR_DOMAIN_MATDB_DOTCODE 4096 |
Functions | |
| ssize_t | getline (char **lineptr, size_t *n, FILE *stream) |
| static void | destroy_string (gpointer data) |
| static void | destroy_double (gpointer data) |
| static void | destroy_inner_bowhash (gpointer data) |
| int | insert_into_matdb (struct matdb *mdb, struct matdb_material **mat, struct matdb_bowing **bow) |
| static void | prettify_line (char *line) |
| struct matdb * | read_matdb_dotcode (const GString *name, int *err) |
| struct matdb * | read_matdb_dotcode_gio (GFile *f, GError **error) |
| #define GERROR_DOMAIN_MATDB_DOTCODE 4096 |
Definition at line 29 of file matdb-dotcode.c.
Referenced by read_matdb_dotcode_gio().
| static void destroy_double | ( | gpointer | data | ) | [static] |
Definition at line 60 of file matdb-dotcode.c.
Referenced by read_matdb_dotcode(), and read_matdb_dotcode_gio().
{
free((double*)data);
}
Here is the caller graph for this function:| static void destroy_inner_bowhash | ( | gpointer | data | ) | [static] |
Definition at line 63 of file matdb-dotcode.c.
Referenced by insert_into_matdb().
{
g_hash_table_unref((GHashTable*)data);
}
Here is the caller graph for this function:| static void destroy_string | ( | gpointer | data | ) | [static] |
Definition at line 57 of file matdb-dotcode.c.
Referenced by insert_into_matdb(), read_matdb_dotcode(), and read_matdb_dotcode_gio().
{
free((char*)data);
}
Here is the caller graph for this function:| ssize_t getline | ( | char ** | lineptr, |
| size_t * | n, | ||
| FILE * | stream | ||
| ) |
Definition at line 33 of file matdb-dotcode.c.
References c.
Referenced by read_matdb_dotcode().
{
GString *s = g_string_new_len("", 4096);
int c;
long int i=0;
while(((c=fgetc(stream)) != '\n') && (c!=EOF) && ((n != NULL) || (i<*n))) {
if((*lineptr) == NULL) {
(*lineptr)[i] = c;
}else{
s = g_string_append_c(s, c);
}
i++;
}
if((*lineptr) == NULL) {
*lineptr = s->str;
g_string_free(s, FALSE);
}else{
g_string_free(s, TRUE);
}
return i;
}
Here is the caller graph for this function:| int insert_into_matdb | ( | struct matdb * | mdb, |
| struct matdb_material ** | mat, | ||
| struct matdb_bowing ** | bow | ||
| ) |
Definition at line 67 of file matdb-dotcode.c.
References matdb::bowings, destroy_inner_bowhash(), destroy_string(), and matdb::materials.
Referenced by read_matdb_dotcode(), and read_matdb_dotcode_gio().
{
if((*mat) != NULL) {
#ifdef DEBUG_2
fprintf(stderr, "inserting material %s\n", (*mat)->name->str);
#endif
g_hash_table_insert(mdb->materials, (gpointer)g_strdup((*mat)->name->str), (gpointer)(*mat));
(*mat) = NULL;
}
if((*bow) != NULL) {
#ifdef DEBUG_2
fprintf(stderr, "inserting bowing %s:%s\n", (*bow)->from->str, (*bow)->to->str);
#endif
/*Inner table*/
GHashTable *it;
if((it=(GHashTable*)g_hash_table_lookup(mdb->bowings, (*bow)->from->str)) == NULL) {
if((it = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_inner_bowhash)) == NULL) {
(*bow) = NULL;
return 1;
}
g_hash_table_insert(mdb->bowings, (*bow)->from->str, it);
#ifdef DEBUG_2
fprintf(stderr, "Got new hash table (from=%s)\n", (*bow)->from->str);
#endif
}
g_hash_table_insert(it, (gpointer)g_strdup((*bow)->to->str), (gpointer)(*bow));
(*bow) = NULL;
}
return 0;
}
Here is the call graph for this function:
Here is the caller graph for this function:| static void prettify_line | ( | char * | line | ) | [static] |
Definition at line 99 of file matdb-dotcode.c.
Referenced by read_matdb_dotcode(), and read_matdb_dotcode_gio().
{
register char *look;
register char *write;
register int in_whitespace;
register int leading_whitespace;
for(look=write=line, in_whitespace=0, leading_whitespace=1; *look != '\0'; look++) {
#ifdef DEBUG_2
fprintf(stderr, " look=%d(%c) write=%d(%c) in_whitespace=%d leading_whitespace=%d: ", (look-line), *look, (write-line), *write, in_whitespace, leading_whitespace);
#endif
if(*look == '#') {
#ifdef DEBUG_2
fprintf(stderr, "comment\n");
#endif
*write = '\0';
break;
}
switch(*look) {
case ' ':
case '\n':
case '\t':
#ifdef DEBUG_2
fprintf(stderr, "whitespace\n");
#endif
if((!leading_whitespace) && (!in_whitespace)) *write++ = '\t';
in_whitespace=1;
break;
default:
#ifdef DEBUG_2
fprintf(stderr, "default\n");
#endif
*write++ = *look;
in_whitespace=leading_whitespace=0;
}
}
*write='\0';
for(look=write=line; *look != '\0'; look++) {
switch(*look) {
case ' ':
case '\n':
case '\t':
if(*(look+1) == '\0') {
*look = '\0';
}
}
}
}
Here is the caller graph for this function:| 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: