X-Git-Url: http://git.maemo.org/git/?p=scdataviz;a=blobdiff_plain;f=matdb-dotcode.c;h=df195fb887b17bb4c5542da58b7b0efb3330c39e;hp=85560e4f74f4532363708baa54ebec73d2d69c5d;hb=f3ddf2cd811f53afd0edaa3b1263035d9faab318;hpb=5f060a36bbc07e238a347d9b160bd4689cd11d7a diff --git a/matdb-dotcode.c b/matdb-dotcode.c index 85560e4..df195fb 100644 --- a/matdb-dotcode.c +++ b/matdb-dotcode.c @@ -3,26 +3,76 @@ - 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 . + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ #include +#define _GNU_SOURCE #include #include +#include + +#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.*/ @@ -32,30 +82,43 @@ static void prettify_line(char *line) { 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; } } - for(look=write=line, *look != '\0'; look++) { + *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'; + } } } } @@ -78,19 +141,22 @@ static void prettify_line(char *line) { *2048: warning reading file: unable to read numeric value for property. */ struct matdb* read_matdb_dotcode(const GString *name, int* err) { +#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_ptr_array_new()) == 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_ptr_array_new()) == NULL) { + if((mdb->bowings = g_hash_table_new_full(&g_str_hash, &g_str_equal, &destroy_string, &destroy_bowing_gpointer)) == NULL) { *err = 1; - g_ptr_array_free(mdb->materials, TRUE); + g_hash_table_unref(mdb->materials); free(mdb); return NULL; } @@ -101,27 +167,42 @@ struct matdb* read_matdb_dotcode(const GString *name, int* err) { * 1 (material) * 2 (bow) */ - section=0; + int section=0; + int 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 + 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(getline(&line, NULL, infile) == -1) { + 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 +#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; @@ -136,112 +217,130 @@ struct matdb* read_matdb_dotcode(const GString *name, int* err) { */ 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_ptr_array_add(mdb->materials, (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_ptr_array_add(mdb->bowings, (gpointer)bow); - 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(strncasecmp(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; - case: 2 - ht = bow->properties; - break; + case 1: + #ifdef DEBUG + fprintf(stderr, "(1)\t"); + #endif + ht = mat->properties; + break; + case 2: + #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)i, 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=value=i=to=NULL; + line=i=to=NULL; + value=NULL; } - fclose(file); + fclose(infile); + insert_into_matdb(mdb, &mat, &bow); return mdb; } -static void destroy_string(gpointer data) { - free((char*)data); -} -static void destroy_double(gpointer data){ - free((double*)data); -}