aboutsummaryrefslogtreecommitdiff
path: root/shared/common/binport.c
diff options
context:
space:
mode:
authorN.N. <krzyszcz@users.sourceforge.net>2004-04-07 19:57:12 +0000
committerN.N. <krzyszcz@users.sourceforge.net>2004-04-07 19:57:12 +0000
commit7873dd1a71b9eac5f08ef35fd3ce0c844e9a54c8 (patch)
treeaeabfb0d818067c7051608dc7db69fd15476dfc4 /shared/common/binport.c
parentdbd3ec671dec8ea39032d3b0b56387df40c66c28 (diff)
parsing old format max files
svn path=/trunk/externals/miXed/; revision=1564
Diffstat (limited to 'shared/common/binport.c')
-rw-r--r--shared/common/binport.c566
1 files changed, 455 insertions, 111 deletions
diff --git a/shared/common/binport.c b/shared/common/binport.c
index c886955..72e89c7 100644
--- a/shared/common/binport.c
+++ b/shared/common/binport.c
@@ -1,17 +1,20 @@
-/* Copyright (c) 1997-2003 Miller Puckette, krzYszcz, and others.
+/* Copyright (c) 1997-2004 Miller Puckette, krzYszcz, and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+/* LATER verify endianness transparency */
+
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#include <math.h>
#define BINPORT_MAXSTRING 256
#define BINPORT_SYMGROW 64
#ifndef BINPORT_STANDALONE
-/* load max binary file to a binbuf */
+/* load a max binary file into a Pd binbuf */
#include "m_pd.h"
@@ -24,7 +27,6 @@
#define BINPORT_VERBOSE
//#define BINPORT_DEBUG
-
#endif
#include "binport.h"
@@ -41,12 +43,14 @@ static void binport_error(char *fmt, ...)
static void binport_warning(char *fmt, ...)
{
+#if defined (BINPORT_STANDALONE) || defined(BINPORT_VERBOSE)
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "warning (binport): ");
vfprintf(stderr, fmt, ap);
putc('\n', stderr);
va_end(ap);
+#endif
}
static void binport_bug(char *fmt, ...)
@@ -59,6 +63,17 @@ static void binport_bug(char *fmt, ...)
va_end(ap);
}
+static void binport_failure(char *filename)
+{
+ binport_error("\"%s\" doesn't look like a patch file", filename);
+}
+
+static void binpold_failure(char *filename)
+{
+ binport_error("tried reading \"%s\" as an old format file, but failed",
+ filename);
+}
+
#ifdef BINPORT_STANDALONE
typedef int t_int;
@@ -171,62 +186,90 @@ t_symbol *gensym(char *s)
#endif /* end of Pd API */
-/* clumsy... LATER find a better way */
-#ifdef BINPORT_STANDALONE
-#define A_INT (A_CANT + 1)
-#endif
+enum {
+ BINPORT_NULLTYPE,
+ BINPORT_INTTYPE = 1, BINPORT_FLOATTYPE, BINPORT_SYMTYPE,
+ BINPORT_DEFINTTYPE = 5, BINPORT_DEFFLOATTYPE, BINPORT_DEFSYMTYPE,
+ BINPORT_SEMITYPE = 10, BINPORT_COMMATYPE,
+ BINPORT_DOLLARTYPE, BINPORT_DOLLSYMTYPE
+};
-static int binport_getint(t_atom *ap)
-{
-#ifdef A_INT
- return (*(int *)&ap->a_w);
-#else
- return (ap->a_w.w_float);
-#endif
-}
+/* We use A_INT atom type not only for listing, but for import too --
+ the parser passes ints to individual token handlers, so that any
+ required conversion has to be done during Pd message generation. */
+#define A_INT A_DEFFLOAT
-static void binport_setint(t_atom *ap, int i)
+static int binport_readbuf(FILE *fp, char *buf, size_t sz)
{
-#ifdef A_INT
- ap->a_type = A_INT;
- *(int *)&ap->a_w = i;
-#else
- SETFLOAT(ap, (float)i);
-#endif
+ return (fread(buf, 1, sz, fp) == sz ? sz : 0);
}
-static void binport_setfloat(t_atom *ap, float f)
+static int binport_readbyte(FILE *fp, unsigned char *buf)
{
- ap->a_type = A_FLOAT;
- ap->a_w.w_float = f;
+ int c;
+ if ((c = fgetc(fp)) == EOF)
+ return (0);
+ *buf = (unsigned char)c;
+ return (1);
}
-typedef struct _binport
+static int binport_readint(FILE *fp, int *iptr)
{
- FILE *b_fp;
- int b_nsymbols;
- int b_symsize;
- t_symbol **b_symtable;
-} t_binport;
-
-static int binport_getbuf(t_binport *bp, char *buf, size_t sz)
-{
- return (fread(buf, 1, sz, bp->b_fp) == sz);
+ unsigned char word[4];
+ if (fread(word, 1, 4, fp) == 4)
+ {
+ *iptr = ((word[0] << 24) | (word[1] << 16) | (word[2] << 8) | word[3]);
+ return (4);
+ }
+ else return (0);
}
-static int binport_getbyte(t_binport *bp, unsigned char *buf)
+/* LATER more testing */
+/* make it binpold_readfloat() */
+static int binport_readfloat(FILE *fp, float *fptr)
{
- int c;
- if ((c = fgetc(bp->b_fp)) == EOF)
- return (0);
- *buf = (unsigned char)c;
- return (1);
+ unsigned char word[10];
+ if (fread(word, 1, 10, fp) == 10)
+ {
+ int ex;
+ unsigned hi, lo;
+ ex = ((word[0] & 0x7F) << 8) | word[1];
+ hi = ((unsigned)word[2] << 24) | ((unsigned)word[3] << 16) |
+ ((unsigned)word[4] << 8) | (unsigned)word[5];
+ lo = ((unsigned)word[6] << 24) | ((unsigned)word[7] << 16) |
+ ((unsigned)word[8] << 8) | (unsigned)word[9];
+ if (ex == 0x7FFF)
+ {
+ binport_warning("NaN atom bashed to zero");
+ *fptr = 0.;
+ }
+ else if (ex || hi || lo)
+ {
+ double d;
+ ex -= 0x401e;
+ hi = ((hi - 0x7fffffff) - 1) + ((float)0x7fffffff + 1.);
+ lo = ((lo - 0x7fffffff) - 1) + ((float)0x7fffffff + 1.);
+ d = ldexp(hi, ex) + ldexp(lo, ex - 32);
+ *fptr = ((word[0] & 0x80) ? -(float)d : (float)d);
+ }
+ else *fptr = 0.;
+#ifdef BINPORT_DEBUG
+ fprintf(stderr, "%02x%02x", (int)word[0], (int)word[1]);
+ fprintf(stderr, " %02x%02x%02x%02x",
+ (int)word[2], (int)word[3], (int)word[4], (int)word[5]);
+ fprintf(stderr, " %02x%02x%02x%02x",
+ (int)word[6], (int)word[7], (int)word[8], (int)word[9]);
+ fprintf(stderr, " == %g\n", *fptr);
+#endif
+ return (10);
+ }
+ else return (0);
}
-static int binport_getstring(t_binport *bp, char *buf)
+static int binport_readstring(FILE *fp, char *buf)
{
- int c, i = 0;
- while (c = fgetc(bp->b_fp))
+ int c, i = 1;
+ while (c = fgetc(fp))
{
if (c == EOF)
return (0);
@@ -236,9 +279,229 @@ static int binport_getstring(t_binport *bp, char *buf)
*buf = '\0';
if (i >= BINPORT_MAXSTRING)
binport_warning("symbol string too long, skipped");
+ return (i);
+}
+
+typedef struct _binpold
+{
+ FILE *o_fp;
+ int o_natoms;
+ int o_bodysize;
+ int o_nsymbols;
+ int o_symbolid;
+ int o_ndx;
+ t_atom *o_atombuf;
+} t_binpold;
+
+#define BINPOLD_NATOMTYPES 16
+#define BINPOLD_MAXATOMS 1000000 /* LATER rethink */
+
+static t_atomtype binpold_atomtypes[BINPOLD_NATOMTYPES] = {
+ A_NULL, A_INT, A_FLOAT, A_SYMBOL,
+ A_CANT, A_CANT, A_CANT, A_CANT, A_CANT, A_CANT,
+ A_SEMI, A_COMMA, A_DOLLAR, A_CANT, A_CANT, A_CANT
+};
+
+static int binpold_gettype(t_binpold *old, t_atom *ap)
+{
+ int typecode;
+ if ((typecode = fgetc(old->o_fp)) != EOF)
+ {
+ if (typecode > 0 && typecode < BINPOLD_NATOMTYPES)
+ {
+ ap->a_type = binpold_atomtypes[typecode];
+ if (ap->a_type != A_CANT)
+ return (1);
+ else binport_warning("unsupported type of atom %d: %d",
+ old->o_ndx, typecode);
+ }
+ else binport_warning("bad type of atom %d: %d", old->o_ndx, typecode);
+ }
+ else binport_warning("failed reading type of atom %d", old->o_ndx);
+ return (0);
+}
+
+static int binpold_getvalue(t_binpold *old, t_atom *ap, int *countp)
+{
+ int ival;
+ float fval;
+ *countp = 0;
+ switch (ap->a_type)
+ {
+ case A_INT:
+ case A_SYMBOL:
+ if (*countp = binport_readint(old->o_fp, &ival))
+ ap->a_w.w_index = ival;
+ else
+ goto valuefailed;
+ if (ap->a_type == A_SYMBOL)
+ {
+ if (ival >= old->o_nsymbols)
+ old->o_nsymbols = ival + 1;
+ ap->a_type = A_DEFSYM; /* invalidate, until w_symbol is known */
+ }
+ break;
+ case A_FLOAT:
+ if (*countp = binport_readfloat(old->o_fp, &fval))
+ ap->a_w.w_float = fval;
+ else
+ goto valuefailed;
+ break;
+ case A_SEMI:
+ case A_COMMA:
+ break;
+ case A_DOLLAR:
+ if (*countp = binport_readint(old->o_fp, &ival))
+ ap->a_w.w_index = ival;
+ else
+ goto valuefailed;
+ break;
+ default:
+ goto valuefailed;
+ }
+ return (1);
+valuefailed:
+ binport_warning("failed reading value of atom %d (type %d)",
+ old->o_ndx, ap->a_type);
+ return (0);
+}
+
+static int binpold_load(t_binpold *old)
+{
+ char buf[BINPORT_MAXSTRING];
+ t_atom *ap;
+ int total;
+#ifdef BINPORT_DEBUG
+ fprintf(stderr, "old format: %d atoms, %d-byte chunk of atom values\n",
+ old->o_natoms, old->o_bodysize);
+#endif
+ for (old->o_ndx = 0, ap = old->o_atombuf;
+ old->o_ndx < old->o_natoms; old->o_ndx++, ap++)
+ if (!binpold_gettype(old, ap))
+ return (0);
+ old->o_nsymbols = 0;
+ total = 0;
+ for (old->o_ndx = 0, ap = old->o_atombuf;
+ old->o_ndx < old->o_natoms; old->o_ndx++, ap++)
+ {
+ int count;
+ if (!binpold_getvalue(old, ap, &count))
+ return (0);
+ total += count;
+ }
+ if (total != old->o_bodysize)
+ {
+ binport_warning("actual chunk size %d inconsistent with declared %d",
+ total, old->o_bodysize);
+ return (0);
+ }
+ for (old->o_symbolid = 0;
+ old->o_symbolid < old->o_nsymbols; old->o_symbolid++)
+ {
+ if (binport_readstring(old->o_fp, buf))
+ {
+ t_symbol *s = gensym(buf);
+ for (old->o_ndx = 0, ap = old->o_atombuf;
+ old->o_ndx < old->o_natoms; old->o_ndx++, ap++)
+ {
+ if (ap->a_type == A_DEFSYM &&
+ ap->a_w.w_index == old->o_symbolid)
+ {
+ ap->a_type = A_SYMBOL;
+ ap->a_w.w_symbol = s;
+ }
+ }
+ }
+ else
+ {
+ binport_warning("failed reading string for symbol %d",
+ old->o_symbolid);
+ return (0);
+ }
+ }
+ for (old->o_ndx = 0, ap = old->o_atombuf;
+ old->o_ndx < old->o_natoms; old->o_ndx++, ap++)
+ {
+ if (ap->a_type == A_DEFSYM)
+ {
+ binport_warning("unknown string for symbol %d", ap->a_w.w_index);
+ return (0);
+ }
+ else if (ap->a_type == A_DOLLAR)
+ {
+ sprintf(buf, "#%d", ap->a_w.w_index);
+ ap->a_type = A_SYMBOL;
+ ap->a_w.w_symbol = gensym(buf);
+ }
+ /* CHECKME A_DOLLSYM */
+ }
return (1);
}
+static void binpold_free(t_binpold *old)
+{
+ if (old->o_fp)
+ fclose(old->o_fp);
+ if (old->o_atombuf)
+ freebytes(old->o_atombuf, old->o_natoms * sizeof(*old->o_atombuf));
+ freebytes(old, sizeof(*old));
+}
+
+static t_binpold *binpold_new(FILE *fp)
+{
+ int natoms, bodysize;
+ if (binport_readint(fp, &natoms))
+ {
+ if (natoms < 0 || natoms > BINPOLD_MAXATOMS)
+ binport_warning("bad number of atoms: %d", natoms);
+ else if (binport_readint(fp, &bodysize))
+ {
+ if (bodysize < 0)
+ binport_warning("negative chunk size: %d", bodysize);
+ else
+ {
+ t_binpold *old = getbytes(sizeof(*old));
+ old->o_fp = fp;
+ old->o_natoms = natoms;
+ old->o_bodysize = bodysize;
+ if (!(old->o_atombuf =
+ getbytes(old->o_natoms * sizeof(*old->o_atombuf))))
+ {
+ binport_error("could not allocate %d atoms", old->o_natoms);
+ freebytes(old, sizeof(*old));
+ fclose(fp);
+ return (0);
+ }
+ return (old);
+ }
+ }
+ }
+ else binport_warning("file too short");
+ fclose(fp);
+ return (0);
+}
+
+typedef struct _binport
+{
+ FILE *b_fp;
+ int b_nsymbols;
+ int b_symsize;
+ t_symbol **b_symtable;
+ t_binpold *b_old;
+} t_binport;
+
+static void binport_setint(t_atom *ap, int i)
+{
+ ap->a_type = A_INT;
+ ap->a_w.w_index = i;
+}
+
+static void binport_setfloat(t_atom *ap, float f)
+{
+ ap->a_type = A_FLOAT;
+ ap->a_w.w_float = f;
+}
+
static t_symbol *binport_makesymbol(t_binport *bp, int id)
{
char s[BINPORT_MAXSTRING];
@@ -246,7 +509,7 @@ static t_symbol *binport_makesymbol(t_binport *bp, int id)
binport_bug("symbol id mismatch");
else if (id > bp->b_nsymbols)
binport_error("unexpected symbol id");
- else if (binport_getstring(bp, s))
+ else if (binport_readstring(bp->b_fp, s))
{
int reqsize = ++bp->b_nsymbols;
if (reqsize > bp->b_symsize)
@@ -295,14 +558,24 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
unsigned char opcode;
int opval;
char buf[64];
- if (!binport_getbyte(bp, &opcode))
+ t_binpold *old = bp->b_old;
+ if (old)
+ {
+ if (old->o_ndx < old->o_natoms)
+ {
+ *ap = old->o_atombuf[old->o_ndx++];
+ return (1);
+ }
+ else return (0);
+ }
+ if (!binport_readbyte(bp->b_fp, &opcode))
goto bad;
opval = opcode & 0x0f;
switch (opcode >> 4)
{
- case 1: /* variable length int,
- opval: length (number of bytes that follow) */
- if (!binport_getbuf(bp, buf, opval))
+ case BINPORT_INTTYPE: /* variable length int,
+ opval: length (number of bytes that follow) */
+ if (!binport_readbuf(bp->b_fp, buf, opval))
goto bad;
else
{
@@ -314,9 +587,9 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
binport_setint(ap, i);
}
break;
- case 2: /* variable length float,
- opval: length (number of bytes that follow) */
- if (!binport_getbuf(bp, buf, opval))
+ case BINPORT_FLOATTYPE: /* variable length float,
+ opval: length (number of bytes that follow) */
+ if (!binport_readbuf(bp->b_fp, buf, opval))
goto bad;
else
{
@@ -326,9 +599,9 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
binport_setfloat(ap, *(t_float *)&i);
}
break;
- case 3: /* variable length symbol id,
- opval: length (number of bytes that follow) */
- if (!binport_getbuf(bp, buf, opval))
+ case BINPORT_SYMTYPE: /* variable length symbol id,
+ opval: length (number of bytes that follow) */
+ if (!binport_readbuf(bp->b_fp, buf, opval))
goto bad;
else
{
@@ -339,21 +612,31 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
goto bad;
}
break;
- case 5: /* half-byte int */
+ case BINPORT_DEFINTTYPE: /* half-byte int */
binport_setint(ap, opval);
break;
- case 7: /* half-byte symbol id */
+ case BINPORT_DEFSYMTYPE: /* half-byte symbol id */
if (!binport_setsymbol(bp, ap, opval))
goto bad;
break;
- case 12: /* #number */
+ case BINPORT_SEMITYPE:
+ /* LATER warn about nonzero opval */
+ ap->a_type = A_SEMI;
+ break;
+ case BINPORT_COMMATYPE:
+ /* CHECKME apparently never used? */
+ binport_warning("found the comma type in max binary...");
+ /* LATER warn about nonzero opval */
+ ap->a_type = A_COMMA;
+ break;
+ case BINPORT_DOLLARTYPE: /* #number */
sprintf(buf, "#%d", opval);
ap->a_type = A_SYMBOL;
ap->a_w.w_symbol = gensym(buf);
break;
- case 13: /* #symbol id,
- opval: length (number of bytes that follow) */
- if (!binport_getbuf(bp, buf, opval))
+ case BINPORT_DOLLSYMTYPE: /* #symbol id,
+ opval: length (number of bytes that follow) */
+ if (!binport_readbuf(bp->b_fp, buf, opval))
goto bad;
else
{
@@ -370,70 +653,96 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
ap->a_w.w_symbol = gensym(buf);
break;
default:
- switch (opcode)
- {
- case 0xa0:
- ap->a_type = A_SEMI;
- break;
- default:
- goto unknown;
- }
+ binport_error("unknown opcode %x", (int)opcode);
+ goto bad;
}
return (1);
-unknown:
- binport_error("unknown opcode %x", (int)opcode);
bad:
return (0);
}
+static int binport_binalike(char *header)
+{
+ static char binport_header[4] = { 2, 0, 0, 0 }; /* CHECKME any others? */
+ return (memcmp(header, binport_header, 4) == 0);
+}
+
+static int binport_oldalike(char *header)
+{
+ static char binpold_header[4] = { 0, 0, 0, 1 }; /* CHECKME any others? */
+ return (memcmp(header, binpold_header, 4) == 0);
+}
+
static void binport_free(t_binport *bp)
{
fclose(bp->b_fp);
- freebytes(bp->b_symtable, bp->b_symsize * sizeof(*bp->b_symtable));
+ if (bp->b_symtable)
+ freebytes(bp->b_symtable, bp->b_symsize * sizeof(*bp->b_symtable));
+ if (bp->b_old)
+ {
+ bp->b_old->o_fp = 0;
+ binpold_free(bp->b_old);
+ }
freebytes(bp, sizeof(*bp));
}
static t_binport *binport_new(FILE *fp, int *ftypep)
{
- static char binport_header[4] = { 2, 0, 0, 0 };
char header[4];
*ftypep = BINPORT_INVALID;
if (fread(header, 1, 4, fp) == 4)
{
- if (memcmp(header, binport_header, 4))
- {
- if (memcmp(header, "max", 3))
- {
- if (header[0] == '#') /* LATER rethink */
- *ftypep = BINPORT_PDFILE;
-#ifdef BINPORT_VERBOSE
- else binport_warning("unknown header: %x %x %x %x",
- (int)header[0], (int)header[1],
- (int)header[2], (int)header[3]);
-#endif
- }
- else *ftypep = BINPORT_MAXTEXT;
- }
- else
+ if (binport_binalike(header))
{
t_binport *bp = getbytes(sizeof(*bp));
bp->b_fp = fp;
bp->b_nsymbols = 0;
bp->b_symsize = BINPORT_SYMGROW;
bp->b_symtable = getbytes(bp->b_symsize * sizeof(*bp->b_symtable));
+ bp->b_old = 0;
*ftypep = BINPORT_OK;
return (bp);
}
+ else if (memcmp(header, "max", 3) == 0)
+ *ftypep = BINPORT_MAXTEXT;
+ else if (binport_oldalike(header))
+ {
+ t_binport *bp = getbytes(sizeof(*bp));
+ bp->b_fp = fp;
+ bp->b_nsymbols = 0;
+ bp->b_symsize = 0;
+ bp->b_symtable = 0;
+ bp->b_old = 0;
+ *ftypep = BINPORT_MAXOLD;
+ return (bp);
+ }
+ else
+ {
+ if (header[0] == '#') /* LATER rethink */
+ *ftypep = BINPORT_PDFILE;
+ else binport_warning("unknown header: %x %x %x %x",
+ (int)header[0], (int)header[1],
+ (int)header[2], (int)header[3]);
+ }
}
-#ifdef BINPORT_VERBOSE
else binport_warning("file too short");
-#endif
fclose(fp);
return (0);
}
#ifndef BINPORT_STANDALONE
+static int binport_tobinbuf(t_binport *bp, t_binbuf *bb)
+{
+ t_atom at;
+ if (bp->b_old)
+ bp->b_old->o_ndx = 0;
+ while (binport_nextatom(bp, &at))
+ if (at.a_type != A_NULL)
+ binbuf_add(bb, 1, &at);
+ return (1);
+}
+
/* LATER deal with corrupt binary files? */
int binport_read(t_binbuf *bb, char *filename, char *dirname)
{
@@ -450,17 +759,30 @@ int binport_read(t_binbuf *bb, char *filename, char *dirname)
t_binport *bp = binport_new(fp, &ftype);
if (bp)
{
- t_atom at;
- while (binport_nextatom(bp, &at))
- if (at.a_type != A_NULL)
- binbuf_add(bb, 1, &at);
+ int result;
+ if (ftype == BINPORT_OK)
+ result = (binport_tobinbuf(bp, bb)
+ ? BINPORT_OK : BINPORT_CORRUPT);
+ else if (ftype == BINPORT_MAXOLD)
+ {
+ t_binpold *old = binpold_new(fp);
+ result = BINPORT_FAILED;
+ if (old)
+ {
+ bp->b_old = old;
+ if (binpold_load(old) && binport_tobinbuf(bp, bb))
+ result = BINPORT_OK;
+ }
+ else binpold_failure(filename);
+ }
+ else result = BINPORT_FAILED;
binport_free(bp);
- return (BINPORT_OK);
+ return (result);
}
else if (ftype == BINPORT_MAXTEXT || ftype == BINPORT_PDFILE)
return (ftype);
else
- binport_error("\"%s\" doesn't look like a patch file", filename);
+ binport_failure(filename);
}
else binport_bug("cannot open file");
return (BINPORT_INVALID);
@@ -478,7 +800,7 @@ static void binport_atomstring(t_atom *ap, char *buf, int bufsize)
case A_COMMA:
strcpy(buf, ","); break;
case A_INT:
- sprintf(buf, "%d", binport_getint(ap)); break;
+ sprintf(buf, "%d", ap->a_w.w_index); break;
case A_FLOAT:
sprintf(buf, "%#f", ap->a_w.w_float);
ep = buf + strlen(buf) - 1;
@@ -514,6 +836,29 @@ static void binport_atomstring(t_atom *ap, char *buf, int bufsize)
}
}
+static void binport_print(t_binport *bp)
+{
+ char buf[BINPORT_MAXSTRING];
+ t_atom at;
+ int ac = 0;
+ if (bp->b_old)
+ bp->b_old->o_ndx = 0;
+ while (binport_nextatom(bp, &at))
+ {
+ if (at.a_type == A_SEMI)
+ {
+ fputs(";\n", stdout);
+ ac = 0;
+ }
+ else if (at.a_type != A_NULL)
+ {
+ if (ac++) fputc(' ', stdout);
+ binport_atomstring(&at, buf, BINPORT_MAXSTRING);
+ fputs(buf, stdout);
+ }
+ }
+}
+
int main(int ac, char **av)
{
if (ac > 1)
@@ -525,22 +870,21 @@ int main(int ac, char **av)
t_binport *bp = binport_new(fp, &ftype);
if (bp)
{
- char buf[BINPORT_MAXSTRING];
- t_atom at;
- int ac = 0;
- while (binport_nextatom(bp, &at))
+ if (ftype == BINPORT_OK)
+ binport_print(bp);
+ else if (ftype == BINPORT_MAXOLD)
{
- if (at.a_type == A_SEMI)
- {
- fputs(";\n", stdout);
- ac = 0;
- }
- else if (at.a_type != A_NULL)
+ t_binpold *old = binpold_new(fp);
+ if (old)
{
- if (ac++) fputc(' ', stdout);
- binport_atomstring(&at, buf, BINPORT_MAXSTRING);
- fputs(buf, stdout);
+ bp->b_old = old;
+ if (binpold_load(old))
+ binport_print(bp);
+ else
+ ftype = BINPORT_FAILED;
}
+ else ftype = BINPORT_FAILED;
+ if (ftype == BINPORT_FAILED) binpold_failure(av[1]);
}
binport_free(bp);
}
@@ -549,7 +893,7 @@ int main(int ac, char **av)
else if (ftype == BINPORT_PDFILE)
binport_warning("\"%s\" looks like a Pd patch file", av[1]);
else
- binport_error("\"%s\" doesn't look like a patch file", av[1]);
+ binport_failure(av[1]);
}
else binport_error("cannot open file \"%s\"", av[1]);
}