Index: /libcuefile/trunk/include/cuetools/cd.h
===================================================================
--- /libcuefile/trunk/include/cuetools/cd.h	(revision 468)
+++ /libcuefile/trunk/include/cuetools/cd.h	(revision 469)
@@ -77,6 +77,12 @@
 typedef struct Track Track;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* return pointer to CD structure */
 Cd *cd_init ();
+
+void cd_delete (Cd *cd);
 
 /* dump all info from CD structure
@@ -159,3 +165,7 @@
 long track_get_index (Track *track, int i);
 
+#ifdef __cplusplus
+}
 #endif
+
+#endif
Index: /libcuefile/trunk/include/cuetools/cdtext.h
===================================================================
--- /libcuefile/trunk/include/cuetools/cdtext.h	(revision 468)
+++ /libcuefile/trunk/include/cuetools/cdtext.h	(revision 469)
@@ -41,4 +41,8 @@
 typedef struct Cdtext Cdtext;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* return a pointer to a new Cdtext */
 Cdtext *cdtext_init ();
@@ -69,3 +73,7 @@
 void cdtext_dump (Cdtext *cdtext, int istrack);
 
+#ifdef __cplusplus
+}
 #endif
+
+#endif
Index: /libcuefile/trunk/include/cuetools/cuefile.h
===================================================================
--- /libcuefile/trunk/include/cuetools/cuefile.h	(revision 468)
+++ /libcuefile/trunk/include/cuetools/cuefile.h	(revision 469)
@@ -6,4 +6,7 @@
  */
 
+#ifndef CUEFILE_H
+#define CUEFILE_H
+
 #include "cd.h"
 
@@ -12,5 +15,15 @@
 typedef struct Cue Cue;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 Cd *cf_parse (char *fname, int *format);
 int cf_print (char *fname, int *format, Cd *cue);
 int cf_format_from_suffix (char *fname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /libcuefile/trunk/src/cd.c
===================================================================
--- /libcuefile/trunk/src/cd.c	(revision 468)
+++ /libcuefile/trunk/src/cd.c	(revision 469)
@@ -59,4 +59,31 @@
 }
 
+void track_delete(Track *track)
+{
+	if (track->isrc)
+		free(track->isrc);
+	if (track->cdtext)
+		cdtext_delete(track->cdtext);
+	if (track->zero_pre.name)
+		free(track->zero_pre.name);
+	if (track->file.name)
+		free(track->file.name);
+	if (track->zero_post.name)
+		free(track->zero_post.name);
+	free(track);
+}
+
+void cd_delete (Cd *cd)
+{
+	size_t i;
+	if (cd->cdtext)
+		cdtext_delete(cd->cdtext);
+	if (cd->catalog)
+		free(cd->catalog);
+	for (i = 0; i < cd->ntrack; i++)
+		track_delete(cd->track[i]);
+	free(cd);
+}
+
 Track *track_init ()
 {
@@ -128,6 +155,8 @@
 	if (MAXTRACK - 1 > cd->ntrack)
 		cd->ntrack++;
-	else
+	else {
 		fprintf(stderr, "too many tracks\n");
+		track_delete(cd->track[cd->ntrack - 1]);
+	}
 
 	/* this will reinit last track if there were too many */
Index: /libcuefile/trunk/src/cue_parse.c
===================================================================
--- /libcuefile/trunk/src/cue_parse.c	(revision 468)
+++ /libcuefile/trunk/src/cue_parse.c	(revision 469)
@@ -1184,10 +1184,10 @@
   case 6:
 #line 115 "cue_parse.y"
-    { cd_set_catalog(cd, yyvsp[-1].sval); }
+    { cd_set_catalog(cd, yyvsp[-1].sval); free(yyvsp[-1].sval); }
     break;
 
   case 7:
 #line 116 "cue_parse.y"
-    { /* ignored */ }
+    { free(yyvsp[-1].sval); /* ignored */ }
     break;
 
@@ -1199,5 +1199,5 @@
 			free(new_filename);
 		}
-		new_filename = strdup(yyvsp[-2].sval);
+		new_filename = yyvsp[-2].sval; /*strdup(yyvsp[-2].sval);*/
 	}
     break;
@@ -1212,7 +1212,10 @@
 		cdtext = track_get_cdtext(track);
 
-		cur_filename = new_filename;
-		if (NULL != cur_filename)
-			prev_filename = cur_filename;
+		if (cur_filename) free(cur_filename);
+		cur_filename = new_filename ? strdup(new_filename) : 0;
+		if (NULL != cur_filename) {
+			if (prev_filename) free(prev_filename);
+			prev_filename = strdup(cur_filename);
+		}
 
 		if (NULL == prev_filename)
@@ -1221,4 +1224,5 @@
 			track_set_filename(track, prev_filename);
 
+		if (new_filename) free(new_filename);
 		new_filename = NULL;
 	}
@@ -1234,5 +1238,5 @@
   case 34:
 #line 195 "cue_parse.y"
-    { track_set_isrc(track, yyvsp[-1].sval); }
+    { track_set_isrc(track, yyvsp[-1].sval); free(yyvsp[-1].sval); }
     break;
 
@@ -1278,5 +1282,5 @@
   case 46:
 #line 235 "cue_parse.y"
-    { cdtext_set (yyvsp[-2].ival, yyvsp[-1].sval, cdtext); }
+    { cdtext_set (yyvsp[-2].ival, yyvsp[-1].sval, cdtext); free(yyvsp[-1].sval); }
     break;
 
@@ -1519,8 +1523,29 @@
 	yydebug = 0;
 
-	if (0 == yyparse())
-		return cd;
-
-	return NULL;
+	int error = yyparse();
+	cue_delete_buffer();
+	if (prev_filename) {
+		free(prev_filename);
+		prev_filename = 0;
+	}
+	if (cur_filename) {
+		free(cur_filename);
+		cur_filename = 0;
+	}
+	if (new_filename) {
+		free(new_filename);
+		new_filename = 0;
+	}
+
+	Cd *res = cd;
+	if (error) {
+		cd_delete(cd);
+		res = 0;
+	}
+	cd = 0;
+	track = 0;
+	prev_track = 0;
+	cdtext = 0;
+	return res;
 }
 
Index: /libcuefile/trunk/src/cue_scan.c
===================================================================
--- /libcuefile/trunk/src/cue_scan.c	(revision 468)
+++ /libcuefile/trunk/src/cue_scan.c	(revision 469)
@@ -2066,4 +2066,5 @@
 	{
 	yylex();
+	cue_delete_buffer();
 	return 0;
 	}
@@ -2071,2 +2072,9 @@
 #line 98 "cue_scan.l"
 
+void cue_delete_buffer()
+{
+	if (yy_current_buffer) {
+		yy_delete_buffer(yy_current_buffer);
+		yy_current_buffer = 0;
+	}
+}
