diff options
author | N.N. <krzyszcz@users.sourceforge.net> | 2004-04-17 17:45:29 +0000 |
---|---|---|
committer | N.N. <krzyszcz@users.sourceforge.net> | 2004-04-17 17:45:29 +0000 |
commit | 691dabc423f0ac541038484ff69a2ec871c121d9 (patch) | |
tree | c04442e5ad96e216987ba065d5f0be401a149cbc /shared | |
parent | 54bcb818c192b63e7121d6259a1b77ea4bfb49c5 (diff) |
importing ints
svn path=/trunk/externals/miXed/; revision=1608
Diffstat (limited to 'shared')
-rw-r--r-- | shared/common/binport.c | 470 | ||||
-rw-r--r-- | shared/common/binport.h | 1 | ||||
-rw-r--r-- | shared/common/loud.c | 15 | ||||
-rw-r--r-- | shared/common/loud.h | 2 | ||||
-rw-r--r-- | shared/common/port.c | 682 | ||||
-rw-r--r-- | shared/toxy/scriptlet.c | 2 | ||||
-rw-r--r-- | shared/unstable/fragile.c | 2 |
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) { |