From bfb359fd22e61faaca3a6e49ad3b7a81f2d71551 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Thu, 27 Jan 2005 14:42:55 +0000 Subject: cyclone alpha52 and toxy alpha15 (see notes.txt for cyclone, toxy and shared) svn path=/trunk/externals/miXed/; revision=2550 --- shared/common/Makefile.sources | 2 +- shared/common/binport.c | 16 +-- shared/common/binport.h | 14 ++- shared/common/fi.c | 54 ---------- shared/common/fi.h | 11 -- shared/common/fitter.c | 33 +++--- shared/common/fitter.h | 5 +- shared/common/loud.c | 26 ++++- shared/common/os.c | 235 +++++++++++++++++++++++++++++++++++++++++ shared/common/os.h | 13 +++ shared/common/port.c | 28 +++-- shared/common/port.h | 4 +- shared/getridof.baddeps | 2 +- shared/hammer/file.c | 117 ++++++++++++++++++-- shared/hammer/file.h | 27 ++--- shared/notes.txt | 29 +++++ shared/unstable/forky.c | 3 +- shared/unstable/fragile.c | 174 +++++++++++++++++++++++++++++- shared/unstable/fragile.h | 9 +- shared/unstable/pd_imp.h | 2 + 20 files changed, 664 insertions(+), 140 deletions(-) delete mode 100644 shared/common/fi.c delete mode 100644 shared/common/fi.h create mode 100644 shared/common/os.c create mode 100644 shared/common/os.h create mode 100644 shared/notes.txt (limited to 'shared') diff --git a/shared/common/Makefile.sources b/shared/common/Makefile.sources index f605df4..76fd3cc 100644 --- a/shared/common/Makefile.sources +++ b/shared/common/Makefile.sources @@ -2,12 +2,12 @@ OTHER_SOURCES = \ binport.c \ clc.c \ dict.c \ -fi.c \ fitter.c \ grow.c \ lex.c \ loud.c \ mifi.c \ +os.c \ port.c \ props.c \ qtree.c \ diff --git a/shared/common/binport.c b/shared/common/binport.c index 4fe46e8..1df9571 100644 --- a/shared/common/binport.c +++ b/shared/common/binport.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997-2004 Miller Puckette, krzYszcz, and others. +/* Copyright (c) 1997-2005 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. */ @@ -584,7 +584,7 @@ static int binport_alike(char *header, int *ftypep) 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; + *ftypep = BINPORT_MAXBINARY; else if (memcmp(header, text_header, 4) == 0) *ftypep = BINPORT_MAXTEXT; else if (memcmp(header, old_header, 4) == 0) @@ -631,7 +631,7 @@ static t_binport *binport_new(FILE *fp, int *ftypep) bp->b_fp = fp; bp->b_ftype = *ftypep; bp->b_nsymbols = 0; - if (*ftypep == BINPORT_OK) + if (*ftypep == BINPORT_MAXBINARY) { bp->b_symsize = BINPORT_SYMGROW; bp->b_symtable = @@ -712,9 +712,9 @@ int binport_read(t_binbuf *bb, char *filename, char *dirname) t_binport *bp = binport_new(fp, &ftype); if (bp) { - if (ftype == BINPORT_OK) + if (ftype == BINPORT_MAXBINARY) result = (binport_tobinbuf(bp, bb) - ? BINPORT_OK : BINPORT_CORRUPT); + ? BINPORT_MAXBINARY : BINPORT_CORRUPT); else if (ftype == BINPORT_MAXTEXT) { t_atom at; @@ -725,7 +725,7 @@ int binport_read(t_binbuf *bb, char *filename, char *dirname) break; binbuf_addv(bb, "ss;", gensym("max"), gensym("v2")); result = (binport_tobinbuf(bp, bb) - ? BINPORT_OK : BINPORT_CORRUPT); + ? BINPORT_MAXTEXT : BINPORT_CORRUPT); } else result = BINPORT_FAILED; } @@ -737,7 +737,7 @@ int binport_read(t_binbuf *bb, char *filename, char *dirname) { bp->b_old = old; if (binpold_load(old) && binport_tobinbuf(bp, bb)) - result = BINPORT_OK; + result = BINPORT_MAXOLD; } else binpold_failure(filename); } @@ -809,7 +809,7 @@ int main(int ac, char **av) t_binport *bp = binport_new(fp, &ftype); if (bp) { - if (ftype == BINPORT_OK) + if (ftype == BINPORT_MAXBINARY) binport_print(bp, stdout); else if (ftype == BINPORT_MAXTEXT) binport_warning("\"%s\" looks like a Max text file", av[1]); diff --git a/shared/common/binport.h b/shared/common/binport.h index f29d24d..b70c555 100644 --- a/shared/common/binport.h +++ b/shared/common/binport.h @@ -1,12 +1,20 @@ -/* Copyright (c) 2003-2004 krzYszcz and others. +/* Copyright (c) 2003-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #ifndef __BINPORT_H__ #define __BINPORT_H__ -enum { BINPORT_OK, BINPORT_MAXTEXT, BINPORT_MAXOLD, BINPORT_PDFILE, - BINPORT_INVALID, BINPORT_CORRUPT, BINPORT_FAILED }; +/* return values of binport_read() and import_max(), also passed to + outlet_float() by cyclone library objects (cyclone, maxmode...) */ +#define BINPORT_FAILED -4 /* internal error */ +#define BINPORT_CORRUPT -3 /* file contents inconsistency */ +#define BINPORT_INVALID -2 /* file type not recognized */ +#define BINPORT_NOFILE -1 /* file not found */ +#define BINPORT_MAXBINARY 0 +#define BINPORT_MAXTEXT 1 +#define BINPORT_MAXOLD 2 +#define BINPORT_PDFILE 3 #ifndef MIXED_STANDALONE int binport_read(t_binbuf *bb, char *filename, char *dirname); diff --git a/shared/common/fi.c b/shared/common/fi.c deleted file mode 100644 index e46d001..0000000 --- a/shared/common/fi.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 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. */ - -#ifdef NT -#include -#else -#include -#endif -#include -#include -#include "m_pd.h" -#include "fi.h" - -FILE *firead_open(char *filename, t_canvas *cv, int textmode) -{ - int fd; - char path[MAXPDSTRING+2], *nameptr; - t_symbol *dirsym = (cv ? canvas_getdir(cv) : 0); - /* path arg is returned unbashed (system-independent) */ - if ((fd = open_via_path((dirsym ? dirsym->s_name : ""), filename, - "", path, &nameptr, MAXPDSTRING, 1)) < 0) - return (0); - /* Closing/reopening dance. This is unnecessary under linux, and we - could have tried to convert fd to fp, but under windows open_via_path() - returns what seems to be an invalid fd. - LATER try to understand what is going on here... */ - close(fd); - if (path != nameptr) - { - char *slashpos = path + strlen(path); - *slashpos++ = '/'; - /* try not to be dependent on current open_via_path() implementation */ - if (nameptr != slashpos) - strcpy(slashpos, nameptr); - } - sys_bashfilename(path, path); - return (fopen(path, (textmode ? "r" : "rb"))); -} - -FILE *fiwrite_open(char *filename, t_canvas *cv, int textmode) -{ - char path[MAXPDSTRING+2]; - if (cv) - /* path arg is returned unbashed (system-independent) */ - canvas_makefilename(cv, filename, path, MAXPDSTRING); - else - { - strncpy(path, filename, MAXPDSTRING); - path[MAXPDSTRING-1] = 0; - } - sys_bashfilename(path, path); - return (fopen(path, (textmode ? "w" : "wb"))); -} diff --git a/shared/common/fi.h b/shared/common/fi.h deleted file mode 100644 index c6e8401..0000000 --- a/shared/common/fi.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) 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. */ - -#ifndef __FI_H__ -#define __FI_H__ - -FILE *firead_open(char *filename, t_canvas *cv, int textmode); -FILE *fiwrite_open(char *filename, t_canvas *cv, int textmode); - -#endif diff --git a/shared/common/fitter.c b/shared/common/fitter.c index 2ccdd53..faba970 100644 --- a/shared/common/fitter.c +++ b/shared/common/fitter.c @@ -25,7 +25,7 @@ static t_symbol *fittermode_value = 0; typedef struct _fittermode_client { t_class *fc_owner; - t_symbol **fc_mirror; + t_canvas *fc_canvas; t_fittermode_callback fc_callback; struct _fittermode_client *fc_next; } t_fittermode_client; @@ -36,6 +36,7 @@ static t_pd *fittermode_target = 0; static int fittermode_ready = 0; static t_symbol *fitterps_hashcompatibility = 0; static t_symbol *fitterps_max = 0; +static t_symbol *fitterps_none = 0; /* read access (query), only from fittermode_dosetup() */ static void fittermode_bang(t_pd *x) @@ -55,6 +56,11 @@ static void fittermode_bang(t_pd *x) /* read access (reply), only from fitter_dosetup() */ static void fittermode_symbol(t_pd *x, t_symbol *s) { + if (!s || s == &s_) + { + loudbug_bug("fittermode_symbol"); + s = fitterps_none; + } fittermode_value = s; } @@ -64,12 +70,8 @@ static void fittermode_set(t_pd *x, t_symbol *s) t_fittermode_client *fc; fittermode_value = s; for (fc = fittermode_clients; fc; fc = fc->fc_next) - { - if (fc->fc_mirror) - *fc->fc_mirror = s; if (fc->fc_callback) - fc->fc_callback(s); - } + fc->fc_callback(); } static void fittermode_dosetup(int noquery) @@ -78,9 +80,11 @@ static void fittermode_dosetup(int noquery) loudbug_bug("fittermode_dosetup"); fitterps_hashcompatibility = gensym("#compatibility"); fitterps_max = gensym("max"); + fitterps_none = gensym("none"); + fittermode_value = fitterps_none; fittermode_class = class_new(fitterps_hashcompatibility, - 0, 0, sizeof(t_pd), - CLASS_PD | CLASS_NOINLET, 0); + 0, 0, sizeof(t_pd), + CLASS_PD | CLASS_NOINLET, 0); class_addbang(fittermode_class, fittermode_bang); class_addsymbol(fittermode_class, fittermode_symbol); class_addmethod(fittermode_class, @@ -93,21 +97,18 @@ static void fittermode_dosetup(int noquery) fittermode_ready = 1; } -void fitter_setup(t_class *owner, t_symbol **mirror, - t_fittermode_callback callback) +void fitter_setup(t_class *owner, t_fittermode_callback callback) { if (!fittermode_class) fittermode_dosetup(0); - if (mirror || callback) + if (callback) { t_fittermode_client *fc = getbytes(sizeof(*fc)); fc->fc_owner = owner; - fc->fc_mirror = mirror; + fc->fc_canvas = 0; /* a global client */ fc->fc_callback = callback; fc->fc_next = fittermode_clients; fittermode_clients = fc; - if (mirror) - *mirror = fittermode_value; } } @@ -140,7 +141,9 @@ void fitter_drop(t_class *owner) void fitter_setmode(t_symbol *s) { - post("setting compatibility mode to '%s'", (s ? s->s_name : "none")); + if (!s || s == &s_) + s = fitterps_none; + post("setting compatibility mode to '%s'", s->s_name); if (!fittermode_class) fittermode_dosetup(1); if (fitterps_hashcompatibility->s_thing) diff --git a/shared/common/fitter.h b/shared/common/fitter.h index 3f3303c..2e5c24d 100644 --- a/shared/common/fitter.h +++ b/shared/common/fitter.h @@ -5,10 +5,9 @@ #ifndef __FITTER_H__ #define __FITTER_H__ -typedef void (*t_fittermode_callback)(t_symbol *s); +typedef void (*t_fittermode_callback)(void); -void fitter_setup(t_class *owner, t_symbol **mirror, - t_fittermode_callback callback); +void fitter_setup(t_class *owner, t_fittermode_callback callback); void fitter_drop(t_class *owner); void fitter_setmode(t_symbol *s); t_symbol *fitter_getmode(void); diff --git a/shared/common/loud.c b/shared/common/loud.c index 6229a77..d87d3c0 100644 --- a/shared/common/loud.c +++ b/shared/common/loud.c @@ -348,6 +348,9 @@ void loudbug_post(char *fmt, ...) vsnprintf(buf, MAXPDSTRING-1, fmt, ap); va_end(ap); fprintf(stderr, "%s\n", buf); +#ifdef MSW + fflush(stderr); +#endif } void loudbug_startpost(char *fmt, ...) @@ -358,11 +361,17 @@ void loudbug_startpost(char *fmt, ...) vsnprintf(buf, MAXPDSTRING-1, fmt, ap); va_end(ap); fputs(buf, stderr); +#ifdef MSW + fflush(stderr); +#endif } void loudbug_endpost(void) { fputs("\n", stderr); +#ifdef MSW + fflush(stderr); +#endif } void loudbug_postatom(int ac, t_atom *av) @@ -372,6 +381,9 @@ void loudbug_postatom(int ac, t_atom *av) char buf[MAXPDSTRING]; atom_string(av++, buf, MAXPDSTRING); fprintf(stderr, " %s", buf); +#ifdef MSW + fflush(stderr); +#endif } } @@ -391,9 +403,18 @@ void loudbug_postbinbuf(t_binbuf *bb) fprintf(stderr, " %s", buf); } else fprintf(stderr, "%s", buf); +#ifdef MSW + fflush(stderr); +#endif aprev = ap++; } - if (aprev) fputs("\n", stderr); + if (aprev) + { + fputs("\n", stderr); +#ifdef MSW + fflush(stderr); +#endif + } } void loudbug_bug(char *fmt, ...) @@ -404,5 +425,8 @@ void loudbug_bug(char *fmt, ...) vsnprintf(buf, MAXPDSTRING-1, fmt, ap); va_end(ap); fprintf(stderr, "miXed consistency check failed: %s\n", buf); +#ifdef MSW + fflush(stderr); +#endif bug(buf); } diff --git a/shared/common/os.c b/shared/common/os.c new file mode 100644 index 0000000..9129f82 --- /dev/null +++ b/shared/common/os.c @@ -0,0 +1,235 @@ +/* Copyright (c) 2004-2005 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#ifdef MSW +#include +#else +#include +#endif +#include +#include +#include +#include "m_pd.h" +#include "os.h" + +static int ospath_doabsolute(char *path, char *cwd, char *result) +{ + if (*path == 0) + { + if (result) + strcpy(result, cwd); + else + return (strlen(cwd)); + } + else if (*path == '~') + { + path++; + if (*path == '/' || *path == 0) + { +#ifdef UNIX + char *home = getenv("HOME"); + if (home) + { + if (result) + { + strcpy(result, home); + if (*path) + strcat(result, path); + } + else return (strlen(home) + strlen(path)); + } + else goto badpath; +#else + goto badpath; +#endif + } + else goto badpath; + } + else if (*path == '/') + { +#ifdef MSW + /* path is absolute, drive is implicit, LATER UNC? */ + if (*cwd && cwd[1] == ':') + { + if (result) + { + *result = *cwd; + result[1] = ':'; + strcpy(result + 2, path); + } + else return (2 + strlen(path)); + } + else goto badpath; +#else + /* path is absolute */ + if (result) + strcpy(result, path); + else + return (strlen(path)); +#endif + } + else + { +#ifdef MSW + if (path[1] == ':') + { + if (path[2] == '/') + { + /* path is absolute */ + if (result) + strcpy(result, path); + else + return (strlen(path)); + } + else if (*cwd == *path) + { + /* path is relative, drive is explicitly current */ + if (result) + { + int ndx = strlen(cwd); + strcpy(result, cwd); + result[ndx++] = '/'; + strcpy(result + ndx, path + 2); + } + else return (strlen(cwd) + strlen(path) - 1); + } + /* we do not maintain per-drive cwd, LATER rethink */ + else goto badpath; + } + /* LATER devices? */ + else + { + /* path is relative */ + if (result) + { + int ndx = strlen(cwd); + strcpy(result, cwd); + result[ndx++] = '/'; + strcpy(result + ndx, path); + } + else return (strlen(cwd) + 1 + strlen(path)); + } +#else + /* path is relative */ + if (result) + { + int ndx = strlen(cwd); + strcpy(result, cwd); + result[ndx++] = '/'; + strcpy(result + ndx, path); + } + else return (strlen(cwd) + 1 + strlen(path)); +#endif + } + if (result && *result && *result != '.') + { + /* clean-up */ + char *inptr, *outptr = result; + int ndx = strlen(result); + if (result[ndx - 1] == '.') + { + result[ndx] = '/'; /* guarding slash */ + result[ndx + 1] = 0; + } + for (inptr = result + 1; *inptr; inptr++) + { + if (*inptr == '/') + { + if (*outptr == '/') + continue; + else if (*outptr == '.') + { + if (outptr[-1] == '/') + { + outptr--; + continue; + } + else if (outptr[-1] == '.' && outptr[-2] == '/') + { + outptr -= 2; + if (outptr == result) + continue; + else for (outptr--; outptr != result; outptr--) + if (*outptr == '/') + break; + continue; + } + } + } + *++outptr = *inptr; + } + if (*outptr == '/' && outptr != result) + *outptr = 0; + else + outptr[1] = 0; + } + else bug("ospath_doabsolute 1"); + return (0); +badpath: + if (result) + bug("ospath_doabsolute 2"); + return (0); +} + +/* Returns an estimated length of an absolute path made up from the first arg. + The actual ospath_absolute()'s length may be shorter (since it erases + superfluous slashes and dots), but not longer. Both args should be unbashed + (system-independent), cwd should be absolute. Returns 0 in case of any + error (LATER revisit). */ +int ospath_length(char *path, char *cwd) +{ + /* one extra byte used internally (guarding slash) */ + return (ospath_doabsolute(path, cwd, 0) + 1); +} + +/* Copies an absolute path to result. Arguments: path and cwd, are the same + as in ospath_length(). Caller should first consult ospath_length(), and + allocate at least ospath_length() + 1 bytes to the result buffer. + Should never fail (failure is a bug). */ +char *ospath_absolute(char *path, char *cwd, char *result) +{ + ospath_doabsolute(path, cwd, result); + return (result); +} + +FILE *fileread_open(char *filename, t_canvas *cv, int textmode) +{ + int fd; + char path[MAXPDSTRING+2], *nameptr; + t_symbol *dirsym = (cv ? canvas_getdir(cv) : 0); + /* path arg is returned unbashed (system-independent) */ + if ((fd = open_via_path((dirsym ? dirsym->s_name : ""), filename, + "", path, &nameptr, MAXPDSTRING, 1)) < 0) + return (0); + /* Closing/reopening dance. This is unnecessary under linux, and we + could have tried to convert fd to fp, but under windows open_via_path() + returns what seems to be an invalid fd. + LATER try to understand what is going on here... */ + close(fd); + if (path != nameptr) + { + char *slashpos = path + strlen(path); + *slashpos++ = '/'; + /* try not to be dependent on current open_via_path() implementation */ + if (nameptr != slashpos) + strcpy(slashpos, nameptr); + } + sys_bashfilename(path, path); + return (fopen(path, (textmode ? "r" : "rb"))); +} + +FILE *filewrite_open(char *filename, t_canvas *cv, int textmode) +{ + char path[MAXPDSTRING+2]; + if (cv) + /* path arg is returned unbashed (system-independent) */ + canvas_makefilename(cv, filename, path, MAXPDSTRING); + else + { + strncpy(path, filename, MAXPDSTRING); + path[MAXPDSTRING-1] = 0; + } + sys_bashfilename(path, path); + return (fopen(path, (textmode ? "w" : "wb"))); +} diff --git a/shared/common/os.h b/shared/common/os.h new file mode 100644 index 0000000..f3dde89 --- /dev/null +++ b/shared/common/os.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2004-2005 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#ifndef __OS_H__ +#define __OS_H__ + +int ospath_length(char *path, char *cwd); +char *ospath_absolute(char *path, char *cwd, char *result); +FILE *fileread_open(char *filename, t_canvas *cv, int textmode); +FILE *filewrite_open(char *filename, t_canvas *cv, int textmode); + +#endif diff --git a/shared/common/port.c b/shared/common/port.c index 159eab1..5845210 100644 --- a/shared/common/port.c +++ b/shared/common/port.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997-2004 Miller Puckette, krzYszcz, and others. +/* Copyright (c) 1997-2005 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. */ @@ -1596,11 +1596,12 @@ endparsing: return (result); } -void import_max(char *fn, char *dir) +int import_max(char *fn, char *dir) { + int result; t_port *x; t_binbuf *inbb, *outbb; - int fd, ftype; + int fd; char buf[MAXPDSTRING], *bufp; t_pd *stackp = 0; int dspstate = canvas_suspend_dsp(); @@ -1608,23 +1609,30 @@ void import_max(char *fn, char *dir) if ((fd = open_via_path(dir, fn, "", buf, &bufp, MAXPDSTRING, 0)) < 0) { loud_error(0, "%s: can't open", fn); - return; + return (BINPORT_NOFILE); } else close (fd); x = port_new(); inbb = binbuf_new(); glob_setfilename(0, gensym(bufp), gensym(buf)); - ftype = binport_read(inbb, bufp, buf); - if (ftype == BINPORT_OK) + result = binport_read(inbb, bufp, buf); + if (result == BINPORT_MAXBINARY || + result == BINPORT_MAXTEXT || + result == BINPORT_MAXOLD) { + int bbresult; #ifdef PORT_DEBUG binport_write(inbb, "import-debug.pat", ""); #endif outbb = binbuf_new(); - if (import_binbuf(x, inbb, outbb) != PORT_OK) + if ((bbresult = import_binbuf(x, inbb, outbb)) != PORT_OK) { - loud_error(0, "%s: import failed", fn); + loud_error(0, "%s: import failed (%d)", fn, bbresult); + if (bbresult == PORT_CORRUPT) + result = BINPORT_CORRUPT; + else + result = BINPORT_FAILED; binbuf_free(outbb); outbb = 0; } @@ -1633,7 +1641,7 @@ void import_max(char *fn, char *dir) if (outbb) binbuf_write(outbb, "import-result.pd", "", 0); #endif } - else if (ftype == BINPORT_PDFILE) + else if (result == BINPORT_PDFILE) outbb = inbb; else { @@ -1656,4 +1664,6 @@ void import_max(char *fn, char *dir) #if 0 /* LATER */ pd_doloadbang(); #endif + + return (result); } diff --git a/shared/common/port.h b/shared/common/port.h index 2053c20..48f58bd 100644 --- a/shared/common/port.h +++ b/shared/common/port.h @@ -1,11 +1,11 @@ -/* Copyright (c) 2003-2004 krzYszcz and others. +/* Copyright (c) 2003-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #ifndef __PORT_H__ #define __PORT_H__ -void import_max(char *fn, char *dir); +int import_max(char *fn, char *dir); void import_setmapping(int size, char **mapping); char **import_getmapping(int *sizep); char *port_usemapping(char *from, int mapsize, char **mapping); diff --git a/shared/getridof.baddeps b/shared/getridof.baddeps index 77c055a..ebbf3df 100644 --- a/shared/getridof.baddeps +++ b/shared/getridof.baddeps @@ -9,7 +9,7 @@ common/qtree -> common/loud common/binport -> common/lex common/port -> common/loud, common/grow, common/binport, unstable/forky, unstable/fragile, unstable/fringe -hammer/file -> unstable/forky +hammer/file -> common/os unstable/forky sickle/sic -> common/loud sickle/arsic -> common/loud, common/vefl, sickle/sic, unstable/fragile toxy/plusbob -> common/loud diff --git a/shared/hammer/file.c b/shared/hammer/file.c index 1cd6bfc..ecb5006 100644 --- a/shared/hammer/file.c +++ b/shared/hammer/file.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002-2003 krzYszcz and others. +/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ @@ -22,9 +22,29 @@ #include #include "m_pd.h" #include "g_canvas.h" +#include "common/os.h" #include "unstable/forky.h" #include "hammer/file.h" +struct _hammerfile +{ + t_pd f_pd; + t_pd *f_master; + t_canvas *f_canvas; + t_symbol *f_bindname; + t_symbol *f_currentdir; + t_symbol *f_inidir; + t_symbol *f_inifile; + t_hammerfilefn f_panelfn; + t_hammerfilefn f_editorfn; + t_hammerembedfn f_embedfn; + t_binbuf *f_binbuf; + t_clock *f_panelclock; + t_clock *f_editorclock; + struct _hammerfile *f_savepanel; + struct _hammerfile *f_next; +}; + static t_class *hammerfile_class = 0; static t_hammerfile *hammerfile_proxies; static t_symbol *ps__C; @@ -183,12 +203,14 @@ static void hammerpanel_guidefs(void) sys_gui(" set filename [tk_getOpenFile \\\n"); sys_gui(" -initialdir $inidir]\n"); sys_gui(" if {$filename != \"\"} {\n"); -#if 0 sys_gui(" set directory [string range $filename 0 \\\n"); sys_gui(" [expr [string last / $filename ] - 1]]\n"); - sys_gui(" set pd_opendir $directory\n"); + sys_gui(" if {$directory == \"\"} {set directory \"/\"}\n"); +#if 1 + sys_gui(" puts stderr [concat $directory]\n"); #endif - sys_gui(" pd [concat $target symbol [pdtk_enquote $filename] \\;]\n"); + sys_gui(" pd [concat $target path \\\n"); + sys_gui(" [pdtk_enquote $filename] [pdtk_enquote $directory] \\;]\n"); sys_gui(" }\n"); sys_gui("}\n"); @@ -200,17 +222,39 @@ static void hammerpanel_guidefs(void) sys_gui(" set filename [tk_getSaveFile]\n"); sys_gui(" }\n"); sys_gui(" if {$filename != \"\"} {\n"); - sys_gui(" pd [concat $target symbol [pdtk_enquote $filename] \\;]\n"); + sys_gui(" set directory [string range $filename 0 \\\n"); + sys_gui(" [expr [string last / $filename ] - 1]]\n"); + sys_gui(" if {$directory == \"\"} {set directory \"/\"}\n"); + sys_gui(" pd [concat $target path \\\n"); + sys_gui(" [pdtk_enquote $filename] [pdtk_enquote $directory] \\;]\n"); sys_gui(" }\n"); sys_gui("}\n"); } +/* There are two modes of -initialdir persistence: + 1. Using last reply from gui (if any, default is canvas directory): + pass null to hammerpanel_open/save() (for explicit cd, optionally call + hammerpanel_setopen/savedir() first). + 2. Starting always in the same directory (eg. canvasdir): + feed hammerpanel_open/save(). + Usually, first mode fits opening better, the second -- saving. */ + +/* This is obsolete, but has to stay, because older versions of miXed libraries + might overwrite new hammerpanel_guidefs(). FIXME we need version control. */ static void hammerpanel_symbol(t_hammerfile *f, t_symbol *s) { if (s && s != &s_ && f->f_panelfn) (*f->f_panelfn)(f->f_master, s, 0, 0); } +static void hammerpanel_path(t_hammerfile *f, t_symbol *s1, t_symbol *s2) +{ + if (s2 && s2 != &s_) + f->f_currentdir = s2; + if (s1 && s1 != &s_ && f->f_panelfn) + (*f->f_panelfn)(f->f_master, s1, 0, 0); +} + static void hammerpanel_tick(t_hammerfile *f) { if (f->f_savepanel) @@ -225,16 +269,63 @@ static void hammerpanel_tick(t_hammerfile *f) a message box redraw to happen -- LATER investigate */ void hammerpanel_open(t_hammerfile *f, t_symbol *inidir) { - f->f_inidir = (inidir ? inidir : &s_); + if (inidir) + f->f_inidir = inidir; + else + f->f_inidir = (f->f_currentdir ? f->f_currentdir : &s_); clock_delay(f->f_panelclock, 0); } +void hammerpanel_setopendir(t_hammerfile *f, t_symbol *dir) +{ + if (f->f_currentdir && f->f_currentdir != &s_) + { + if (dir && dir != &s_) + { + int length; + if (length = ospath_length(dir->s_name, f->f_currentdir->s_name)) + { + char *path = getbytes(length + 1); + if (ospath_absolute(dir->s_name, f->f_currentdir->s_name, path)) + /* LATER stat (think how to report a failure) */ + f->f_currentdir = gensym(path); + freebytes(path, length + 1); + } + } + else if (f->f_canvas) + f->f_currentdir = canvas_getdir(f->f_canvas); + } + else bug("hammerpanel_setopendir"); +} + +t_symbol *hammerpanel_getopendir(t_hammerfile *f) +{ + return (f->f_currentdir); +} + void hammerpanel_save(t_hammerfile *f, t_symbol *inidir, t_symbol *inifile) { - /* LATER ask if we can rely on s_ pointing to "" */ - f->f_savepanel->f_inidir = (inidir ? inidir : &s_); - f->f_savepanel->f_inifile = (inifile ? inifile : &s_); - clock_delay(f->f_savepanel->f_panelclock, 0); + if (f = f->f_savepanel) + { + if (inidir) + f->f_inidir = inidir; + else + /* LATER ask if we can rely on s_ pointing to "" */ + f->f_inidir = (f->f_currentdir ? f->f_currentdir : &s_); + f->f_inifile = (inifile ? inifile : &s_); + clock_delay(f->f_panelclock, 0); + } +} + +void hammerpanel_setsavedir(t_hammerfile *f, t_symbol *dir) +{ + if (f = f->f_savepanel) + hammerpanel_setopendir(f, dir); +} + +t_symbol *hammerpanel_getsavedir(t_hammerfile *f) +{ + return (f->f_savepanel ? f->f_savepanel->f_currentdir : 0); } /* Currently embeddable hammer classes do not use the 'saveto' method. @@ -363,13 +454,17 @@ t_hammerfile *hammerfile_new(t_pd *master, t_hammerembedfn embedfn, sprintf(buf, "miXed.%x", (int)result); result->f_bindname = gensym(buf); pd_bind((t_pd *)result, result->f_bindname); + result->f_currentdir = + result->f_inidir = canvas_getdir(result->f_canvas); result->f_panelfn = readfn; result->f_panelclock = clock_new(result, (t_method)hammerpanel_tick); f = (t_hammerfile *)pd_new(hammerfile_class); f->f_master = master; + f->f_canvas = result->f_canvas; sprintf(buf, "miXed.%x", (int)f); f->f_bindname = gensym(buf); pd_bind((t_pd *)f, f->f_bindname); + f->f_currentdir = f->f_inidir = result->f_currentdir; f->f_panelfn = writefn; f->f_panelclock = clock_new(f, (t_method)hammerpanel_tick); result->f_savepanel = f; @@ -406,6 +501,8 @@ void hammerfile_setup(t_class *c, int embeddable) sizeof(t_hammerfile), CLASS_PD | CLASS_NOINLET, 0); class_addsymbol(hammerfile_class, hammerpanel_symbol); + class_addmethod(hammerfile_class, (t_method)hammerpanel_path, + gensym("path"), A_SYMBOL, A_DEFSYM, 0); class_addmethod(hammerfile_class, (t_method)hammereditor_clear, gensym("clear"), 0); class_addmethod(hammerfile_class, (t_method)hammereditor_addline, diff --git a/shared/hammer/file.h b/shared/hammer/file.h index fb87ed1..13be3b8 100644 --- a/shared/hammer/file.h +++ b/shared/hammer/file.h @@ -1,36 +1,25 @@ -/* Copyright (c) 2002-2003 krzYszcz and others. +/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ #ifndef __HAMMERFILE_H__ #define __HAMMERFILE_H__ +EXTERN_STRUCT _hammerfile; +#define t_hammerfile struct _hammerfile + typedef void (*t_hammerfilefn)(t_pd *, t_symbol *, int, t_atom *); typedef void (*t_hammerembedfn)(t_pd *, t_binbuf *, t_symbol *); -typedef struct _hammerfile -{ - t_pd f_pd; - t_pd *f_master; - t_canvas *f_canvas; - t_symbol *f_bindname; - t_symbol *f_inidir; - t_symbol *f_inifile; - t_hammerfilefn f_panelfn; - t_hammerfilefn f_editorfn; - t_hammerembedfn f_embedfn; - t_binbuf *f_binbuf; - t_clock *f_panelclock; - t_clock *f_editorclock; - struct _hammerfile *f_savepanel; - struct _hammerfile *f_next; -} t_hammerfile; - void hammereditor_open(t_hammerfile *f, char *title); void hammereditor_close(t_hammerfile *f, int ask); void hammereditor_append(t_hammerfile *f, char *contents); void hammerpanel_open(t_hammerfile *f, t_symbol *inidir); +void hammerpanel_setopendir(t_hammerfile *f, t_symbol *dir); +t_symbol *hammerpanel_getopendir(t_hammerfile *f); void hammerpanel_save(t_hammerfile *f, t_symbol *inidir, t_symbol *inifile); +void hammerpanel_setsavedir(t_hammerfile *f, t_symbol *dir); +t_symbol *hammerpanel_getsavedir(t_hammerfile *f); int hammerfile_ismapped(t_hammerfile *f); int hammerfile_isloading(t_hammerfile *f); int hammerfile_ispasting(t_hammerfile *f); diff --git a/shared/notes.txt b/shared/notes.txt new file mode 100644 index 0000000..44c0c11 --- /dev/null +++ b/shared/notes.txt @@ -0,0 +1,29 @@ +TODO for root and shared + * fitter: abstraction-scoped, class-selective compatibility control + * fitter: mode list + * hammerfile, hammergui: version control + +DONE for root and shared + +with cyclone alpha52 + * fragile: class name resolution based on voluntary mutation and raising + * fitter: mirroring removed + * new module, os: opening files, parsing path + * hammerpanel: two modes of -initialdir persistence + * more mingw fixes + +with cyclone alpha51 + * new module, fitter: encapsulates compatibility support (formerly in maxmode) + * fitter: per-class callback and mirroring interface to compatibility mode + * mingw fixes + +with toxy alpha14 + * scriptlet: version control (verslet_ routines) + * debug printout restricted to krzYszcz, sent to stderr + +with cyclone alpha50 + * bug fixes + . hammertree crasher (affecting funbuff and offer) + . MouseState/toxy clash + * builds with gcc3 by default (no need to edit Makefile.common) + * midi file code has been cleaned, now ready for using in qlist diff --git a/shared/unstable/forky.c b/shared/unstable/forky.c index fcdbd61..3383dac 100644 --- a/shared/unstable/forky.c +++ b/shared/unstable/forky.c @@ -78,7 +78,8 @@ int forky_hasfeeders(t_object *x, t_glist *glist, int inno, t_symbol *outsym) } /* Not really a forky, just found no better place to put it in. - Used in bitwise signal binops (sickle). Checked against msp2. */ + Used in sickle's bitwise signal binops (which use forky_hasfeeders() too). + Checked against msp2. */ t_int forky_getbitmask(int ac, t_atom *av) { t_int result = 0; diff --git a/shared/unstable/fragile.c b/shared/unstable/fragile.c index cd92b72..aed4d83 100644 --- a/shared/unstable/fragile.c +++ b/shared/unstable/fragile.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997-2003 Miller Puckette, krzYszcz, and others. +/* Copyright (c) 1997-2005 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. */ @@ -15,6 +15,178 @@ int fragile_class_count(void) return (pd_objectmaker->c_nmethod); } +/* Raising and voluntary mutation is a method of resolving name clashes. + A raised class hides other equivocal candidates. A simpler method, + raising and lowering, works only in global scope, because, currently, Pd + has only one visibility stack. Until this is changed, abstraction scope + will involve some kind of a hack for overriding global visibility stack. */ + +void fragile_class_raise(t_symbol *cname, t_newmethod thiscall) +{ + t_methodentry *mp = pd_objectmaker->c_methods, *topmp = 0; + int count = pd_objectmaker->c_nmethod; + while (count--) + { + if (mp->me_name == cname) + { + if (mp->me_fun == (t_gotfn)thiscall) + { + if (topmp) + { + t_methodentry auxmp; + /* no linkage there, but anyway... */ + loud_warning(0, 0, "%s is raising itself...", + cname->s_name); + memcpy(&auxmp, mp, sizeof(t_methodentry)); + memcpy(mp, topmp, sizeof(t_methodentry)); + memcpy(topmp, &auxmp, sizeof(t_methodentry)); + } + return; + } + else if (!topmp) + topmp = mp; + } + mp++; + } + loudbug_bug("fragile_class_raise"); +} + +t_pd *fragile_class_mutate(t_symbol *cname, t_newmethod thiscall, + int ac, t_atom *av) +{ + t_newmethod fn; + t_atomtype *argtypes; + if (fn = fragile_class_getalien(cname, thiscall, &argtypes)) + { + t_pd *z; + loud_warning(0, 0, "%s is mutating now...", cname->s_name); + if (z = fragile_class_createobject(cname, fn, argtypes, ac, av)) + { + post("...succeeded"); + return (z); + } + else post("...failed"); + } + return (0); +} + +t_newmethod fragile_class_getalien(t_symbol *cname, t_newmethod thiscall, + t_atomtype **argtypesp) +{ + t_methodentry *mp = pd_objectmaker->c_methods; + int count = pd_objectmaker->c_nmethod; + while (count--) + { + if (mp->me_name == cname && mp->me_fun != (t_gotfn)thiscall) + { + *argtypesp = mp->me_arg; + return ((t_newmethod)mp->me_fun); + } + mp++; + } + return (0); +} + +/* A specialized copy of pd_typedmess() from m_class.c, + somewhat simplified for readability. */ + +typedef t_pd *(*t_newgimme)(t_symbol *s, int ac, t_atom *av); +typedef t_pd *(*t_new0)( + t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg); +typedef t_pd *(*t_new1)( + t_symbol*, + t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg); +typedef t_pd *(*t_new2)( + t_symbol*, t_symbol*, + t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg); +typedef t_pd *(*t_new3)( + t_symbol*, t_symbol*, t_symbol*, + t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg); +typedef t_pd *(*t_new4)( + t_symbol*, t_symbol*, t_symbol*, t_symbol*, + t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg); +typedef t_pd *(*t_new5)( + t_symbol*, t_symbol*, t_symbol*, t_symbol*, t_symbol*, + t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg); +typedef t_pd *(*t_new6)( + t_symbol*, t_symbol*, t_symbol*, t_symbol*, t_symbol*, t_symbol*, + t_floatarg, t_floatarg, t_floatarg, t_floatarg, t_floatarg); + +t_pd *fragile_class_createobject(t_symbol *cname, t_newmethod callthis, + t_atomtype *argtypes, int ac, t_atom *av) +{ + t_floatarg ff[MAXPDARG+1], *fp = ff; + t_symbol *ss[MAXPDARG+1], **sp = ss; + int nsymbols = 0; + t_atomtype wanttype; + if (*argtypes == A_GIMME) + return ((*((t_newgimme)(callthis)))(cname, ac, av)); + if (ac > MAXPDARG) + ac = MAXPDARG; + while (wanttype = *argtypes++) + { + switch (wanttype) + { + case A_POINTER: + goto badarg; + case A_FLOAT: + if (!ac) goto badarg; + case A_DEFFLOAT: + if (!ac) *fp = 0; + else + { + if (av->a_type == A_FLOAT) + *fp = av->a_w.w_float; + else goto badarg; + ac--; av++; + } + fp++; + break; + case A_SYMBOL: + if (!ac) goto badarg; + case A_DEFSYM: + if (!ac) *sp = &s_; + else + { + if (av->a_type == A_SYMBOL) + *sp = av->a_w.w_symbol; + else if (av->a_type == A_FLOAT && av->a_w.w_float == 0) + *sp = &s_; + else goto badarg; + ac--; av++; + } + nsymbols++; + sp++; + } + } + switch (nsymbols) + { + case 0: return ((*(t_new0)(callthis)) + (ff[0], ff[1], ff[2], ff[3], ff[4])); + case 1: return ((*(t_new1)(callthis)) + (ss[0], + ff[0], ff[1], ff[2], ff[3], ff[4])); + case 2: return ((*(t_new2)(callthis)) + (ss[0], ss[1], + ff[0], ff[1], ff[2], ff[3], ff[4])); + case 3: return ((*(t_new3)(callthis)) + (ss[0], ss[1], ss[2], + ff[0], ff[1], ff[2], ff[3], ff[4])); + case 4: return ((*(t_new4)(callthis)) + (ss[0], ss[1], ss[2], ss[3], + ff[0], ff[1], ff[2], ff[3], ff[4])); + case 5: return ((*(t_new5)(callthis)) + (ss[0], ss[1], ss[2], ss[3], ss[4], + ff[0], ff[1], ff[2], ff[3], ff[4])); + case 6: return ((*(t_new6)(callthis)) + (ss[0], ss[1], ss[2], ss[3], ss[4], ss[5], + ff[0], ff[1], ff[2], ff[3], ff[4])); + } +badarg: + loud_error(0, "bad creation arguments for class '%s'", cname->s_name); + return (0); +} + void fragile_class_printnames(char *msg, int firstndx, int lastndx) { t_methodentry *mp = pd_objectmaker->c_methods; diff --git a/shared/unstable/fragile.h b/shared/unstable/fragile.h index ad26384..6e79475 100644 --- a/shared/unstable/fragile.h +++ b/shared/unstable/fragile.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2003 krzYszcz and others. +/* Copyright (c) 2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ @@ -6,6 +6,13 @@ #define __FRAGILE_H__ int fragile_class_count(void); +void fragile_class_raise(t_symbol *cname, t_newmethod thiscall); +t_pd *fragile_class_mutate(t_symbol *cname, t_newmethod thiscall, + int ac, t_atom *av); +t_newmethod fragile_class_getalien(t_symbol *cname, t_newmethod thiscall, + t_atomtype **argtypesp); +t_pd *fragile_class_createobject(t_symbol *cname, t_newmethod callthis, + t_atomtype *argtypes, int ac, t_atom *av); void fragile_class_printnames(char *msg, int firstndx, int lastndx); t_glist *fragile_garray_glist(void *arr); t_outconnect *fragile_outlet_connections(t_outlet *o); diff --git a/shared/unstable/pd_imp.h b/shared/unstable/pd_imp.h index bf659ed..513f927 100644 --- a/shared/unstable/pd_imp.h +++ b/shared/unstable/pd_imp.h @@ -6,8 +6,10 @@ #define __PD_IMP_H__ #ifdef PD_MINOR_VERSION +/* 0.37 and up */ #include "m_imp.h" #else +/* 0.36 and down */ typedef struct _methodentry { -- cgit v1.2.1