diff 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
line wrap: on
line diff
--- a/src/xs_stil.c	Tue May 30 04:50:04 2006 +0000
+++ b/src/xs_stil.c	Wed May 31 10:02:00 2006 +0000
@@ -26,11 +26,69 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <stdarg.h>
 
 
 /* Database handling functions
  */
-static t_xs_stil_node *xs_stildb_node_new(gchar * pcFilename)
+static gboolean xs_stildb_node_realloc(t_xs_stil_node *pNode, gint nsubTunes)
+{
+	if (!pNode) return FALSE;
+	
+	/* Re-allocate subTune structure if needed */
+	if (nsubTunes >= pNode->nsubTunes) {
+		pNode->subTunes =
+			(t_xs_stil_subnode **) g_realloc(pNode->subTunes,
+			(nsubTunes + 1) * sizeof(t_xs_stil_subnode **));
+
+		if (!pNode->subTunes)
+			return FALSE;
+		
+		/* Clear the newly allocated memory */
+		memset(&(pNode->subTunes[pNode->nsubTunes]), 0,
+			(nsubTunes + 1 - pNode->nsubTunes) *
+			sizeof(t_xs_stil_subnode **));
+	}
+			
+	/* Allocate memory for subTune */
+	if (!pNode->subTunes[nsubTunes]) {
+		pNode->subTunes[nsubTunes] = (t_xs_stil_subnode *)
+			g_malloc0(sizeof(t_xs_stil_subnode));
+		
+		if (!pNode->subTunes[nsubTunes])
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+static void xs_stildb_node_free(t_xs_stil_node *pNode)
+{
+	gint i;
+	t_xs_stil_subnode *pSub;
+
+	if (pNode) {
+		/* Free subtune information */
+		for (i = 0; i < pNode->nsubTunes; i++) {
+			pSub = pNode->subTunes[i];
+			if (pSub) {
+				g_free(pSub->pName);
+				g_free(pSub->pAuthor);
+				g_free(pSub->pInfo);
+
+				g_free(pSub);
+			}
+		}
+		
+		g_free(pNode->subTunes);
+		g_free(pNode->pcFilename);
+		g_free(pNode);
+	}
+}
+
+
+static t_xs_stil_node *xs_stildb_node_new(gchar *pcFilename)
 {
 	t_xs_stil_node *pResult;
 
@@ -39,37 +97,20 @@
 	if (!pResult)
 		return NULL;
 
+	/* Allocate filename and initial space for one subtune */
 	pResult->pcFilename = g_strdup(pcFilename);
-	if (!pResult->pcFilename) {
-		g_free(pResult);
+	if (!pResult->pcFilename || !xs_stildb_node_realloc(pResult, 1)) {
+		xs_stildb_node_free(pResult);
 		return NULL;
 	}
-
+	
 	return pResult;
 }
 
 
-static void xs_stildb_node_free(t_xs_stil_node * pNode)
-{
-	gint i;
-
-	if (pNode) {
-		/* Free subtune information */
-		for (i = 0; i <= XS_STIL_MAXENTRY; i++) {
-			g_free(pNode->subTunes[i].pName);
-			g_free(pNode->subTunes[i].pAuthor);
-			g_free(pNode->subTunes[i].pInfo);
-		}
-
-		g_free(pNode->pcFilename);
-		g_free(pNode);
-	}
-}
-
-
 /* Insert given node to db linked list
  */
-static void xs_stildb_node_insert(t_xs_stildb * db, t_xs_stil_node * pNode)
+static void xs_stildb_node_insert(t_xs_stildb *db, t_xs_stil_node *pNode)
 {
 	assert(db);
 
@@ -89,10 +130,24 @@
 
 /* Read database (additively) to given db-structure
  */
-#define XS_STILDB_MULTI if (isMulti) { isMulti = FALSE; xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), "\n"); }
+#define XS_STILDB_MULTI							\
+	if (isMulti) {							\
+		isMulti = FALSE;					\
+		xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), "\n");\
+	}
 
+void XS_STILDB_ERR(gint lineNum, gchar *inLine, const char *fmt, ...)
+{
+	va_list ap;
 
-gint xs_stildb_read(t_xs_stildb * db, gchar * dbFilename)
+	va_start(ap, fmt);
+	xs_error(fmt, ap);
+	va_end(ap);
+	
+	fprintf(stderr, "#%d: '%s'\n", lineNum, inLine);
+}
+
+gint xs_stildb_read(t_xs_stildb *db, gchar *dbFilename)
 {
 	FILE *inFile;
 	gchar inLine[XS_BUF_SIZE + 16];	/* Since we add some chars here and there */
@@ -104,7 +159,7 @@
 
 	/* Try to open the file */
 	if ((inFile = fopen(dbFilename, "ra")) == NULL) {
-		XSERR("Could not open STILDB '%s'\n", dbFilename);
+		xs_error("Could not open STILDB '%s'\n", dbFilename);
 		return -1;
 	}
 
@@ -128,9 +183,9 @@
 			/* Check if we are already parsing entry */
 			isMulti = FALSE;
 			if (tmpNode) {
-				XSERR("New entry ('%s') before end of current ('%s')! Possibly malformed STIL-file!\n",
-				      inLine, tmpNode->pcFilename);
-
+				XS_STILDB_ERR(lineNum, inLine,
+					"New entry found before end of current ('%s')!\n",
+					tmpNode->pcFilename);
 				xs_stildb_node_free(tmpNode);
 			}
 
@@ -139,7 +194,8 @@
 			tmpNode = xs_stildb_node_new(inLine);
 			if (!tmpNode) {
 				/* Allocation failed */
-				XSERR("Could not allocate new STILdb-node for '%s'!\n", inLine);
+				XS_STILDB_ERR(lineNum, inLine,
+					"Could not allocate new STILdb-node!\n");
 				isError = TRUE;
 			}
 			break;
@@ -156,12 +212,16 @@
 					subEntry = atol(&inLine[2]);
 
 					/* Sanity check */
-					if ((subEntry < 1) || (subEntry > XS_STIL_MAXENTRY)) {
-						XSERR("Number of subEntry (%i) for '%s' is invalid\n", subEntry,
-						      tmpNode->pcFilename);
+					if (subEntry < 1) {
+						XS_STILDB_ERR(lineNum, inLine,
+							"Number of subEntry (%i) for '%s' is invalid\n",
+							subEntry, tmpNode->pcFilename);
 						subEntry = 0;
 					}
 				}
+			} else {
+				XS_STILDB_ERR(lineNum, inLine,
+					"Syntax error, expected subEntry number.\n");
 			}
 
 			break;
@@ -182,30 +242,48 @@
 		default:
 			/* Check if we are parsing an entry */
 			if (!tmpNode) {
-				XSERR("Entry data encountered outside of entry!\n");
+				XS_STILDB_ERR(lineNum, inLine,
+					"Entry data encountered outside of entry or syntax error!\n");
 				break;
 			}
 
+			if (xs_stildb_node_realloc(tmpNode, subEntry)) {
+				XS_STILDB_ERR(lineNum, inLine,
+					"Could not (re)allocate memory for subEntries!\n");
+				isError = TRUE;
+				break;
+			}
+			
 			/* Some other type */
 			if (strncmp(inLine, "   NAME:", 8) == 0) {
-				XS_STILDB_MULTI g_free(tmpNode->subTunes[subEntry].pName);
-				tmpNode->subTunes[subEntry].pName = g_strdup(&inLine[9]);
+				XS_STILDB_MULTI;
+				g_free(tmpNode->subTunes[subEntry]->pName);
+				tmpNode->subTunes[subEntry]->pName = g_strdup(&inLine[9]);
 			} else if (strncmp(inLine, " AUTHOR:", 8) == 0) {
-				XS_STILDB_MULTI g_free(tmpNode->subTunes[subEntry].pAuthor);
-				tmpNode->subTunes[subEntry].pAuthor = g_strdup(&inLine[9]);
+				XS_STILDB_MULTI;
+				g_free(tmpNode->subTunes[subEntry]->pAuthor);
+				tmpNode->subTunes[subEntry]->pAuthor = g_strdup(&inLine[9]);
 			} else if (strncmp(inLine, "  TITLE:", 8) == 0) {
-				XS_STILDB_MULTI inLine[eolPos++] = '\n';
+				XS_STILDB_MULTI;
+				inLine[eolPos++] = '\n';
 				inLine[eolPos++] = 0;
-				xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), &inLine[2]);
+				xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), &inLine[2]);
 			} else if (strncmp(inLine, " ARTIST:", 8) == 0) {
-				XS_STILDB_MULTI inLine[eolPos++] = '\n';
+				XS_STILDB_MULTI;
+				inLine[eolPos++] = '\n';
 				inLine[eolPos++] = 0;
-				xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), &inLine[1]);
+				xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), &inLine[1]);
 			} else if (strncmp(inLine, "COMMENT:", 8) == 0) {
-				XS_STILDB_MULTI isMulti = TRUE;
-				xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), inLine);
+				XS_STILDB_MULTI;
+				isMulti = TRUE;
+				xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), inLine);
 			} else if (strncmp(inLine, "        ", 8) == 0) {
-				xs_pstrcat(&(tmpNode->subTunes[subEntry].pInfo), &inLine[8]);
+				if (isMulti) {
+					xs_pstrcat(&(tmpNode->subTunes[subEntry]->pInfo), &inLine[8]);
+				} else {
+					XS_STILDB_ERR(lineNum, inLine,
+					"Entry continuation found when isMulti == FALSE.\n");
+				}
 			}
 			break;
 		}
@@ -228,13 +306,15 @@
 static gint xs_stildb_cmp(const void *pNode1, const void *pNode2)
 {
 	/* We assume here that we never ever get NULL-pointers or similar */
-	return strcmp((*(t_xs_stil_node **) pNode1)->pcFilename, (*(t_xs_stil_node **) pNode2)->pcFilename);
+	return strcmp(
+		(*(t_xs_stil_node **) pNode1)->pcFilename,
+		(*(t_xs_stil_node **) pNode2)->pcFilename);
 }
 
 
 /* (Re)create index
  */
-gint xs_stildb_index(t_xs_stildb * db)
+gint xs_stildb_index(t_xs_stildb *db)
 {
 	t_xs_stil_node *pCurr;
 	gint i;
@@ -275,9 +355,10 @@
 	return 0;
 }
 
+
 /* Free a given STIL database
  */
-void xs_stildb_free(t_xs_stildb * db)
+void xs_stildb_free(t_xs_stildb *db)
 {
 	t_xs_stil_node *pCurr, *pNext;
 
@@ -308,7 +389,7 @@
 
 /* Get STIL information node from database
  */
-static t_xs_stil_node *xs_stildb_get_node(t_xs_stildb * db, gchar * pcFilename)
+static t_xs_stil_node *xs_stildb_get_node(t_xs_stildb *db, gchar *pcFilename)
 {
 	gint iStartNode, iEndNode, iQNode, r, i;
 	gboolean iFound;
@@ -426,7 +507,7 @@
 }
 
 
-t_xs_stil_node *xs_stil_get(gchar * pcFilename)
+t_xs_stil_node *xs_stil_get(gchar *pcFilename)
 {
 	t_xs_stil_node *pResult;
 	gchar *tmpFilename;