Mercurial > hg > xmms-sid
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); |