aboutsummaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/common/binport.c470
-rw-r--r--shared/common/binport.h1
-rw-r--r--shared/common/loud.c15
-rw-r--r--shared/common/loud.h2
-rw-r--r--shared/common/port.c682
-rw-r--r--shared/toxy/scriptlet.c2
-rw-r--r--shared/unstable/fragile.c2
7 files changed, 887 insertions, 287 deletions
diff --git a/shared/common/binport.c b/shared/common/binport.c
index 72e89c7..90eb4a1 100644
--- a/shared/common/binport.c
+++ b/shared/common/binport.c
@@ -10,8 +10,8 @@
#include <string.h>
#include <math.h>
-#define BINPORT_MAXSTRING 256
-#define BINPORT_SYMGROW 64
+#define BINPORT_MAXSTRING 1000
+#define BINPORT_SYMGROW 64
#ifndef BINPORT_STANDALONE
/* load a max binary file into a Pd binbuf */
@@ -438,6 +438,16 @@ static int binpold_load(t_binpold *old)
return (1);
}
+static int binpold_nextatom(t_binpold *old, t_atom *ap)
+{
+ if (old->o_ndx < old->o_natoms)
+ {
+ *ap = old->o_atombuf[old->o_ndx++];
+ return (1);
+ }
+ else return (0);
+}
+
static void binpold_free(t_binpold *old)
{
if (old->o_fp)
@@ -484,6 +494,7 @@ static t_binpold *binpold_new(FILE *fp)
typedef struct _binport
{
FILE *b_fp;
+ int b_ftype;
int b_nsymbols;
int b_symsize;
t_symbol **b_symtable;
@@ -502,6 +513,12 @@ static void binport_setfloat(t_atom *ap, float f)
ap->a_w.w_float = f;
}
+static void binport_setsymbol(t_atom *ap, t_symbol *s)
+{
+ ap->a_type = A_SYMBOL;
+ ap->a_w.w_symbol = s;
+}
+
static t_symbol *binport_makesymbol(t_binport *bp, int id)
{
char s[BINPORT_MAXSTRING];
@@ -534,17 +551,13 @@ static t_symbol *binport_makesymbol(t_binport *bp, int id)
return (0);
}
-static t_symbol *binport_getsymbol(t_binport *bp, int id)
+static int binport_setbysymtable(t_binport *bp, t_atom *ap, int id)
{
+ t_symbol *s;
if (id < bp->b_nsymbols)
- return (bp->b_symtable[id]);
+ s = bp->b_symtable[id];
else
- return (binport_makesymbol(bp, id));
-}
-
-static int binport_setsymbol(t_binport *bp, t_atom *ap, int id)
-{
- t_symbol *s = binport_getsymbol(bp, id);
+ s = binport_makesymbol(bp, id);
if (s)
{
ap->a_type = A_SYMBOL;
@@ -553,30 +566,146 @@ static int binport_setsymbol(t_binport *bp, t_atom *ap, int id)
return (s != 0);
}
-static int binport_nextatom(t_binport *bp, t_atom *ap)
+/* single pass of binbuf_text(), int-preserving version */
+static int maxtext_nextatom(FILE *fp, t_atom *ap)
{
- unsigned char opcode;
- int opval;
- char buf[64];
- t_binpold *old = bp->b_old;
- if (old)
+ char buf[BINPORT_MAXSTRING + 1], *bufp, *ebuf = buf + BINPORT_MAXSTRING;
+ int ready;
+ unsigned char ch;
+ ap->a_type = A_NULL;
+ while ((ready = binport_readbyte(fp, &ch)) &&
+ (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'));
+ if (!ready)
+ return (0);
+ if (ch == ';')
+ ap->a_type = A_SEMI;
+ else if (ch == ',')
+ ap->a_type = A_COMMA;
+ else
{
- if (old->o_ndx < old->o_natoms)
+ int floatstate = 0, slash = 0, lastslash = 0, firstslash = (ch == '\\');
+ bufp = buf;
+ do
+ {
+ *bufp = ch;
+ lastslash = slash;
+ slash = (ch == '\\');
+
+ if (floatstate >= 0)
+ {
+ int digit = (ch >= '0' && ch <= '9'),
+ dot = (ch == '.'), minus = (ch == '-'),
+ plusminus = (minus || (ch == '+')),
+ expon = (ch == 'e' || ch == 'E');
+ if (floatstate == 0) /* beginning */
+ {
+ if (minus) floatstate = 1;
+ else if (digit) floatstate = 2;
+ else if (dot) floatstate = 3;
+ else floatstate = -1;
+ }
+ else if (floatstate == 1) /* got minus */
+ {
+ if (digit) floatstate = 2;
+ else if (dot) floatstate = 3;
+ else floatstate = -1;
+ }
+ else if (floatstate == 2) /* got digits */
+ {
+ if (dot) floatstate = 4;
+ else if (expon) floatstate = 6;
+ else if (!digit) floatstate = -1;
+ }
+ else if (floatstate == 3) /* got '.' without digits */
+ {
+ if (digit) floatstate = 5;
+ else floatstate = -1;
+ }
+ else if (floatstate == 4) /* got '.' after digits */
+ {
+ if (digit) floatstate = 5;
+ else if (expon) floatstate = 6;
+ else floatstate = -1;
+ }
+ else if (floatstate == 5) /* got digits after . */
+ {
+ if (expon) floatstate = 6;
+ else if (!digit) floatstate = -1;
+ }
+ else if (floatstate == 6) /* got 'e' */
+ {
+ if (plusminus) floatstate = 7;
+ else if (digit) floatstate = 8;
+ else floatstate = -1;
+ }
+ else if (floatstate == 7) /* got plus or minus */
+ {
+ if (digit) floatstate = 8;
+ else floatstate = -1;
+ }
+ else if (floatstate == 8) /* got digits */
+ {
+ if (!digit) floatstate = -1;
+ }
+ }
+ if (!slash) bufp++;
+ }
+ while ((ready = binport_readbyte(fp, &ch)) && bufp != ebuf
+ && (slash || (ch != ' ' && ch != '\n' && ch != '\r'
+ && ch != '\t' && ch != ',' && ch != ';')));
+ if (ready && (ch == ',' || ch == ';'))
+ ungetc(ch, fp);
+ *bufp = 0;
+#if 0
+ fprintf(stderr, "buf %s\n", buf);
+#endif
+ if (*buf == '$' && buf[1] >= '0' && buf[1] <= '9' && !firstslash)
{
- *ap = old->o_atombuf[old->o_ndx++];
- return (1);
+ for (bufp = buf+2; *bufp; bufp++)
+ {
+ if (*bufp < '0' || *bufp > '9')
+ {
+ ap->a_type = A_DOLLSYM;
+ ap->a_w.w_symbol = gensym(buf+1);
+ break;
+ }
+ }
+ if (ap->a_type == A_NULL)
+ {
+ ap->a_type = A_DOLLAR;
+ ap->a_w.w_index = atoi(buf+1);
+ }
}
- else return (0);
+ else if (floatstate == 2)
+ binport_setint(ap, atoi(buf));
+ else if (floatstate == 4 || floatstate == 5 || floatstate == 8)
+ binport_setfloat(ap, atof(buf));
+ else
+ binport_setsymbol(ap, gensym(buf));
}
+ return (1);
+}
+
+static int binport_nextatom(t_binport *bp, t_atom *ap)
+{
+ unsigned char opcode;
+ int opval;
+ char buf[64];
+
+ if (bp->b_ftype == BINPORT_MAXTEXT)
+ return (maxtext_nextatom(bp->b_fp, ap));
+ else if (bp->b_ftype == BINPORT_MAXOLD && bp->b_old)
+ return (binpold_nextatom(bp->b_old, ap));
+
if (!binport_readbyte(bp->b_fp, &opcode))
- goto bad;
+ goto badbin;
opval = opcode & 0x0f;
switch (opcode >> 4)
{
case BINPORT_INTTYPE: /* variable length int,
opval: length (number of bytes that follow) */
if (!binport_readbuf(bp->b_fp, buf, opval))
- goto bad;
+ goto badbin;
else
{
unsigned char *p = (unsigned char *)buf + opval;
@@ -590,7 +719,7 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
case BINPORT_FLOATTYPE: /* variable length float,
opval: length (number of bytes that follow) */
if (!binport_readbuf(bp->b_fp, buf, opval))
- goto bad;
+ goto badbin;
else
{
unsigned char *p = (unsigned char *)buf + opval;
@@ -602,22 +731,22 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
case BINPORT_SYMTYPE: /* variable length symbol id,
opval: length (number of bytes that follow) */
if (!binport_readbuf(bp->b_fp, buf, opval))
- goto bad;
+ goto badbin;
else
{
unsigned char *p = (unsigned char *)buf + opval;
int i = 0;
while (opval--) i = (i << 8) | *--p;
- if (!binport_setsymbol(bp, ap, i))
- goto bad;
+ if (!binport_setbysymtable(bp, ap, i))
+ goto badbin;
}
break;
case BINPORT_DEFINTTYPE: /* half-byte int */
binport_setint(ap, opval);
break;
case BINPORT_DEFSYMTYPE: /* half-byte symbol id */
- if (!binport_setsymbol(bp, ap, opval))
- goto bad;
+ if (!binport_setbysymtable(bp, ap, opval))
+ goto badbin;
break;
case BINPORT_SEMITYPE:
/* LATER warn about nonzero opval */
@@ -637,14 +766,14 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
case BINPORT_DOLLSYMTYPE: /* #symbol id,
opval: length (number of bytes that follow) */
if (!binport_readbuf(bp->b_fp, buf, opval))
- goto bad;
+ goto badbin;
else
{
unsigned char *p = (unsigned char *)buf + opval;
int i = 0;
while (opval--) i = (i << 8) | *--p;
- if (!binport_setsymbol(bp, ap, i))
- goto bad;
+ if (!binport_setbysymtable(bp, ap, i))
+ goto badbin;
}
sprintf(buf, "#%s", ap->a_w.w_symbol->s_name);
#ifdef BINPORT_DEBUG
@@ -654,23 +783,34 @@ static int binport_nextatom(t_binport *bp, t_atom *ap)
break;
default:
binport_error("unknown opcode %x", (int)opcode);
- goto bad;
+ goto badbin;
}
return (1);
-bad:
+badbin:
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 int binport_alike(char *header, int *ftypep)
{
- static char binpold_header[4] = { 0, 0, 0, 1 }; /* CHECKME any others? */
- return (memcmp(header, binpold_header, 4) == 0);
+ static char bin_header[4] = { 2, 0, 0, 0 }; /* CHECKME any others? */
+ static char old_header[4] = { 0, 0, 0, 1 }; /* CHECKME any others? */
+ static char text_header[4] = { 'm', 'a', 'x', ' ' };
+ static char pd_header[3] = { '#', 'N', ' ' }; /* canvas or struct */
+ if (memcmp(header, bin_header, 4) == 0)
+ *ftypep = BINPORT_OK;
+ else if (memcmp(header, text_header, 4) == 0)
+ *ftypep = BINPORT_MAXTEXT;
+ else if (memcmp(header, old_header, 4) == 0)
+ *ftypep = BINPORT_MAXOLD;
+ else
+ {
+ if (memcmp(header, pd_header, 3) == 0)
+ *ftypep = BINPORT_PDFILE;
+ else
+ *ftypep = BINPORT_INVALID;
+ return (0);
+ }
+ return (1);
}
static void binport_free(t_binport *bp)
@@ -688,108 +828,44 @@ static void binport_free(t_binport *bp)
static t_binport *binport_new(FILE *fp, int *ftypep)
{
+ t_binport *bp = 0;
char header[4];
- *ftypep = BINPORT_INVALID;
if (fread(header, 1, 4, fp) == 4)
{
- if (binport_binalike(header))
+ int alike = binport_alike(header, ftypep);
+ if (alike)
{
- t_binport *bp = getbytes(sizeof(*bp));
+ bp = getbytes(sizeof(*bp));
bp->b_fp = fp;
+ bp->b_ftype = *ftypep;
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;
+ if (*ftypep == BINPORT_OK)
+ {
+ bp->b_symsize = BINPORT_SYMGROW;
+ bp->b_symtable =
+ getbytes(bp->b_symsize * sizeof(*bp->b_symtable));
+ }
+ else
+ {
+ 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]);
}
+ else if (*ftypep != BINPORT_PDFILE)
+ binport_warning("unknown header: %02x%02x%02x%02x",
+ (int)header[0], (int)header[1],
+ (int)header[2], (int)header[3]);
}
- else binport_warning("file too short");
- 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)
-{
- FILE *fp;
- char namebuf[MAXPDSTRING];
- namebuf[0] = 0;
- if (*dirname)
- strcat(namebuf, dirname), strcat(namebuf, "/");
- strcat(namebuf, filename);
- sys_bashfilename(namebuf, namebuf);
- if (fp = fopen(namebuf, "rb"))
+ else
{
- int ftype;
- t_binport *bp = binport_new(fp, &ftype);
- if (bp)
- {
- 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 (result);
- }
- else if (ftype == BINPORT_MAXTEXT || ftype == BINPORT_PDFILE)
- return (ftype);
- else
- binport_failure(filename);
+ binport_warning("file too short");
+ *ftypep = BINPORT_INVALID;
}
- else binport_bug("cannot open file");
- return (BINPORT_INVALID);
+ if (!bp) fclose(fp);
+ return (bp);
}
-#else
-
static void binport_atomstring(t_atom *ap, char *buf, int bufsize)
{
char *sp, *bp, *ep;
@@ -836,29 +912,141 @@ static void binport_atomstring(t_atom *ap, char *buf, int bufsize)
}
}
-static void binport_print(t_binport *bp)
+static void binport_print(t_binport *bp, FILE *fp)
{
char buf[BINPORT_MAXSTRING];
t_atom at;
- int ac = 0;
+ int cnt = 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;
+ fputs(";\n", fp);
+ cnt = 0;
}
else if (at.a_type != A_NULL)
{
- if (ac++) fputc(' ', stdout);
+ if (cnt++) fputc(' ', fp);
binport_atomstring(&at, buf, BINPORT_MAXSTRING);
- fputs(buf, stdout);
+ fputs(buf, fp);
}
}
}
+#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)
+{
+ int result;
+ FILE *fp;
+ char namebuf[MAXPDSTRING];
+ namebuf[0] = 0;
+ if (*dirname)
+ strcat(namebuf, dirname), strcat(namebuf, "/");
+ strcat(namebuf, filename);
+ sys_bashfilename(namebuf, namebuf);
+ if (fp = fopen(namebuf, "rb"))
+ {
+ int ftype;
+ t_binport *bp = binport_new(fp, &ftype);
+ if (bp)
+ {
+ if (ftype == BINPORT_OK)
+ result = (binport_tobinbuf(bp, bb)
+ ? BINPORT_OK : BINPORT_CORRUPT);
+ else if (ftype == BINPORT_MAXTEXT)
+ {
+ t_atom at;
+ while (binport_nextatom(bp, &at))
+ if (at.a_type == A_SEMI)
+ break;
+ binbuf_addv(bb, "ss;", gensym("max"), gensym("v2"));
+ 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);
+ }
+ else if (ftype == BINPORT_PDFILE)
+ result = (binbuf_read(bb, filename, dirname, 0)
+ ? BINPORT_FAILED : BINPORT_PDFILE);
+ else
+ {
+ binport_failure(filename);
+ result = BINPORT_INVALID;
+ }
+ }
+ else
+ {
+ binport_bug("cannot open file");
+ result = BINPORT_FAILED;
+ }
+ return (result);
+}
+
+/* save as MAXTEXT */
+void binport_write(t_binbuf *bb, char *filename, char *dirname)
+{
+ int result;
+ FILE *fp;
+ char namebuf[MAXPDSTRING];
+ namebuf[0] = 0;
+ if (*dirname)
+ strcat(namebuf, dirname), strcat(namebuf, "/");
+ strcat(namebuf, filename);
+ sys_bashfilename(namebuf, namebuf);
+ if (fp = fopen(namebuf, "w"))
+ {
+ char buf[BINPORT_MAXSTRING];
+ t_atom *ap = binbuf_getvec(bb);
+ int cnt = 0, ac = binbuf_getnatom(bb);
+ while (ac--)
+ {
+ if (ap->a_type == A_SEMI)
+ {
+ fputs(";\n", fp);
+ cnt = 0;
+ }
+ else if (ap->a_type != A_NULL)
+ {
+ if (cnt++) fputc(' ', fp);
+ binport_atomstring(ap, buf, BINPORT_MAXSTRING);
+ fputs(buf, fp);
+ }
+ ap++;
+ }
+ fclose(fp);
+ }
+}
+
+#else
+
int main(int ac, char **av)
{
if (ac > 1)
@@ -871,7 +1059,9 @@ int main(int ac, char **av)
if (bp)
{
if (ftype == BINPORT_OK)
- binport_print(bp);
+ binport_print(bp, stdout);
+ else if (ftype == BINPORT_MAXTEXT)
+ binport_warning("\"%s\" looks like a Max text file", av[1]);
else if (ftype == BINPORT_MAXOLD)
{
t_binpold *old = binpold_new(fp);
@@ -879,7 +1069,7 @@ int main(int ac, char **av)
{
bp->b_old = old;
if (binpold_load(old))
- binport_print(bp);
+ binport_print(bp, stdout);
else
ftype = BINPORT_FAILED;
}
@@ -888,8 +1078,6 @@ int main(int ac, char **av)
}
binport_free(bp);
}
- else if (ftype == BINPORT_MAXTEXT)
- binport_warning("\"%s\" looks like a Max text file", av[1]);
else if (ftype == BINPORT_PDFILE)
binport_warning("\"%s\" looks like a Pd patch file", av[1]);
else
diff --git a/shared/common/binport.h b/shared/common/binport.h
index bdf1ca1..93120fa 100644
--- a/shared/common/binport.h
+++ b/shared/common/binport.h
@@ -10,6 +10,7 @@ enum { BINPORT_OK, BINPORT_MAXTEXT, BINPORT_MAXOLD, BINPORT_PDFILE,
#ifndef BINPORT_STANDALONE
int binport_read(t_binbuf *bb, char *filename, char *dirname);
+void binport_write(t_binbuf *bb, char *filename, char *dirname);
#endif
#endif
diff --git a/shared/common/loud.c b/shared/common/loud.c
index d5afada..d176eb0 100644
--- a/shared/common/loud.c
+++ b/shared/common/loud.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002-2003 krzYszcz and others.
+/* Copyright (c) 2002-2004 krzYszcz and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
@@ -127,11 +127,12 @@ void loud_classarg(t_class *c)
loud_error(0, "missing or bad arguments in \"%s\"", class_getname(c));
}
-void loud_warning(t_pd *x, char *fmt, ...)
+void loud_warning(t_pd *x, char *who, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "warning (%s): ", (x ? class_getname(*x) : "miXed"));
+ fprintf(stderr, "warning (%s): ",
+ (x ? class_getname(*x) : (who ? who : "miXed")));
vfprintf(stderr, fmt, ap);
va_end(ap);
putc('\n', stderr);
@@ -140,9 +141,9 @@ void loud_warning(t_pd *x, char *fmt, ...)
void loud_notimplemented(t_pd *x, char *name)
{
if (name)
- loud_warning(x, "\"%s\" method not implemented (yet)", name);
+ loud_warning(x, 0, "\"%s\" method not implemented (yet)", name);
else
- loud_warning(x, "not implemented (yet)");
+ loud_warning(x, 0, "not implemented (yet)");
}
void loud_incompatible(t_class *c, char *fmt, ...)
@@ -197,7 +198,7 @@ int loud_floatarg(t_class *c, int which, int ac, t_atom *av,
if (underaction & LOUD_WARN)
{
if (underaction & LOUD_CLIP)
- loud_warning(&c, "%s rounded up to %g", what, minval);
+ loud_warning(&c, 0, "%s rounded up to %g", what, minval);
else
loud_incompatible(c, "less than %g %s requested",
minval, what);
@@ -207,7 +208,7 @@ int loud_floatarg(t_class *c, int which, int ac, t_atom *av,
if (overaction & LOUD_WARN)
{
if (overaction & LOUD_CLIP)
- loud_warning(&c, "%s truncated to %g", what, maxval);
+ loud_warning(&c, 0, "%s truncated to %g", what, maxval);
else
loud_incompatible(c, "more than %g %s requested",
maxval, what);
diff --git a/shared/common/loud.h b/shared/common/loud.h
index eebb2c0..6073a85 100644
--- a/shared/common/loud.h
+++ b/shared/common/loud.h
@@ -21,7 +21,7 @@ void loud_nomethod(t_pd *x, t_symbol *s);
void loud_messarg(t_pd *x, t_symbol *s);
int loud_checkint(t_pd *x, t_float f, int *valuep, t_symbol *mess);
void loud_classarg(t_class *c);
-void loud_warning(t_pd *x, char *fmt, ...);
+void loud_warning(t_pd *x, char *who, char *fmt, ...);
void loud_notimplemented(t_pd *x, char *name);
void loud_incompatible(t_class *c, char *fmt, ...);
void loud_incompatible_max(t_class *c, int maxmax, char *what);
diff --git a/shared/common/port.c b/shared/common/port.c
index 95ccc7f..e6de120 100644
--- a/shared/common/port.c
+++ b/shared/common/port.c
@@ -27,6 +27,7 @@
//#define PORT_DEBUG
#define PORT_LOG
+#define PORT_DUMP /* fill separate files with ignored data, e.g. pictures */
#define PORT_INISTACK 256 /* LATER rethink */
#define PORT_INISIZE 512 /* LATER rethink */
@@ -51,8 +52,12 @@ enum { PORT_OK,
typedef struct _port
{
- t_binbuf *x_inbb;
t_binbuf *x_outbb;
+ int x_messcount;
+ int x_illmess;
+ int x_lastunexpected;
+ int x_lastbroken;
+ int x_lastinconsistent;
int x_nobj;
int x_withbogus;
int x_inatoms;
@@ -65,43 +70,59 @@ typedef struct _port
int x_stackdepth;
int *x_stack;
int x_stackini[PORT_INISTACK];
+ t_symbol *x_emstate;
+ t_binbuf *x_embb;
+ t_symbol *x_emname;
+ int x_emsize;
+ int x_emcount;
+ int x_dumping;
+ /* class-specifics, LATER find a better way */
+ int x_tablerange;
+ int x_tableleft;
+ int x_tabletop;
+ int x_tableright;
+ int x_tablebottom;
+ int x_tableflags;
+ FILE *x_pictfp;
+ int x_pictno;
} t_port;
static t_symbol *portps_bogus;
static t_symbol *portps_cleanup;
static t_symbol *portps_inlet;
static t_symbol *portps_outlet;
+static t_symbol *portps_vtable;
+static t_symbol *portps_coll;
+static t_symbol *portps_picture;
-static t_float port_floatarg(t_port *x, int ndx)
+static t_int port_getint(t_port *x, int ndx)
{
if (ndx < x->x_inatoms)
{
t_atom *av = &x->x_inmess[ndx];
- return (av->a_type == A_FLOAT ? av->a_w.w_float : 0);
+ if (av->a_type == A_INT)
+ return (av->a_w.w_index);
+ else if (av->a_type == A_FLOAT)
+ {
+ loud_warning(0, "import", "[%d] float atom %d, int expected",
+ x->x_messcount, ndx);
+ return ((t_int)av->a_w.w_float);
+ }
}
- else return (0);
+ return (0);
}
-static t_int port_intarg(t_port *x, int ndx)
+static t_float port_getfloat(t_port *x, int ndx)
{
if (ndx < x->x_inatoms)
{
t_atom *av = &x->x_inmess[ndx];
-#ifdef FIXME
- return (av->a_type == A_INT ? av->a_w.w_index : 0);
-#else
- if (av->a_type == A_INT)
- return (av->a_w.w_index);
- else if (av->a_type == A_FLOAT)
- return ((t_int)av->a_w.w_float);
- else
- return (0);
-#endif
+ return (av->a_type == A_FLOAT ? av->a_w.w_float : 0);
}
else return (0);
}
-static t_symbol *port_symbolarg(t_port *x, int ndx)
+static t_symbol *port_getsymbol(t_port *x, int ndx)
{
if (ndx < x->x_inatoms)
{
@@ -111,6 +132,36 @@ static t_symbol *port_symbolarg(t_port *x, int ndx)
else return (&s_);
}
+static t_symbol *port_getanysymbol(t_port *x, int ndx)
+{
+ t_symbol *sel = &s_;
+ if (ndx < x->x_inatoms)
+ {
+ t_atom *av = &x->x_inmess[ndx];
+ if (av->a_type == A_SYMBOL)
+ sel = av->a_w.w_symbol;
+ else if (av->a_type == A_INT)
+ sel = gensym("int");
+ else if (av->a_type == A_FLOAT)
+ sel = &s_float;
+ }
+ return (sel);
+}
+
+static t_symbol *port_gettarget(t_port *x)
+{
+ t_symbol *sel = port_getsymbol(x, 0);
+ if (sel == &s_) bug("port_gettarget");
+ return (sel);
+}
+
+static t_symbol *port_getselector(t_port *x)
+{
+ t_symbol *sel = port_getanysymbol(x, 1);
+ if (sel == &s_) bug("port_getselector");
+ return (sel);
+}
+
static int port_xstretch(float f)
{
return ((int)(f * PORT_XSTRETCH + 0.5));
@@ -126,27 +177,27 @@ static int port_wstretch(float f)
return ((int)(f * PORT_WSTRETCH + 0.5));
}
-static t_float port_xarg(t_port *x, int ndx)
+static t_float port_getx(t_port *x, int ndx)
{
- return ((t_float)port_xstretch(port_intarg(x, ndx)));
+ return ((t_float)port_xstretch(port_getint(x, ndx)));
}
-static t_float port_yarg(t_port *x, int ndx)
+static t_float port_gety(t_port *x, int ndx)
{
- return ((t_float)port_ystretch(port_intarg(x, ndx)));
+ return ((t_float)port_ystretch(port_getint(x, ndx)));
}
-static t_float port_widtharg(t_port *x, int ndx)
+static t_float port_getwidth(t_port *x, int ndx)
{
- return ((t_float)port_wstretch(port_intarg(x, ndx)));
+ return ((t_float)port_wstretch(port_getint(x, ndx)));
}
static void port_setxy(t_port *x, int ndx, t_atom *ap)
{
- float f = port_xarg(x, ndx);
+ float f = port_getx(x, ndx);
SETFLOAT(ap, f);
ndx++; ap++;
- f = port_yarg(x, ndx);
+ f = port_gety(x, ndx);
SETFLOAT(ap, f);
}
@@ -164,28 +215,156 @@ static t_atom *import_copyatoms(t_atom *out, t_atom *in, int ac)
return (out);
}
+static void import_unexpected(t_port *x)
+{
+ if (x->x_lastunexpected < x->x_messcount) /* ignore redundant calls */
+ {
+ x->x_lastunexpected = x->x_messcount;
+ loud_warning(0, "import", "[%d] unexpected \"%s %s\"", x->x_messcount,
+ port_gettarget(x)->s_name, port_getselector(x)->s_name);
+ }
+}
+
+static void import_illegal(t_port *x)
+{
+ x->x_illmess++;
+}
+
+static void import_flushillegal(t_port *x)
+{
+ if (x->x_illmess)
+ {
+ if (x->x_illmess == 1)
+ loud_warning(0, "import", "[%d] illegal line", x->x_messcount);
+ else
+ loud_warning(0, "import", "[%d] %d illegal lines",
+ x->x_messcount, x->x_illmess);
+ x->x_illmess = 0;
+ }
+}
+
+static void import_embroken(t_port *x, char *cause)
+{
+ if (x->x_lastbroken < x->x_messcount) /* ignore redundant calls */
+ {
+ x->x_lastbroken = x->x_messcount;
+ loud_warning(0, "import", "[%d] %s embedding broken by %s",
+ x->x_messcount, x->x_emstate->s_name, cause);
+ }
+}
+
+static int import_emcheck(t_port *x, t_symbol *state)
+{
+ if (x->x_emstate == state)
+ return (1);
+ else if (x->x_emstate)
+ import_embroken(x, state->s_name);
+ else
+ import_unexpected(x);
+ return (0);
+}
+
+static void import_eminconsistent(t_port *x, t_symbol *state)
+{
+ if (import_emcheck(x, state) &&
+ x->x_lastinconsistent < x->x_messcount) /* ignore redundant calls */
+ {
+ x->x_lastinconsistent = x->x_messcount;
+ loud_warning(0, "import", "[%d] %s embedding ended inconsistently",
+ x->x_messcount, state->s_name);
+ }
+}
+
+static int import_emcheckend(t_port *x, t_symbol *state, t_symbol *name)
+{
+ if (import_emcheck(x, state))
+ {
+ if (x->x_emcount /* empty ok for vtable, CHECKME other cases */
+ && x->x_emsize != x->x_emcount)
+ loud_warning(0, "import",
+ "[%d] corrupt %s (%d atoms declared, %d provided)",
+ x->x_messcount, state->s_name,
+ x->x_emsize, x->x_emcount);
+ else
+ {
+ if (name != x->x_emname) /* warn and accept, LATER rethink */
+ import_eminconsistent(x, state);
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static void import_emstart(t_port *x, t_symbol *state, t_symbol *name, int size)
+{
+ if (x->x_emstate) import_embroken(x, state->s_name);
+ x->x_emstate = state;
+ binbuf_clear(x->x_embb);
+ x->x_emname = name;
+ x->x_emsize = size;
+ x->x_emcount = 0;
+}
+
+static void import_emend(t_port *x, t_symbol *state, t_symbol *name)
+{
+ import_emcheckend(x, state, name);
+ x->x_emstate = 0;
+ x->x_emname = 0;
+ x->x_emsize = 0;
+ x->x_emcount = 0;
+ binbuf_clear(x->x_embb);
+}
+
+static void import_emflush(t_port *x, t_symbol *state, t_symbol *name)
+{
+ int ac = binbuf_getnatom(x->x_embb);
+ if (import_emcheckend(x, state, name) && ac)
+ binbuf_add(x->x_outbb, ac, binbuf_getvec(x->x_embb));
+ x->x_emstate = 0;
+ x->x_emname = 0;
+ x->x_emsize = 0;
+ x->x_emcount = 0;
+ if (ac) binbuf_clear(x->x_embb);
+ binbuf_addv(x->x_outbb, "ss;", gensym("#C"), gensym("restore"));
+}
+
+static int import_emcopy(t_port *x, t_symbol *state)
+{
+ if (import_emcheck(x, state))
+ {
+ t_atom *out = x->x_outmess;
+ SETSYMBOL(out, gensym("#C")); out++;
+ out = import_copyatoms(out, x->x_inmess + 1, x->x_inatoms - 1);
+ SETSEMI(out);
+ binbuf_add(x->x_embb, x->x_inatoms + 1, x->x_outmess);
+ return (1);
+ }
+ else return (0);
+}
+
static void import_addclassname(t_port *x, char *outname, t_atom *inatom)
{
t_atom at;
if (outname)
SETSYMBOL(&at, gensym(outname));
- else if (inatom->a_type == A_SYMBOL)
+ else
{
- /* LATER bash inatom to lowercase (CHECKME first) */
- t_symbol *insym = inatom->a_w.w_symbol;
- if (insym != &s_bang && insym != &s_float &&
- insym != &s_symbol && insym != &s_list &&
- (insym == portps_inlet || insym == portps_outlet ||
- zgetfn(&pd_objectmaker, insym) == 0))
-
+ if (inatom->a_type == A_SYMBOL)
{
- x->x_withbogus = 1;
- SETSYMBOL(&at, portps_bogus);
- binbuf_add(x->x_outbb, 1, &at);
+ /* LATER bash inatom to lowercase (CHECKME first) */
+ t_symbol *insym = inatom->a_w.w_symbol;
+ if (insym != &s_bang && insym != &s_float &&
+ insym != &s_symbol && insym != &s_list &&
+ (insym == portps_inlet || insym == portps_outlet ||
+ zgetfn(&pd_objectmaker, insym) == 0))
+ {
+ x->x_withbogus = 1;
+ SETSYMBOL(&at, portps_bogus);
+ binbuf_add(x->x_outbb, 1, &at);
+ }
}
- SETSYMBOL(&at, insym);
+ import_copyatoms(&at, inatom, 1);
}
- else at = *inatom;
binbuf_add(x->x_outbb, 1, &at);
}
@@ -194,7 +373,7 @@ static int import_obj(t_port *x, char *name)
int ndx = (x->x_inmess[1].a_w.w_symbol == gensym("user") ? 3 : 2);
binbuf_addv(x->x_outbb, "ssff",
gensym("#X"), gensym("obj"),
- port_xarg(x, ndx), port_yarg(x, ndx + 1));
+ port_getx(x, ndx), port_gety(x, ndx + 1));
import_addclassname(x, name, &x->x_inmess[ndx == 2 ? 6 : 2]);
binbuf_addsemi(x->x_outbb);
x->x_nobj++;
@@ -242,44 +421,58 @@ static int imaction_N1_vpatcher(t_port *x, char *arg)
x->x_nobj = 0;
binbuf_addv(x->x_outbb, "ssfffff;",
gensym("#N"), gensym("canvas"),
- port_xarg(x, 2), port_yarg(x, 3),
- (float)port_xstretch(port_intarg(x, 4) - port_intarg(x, 2)),
- (float)port_ystretch(port_intarg(x, 5) - port_intarg(x, 3)),
+ port_getx(x, 2), port_gety(x, 3),
+ (float)port_xstretch(port_getint(x, 4) - port_getint(x, 2)),
+ (float)port_ystretch(port_getint(x, 5) - port_getint(x, 3)),
PORT_DEFFONTSIZE);
return (PORT_NEXT);
}
-/* FIXME */
static int imaction_N1_vtable(t_port *x, char *arg)
{
-#if 1
+ import_emstart(x, portps_vtable, port_getsymbol(x, 9), port_getint(x, 2));
+ x->x_tablerange = port_getint(x, 8);
+ x->x_tableleft = port_getint(x, 3);
+ x->x_tabletop = port_getint(x, 4);
+ x->x_tableright = port_getint(x, 5);
+ x->x_tablebottom = port_getint(x, 6);
+ x->x_tableflags = port_getint(x, 7);
+#ifdef PORT_DEBUG
post("vtable \"%s\": size %d, range %d, coords %d %d %d %d, flags %d",
- port_symbolarg(x, 9)->s_name,
- port_intarg(x, 2), port_intarg(x, 8),
- port_intarg(x, 3), port_intarg(x, 4),
- port_intarg(x, 5), port_intarg(x, 6),
- port_intarg(x, 7));
+ x->x_emname->s_name, x->x_emsize, x->x_tablerange,
+ x->x_tableleft, x->x_tabletop, x->x_tableright, x->x_tablebottom,
+ x->x_tableflags);
#endif
return (PORT_NEXT);
}
-/* FIXME */
+static int imaction_N1_coll(t_port *x, char *arg)
+{
+ import_emstart(x, portps_coll, port_getsymbol(x, 2), 0);
+ return (PORT_NEXT);
+}
+
static int imaction_N1_picture(t_port *x, char *arg)
{
-#if 1
- post("picture");
-#endif
+ import_emstart(x, portps_picture, 0, 0);
+ if (x->x_pictfp)
+ {
+ import_unexpected(x);
+ if (x->x_dumping)
+ fclose(x->x_pictfp);
+ x->x_pictfp = 0;
+ }
return (PORT_NEXT);
}
static int imaction_P6_patcher(t_port *x, char *arg)
{
- binbuf_addv(x->x_outbb, "ss;", portps_cleanup, portps_cleanup);
- x->x_withbogus = 0;
+ if (x->x_withbogus)
+ binbuf_addv(x->x_outbb, "ss;", portps_cleanup, portps_cleanup);
binbuf_addv(x->x_outbb, "ssffss;",
gensym("#X"), gensym("restore"),
- port_xarg(x, 2), port_yarg(x, 3),
- gensym("pd"), port_symbolarg(x, 7));
+ port_getx(x, 2), port_gety(x, 3),
+ gensym("pd"), port_getsymbol(x, 7));
if (x->x_stackdepth) /* LATER consider returning PORT_FATAL otherwise */
x->x_stackdepth--;
x->x_nobj = x->x_stack[x->x_stackdepth];
@@ -287,13 +480,71 @@ static int imaction_P6_patcher(t_port *x, char *arg)
return (PORT_NEXT);
}
-static int imaction_P6_trigger(t_port *x, char *arg)
+static int imaction_P6_table(t_port *x, char *arg)
+{
+ t_symbol *tablename = port_getsymbol(x, 7);
+ binbuf_addv(x->x_outbb, "ssffs",
+ gensym("#X"), gensym("obj"),
+ port_getx(x, 2), port_gety(x, 3), gensym("Table"));
+ if (tablename != &s_)
+ {
+ t_atom at;
+ SETSYMBOL(&at, tablename);
+ binbuf_add(x->x_outbb, 1, &at);
+ }
+ binbuf_addsemi(x->x_outbb);
+ import_emflush(x, portps_vtable, tablename);
+ x->x_nobj++;
+ return (PORT_NEXT);
+}
+
+static int imaction_P6_coll(t_port *x, char *arg)
+{
+ t_symbol *collname = port_getsymbol(x, 7);
+ binbuf_addv(x->x_outbb, "ssffs",
+ gensym("#X"), gensym("obj"),
+ port_getx(x, 2), port_gety(x, 3), portps_coll);
+ if (collname != &s_)
+ {
+ t_atom at;
+ SETSYMBOL(&at, collname);
+ binbuf_add(x->x_outbb, 1, &at);
+ }
+ binbuf_addsemi(x->x_outbb);
+ import_emflush(x, portps_coll, collname);
+ x->x_nobj++;
+ return (PORT_NEXT);
+}
+
+/* LATER use hammer replacements */
+static int imaction_P6_pack(t_port *x, char *arg)
{
int i;
for (i = 7; i < x->x_inatoms; i++)
- if (x->x_inmess[i].a_type == A_SYMBOL &&
- x->x_inmess[i].a_w.w_symbol == gensym("i"))
- x->x_inmess[i].a_w.w_symbol = gensym("f");
+ {
+ if (x->x_inmess[i].a_type == A_SYMBOL)
+ {
+ t_symbol *s = x->x_inmess[i].a_w.w_symbol;
+ if (s->s_name[1])
+ x->x_inmess[i].a_w.w_symbol = gensym("s");
+ else switch (*s->s_name) {
+ case 'b': case 'f': case 's': case 'l':
+ break;
+ case 'i':
+ x->x_inmess[i].a_w.w_symbol = gensym("f");
+ break;
+ default:
+ x->x_inmess[i].a_w.w_symbol = gensym("s");
+ }
+ }
+ }
+ return (PORT_OK);
+}
+
+/* LATER consider using hammer replacements */
+static int imaction_P6_midi(t_port *x, char *arg)
+{
+ x->x_inatoms = 7; /* ugly, LATER rethink */
return (PORT_OK);
}
@@ -334,7 +585,7 @@ static int imaction_P1_comment(t_port *x, char *arg)
if (x->x_inatoms > 5)
{
int i, fontsize, fontprops;
- float width = port_widtharg(x, 4);
+ float width = port_getwidth(x, 4);
t_atom *ap = x->x_inmess + 5;
SETFLOAT(x->x_outmess + 5, width);
if (ap->a_type == A_INT)
@@ -383,7 +634,7 @@ static int imaction_P1_io(t_port *x, char *arg)
{
binbuf_addv(x->x_outbb, "ssff",
gensym("#X"), gensym("obj"),
- port_xarg(x, 2), port_yarg(x, 3));
+ port_getx(x, 2), port_gety(x, 3));
if (x->x_inmess[1].a_w.w_symbol == portps_inlet ||
x->x_inmess[1].a_w.w_symbol == portps_outlet)
{
@@ -401,7 +652,25 @@ static int imaction_P1_number(t_port *x, char *arg)
{
binbuf_addv(x->x_outbb, "ssff;",
gensym("#X"), gensym("floatatom"),
- port_xarg(x, 2), port_yarg(x, 3));
+ port_getx(x, 2), port_gety(x, 3));
+ x->x_nobj++;
+ return (PORT_NEXT);
+}
+
+static int imaction_P1_vpicture(t_port *x, char *arg)
+{
+ import_emend(x, portps_picture, 0);
+ if (x->x_pictfp)
+ {
+ if (x->x_dumping)
+ fclose(x->x_pictfp);
+ x->x_pictfp = 0;
+ }
+ else import_unexpected(x);
+ binbuf_addv(x->x_outbb, "ssffs;",
+ gensym("#X"), gensym("obj"),
+ port_getx(x, 2), port_gety(x, 3),
+ gensym("vpicture"));
x->x_nobj++;
return (PORT_NEXT);
}
@@ -410,41 +679,91 @@ static int imaction_P1_connect(t_port *x, char *arg)
{
binbuf_addv(x->x_outbb, "ssiiii;",
gensym("#X"), gensym("connect"),
- x->x_nobj - port_intarg(x, 2) - 1,
- port_intarg(x, 3),
- x->x_nobj - port_intarg(x, 4) - 1,
- port_intarg(x, 5));
+ x->x_nobj - port_getint(x, 2) - 1,
+ port_getint(x, 3),
+ x->x_nobj - port_getint(x, 4) - 1,
+ port_getint(x, 5));
+ return (PORT_NEXT);
+}
+
+static int imaction_T1_int(t_port *x, char *arg)
+{
+ import_emcopy(x, portps_coll);
+ return (PORT_NEXT);
+}
+
+static int imaction_T1_flags(t_port *x, char *arg)
+{
+ import_emcopy(x, portps_coll);
return (PORT_NEXT);
}
-/* FIXME */
static int imaction_T1_set(t_port *x, char *arg)
{
-#if 1
- post("set (%d atoms from %d): %d ... %d",
- x->x_inatoms - 3, port_intarg(x, 2),
- port_intarg(x, 3), port_intarg(x, x->x_inatoms - 1));
-#endif
+ if (import_emcopy(x, portps_vtable))
+ {
+ int count = port_getint(x, 2);
+ if (count != x->x_emcount)
+ loud_warning(0, "import",
+ "[%d] bad vtable chunk index %d (%d already taken)",
+ x->x_messcount, count, x->x_emcount);
+ x->x_emcount += x->x_inatoms - 3;
+ }
return (PORT_NEXT);
}
-/* FIXME */
static int imaction_K1_replace(t_port *x, char *arg)
{
-#if 1
- post("replace %d", port_intarg(x, 2));
-#endif
+ if (x->x_pictfp)
+ {
+ import_unexpected(x);
+ if (x->x_dumping)
+ fclose(x->x_pictfp);
+ x->x_pictfp = 0;
+ }
+ else if (import_emcheck(x, portps_picture))
+ {
+ char buf[32];
+ x->x_emsize = port_getint(x, 2);
+ x->x_emcount = 0;
+ sprintf(buf, "port-%02d.pict", ++x->x_pictno);
+ if (x->x_dumping)
+ {
+ if (x->x_pictfp = fopen(buf, "wb"))
+ {
+ int i;
+ for (i = 0; i < 512; i++) fputc(0, x->x_pictfp);
+ }
+ }
+ else x->x_pictfp = (FILE *)1;
+ }
return (PORT_NEXT);
}
-/* FIXME */
static int imaction_K1_set(t_port *x, char *arg)
{
-#if 1
- post("set (%d atoms from %d): %d ... %d",
- x->x_inatoms - 3, port_intarg(x, 2),
- port_intarg(x, 3), port_intarg(x, x->x_inatoms - 1));
-#endif
+ if (!x->x_pictfp)
+ import_unexpected(x);
+ else if (import_emcheck(x, portps_picture))
+ {
+ int i, count = port_getint(x, 2);
+ if (count != x->x_emcount)
+ loud_warning(0, "import",
+ "[%d] bad picture chunk index %d (%d already taken)",
+ x->x_messcount, count, x->x_emcount);
+ x->x_emcount += x->x_inatoms - 3;
+ if (x->x_dumping)
+ {
+ for (i = 3; i < x->x_inatoms; i++)
+ {
+ int v = port_getint(x, i);
+ fputc(v >> 24, x->x_pictfp);
+ fputc((v >> 16) & 0x0ff, x->x_pictfp);
+ fputc((v >> 8) & 0x0ff, x->x_pictfp);
+ fputc(v & 0x0ff, x->x_pictfp);
+ }
+ }
+ }
return (PORT_NEXT);
}
@@ -472,6 +791,7 @@ static t_portslot imslots__N[] =
{
{ "vpatcher", imaction_N1_vpatcher, 0, 0, 0 },
{ "vtable", imaction_N1_vtable, 0, 0, 0 },
+ { "coll", imaction_N1_coll, 0, 0, 0 },
{ "picture", imaction_N1_picture, 0, 0, 0 }
};
static t_portnode imnode__N = { imslots__N, PORT_NSLOTS(imslots__N), 1 };
@@ -480,8 +800,8 @@ static t_portslot imslots_newobj[] =
{
{ "patcher", imaction_P6_patcher, 0, 0, 0 },
{ "p", imaction_P6_patcher, 0, 0, 0 },
- /* state is embedded in #N vtable...; #T set...; */
- { "table", import_obj, "Table", 0, 0 }
+ { "table", imaction_P6_table, 0, 0, 0 },
+ { "coll", imaction_P6_coll, 0, 0, 0 }
};
static t_portnode imnode_newobj = { imslots_newobj,
PORT_NSLOTS(imslots_newobj), 6 };
@@ -500,8 +820,22 @@ static t_portslot imslots_newex[] =
{ "line~", import_objarg, "Line~", 0, 0 },
{ "poly", import_objarg, "Poly", 0, 0 },
{ "snapshot~", import_objarg, "Snapshot~", 0, 0 },
- { "trigger", imaction_P6_trigger, 0, 0, 0 },
- { "t", imaction_P6_trigger, 0, 0, 0 },
+
+ { "pack", imaction_P6_pack, 0, 0, 0 },
+ { "unpack", imaction_P6_pack, 0, 0, 0 },
+ { "trigger", imaction_P6_pack, 0, 0, 0 },
+ { "t", imaction_P6_pack, 0, 0, 0 },
+
+ { "midiin", imaction_P6_midi, 0, 0, 0 },
+ { "midiout", imaction_P6_midi, 0, 0, 0 },
+ { "notein", imaction_P6_midi, 0, 0, 0 },
+ { "noteout", imaction_P6_midi, 0, 0, 0 },
+ { "pgmin", imaction_P6_midi, 0, 0, 0 },
+ { "pgmout", imaction_P6_midi, 0, 0, 0 },
+ { "ctlin", imaction_P6_midi, 0, 0, 0 },
+ { "ctlout", imaction_P6_midi, 0, 0, 0 },
+ { "bendin", imaction_P6_midi, 0, 0, 0 },
+ { "bendout", imaction_P6_midi, 0, 0, 0 },
/* LATER rethink */
{ "Borax", import_objarg, "Borax", 0, 0 },
@@ -549,7 +883,7 @@ static t_portslot imslots__P[] =
{ "preset", import_obj, "preset", 0, 0 },
/* an object created from the "Paste Picture" menu,
state is embedded in #N picture; #K...; */
- { "vpicture", import_obj, "vpicture", 0, 0 },
+ { "vpicture", imaction_P1_vpicture, 0, 0, 0 },
{ "connect", imaction_P1_connect, 0, 0, 0 },
{ "fasten", imaction_P1_connect, 0, 0, 0 }
};
@@ -557,6 +891,8 @@ static t_portnode imnode__P = { imslots__P, PORT_NSLOTS(imslots__P), 1 };
static t_portslot imslots__T[] =
{
+ { "int", imaction_T1_int, 0, 0, 0 },
+ { "flags", imaction_T1_flags, 0, 0, 0 },
{ "set", imaction_T1_set, 0, 0, 0 }
};
static t_portnode imnode__T = { imslots__T, PORT_NSLOTS(imslots__T), 1 };
@@ -577,13 +913,13 @@ static t_portslot imslots_[] =
};
static t_portnode imnode_ = { imslots_, PORT_NSLOTS(imslots_), 0 };
-static int port_doline(t_port *x, t_portnode *node)
+static int port_doparse(t_port *x, t_portnode *node)
{
int nslots = node->n_nslots;
if (nslots > 0)
{
t_portslot *slot = node->n_table;
- t_symbol *insym = port_symbolarg(x, node->n_index);
+ t_symbol *insym = port_getanysymbol(x, node->n_index);
char *inname = 0;
secondpass:
while (nslots--)
@@ -594,7 +930,7 @@ secondpass:
if (slot->s_subtree)
{
int nobj = x->x_nobj;
- int result = port_doline(x, slot->s_subtree);
+ int result = port_doparse(x, slot->s_subtree);
if (result == PORT_FATAL || result == PORT_CORRUPT ||
result == PORT_NEXT)
return (result);
@@ -614,10 +950,55 @@ secondpass:
goto secondpass;
}
}
- else bug("port_doline");
+ else bug("port_doparse");
return (PORT_UNKNOWN);
}
+static int port_parsemessage(t_port *x)
+{
+ import_flushillegal(x);
+ x->x_messcount++;
+ return (port_doparse(x, &imnode_));
+}
+
+static void port_startparsing(t_port *x)
+{
+#ifdef PORT_DEBUG
+ post("parsing...");
+#endif
+ x->x_messcount = 0;
+ x->x_illmess = 0;
+ x->x_lastunexpected = -1;
+ x->x_lastbroken = -1;
+ x->x_lastinconsistent = -1;
+ x->x_nobj = 0;
+ x->x_emstate = 0;
+ binbuf_clear(x->x_embb);
+ x->x_pictno = 0;
+ x->x_pictfp = 0;
+}
+
+static void port_endparsing(t_port *x)
+{
+ import_flushillegal(x);
+ if (x->x_emstate)
+ {
+ import_embroken(x, "end of file");
+ x->x_emstate = 0;
+ }
+ binbuf_clear(x->x_embb);
+ if (x->x_pictfp)
+ {
+ loud_warning(0, "import", "incomplete picture");
+ if (x->x_dumping)
+ fclose(x->x_pictfp);
+ x->x_pictfp = 0;
+ }
+#ifdef PORT_DEBUG
+ post("end of parsing");
+#endif
+}
+
static void port_dochecksetup(t_portnode *node)
{
t_portslot *slots = node->n_table;
@@ -660,7 +1041,7 @@ static void bogus_tick(t_bogus *x)
if (x->x_bound)
{
#ifdef PORT_DEBUG
- post("unbinding '%x'", (int)x);
+ post("bogus_tick: unbinding '%x'", (int)x);
#endif
pd_unbind((t_pd *)x, portps_cleanup);
x->x_bound = 0;
@@ -674,7 +1055,7 @@ static void bogushook_tick(t_bogushook *x)
static void bogus_cleanup(t_bogus *x)
{
- if (x->x_glist)
+ if (x->x_glist && x->x_glist == canvas_getcurrent())
{
t_text *t = (t_text *)x;
int ac = binbuf_getnatom(t->te_binbuf);
@@ -838,6 +1219,9 @@ static void port_checksetup(void)
portps_cleanup = gensym("_port.cleanup");
portps_inlet = gensym("inlet");
portps_outlet = gensym("outlet");
+ portps_vtable = gensym("vtable");
+ portps_coll = gensym("coll");
+ portps_picture = gensym("picture");
if (zgetfn(&pd_objectmaker, portps_bogus) == 0)
{
@@ -860,7 +1244,6 @@ static void port_checksetup(void)
static t_port *port_new(void)
{
t_port *x = (t_port *)getbytes(sizeof(*x));
- x->x_inbb = binbuf_new();
x->x_outbb = 0;
x->x_withbogus = 0;
x->x_outsize = PORT_INISIZE;
@@ -869,6 +1252,13 @@ static t_port *port_new(void)
x->x_stacksize = PORT_INISTACK;
x->x_stackdepth = 0;
x->x_stack = x->x_stackini;
+ x->x_emstate = 0;
+ x->x_embb = binbuf_new();
+#ifdef PORT_DUMP
+ x->x_dumping = 1;
+#else
+ x->x_dumping = 0;
+#endif
return (x);
}
@@ -888,14 +1278,19 @@ static void port_free(t_port *x)
freebytes(x->x_outmess, x->x_outsize * sizeof(*x->x_outmess));
if (x->x_stack != x->x_stackini)
freebytes(x->x_stack, x->x_stacksize * sizeof(*x->x_stack));
+ if (x->x_embb)
+ binbuf_free(x->x_embb);
freebytes(x, sizeof(*x));
}
-static int import_binbuf(t_port *x)
+static int import_binbuf(t_port *x, t_binbuf *inbb, t_binbuf *outbb)
{
- t_atom *av = binbuf_getvec(x->x_inbb);
- int ac = binbuf_getnatom(x->x_inbb);
+ int result = PORT_OK;
+ t_atom *av = binbuf_getvec(inbb);
+ int ac = binbuf_getnatom(inbb);
int startmess, endmess;
+ x->x_outbb = outbb;
+ port_startparsing(x);
for (startmess = 0; startmess < ac; startmess = endmess + 1)
{
t_atom *mess = av + startmess, *ap;
@@ -903,14 +1298,27 @@ static int import_binbuf(t_port *x)
for (endmess = startmess, ap = mess;
ap->a_type != A_SEMI; endmess++, ap++)
if (endmess == ac)
- return (PORT_CORRUPT); /* no final semi */
+ {
+ result = PORT_CORRUPT; /* no final semi */
+ goto endparsing;
+ }
if (endmess == startmess || endmess == startmess + 1
- || mess->a_type != A_SYMBOL || mess[1].a_type != A_SYMBOL)
+ || mess->a_type != A_SYMBOL)
{
startmess = endmess + 1;
+ import_illegal(x);
continue;
}
- if (mess[1].a_w.w_symbol == gensym("hidden"))
+ if (mess[1].a_type != A_SYMBOL)
+ {
+ if (mess[1].a_type != A_INT && mess[1].a_type != A_FLOAT)
+ {
+ startmess = endmess + 1;
+ import_illegal(x);
+ continue;
+ }
+ }
+ else if (mess[1].a_w.w_symbol == gensym("hidden"))
{
t_symbol *sel = mess[1].a_w.w_symbol;
mess[1].a_w.w_symbol = mess->a_w.w_symbol;
@@ -919,6 +1327,7 @@ static int import_binbuf(t_port *x)
if (endmess == startmess + 1 || mess[1].a_type != A_SYMBOL)
{
startmess = endmess + 1;
+ import_illegal(x);
continue;
}
}
@@ -954,16 +1363,22 @@ static int import_binbuf(t_port *x)
SETSYMBOL(ap, gensym(buf));
}
}
- if (port_doline(x, &imnode_) == PORT_FATAL)
- return (PORT_FATAL);
+ if (port_parsemessage(x) == PORT_FATAL)
+ {
+ result = PORT_FATAL;
+ goto endparsing;
+ }
}
- return (PORT_OK);
+endparsing:
+ port_endparsing(x);
+ return (result);
}
void import_max(char *fn, char *dir)
{
t_port *x;
- int failure, fd, ftype;
+ t_binbuf *inbb, *outbb;
+ int fd, ftype;
char buf[MAXPDSTRING], *bufp;
t_pd *stackp = 0;
int dspstate = canvas_suspend_dsp();
@@ -976,43 +1391,38 @@ void import_max(char *fn, char *dir)
else close (fd);
x = port_new();
+ inbb = binbuf_new();
glob_setfilename(0, gensym(bufp), gensym(buf));
- ftype = binport_read(x->x_inbb, bufp, buf);
- /* FIXME for BINPORT_MAXTEXT use an int-preserving version of binbuf_read */
- if (ftype == BINPORT_MAXTEXT || ftype == BINPORT_PDFILE)
- failure = binbuf_read(x->x_inbb, bufp, buf, 0);
- else
- failure = (ftype != BINPORT_OK); /* LATER rethink */
- if (failure)
- {
- perror(fn); /* FIXME */
- binbuf_free(x->x_inbb);
- }
- else
+ ftype = binport_read(inbb, bufp, buf);
+ if (ftype == BINPORT_OK)
{
- if (ftype == BINPORT_PDFILE) x->x_outbb = x->x_inbb;
- else
- {
#ifdef PORT_DEBUG
- /* save as .pd (bypass export translation) */
- binbuf_write(x->x_inbb, "import-debug.pd", "", 0);
+ binport_write(inbb, "import-debug.pat", "");
#endif
- x->x_outbb = binbuf_new();
- if (import_binbuf(x) != PORT_OK)
- {
- loud_error(0, "%s: import failed", fn);
- x->x_outbb = 0;
- }
- binbuf_free(x->x_inbb);
+ outbb = binbuf_new();
+ if (import_binbuf(x, inbb, outbb) != PORT_OK)
+ {
+ loud_error(0, "%s: import failed", fn);
+ binbuf_free(outbb);
+ outbb = 0;
+ }
+ binbuf_free(inbb);
#ifdef PORT_LOG
- if (x->x_outbb) binbuf_write(x->x_outbb, "import-result.pd", "", 0);
+ if (outbb) binbuf_write(outbb, "import-result.pd", "", 0);
#endif
- }
- if (x->x_outbb)
- {
- binbuf_eval(x->x_outbb, 0, 0, 0);
- binbuf_free(x->x_outbb);
- }
+ }
+ else if (ftype == BINPORT_PDFILE)
+ outbb = inbb;
+ else
+ {
+ perror(fn); /* FIXME */
+ binbuf_free(inbb);
+ outbb = 0;
+ }
+ if (outbb)
+ {
+ binbuf_eval(outbb, 0, 0, 0);
+ binbuf_free(outbb);
}
port_free(x);
diff --git a/shared/toxy/scriptlet.c b/shared/toxy/scriptlet.c
index 192eaa6..df94e90 100644
--- a/shared/toxy/scriptlet.c
+++ b/shared/toxy/scriptlet.c
@@ -747,7 +747,7 @@ int scriptlet_write(t_scriptlet *sp, t_symbol *fn)
}
else
{
- loud_warning(sp->s_owner, "empty scriptlet not written");
+ loud_warning(sp->s_owner, "scriptlet", "empty scriptlet not written");
return (SCRIPTLET_IGNORED);
}
}
diff --git a/shared/unstable/fragile.c b/shared/unstable/fragile.c
index b86fba8..cd92b72 100644
--- a/shared/unstable/fragile.c
+++ b/shared/unstable/fragile.c
@@ -110,7 +110,7 @@ t_object *fragile_outlet_destination(t_outlet *op,
if (booty)
{
if (count > 1 && caller)
- loud_warning(caller, "multiple targets");
+ loud_warning(caller, 0, "multiple targets");
}
else if (caller)
{