- Copyright (C) 2008 Joseph Pingenot
+ Copyright (C) 2008 Joseph Pingenot
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <matdb-dotcode.h>
-#define _GNU_C
+#define _GNU_SOURCE
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
+#ifdef DEBUG
+#undef DEBUG
+#endif
+#ifdef DEBUG_2
+#undef DEBUG_2
+#endif
+
/*Functions to be used by the hash.*/
static void destroy_string(gpointer data) {
free((char*)data);
static void destroy_double(gpointer data){
free((double*)data);
}
+static void destroy_inner_bowhash(gpointer data) {
+ g_hash_table_unref(data);
+}
+
+int insert_into_matdb(struct matdb *mdb, struct matdb_material **mat, struct matdb_bowing **bow) {
+ if((*mat) != NULL) {
+#ifdef DEBUG
+ 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
+ fprintf(stderr, "inserting bowing %s:%s\n", (*bow)->from->str, (*bow)->to->str);
+#endif
+ /*Inner table*/
+ GHashTable *it;
+ if((it=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
+ 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;
+}
/*Removes leading and trailing whitespace, comments, and reduces
redundant whitespace down to one tab, makes an empty line an empty string.*/
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;
- case '#':
- *write='\0';
- 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') break;
- break;
- default:
- *write++ = *look;
+ if(*(look+1) == '\0') {
+ *look = '\0';
+ }
}
}
}
*2048: warning reading file: unable to read numeric value for property.
*/
struct matdb* read_matdb_dotcode(const GString *name, int* err) {
- #ifdef DEBUG
+#ifdef DEBUG_2
fprintf(stderr, "in read_matdb_dotcode(%s, %d)\n", name->str, *err);
- #endif
+#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) {
+ 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) {
+ 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);
* 2 (bow)
*/
int section=0;
+ int n;
char *line;
FILE *infile = fopen(name->str, "r");
if(infile == NULL) {
free(mdb);
*err=2;
return NULL;
- #ifdef DEBUG
+#ifdef DEBUG_2
}else{
fprintf(stderr, "infile=%x\n", (unsigned int)infile);
- #endif
+#endif
}
int val;
while(!feof(infile)) {
+#ifdef DEBUG
+ fprintf(stderr, "mat=%x(%s), bow=%x(%s:%s)\n", (unsigned int)mat, mat?mat->name->str:"", (unsigned int)bow, bow?bow->from->str:"", bow?bow->to->str:"");
+#endif
line=NULL;
- if((val = getline(&line, NULL, infile)) == -1) {
- #ifdef DEBUG
+ if((val = getline(&line, &n, infile)) == -1) {
+#ifdef DEBUG_2
fprintf(stderr, "getline returned %d\n", val);
- #endif
+#endif
if(!feof(infile)) *err = 4;
//fclose(infile);
break;
- }else{
- #ifdef DEBUG
- fprintf(stderr, "getline got line (%s)\n", line);
- #endif
}
- #ifdef DEBUG
+#ifdef DEBUG_2
fprintf(stderr, "line=(%s)\n", line);
- #endif
+#endif
prettify_line(line);
- #ifdef DEBUG
- fprintf(stderr, "prettified line=(%s)\n", line);
- #endif
+#ifdef DEBUG
+ fprintf(stderr, "%d: prettified line=(%s)\n", section, line);
+#endif
if(*line == '\0') {
free(line);
continue;
*/
char *to;
GHashTable *ht;
- #ifdef DEBUG
+#ifdef DEBUG_2
fprintf(stderr, "part_a=(%s) part_b=(%s)\n", line, i);
- #endif
- if(section == 0) {
- /*If we have a material or bowing underway, save it off*/
- if(mat != NULL) {
- g_hash_table_insert(mdb->materials, (gpointer)g_strdup(mat->name->str), (gpointer)mat);
- mat = NULL;
+#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(bow != NULL) {
- g_hash_table_insert(mdb->materials, (gpointer)g_strdup(bow->from->str), (gpointer)mat);
- bow = NULL;
+ if((mat->name = g_string_new(i)) == NULL) {
+ *err &= 32;
+ free(mat);
+ section=0;
+ continue;
}
- if(strcasecmp(line, "material") == 0) {
- 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);
- 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);
- continue;
- }
-#ifdef DEBUG
- fprintf(stderr, "new material (%s):\n", i);
-#endif
- }else if(strcasecmp(line, "bow") == 0) {
- if((bow = (struct matdb_bowing*)malloc(sizeof(struct matdb_bowing))) == NULL) {
- *err &= 128;
- }
- if((to = index(i, ':')) == NULL) {
- *err &= 1024;
- free(bow);
- 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);
- continue;
- }
- if((bow->to = g_string_new(to)) == NULL) {
- *err &= 128;
- g_string_free(bow->from, TRUE);
- free(bow);
- 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);
- continue;
- }
-#ifdef DEBUG
- fprintf(stderr, "new bowing (%s:%s):\n", i, to);
+ 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
- }else{
- *err &= 16;
- section = 0;
+ 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
+ fprintf(stderr, "\t%d/%s\t", section, line);
+ #endif
/*Process a property.*/
switch(section) {
case 1:
- ht = mat->properties;
- break;
+ #ifdef DEBUG
+ fprintf(stderr, "(1)\t");
+ #endif
+ ht = mat->properties;
+ break;
case 2:
- ht = bow->properties;
- break;
+ #ifdef DEBUG
+ fprintf(stderr, "(2)\t");
+ #endif
+ ht = bow->properties;
+ break;
default:
- *err &= 512;
+ #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;
}
- if(sscanf(" %g", i, value) != 1) {
+ 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, (gpointer)g_strdup(i), (gpointer)value);
- #ifdef DEBUG
- fprintf(stderr, "\t%d/%s\t%g(%s)\n", section, line, *value, i);
- #endif
+ g_hash_table_insert(ht, g_strdup(line), value);
+#ifdef DEBUG
+ 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;
}