2 * matdb-dotcode: reads in Craig's Dotcode materials database.
6 Copyright (C) 2008 Joseph Pingenot
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Affero General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <matdb-dotcode.h>
27 /*Removes leading and trailing whitespace, comments, and reduces
28 redundant whitespace down to one tab, makes an empty line an empty string.*/
29 static void prettify_line(char *line) {
32 register int in_whitespace;
33 register int leading_whitespace;
34 for(look=write=line, in_whitespace=0, leading_whitespace=1; *look != '\0'; look++) {
39 if((!leading_whitespace) && (!in_whitespace)) *write++ = '\t';
47 in_whitespace=leading_whitespace=0;
50 for(look=write=line, *look != '\0'; look++) {
55 if(*(look+1) == '\0') break;
65 * 1: failure malloc'ing / initializing mdb struct
66 * 2: failure opening file.
67 * 4: failure reading line.
68 * 8: warning reading line: no tab separator (line parsing error)
69 * 16: warning reading line: bad section declaration
70 * 32: warning reading line: unable to allocate material struct.
71 * 64: warning reading line: ignored line (unallocated material struct)
72 * 128: warning reading line: unable to allocate bowing struct
73 * 256: warning reading line: ignored line (unallocated bowing struct)
74 * 512: warning reading file: improper section detected (programming
76 *1024: warning reading file: no : separator in bowing materials
78 *2048: warning reading file: unable to read numeric value for property.
80 struct matdb* read_matdb_dotcode(const GString *name, int* err) {
82 struct matdb *mdb = (struct matdb*)malloc(sizeof(struct matdb));
83 if(mdb == NULL) {*err = 1; return NULL;}
86 if((mdb->materials = g_ptr_array_new()) == NULL) {
91 if((mdb->bowings = g_ptr_array_new()) == NULL) {
93 g_ptr_array_free(mdb->materials, TRUE);
97 struct matdb_material *mat = NULL;
98 struct matdb_bowing *bow = NULL;
100 * 0 (no/global section)
106 FILE *infile = fopen(name->str, "r");
112 while(!feof(infile)) {
114 if(getline(&line, NULL, infile) == -1) {
115 if(!feof(infile)) *err = 4;
119 fprintf(stderr, "line=(%s)\n", line);
123 fprintf(stderr, "prettified line=(%s)\n", line);
129 char *i = index(line, '\t');
134 /*At this point, we have line which stores the first word on the
135 line, and i which stores the second word on the line.
140 fprintf(stderr, "part_a=(%s) part_b=(%s)\n", line, i);
143 /*If we have a material or bowing underway, save it off*/
145 g_ptr_array_add(mdb->materials, (gpointer)mat);
149 g_ptr_array_add(mdb->bowings, (gpointer)bow);
152 if(strcasecmp(line, "material") == 0) {
153 if((mat = (struct *matdb_material)malloc(sizeof(struct matdb_material))) == NULL) {
156 if((mat->name = g_string_new(i)) == NULL) {
161 if((mat->properties = g_hash_table_new_full(g_str_hash, g_str_equal, &destroy_string, &destroy_double)) == NULL) {
163 g_string_free(mat->name, TRUE);
168 fprintf(stderr, "new material (%s):\n", i);
170 }else if(strncasecmp(line, "bow") == 0) {
171 if((bow = (struct *matdb_bowing)malloc(sizeof(struct matdb_bowing))) == NULL) {
174 if((to = index(i, ':')) == NULL) {
180 /*Same trick as before, but i now stores the from material,
181 and to the to material
183 if((bow->from = g_string_new(i)) == NULL) {
188 if((bow->to = g_string_new(to)) == NULL) {
190 g_string_free(bow->from, TRUE);
194 if((bow->properties = g_hash_table_new_full(g_str_hash, g_str_equal, &destroy_string, &destroy_double)) == NULL) {
196 g_string_free(bow->to, TRUE);
197 g_string_free(bow->from, TRUE);
202 fprintf(stderr, "new bowing (%s:%s):\n", i, to);
209 /*Process a property.*/
212 ht = mat->properties;
215 ht = bow->properties;
222 if((value = (double*)malloc(sizeof(double))) == NULL) {
226 if(sscanf(" %g", i, value) != 1) {
230 g_hash_table_insert(ht, (gpointer)i, value);
232 fprintf(stderr, "\t%d/%s\t%g(%s)\n", section, line, value, i);
236 line=value=i=to=NULL;
242 static void destroy_string(gpointer data) {
245 static void destroy_double(gpointer data){