comparison src/xs_stil.c @ 392:b09d74eb71e6

Working on getting STIL and SLDB using completely dynamically allocated structures. Indentation cleanups, etc.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 31 May 2006 10:02:00 +0000
parents 4611f1194941
children b571000e1f8c
comparison
equal deleted inserted replaced
391:3cc7455360ad 392:b09d74eb71e6
24 #include "xs_support.h" 24 #include "xs_support.h"
25 #include "xs_config.h" 25 #include "xs_config.h"
26 #include <stdio.h> 26 #include <stdio.h>
27 #include <stdlib.h> 27 #include <stdlib.h>
28 #include <ctype.h> 28 #include <ctype.h>
29 #include <stdarg.h>
29 30
30 31
31 /* Database handling functions 32 /* Database handling functions
32 */ 33 */
33 static t_xs_stil_node *xs_stildb_node_new(gchar * pcFilename) 34 static gboolean xs_stildb_node_realloc(t_xs_stil_node *pNode, gint nsubTunes)
35 {
36 if (!pNode) return FALSE;
37
38 /* Re-allocate subTune structure if needed */
39 if (nsubTunes >= pNode->nsubTunes) {
40 pNode->subTunes =
41 (t_xs_stil_subnode **) g_realloc(pNode->subTunes,
42 (nsubTunes + 1) * sizeof(t_xs_stil_subnode **));
43
44 if (!pNode->subTunes)
45 return FALSE;
46
47 /* Clear the newly allocated memory */
48 memset(&(pNode->subTunes[pNode->nsubTunes]), 0,
49 (nsubTunes + 1 - pNode->nsubTunes) *
50 sizeof(t_xs_stil_subnode **));
51 }
52
53 /* Allocate memory for subTune */
54 if (!pNode->subTunes[nsubTunes]) {
55 pNode->subTunes[nsubTunes] = (t_xs_stil_subnode *)
56 g_malloc0(sizeof(t_xs_stil_subnode));
57
58 if (!pNode->subTunes[nsubTunes])
59 return FALSE;
60 }
61
62 return TRUE;
63 }
64
65
66 static void xs_stildb_node_free(t_xs_stil_node *pNode)
67 {
68 gint i;
69 t_xs_stil_subnode *pSub;
70
71 if (pNode) {
72 /* Free subtune information */
73 for (i = 0; i < pNode->nsubTunes; i++) {
74 pSub = pNode->subTunes[i];
75 if (pSub) {
76 g_free(pSub->pName);
77 g_free(pSub->pAuthor);
78 g_free(pSub->pInfo);
79
80 g_free(pSub);
81 }
82 }
83
84 g_free(pNode->subTunes);
85 g_free(pNode->pcFilename);
86 g_free(pNode);
87 }
88 }
89
90
91 static t_xs_stil_node *xs_stildb_node_new(gchar *pcFilename)
34 { 92 {
35 t_xs_stil_node *pResult; 93 t_xs_stil_node *pResult;
36 94
37 /* Allocate memory for new node */ 95 /* Allocate memory for new node */
38 pResult = (t_xs_stil_node *) g_malloc0(sizeof(t_xs_stil_node)); 96 pResult = (t_xs_stil_node *) g_malloc0(sizeof(t_xs_stil_node));
39 if (!pResult) 97 if (!pResult)
40 return NULL; 98 return NULL;
41 99
100 /* Allocate filename and initial space for one subtune */
42 pResult->pcFilename = g_strdup(pcFilename); 101 pResult->pcFilename = g_strdup(pcFilename);
43 if (!pResult->pcFilename) { 102 if (!pResult->pcFilename || !xs_stildb_node_realloc(pResult, 1)) {
44 g_free(pResult); 103 xs_stildb_node_free(pResult);
45 return NULL; 104 return NULL;
46 } 105 }
47 106
48 return pResult; 107 return pResult;
49 } 108 }
50 109
51 110
52 static void xs_stildb_node_free(t_xs_stil_node * pNode)
53 {
54 gint i;
55
56 if (pNode) {
57 /* Free subtune information */
58 for (i = 0; i <= XS_STIL_MAXENTRY; i++) {
59 g_free(pNode->subTunes[i].pName);
60 g_free(pNode->subTunes[i].pAuthor);
61 g_free(pNode->subTunes[i].pInfo);
62 }
63
64 g_free(pNode->pcFilename);
65 g_free(pNode);
66 }
67 }
68
69
70 /* Insert given node to db linked list 111 /* Insert given node to db linked list
71 */ 112 */
72 static void xs_stildb_node_insert(t_xs_stildb * db, t_xs_stil_node * pNode) 113 static void xs_stildb_node_insert(t_xs_stildb *db, t_xs_stil_node *pNode)
73 { 114 {
74 assert(db); 115 assert(db);
75 116
76 if (db->pNodes) { 117 if (db->pNodes) {
77 /* The first node's pPrev points to last node */ 118 /* The first node's pPrev points to last node */
87 } 128 }
88 129
89 130
90 /* Read database (additively) to given db-structure 131 /* Read database (additively) to given db-structure
91 */ 132 */
92 #define XS_STILDB_MULTI if (isMulti) { isMulti = FALSE; xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), "\n"); } 133 #define XS_STILDB_MULTI \
93 134 if (isMulti) { \
94 135 isMulti = FALSE; \
95 gint xs_stildb_read(t_xs_stildb * db, gchar * dbFilename) 136 xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), "\n");\
137 }
138
139 void XS_STILDB_ERR(gint lineNum, gchar *inLine, const char *fmt, ...)
140 {
141 va_list ap;
142
143 va_start(ap, fmt);
144 xs_error(fmt, ap);
145 va_end(ap);
146
147 fprintf(stderr, "#%d: '%s'\n", lineNum, inLine);
148 }
149
150 gint xs_stildb_read(t_xs_stildb *db, gchar *dbFilename)
96 { 151 {
97 FILE *inFile; 152 FILE *inFile;
98 gchar inLine[XS_BUF_SIZE + 16]; /* Since we add some chars here and there */ 153 gchar inLine[XS_BUF_SIZE + 16]; /* Since we add some chars here and there */
99 guint lineNum, linePos, eolPos; 154 guint lineNum, linePos, eolPos;
100 t_xs_stil_node *tmpNode; 155 t_xs_stil_node *tmpNode;
102 gint subEntry; 157 gint subEntry;
103 assert(db); 158 assert(db);
104 159
105 /* Try to open the file */ 160 /* Try to open the file */
106 if ((inFile = fopen(dbFilename, "ra")) == NULL) { 161 if ((inFile = fopen(dbFilename, "ra")) == NULL) {
107 XSERR("Could not open STILDB '%s'\n", dbFilename); 162 xs_error("Could not open STILDB '%s'\n", dbFilename);
108 return -1; 163 return -1;
109 } 164 }
110 165
111 /* Read and parse the data */ 166 /* Read and parse the data */
112 lineNum = 0; 167 lineNum = 0;
126 switch (inLine[0]) { 181 switch (inLine[0]) {
127 case '/': 182 case '/':
128 /* Check if we are already parsing entry */ 183 /* Check if we are already parsing entry */
129 isMulti = FALSE; 184 isMulti = FALSE;
130 if (tmpNode) { 185 if (tmpNode) {
131 XSERR("New entry ('%s') before end of current ('%s')! Possibly malformed STIL-file!\n", 186 XS_STILDB_ERR(lineNum, inLine,
132 inLine, tmpNode->pcFilename); 187 "New entry found before end of current ('%s')!\n",
133 188 tmpNode->pcFilename);
134 xs_stildb_node_free(tmpNode); 189 xs_stildb_node_free(tmpNode);
135 } 190 }
136 191
137 /* A new node */ 192 /* A new node */
138 subEntry = 0; 193 subEntry = 0;
139 tmpNode = xs_stildb_node_new(inLine); 194 tmpNode = xs_stildb_node_new(inLine);
140 if (!tmpNode) { 195 if (!tmpNode) {
141 /* Allocation failed */ 196 /* Allocation failed */
142 XSERR("Could not allocate new STILdb-node for '%s'!\n", inLine); 197 XS_STILDB_ERR(lineNum, inLine,
198 "Could not allocate new STILdb-node!\n");
143 isError = TRUE; 199 isError = TRUE;
144 } 200 }
145 break; 201 break;
146 202
147 case '(': 203 case '(':
154 xs_findnum(inLine, &linePos); 210 xs_findnum(inLine, &linePos);
155 inLine[linePos] = 0; 211 inLine[linePos] = 0;
156 subEntry = atol(&inLine[2]); 212 subEntry = atol(&inLine[2]);
157 213
158 /* Sanity check */ 214 /* Sanity check */
159 if ((subEntry < 1) || (subEntry > XS_STIL_MAXENTRY)) { 215 if (subEntry < 1) {
160 XSERR("Number of subEntry (%i) for '%s' is invalid\n", subEntry, 216 XS_STILDB_ERR(lineNum, inLine,
161 tmpNode->pcFilename); 217 "Number of subEntry (%i) for '%s' is invalid\n",
218 subEntry, tmpNode->pcFilename);
162 subEntry = 0; 219 subEntry = 0;
163 } 220 }
164 } 221 }
222 } else {
223 XS_STILDB_ERR(lineNum, inLine,
224 "Syntax error, expected subEntry number.\n");
165 } 225 }
166 226
167 break; 227 break;
168 228
169 case 0: 229 case 0:
180 break; 240 break;
181 241
182 default: 242 default:
183 /* Check if we are parsing an entry */ 243 /* Check if we are parsing an entry */
184 if (!tmpNode) { 244 if (!tmpNode) {
185 XSERR("Entry data encountered outside of entry!\n"); 245 XS_STILDB_ERR(lineNum, inLine,
246 "Entry data encountered outside of entry or syntax error!\n");
186 break; 247 break;
187 } 248 }
188 249
250 if (xs_stildb_node_realloc(tmpNode, subEntry)) {
251 XS_STILDB_ERR(lineNum, inLine,
252 "Could not (re)allocate memory for subEntries!\n");
253 isError = TRUE;
254 break;
255 }
256
189 /* Some other type */ 257 /* Some other type */
190 if (strncmp(inLine, " NAME:", 8) == 0) { 258 if (strncmp(inLine, " NAME:", 8) == 0) {
191 XS_STILDB_MULTI g_free(tmpNode->subTunes[subEntry].pName); 259 XS_STILDB_MULTI;
192 tmpNode->subTunes[subEntry].pName = g_strdup(&inLine[9]); 260 g_free(tmpNode->subTunes[subEntry]->pName);
261 tmpNode->subTunes[subEntry]->pName = g_strdup(&inLine[9]);
193 } else if (strncmp(inLine, " AUTHOR:", 8) == 0) { 262 } else if (strncmp(inLine, " AUTHOR:", 8) == 0) {
194 XS_STILDB_MULTI g_free(tmpNode->subTunes[subEntry].pAuthor); 263 XS_STILDB_MULTI;
195 tmpNode->subTunes[subEntry].pAuthor = g_strdup(&inLine[9]); 264 g_free(tmpNode->subTunes[subEntry]->pAuthor);
265 tmpNode->subTunes[subEntry]->pAuthor = g_strdup(&inLine[9]);
196 } else if (strncmp(inLine, " TITLE:", 8) == 0) { 266 } else if (strncmp(inLine, " TITLE:", 8) == 0) {
197 XS_STILDB_MULTI inLine[eolPos++] = '\n'; 267 XS_STILDB_MULTI;
268 inLine[eolPos++] = '\n';
198 inLine[eolPos++] = 0; 269 inLine[eolPos++] = 0;
199 xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), &inLine[2]); 270 xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), &inLine[2]);
200 } else if (strncmp(inLine, " ARTIST:", 8) == 0) { 271 } else if (strncmp(inLine, " ARTIST:", 8) == 0) {
201 XS_STILDB_MULTI inLine[eolPos++] = '\n'; 272 XS_STILDB_MULTI;
273 inLine[eolPos++] = '\n';
202 inLine[eolPos++] = 0; 274 inLine[eolPos++] = 0;
203 xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), &inLine[1]); 275 xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), &inLine[1]);
204 } else if (strncmp(inLine, "COMMENT:", 8) == 0) { 276 } else if (strncmp(inLine, "COMMENT:", 8) == 0) {
205 XS_STILDB_MULTI isMulti = TRUE; 277 XS_STILDB_MULTI;
206 xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), inLine); 278 isMulti = TRUE;
279 xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), inLine);
207 } else if (strncmp(inLine, " ", 8) == 0) { 280 } else if (strncmp(inLine, " ", 8) == 0) {
208 xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), &inLine[8]); 281 if (isMulti) {
282 xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), &inLine[8]);
283 } else {
284 XS_STILDB_ERR(lineNum, inLine,
285 "Entry continuation found when isMulti == FALSE.\n");
286 }
209 } 287 }
210 break; 288 break;
211 } 289 }
212 290
213 } /* while */ 291 } /* while */
226 /* Compare two nodes 304 /* Compare two nodes
227 */ 305 */
228 static gint xs_stildb_cmp(const void *pNode1, const void *pNode2) 306 static gint xs_stildb_cmp(const void *pNode1, const void *pNode2)
229 { 307 {
230 /* We assume here that we never ever get NULL-pointers or similar */ 308 /* We assume here that we never ever get NULL-pointers or similar */
231 return strcmp((*(t_xs_stil_node **) pNode1)->pcFilename, (*(t_xs_stil_node **) pNode2)->pcFilename); 309 return strcmp(
310 (*(t_xs_stil_node **) pNode1)->pcFilename,
311 (*(t_xs_stil_node **) pNode2)->pcFilename);
232 } 312 }
233 313
234 314
235 /* (Re)create index 315 /* (Re)create index
236 */ 316 */
237 gint xs_stildb_index(t_xs_stildb * db) 317 gint xs_stildb_index(t_xs_stildb *db)
238 { 318 {
239 t_xs_stil_node *pCurr; 319 t_xs_stil_node *pCurr;
240 gint i; 320 gint i;
241 321
242 /* Free old index */ 322 /* Free old index */
273 } 353 }
274 354
275 return 0; 355 return 0;
276 } 356 }
277 357
358
278 /* Free a given STIL database 359 /* Free a given STIL database
279 */ 360 */
280 void xs_stildb_free(t_xs_stildb * db) 361 void xs_stildb_free(t_xs_stildb *db)
281 { 362 {
282 t_xs_stil_node *pCurr, *pNext; 363 t_xs_stil_node *pCurr, *pNext;
283 364
284 if (!db) 365 if (!db)
285 return; 366 return;
306 } 387 }
307 388
308 389
309 /* Get STIL information node from database 390 /* Get STIL information node from database
310 */ 391 */
311 static t_xs_stil_node *xs_stildb_get_node(t_xs_stildb * db, gchar * pcFilename) 392 static t_xs_stil_node *xs_stildb_get_node(t_xs_stildb *db, gchar *pcFilename)
312 { 393 {
313 gint iStartNode, iEndNode, iQNode, r, i; 394 gint iStartNode, iEndNode, iQNode, r, i;
314 gboolean iFound; 395 gboolean iFound;
315 t_xs_stil_node *pResult; 396 t_xs_stil_node *pResult;
316 397
424 xs_stildb_db = NULL; 505 xs_stildb_db = NULL;
425 XS_MUTEX_UNLOCK(xs_stildb_db); 506 XS_MUTEX_UNLOCK(xs_stildb_db);
426 } 507 }
427 508
428 509
429 t_xs_stil_node *xs_stil_get(gchar * pcFilename) 510 t_xs_stil_node *xs_stil_get(gchar *pcFilename)
430 { 511 {
431 t_xs_stil_node *pResult; 512 t_xs_stil_node *pResult;
432 gchar *tmpFilename; 513 gchar *tmpFilename;
433 514
434 XS_MUTEX_LOCK(xs_stildb_db); 515 XS_MUTEX_LOCK(xs_stildb_db);