shithub: sox

Download patch

ref: 689b86e5ae687e7c484fc87a508dae47125ec47a
parent: 3913916c634913a624461fc48fd0344983367b00
author: cbagwell <cbagwell>
date: Mon Mar 6 21:53:40 EST 2000

Added support for new st_fail() function and converted sox.c and 8svx.c to
understand it.  Still need to update effects support in sox.c and update
all handlers and effects.

--- a/src/8svx.c
+++ b/src/8svx.c
@@ -60,13 +60,13 @@
 	/* read FORM chunk */
 	if (st_reads(ft, buf, 4) == ST_EOF || strncmp(buf, "FORM", 4) != 0)
 	{
-		fail("8SVX: header does not begin with magic word 'FORM'");
+		st_fail(ft, ST_EHDR, "Header did not begin with magic word 'FORM'");
 		return(ST_EOF);
 	}
 	st_readdw(ft, &totalsize);
 	if (st_reads(ft, buf, 4) == ST_EOF || strncmp(buf, "8SVX", 4) != 0)
 	{
-		fail("8SVX: 'FORM' chunk does not specify '8SVX' as type");
+		st_fail(ft, ST_EHDR, "'FORM' chunk does not specify '8SVX' as type");
 		return(ST_EOF);
 	}
 
@@ -76,7 +76,7 @@
 			st_readdw(ft, &chunksize);
 			if (chunksize != 20)
 			{
-				fail ("8SVX: VHDR chunk has bad size");
+				st_fail(ft, ST_EHDR, "VHDR chunk has bad size");
 				return(ST_EOF);
 			}
 			fseek(ft->fp,12,SEEK_CUR);
@@ -85,7 +85,7 @@
 			fread(buf,1,1,ft->fp);
 			if (buf[0] != 0)
 			{
-				fail ("8SVX: unsupported data compression");
+				st_fail(ft, ST_EFMT, "Unsupported data compression");
 				return(ST_EOF);
 			}
 			fseek(ft->fp,4,SEEK_CUR);
@@ -99,13 +99,13 @@
 			chunk_buf = (char *) malloc(chunksize + 2);
 			if (chunk_buf == 0)
 			{
-			    fail("Couldn't alloc resources");
+			    st_fail(ft, ST_ENOMEM, "Unable to alloc memory");
 			    return(ST_EOF);
 			}
 			if (fread(chunk_buf,1,(size_t)chunksize,ft->fp) 
 					!= chunksize)
 			{
-				fail("8SVX: Unexpected EOF in ANNO header");
+				st_fail(ft, ST_EHDR, "Couldn't read all of header");
 				return(ST_EOF);
 			}
 			chunk_buf[chunksize] = '\0';
@@ -122,13 +122,13 @@
 			chunk_buf = (char *) malloc(chunksize + 1);
 			if (chunk_buf == 0)
 			{
-			    fail("Couldn't alloc resources");
+			    st_fail(ft, ST_ENOMEM, "Unable to alloc memory");
 			    return(ST_EOF);
 			}
 			if (fread (chunk_buf,1,(size_t)chunksize,ft->fp) 
 					!= chunksize)
 			{
-				fail("8SVX: Unexpected EOF in NAME header");
+				st_fail(ft, ST_EHDR, "Couldn't read all of header");
 				return(ST_EOF);
 			}
 			chunk_buf[chunksize] = '\0';
@@ -142,7 +142,7 @@
 			st_readdw(ft, &chunksize);
 			if (chunksize != 4) 
 			{
-				fail("8SVX: Short channel chunk");
+				st_fail(ft, ST_EHDR, "Couldn't read all of header");
 				return(ST_EOF);
 			}
 			st_readdw(ft, &channels);
@@ -165,12 +165,12 @@
 
 	if (rate == 0)
 	{
-		fail ("8SVX: invalid rate");
+		st_fail(ft, ST_ERATE, "Invalid sample rate");
 		return(ST_EOF);
 	}
 	if (strncmp(buf,"BODY",4) != 0)
 	{
-		fail ("8SVX: BODY chunk not found");
+		st_fail(ft, ST_EHDR, "BODY chunk not found");
 		return(ST_EOF);
 	}
 	st_readdw(ft, &(p->nsamples));
@@ -187,8 +187,8 @@
 	for (i = 1; i < channels; i++) {
 		if ((p->ch[i] = fopen(ft->filename, READBINARY)) == NULL)
 		{
-			fail("Can't open channel file '%s': %s",
-				ft->filename, strerror(errno));
+			st_fail(ft,errno,"Can't open channel file '%s'",
+				ft->filename);
 			return(ST_EOF);
 		}
 
@@ -195,12 +195,12 @@
 		/* position channel files */
 		if (fseek(p->ch[i],chan1_pos,SEEK_SET))
 		{
-		    fail ("Can't position channel %d: %s",i,strerror(errno));
+		    st_fail (ft,errno,"Can't position channel %d",i);
 		    return(ST_EOF);
 		}
 		if (fseek(p->ch[i],p->nsamples/channels*i,SEEK_CUR))
 		{
-		    fail ("Can't seek channel %d: %s",i,strerror(errno));
+		    st_fail (ft,errno,"Can't seek channel %d",i);
 		    return(ST_EOF);
 		}
 	}
@@ -277,8 +277,7 @@
 	for (i = 1; i < ft->info.channels; i++) {
 		if ((p->ch[i] = tmpfile()) == NULL)
 		{
-			fail("Can't open channel output file: %s",
-				strerror(errno));
+			st_fail(ft,errno,"Can't open channel output file");
 			return(ST_EOF);
 		}
 	}
@@ -337,7 +336,7 @@
 	for (i = 1; i < ft->info.channels; i++) {
 		if (fseek (p->ch[i], 0L, 0))
 		{
-			fail ("Can't rewind channel output file %d",i);
+			st_fail (ft,errno,"Can't rewind channel output file %d",i);
 			return(ST_EOF);
 		}
 		while (!feof(p->ch[i])) {
@@ -354,7 +353,7 @@
 	/* fixup file sizes in header */
 	if (fseek(ft->fp, 0L, 0) != 0)
 	{
-		fail("can't rewind output file to rewrite 8SVX header");
+		st_fail(ft,errno,"can't rewind output file to rewrite 8SVX header");
 		return(ST_EOF);
 	}
 	svxwriteheader(ft, p->nsamples);
--- a/src/sox.c
+++ b/src/sox.c
@@ -405,7 +405,10 @@
 	st_gettype(&outformat);
     
     /* Read and write starters can change their formats. */
-    (* informat.h->startread)(&informat);
+    if ((* informat.h->startread)(&informat) == ST_EOF)
+    {
+        fail(informat.st_errstr);
+    }
     st_checkformat(&informat);
     
     if (informat.info.dovol)
@@ -461,7 +464,10 @@
 #endif
 
 	st_copyformat(&informat, &outformat);
-	(* outformat.h->startwrite)(&outformat);
+	if ((* outformat.h->startwrite)(&outformat) == ST_EOF)
+	{
+	    fail(outformat.st_errstr);
+	}
 	st_checkformat(&outformat);
 	st_cmpformats(&informat, &outformat);
 	report("Output file: using sample rate %lu\n\tsize %s, encoding %s, %d %s",
@@ -505,6 +511,8 @@
 
 
     /* Run input data through effects and get more until olen == 0 */
+    informat.st_errno = 0;
+    outformat.st_errno = 0;
     while (informat.info.x < informat.info.x1) {
 	ULONG ct, r;
 
@@ -528,6 +536,7 @@
 	    efftab[e].odone = efftab[e].olen = 0;
 
 	do {
+	    ULONG w;
 
 	    /* run entire chain BACKWARDS: pull, don't push.*/
 	    /* this is because buffering system isn't a nice queueing system */
@@ -537,11 +546,14 @@
 
 	    /* If outputing and output data was generated then write it */
 	    if (writing&&(efftab[neffects-1].olen>efftab[neffects-1].odone)) {
-		(* outformat.h->write)(&outformat, efftab[neffects-1].obuf, 
-				       (LONG) efftab[neffects-1].olen);
+		w = (* outformat.h->write)(&outformat, efftab[neffects-1].obuf, 
+				           (LONG) efftab[neffects-1].olen);
 	        efftab[neffects-1].odone = efftab[neffects-1].olen;
 	    }
 
+	    if (outformat.st_errno)
+		fail(outformat.st_errstr);
+
 	    /* if stuff still in pipeline, set up to flow effects again */
 	    havedata = 0;
 	    for(e = 0; e < neffects - 1; e++)
@@ -553,6 +565,9 @@
 
     }
 
+    if (informat.st_errno)
+	fail(informat.st_errstr);
+
     /* Drain the effects out first to last, 
      * pushing residue through subsequent effects */
     /* oh, what a tangled web we weave */
@@ -584,11 +599,15 @@
 	    (* efftabR[e].h->stop)(&efftabR[e]);
     }
 
-    (* informat.h->stopread)(&informat);
+    if ((* informat.h->stopread)(&informat) == ST_EOF)
+	fail(informat.st_errstr);
     fclose(informat.fp);
 
     if (writing)
-        (* outformat.h->stopwrite)(&outformat);
+    {
+        if ((* outformat.h->stopwrite)(&outformat) == ST_EOF)
+	    fail(outformat.st_errstr);
+    }
     if (writing)
         fclose(outformat.fp);
 }
--- a/src/st.h
+++ b/src/st.h
@@ -183,6 +183,8 @@
 	char	*comment;		/* comment string */
 	FILE	*fp;			/* File stream pointer */
 	struct	st_fileinfo file;	/* File data block */
+	int     st_errno;		/* Failure error codes */
+	char	st_errstr[256];		/* Extend Failure text */
 	st_format_t *h;			/* format struct for this file */
 	/* FIXME: I perfer void * or char * */
 	double	priv[ST_MAX_PRIVSIZE/8]; /* format's private data area */
@@ -331,6 +333,7 @@
 void report(P2(const char *, ...));
 void warn(P2(const char *, ...));
 void fail(P2(const char *, ...))NORET;
+void st_fail(P4(ft_t, int, const char *, ...));
 
 void st_geteffect(P1(eff_t));
 void st_gettype(P1(ft_t));
@@ -371,6 +374,12 @@
 #define ST_SUCCESS (0)
 
 const char *st_version(P0);			/* return version number */
+
+/* ST specific error codes.  The rest directly map from errno. */
+#define ST_EHDR 2000		/* Invalid Audio Header */
+#define ST_EFMT 2001		/* Unsupported data format */
+#define ST_ERATE 20002		/* Unsupported rate for format */
+#define ST_ENOMEM 2003		/* Can't alloc memory */
 
 #ifdef __cplusplus
 } /* end of extern "C" */
--- a/src/util.c
+++ b/src/util.c
@@ -29,12 +29,14 @@
  */
 
 /* export flags */
+/* FIXME: To be moved inside of fileop structure per handler. */
 int verbose = 0;	/* be noisy on stderr */
 
+/* FIXME:  These functions are user level concepts.  Move them outside
+ * the ST library. 
+ */
 char *myname = 0;
 
-
-
 void
 report(const char *fmt, ...) 
 {
@@ -80,6 +82,21 @@
 	exit(2);
 }
 
+
+/* Warning: no error checking is done with errstr.  Be sure not to
+ * go over the array limit ourself!
+ */
+void
+st_fail(ft_t ft, int errno, const char *fmt, ...)
+{
+	va_list args;
+
+	ft->st_errno = errno;
+
+	va_start(args, fmt);
+	vsprintf(ft->st_errstr, fmt, args);
+	va_end(args);
+}
 
 int strcmpcase(s1, s2)
 char *s1, *s2;