Update of /cvsroot/pure-data/externals/miXed/shared/common In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29556/shared/common
Modified Files: Makefile.sources fitter.c fitter.h loud.c loud.h os.c os.h port.c qtree.c qtree.h Added Files: messtree.c messtree.h Log Message: cyclone alpha55 (see notes.txt for cyclone and shared)
Index: loud.h =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/loud.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** loud.h 12 Mar 2005 00:19:10 -0000 1.6 --- loud.h 21 Nov 2005 22:16:37 -0000 1.7 *************** *** 19,23 **** void loud_error(t_pd *x, char *fmt, ...); void loud_errand(t_pd *x, char *fmt, ...); ! void loud_syserror(t_pd *x, char *msg); void loud_nomethod(t_pd *x, t_symbol *s); void loud_messarg(t_pd *x, t_symbol *s); --- 19,23 ---- void loud_error(t_pd *x, char *fmt, ...); void loud_errand(t_pd *x, char *fmt, ...); ! void loud_syserror(t_pd *x, char *fmt, ...); void loud_nomethod(t_pd *x, t_symbol *s); void loud_messarg(t_pd *x, t_symbol *s);
Index: loud.c =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/loud.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** loud.c 12 Mar 2005 00:19:10 -0000 1.7 --- loud.c 21 Nov 2005 22:16:37 -0000 1.8 *************** *** 89,98 **** }
! void loud_syserror(t_pd *x, char *msg) { ! if (msg) ! loud_error(x, "%s (%s)", msg, strerror(errno)); ! else ! loud_error(x, strerror(errno)); }
--- 89,104 ---- }
! void loud_syserror(t_pd *x, char *fmt, ...) { ! if (fmt) ! { ! char buf[MAXPDSTRING]; ! va_list ap; ! va_start(ap, fmt); ! vsprintf(buf, fmt, ap); ! loud_error(x, "%s (%s)", buf, strerror(errno)); ! va_end(ap); ! } ! else loud_error(x, strerror(errno)); }
Index: fitter.c =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/fitter.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** fitter.c 27 Jan 2005 14:42:53 -0000 1.2 --- fitter.c 21 Nov 2005 22:16:37 -0000 1.3 *************** *** 18,113 **** /* FIXME compatibility mode should be a standard Pd feature. When it is, it will be possible to simplify the implementation. Until then, ! we have to handle multiple copies of the 'fittermode_value' variable (coming from different externals), and the only way is multicasting ! through a symbol (#compatibility). */ ! static t_symbol *fittermode_value = 0;
! typedef struct _fittermode_client { ! t_class *fc_owner; ! t_canvas *fc_canvas; ! t_fittermode_callback fc_callback; ! struct _fittermode_client *fc_next; ! } t_fittermode_client;
! static t_fittermode_client *fittermode_clients = 0; ! static t_class *fittermode_class = 0; ! 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) { ! if (fitterps_hashcompatibility) { ! if (fittermode_ready /* do not reply to own request */ ! && fitterps_hashcompatibility->s_thing) ! /* this proliferates for the third and subsequent ! fittermode_dosetup() calls... */ ! pd_symbol(fitterps_hashcompatibility->s_thing, ! fittermode_value); } ! else loudbug_bug("fittermode_bang"); }
! /* 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; }
! /* write access, only from fitter_setmode() */ ! 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_callback) fc->fc_callback(); }
! static void fittermode_dosetup(int noquery) { ! if (fittermode_class || fittermode_target) ! 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); ! class_addbang(fittermode_class, fittermode_bang); ! class_addsymbol(fittermode_class, fittermode_symbol); ! class_addmethod(fittermode_class, ! (t_method)fittermode_set, ! gensym("set"), A_SYMBOL, 0); ! fittermode_target = pd_new(fittermode_class); ! pd_bind(fittermode_target, fitterps_hashcompatibility); if (!noquery) ! pd_bang(fitterps_hashcompatibility->s_thing); ! fittermode_ready = 1; }
! void fitter_setup(t_class *owner, t_fittermode_callback callback) { ! if (!fittermode_class) ! fittermode_dosetup(0); if (callback) { ! t_fittermode_client *fc = getbytes(sizeof(*fc)); fc->fc_owner = owner; fc->fc_canvas = 0; /* a global client */ fc->fc_callback = callback; ! fc->fc_next = fittermode_clients; ! fittermode_clients = fc; } } --- 18,162 ---- /* FIXME compatibility mode should be a standard Pd feature. When it is, it will be possible to simplify the implementation. Until then, ! we have to handle multiple copies of the 'fitterstate_mode' variable (coming from different externals), and the only way is multicasting ! through a symbol (#miXed). */ ! static t_symbol *fitterstate_mode = 0;
! /* FIXME keep state in an extensible fitterstate_dictionary */ ! static t_symbol *fitterstate_test = 0; ! ! typedef struct _fitterstate_client { ! t_class *fc_owner; ! t_canvas *fc_canvas; ! t_fitterstate_callback fc_callback; ! struct _fitterstate_client *fc_next; ! } t_fitterstate_client;
! static t_fitterstate_client *fitterstate_clients = 0; ! static t_class *fitterstate_class = 0; ! static t_pd *fitterstate_target = 0; ! static int fitterstate_ready = 0; ! static t_symbol *fitterps_hashmiXed = 0; ! static t_symbol *fitterps_mode = 0; ! static t_symbol *fitterps_test = 0; static t_symbol *fitterps_max = 0; static t_symbol *fitterps_none = 0;
! /* read access (query), called only from fitterstate_dosetup() ! or through "#miXed" */ ! static void fitterstate_bang(t_pd *x) { ! if (fitterps_hashmiXed) { ! if (fitterstate_ready /* do not reply to own request */ ! && fitterps_hashmiXed->s_thing) ! { ! t_atom atout[2]; ! /* these proliferate for the third and subsequent ! fitterstate_dosetup() calls... */ ! SETSYMBOL(&atout[0], fitterps_mode); ! SETSYMBOL(&atout[1], fitterstate_mode); ! typedmess(fitterps_hashmiXed->s_thing, gensym("reply"), 2, atout); ! SETSYMBOL(&atout[0], fitterps_test); ! SETSYMBOL(&atout[1], fitterstate_test); ! typedmess(fitterps_hashmiXed->s_thing, gensym("reply"), 2, atout); ! } } ! else loudbug_bug("fitterstate_bang"); }
! /* read access (query), called only through "#miXed" */ ! static void fitterstate_symbol(t_pd *x, t_symbol *s) { ! if (fitterstate_ready && fitterps_hashmiXed && fitterps_hashmiXed->s_thing) { ! t_atom atout[2]; ! if (s == fitterps_mode) ! { ! SETSYMBOL(&atout[0], fitterps_mode); ! SETSYMBOL(&atout[1], fitterstate_mode); ! typedmess(fitterps_hashmiXed->s_thing, gensym("reply"), 2, atout); ! } ! else if (s == fitterps_test) ! { ! SETSYMBOL(&atout[0], fitterps_test); ! SETSYMBOL(&atout[1], fitterstate_test); ! typedmess(fitterps_hashmiXed->s_thing, gensym("reply"), 2, atout); ! } ! else post(""%s": no such key in the miXed state", ! (s ? s->s_name : "???")); } ! else loudbug_bug("fitterstate_symbol"); }
! /* read access (reply), called only from fitter_dosetup() or through "#miXed" */ ! static void fitterstate_reply(t_pd *x, t_symbol *s1, t_symbol *s2) { ! if (!s2 || s2 == &s_) ! { ! loudbug_bug("fitterstate_reply"); ! s2 = fitterps_none; ! } ! if (s1 == fitterps_mode) ! fitterstate_mode = s2; ! else if (s1 == fitterps_test) ! fitterstate_test = s2; ! } ! ! /* write access, called only from fitter_setmode() or through "#miXed" */ ! static void fitterstate_set(t_pd *x, t_symbol *s1, t_symbol *s2) ! { ! t_fitterstate_client *fc; ! if (s1 == fitterps_mode) ! fitterstate_mode = s2; ! else if (s1 == fitterps_test) ! fitterstate_test = s2; ! for (fc = fitterstate_clients; fc; fc = fc->fc_next) if (fc->fc_callback) fc->fc_callback(); }
! static void fitterstate_dosetup(int noquery) { ! if (fitterstate_class || fitterstate_target) ! loudbug_bug("fitterstate_dosetup"); ! fitterps_hashmiXed = gensym("#miXed"); ! fitterps_mode = gensym("mode"); ! fitterps_test = gensym("test"); fitterps_max = gensym("max"); fitterps_none = gensym("none"); ! fitterstate_mode = fitterps_none; ! fitterstate_test = fitterps_none; ! fitterstate_class = class_new(fitterps_hashmiXed, ! 0, 0, sizeof(t_pd), ! CLASS_PD | CLASS_NOINLET, 0); ! class_addbang(fitterstate_class, fitterstate_bang); ! class_addsymbol(fitterstate_class, fitterstate_symbol); ! class_addmethod(fitterstate_class, ! (t_method)fitterstate_reply, ! gensym("reply"), A_SYMBOL, A_SYMBOL, 0); ! class_addmethod(fitterstate_class, ! (t_method)fitterstate_set, ! gensym("set"), A_SYMBOL, A_SYMBOL, 0); ! fitterstate_target = pd_new(fitterstate_class); ! pd_bind(fitterstate_target, fitterps_hashmiXed); if (!noquery) ! pd_bang(fitterps_hashmiXed->s_thing); ! fitterstate_ready = 1; }
! void fitter_setup(t_class *owner, t_fitterstate_callback callback) { ! if (!fitterstate_class) ! fitterstate_dosetup(0); if (callback) { ! t_fitterstate_client *fc = getbytes(sizeof(*fc)); fc->fc_owner = owner; fc->fc_canvas = 0; /* a global client */ fc->fc_callback = callback; ! fc->fc_next = fitterstate_clients; ! fitterstate_clients = fc; } } *************** *** 115,122 **** void fitter_drop(t_class *owner) { ! if (fittermode_class && fitterps_hashcompatibility->s_thing) { ! t_fittermode_client *fcp = 0, ! *fc = fittermode_clients; while (fc) { --- 164,171 ---- void fitter_drop(t_class *owner) { ! if (fitterstate_class && fitterps_hashmiXed->s_thing) { ! t_fitterstate_client *fcp = 0, ! *fc = fitterstate_clients; while (fc) { *************** *** 126,130 **** fcp->fc_next = fc->fc_next; else ! fittermode_clients = fc->fc_next; break; } --- 175,179 ---- fcp->fc_next = fc->fc_next; else ! fitterstate_clients = fc->fc_next; break; } *************** *** 140,143 **** --- 189,215 ---- }
+ t_float *fitter_getfloat(t_symbol *s) + { + if (!fitterstate_class) + fitterstate_dosetup(0); + loudbug_bug("fitter_getfloat"); + return (0); + } + + t_symbol *fitter_getsymbol(t_symbol *s) + { + if (!fitterstate_class) + fitterstate_dosetup(0); + if (s == fitterps_mode) + return (fitterstate_mode); + else if (s == fitterps_test) + return (fitterstate_test); + else + { + loudbug_bug("fitter_getsymbol"); + return (0); + } + } + void fitter_setmode(t_symbol *s) { *************** *** 145,155 **** s = fitterps_none; post("setting compatibility mode to '%s'", s->s_name); ! if (!fittermode_class) ! fittermode_dosetup(1); ! if (fitterps_hashcompatibility->s_thing) { ! t_atom at; ! SETSYMBOL(&at, s); ! typedmess(fitterps_hashcompatibility->s_thing, gensym("set"), 1, &at); } else loudbug_bug("fitter_setmode"); --- 217,228 ---- s = fitterps_none; post("setting compatibility mode to '%s'", s->s_name); ! if (!fitterstate_class) ! fitterstate_dosetup(1); ! if (fitterps_hashmiXed->s_thing) { ! t_atom atout[2]; ! SETSYMBOL(&atout[0], fitterps_mode); ! SETSYMBOL(&atout[1], s); ! typedmess(fitterps_hashmiXed->s_thing, gensym("set"), 2, atout); } else loudbug_bug("fitter_setmode"); *************** *** 158,170 **** t_symbol *fitter_getmode(void) { ! if (!fittermode_class) ! fittermode_dosetup(0); ! return (fittermode_value); }
void fittermax_set(void) { ! if (!fittermode_class) ! fittermode_dosetup(0); fitter_setmode(fitterps_max); } --- 231,243 ---- t_symbol *fitter_getmode(void) { ! if (!fitterstate_class) ! fitterstate_dosetup(0); ! return (fitterstate_mode); }
void fittermax_set(void) { ! if (!fitterstate_class) ! fitterstate_dosetup(0); fitter_setmode(fitterps_max); } *************** *** 172,185 **** int fittermax_get(void) { ! if (!fittermode_class) ! fittermode_dosetup(0); ! return (fittermode_value == fitterps_max); }
void fittermax_warning(t_class *c, char *fmt, ...) { ! if (!fittermode_class) ! fittermode_dosetup(0); ! if (fittermode_value == fitterps_max) { char buf[MAXPDSTRING]; --- 245,258 ---- int fittermax_get(void) { ! if (!fitterstate_class) ! fitterstate_dosetup(0); ! return (fitterstate_mode == fitterps_max); }
void fittermax_warning(t_class *c, char *fmt, ...) { ! if (!fitterstate_class) ! fitterstate_dosetup(0); ! if (fitterstate_mode == fitterps_max) { char buf[MAXPDSTRING];
Index: Makefile.sources =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/Makefile.sources,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Makefile.sources 10 May 2005 17:58:40 -0000 1.7 --- Makefile.sources 21 Nov 2005 22:16:37 -0000 1.8 *************** *** 7,10 **** --- 7,11 ---- lex.c \ loud.c \ + messtree.c \ mifi.c \ os.c \
Index: qtree.h =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/qtree.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** qtree.h 8 Dec 2004 15:45:25 -0000 1.1 --- qtree.h 21 Nov 2005 22:16:37 -0000 1.2 *************** *** 61,68 ****
t_qnode *qtree_search(t_qtree *tree, double key); ! t_qnode *qtree_closest(t_qtree *tree, double key, int geqflag);
! t_qnode *qtree_insert(t_qtree *tree, double key, int *foundp); ! t_qnode *qtree_multiinsert(t_qtree *tree, double key, int fifoflag); t_qnode *qtree_insertfloat(t_qtree *tree, double key, t_float f, int replaceflag); --- 61,73 ----
t_qnode *qtree_search(t_qtree *tree, double key); ! t_qnode *qtree_closestunder(t_qtree *tree, double key, double *deltap); ! t_qnode *qtree_closestover(t_qtree *tree, double key, double *deltap); ! t_qnode *qtree_closest(t_qtree *tree, double key, double *deltap);
! t_qnode *qtree_insert(t_qtree *tree, double key, ! t_qnode *preexisting, int *foundp); ! t_qnode *qtree_multiinsert(t_qtree *tree, double key, ! t_qnode *preexisting, int fifoflag); ! t_qnode *qtree_override(t_qtree *tree, t_qnode *oldnode, t_qnode *newnode); t_qnode *qtree_insertfloat(t_qtree *tree, double key, t_float f, int replaceflag);
Index: port.c =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/port.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** port.c 27 Jan 2005 14:42:53 -0000 1.17 --- port.c 21 Nov 2005 22:16:37 -0000 1.18 *************** *** 36,41 **** #define PORT_INISIZE 512 /* LATER rethink */
! enum { PORT_OK, ! PORT_NEXT, /* next line, please */ PORT_UNKNOWN, PORT_CORRUPT, PORT_FATAL };
--- 36,43 ---- #define PORT_INISIZE 512 /* LATER rethink */
! /* FIXME use messtree api */ ! ! enum { PORT_OK, /* MESSTREE_CONTINUE */ ! PORT_NEXT, /* next line, please: MESSTREE_OK */ PORT_UNKNOWN, PORT_CORRUPT, PORT_FATAL };
--- NEW FILE: messtree.c --- /* 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. */
/* This module covers parsing of a single message received by an object or used for creation of an object, as well as parsing of multiple messages contained in an imported buffer, etc. */
#include "m_pd.h" #include "common/loud.h" #include "messtree.h"
#ifdef KRZYSZCZ #define MESSTREE_DEBUG #endif
/* There are two different messtree structures: the compile-time input (t_messslot/t_messnode) and the run-time one (t_messtree). The reasons are: to allow plugins to extend a message tree, and to make the compile-time input initializer-friendly. */
struct _messtree { t_messslot *mt_slot; t_symbol *mt_selector; t_messcall mt_method; int mt_nonexclusive; struct _messtree *mt_sublist; struct _messtree *mt_next; };
t_messtree *messtree_new(t_symbol *selector) { t_messtree *mt = getbytes(sizeof(*mt)); mt->mt_slot = 0; mt->mt_selector = selector; mt->mt_method = 0; /* LATER define a default */ mt->mt_nonexclusive = 0; mt->mt_sublist = 0; mt->mt_next = 0; return (mt); }
static void messtree_addnode(t_messtree *mt, t_messnode *mn) { /* LATER respect mn->mn_index */ t_messslot *ms; int i; for (i = 0, ms = mn->mn_table + mn->mn_nslots - 1; i < mn->mn_nslots; i++, ms--) { t_messtree *bch = messtree_new(gensym(ms->ms_name)); bch->mt_slot = ms; bch->mt_method = ms->ms_call; bch->mt_nonexclusive = (ms->ms_flags & MESSTREE_NONEXCLUSIVE); bch->mt_next = mt->mt_sublist; mt->mt_sublist = bch; if (ms->ms_subnode) messtree_addnode(bch, ms->ms_subnode); } }
void messtree_add(t_messtree *mt, t_messnode *rootnode) { messtree_addnode(mt, rootnode); }
t_messtree *messtree_build(t_messslot *rootslot) { t_messtree *mt = messtree_new(gensym(rootslot->ms_name)); mt->mt_slot = rootslot; mt->mt_method = rootslot->ms_call; mt->mt_nonexclusive = (rootslot->ms_flags & MESSTREE_NONEXCLUSIVE); mt->mt_sublist = 0; mt->mt_next = 0; if (rootslot->ms_subnode) messtree_addnode(mt, rootslot->ms_subnode); return (mt); }
int messtree_doit(t_messtree *mt, t_messslot **msp, int *nargp, t_pd *target, t_symbol *s, int ac, t_atom *av) { int result = MESSTREE_OK, nargpdummy; t_messslot *mspdummy; if (!msp) msp = &mspdummy; if (!nargp) nargp = &nargpdummy; if (s && s != mt->mt_selector) { loud_warning(target, (target ? 0 : "messtree"), "unexpected selector "%s"", s->s_name); *msp = 0; *nargp = 0; return (MESSTREE_CORRUPT); } if (ac && av->a_type == A_SYMBOL) { t_messtree *bch; for (bch = mt->mt_sublist; bch; bch = bch->mt_next) { if (av->a_w.w_symbol == bch->mt_selector) { if (bch->mt_sublist) return (messtree_doit(bch, msp, nargp, target, av->a_w.w_symbol, ac - 1, av + 1)); else { if (target && bch->mt_method) result = bch->mt_method(target, av->a_w.w_symbol, ac - 1, av + 1); *msp = (result == MESSTREE_OK ? bch->mt_slot : 0); *nargp = ac - 1; return (result); } } } if (mt->mt_nonexclusive) { if (target && mt->mt_method) result = mt->mt_method(target, 0, ac, av); /* LATER rethink */ *msp = (result == MESSTREE_OK ? mt->mt_slot : 0); *nargp = ac; return (result); } else { loud_warning(target, (target ? 0 : "messtree"), "unknown property "%s"", av->a_w.w_symbol->s_name); *msp = 0; *nargp = 0; return (MESSTREE_UNKNOWN); } } else { if (target && mt->mt_method) result = mt->mt_method(target, 0, ac, av); *msp = (result == MESSTREE_OK ? mt->mt_slot : 0); *nargp = ac; return (result); } }
Index: fitter.h =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/fitter.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** fitter.h 27 Jan 2005 14:42:53 -0000 1.2 --- fitter.h 21 Nov 2005 22:16:37 -0000 1.3 *************** *** 6,13 **** #define __FITTER_H__
! typedef void (*t_fittermode_callback)(void);
! 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); --- 6,15 ---- #define __FITTER_H__
! typedef void (*t_fitterstate_callback)(void);
! void fitter_setup(t_class *owner, t_fitterstate_callback callback); void fitter_drop(t_class *owner); + t_float *fitter_getfloat(t_symbol *s); + t_symbol *fitter_getsymbol(t_symbol *s); void fitter_setmode(t_symbol *s); t_symbol *fitter_getmode(void);
Index: os.h =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/os.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** os.h 27 Jan 2005 14:42:53 -0000 1.1 --- os.h 21 Nov 2005 22:16:37 -0000 1.2 *************** *** 6,13 **** --- 6,28 ---- #define __OS_H__
+ EXTERN_STRUCT _osdir; + #define t_osdir struct _osdir + + #define OSDIR_FILEMODE 1 + #define OSDIR_DIRMODE 2 + 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);
+ t_osdir *osdir_open(char *dirname); + void osdir_setmode(t_osdir *dp, int flags); + void osdir_close(t_osdir *dp); + void osdir_rewind(t_osdir *dp); + char *osdir_next(t_osdir *dp); + int osdir_isfile(t_osdir *dp); + int osdir_isdir(t_osdir *dp); + #endif
Index: qtree.c =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/qtree.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** qtree.c 11 Jan 2005 10:33:21 -0000 1.2 --- qtree.c 21 Nov 2005 22:16:37 -0000 1.3 *************** *** 295,299 **** either empty, or returns null. Hook's nonempty return is the parent for the new node. It is expected to have no more than one child. */ ! static t_qnode *qtree_doinsert(t_qtree *tree, double key, t_qtree_inserthook hook, int *foundp) { --- 295,299 ---- either empty, or returns null. Hook's nonempty return is the parent for the new node. It is expected to have no more than one child. */ ! static t_qnode *qtree_doinsert(t_qtree *tree, double key, t_qnode *preexisting, t_qtree_inserthook hook, int *foundp) { *************** *** 303,311 **** if (!(np = tree->t_root)) { ! if (!(np = getbytes(tree->t_nodesize))) return (0); np->n_key = key; np->n_black = 1; tree->t_root = tree->t_first = tree->t_last = np; return (np); } --- 303,318 ---- if (!(np = tree->t_root)) { ! if (!(np = (tree->t_nodesize > 0 ? ! getbytes(tree->t_nodesize) : preexisting))) ! { ! if (tree->t_nodesize == 0) ! loudbug_bug("qtree_insert, node not supplied"); return (0); + } np->n_key = key; np->n_black = 1; + np->n_left = np->n_right = np->n_parent = 0; tree->t_root = tree->t_first = tree->t_last = np; + np->n_prev = np->n_next = 0; return (np); } *************** *** 344,349 **** /* parent has no more than one child, new node becomes parent's immediate successor or predecessor */ ! if (!(np = getbytes(tree->t_nodesize))) return (0); np->n_key = key; np->n_parent = parent; --- 351,361 ---- /* parent has no more than one child, new node becomes parent's immediate successor or predecessor */ ! if (!(np = (tree->t_nodesize > 0 ? ! getbytes(tree->t_nodesize) : preexisting))) ! { ! if (tree->t_nodesize == 0) ! loudbug_bug("qtree_insert, node not supplied"); return (0); + } np->n_key = key; np->n_parent = parent; *************** *** 441,445 **** and it has no left child. The simplistic scheme is to replace gone's fields with successor's fields, and delete the successor. ! We cannot do so, however, because successor may be pointed at... */ t_qnode *successor = gone->n_next; child = successor->n_right; --- 453,458 ---- and it has no left child. The simplistic scheme is to replace gone's fields with successor's fields, and delete the successor. ! We cannot do so, however, because 1. nodes may be caller-owned ! (nodesize == 0), 2. successor may be pointed at... */ t_qnode *successor = gone->n_next; child = successor->n_right; *************** *** 625,629 **** } done: ! freebytes(gone, tree->t_nodesize); #ifdef QTREE_DEBUG qtree_verify(tree); --- 638,643 ---- } done: ! if (tree->t_nodesize) ! freebytes(gone, tree->t_nodesize); #ifdef QTREE_DEBUG qtree_verify(tree); *************** *** 639,643 **** }
! t_qnode *qtree_closest(t_qtree *tree, double key, int geqflag) { t_qnode *np, *parent; --- 653,659 ---- }
! /* Returns the greatest node <= key, if any (may return null). ! If deltap is not null, it will hold the abs diff (key - node.n_key). */ ! t_qnode *qtree_closestunder(t_qtree *tree, double key, double *deltap) { t_qnode *np, *parent; *************** *** 646,670 **** do if (np->n_key == key) return (np); ! else ! parent = np; while (np = (key < np->n_key ? np->n_left : np->n_right)); ! if (geqflag) ! return (key > parent->n_key ? parent->n_next : parent); else ! return (key < parent->n_key ? parent->n_prev : parent); }
! t_qnode *qtree_insert(t_qtree *tree, double key, int *foundp) { ! return (qtree_doinsert(tree, key, 0, foundp)); }
! t_qnode *qtree_multiinsert(t_qtree *tree, double key, int fifoflag) { int found; ! return (qtree_doinsert(tree, key, (fifoflag ? ! qtree_postinserthook : ! qtree_preinserthook), &found)); }
--- 662,832 ---- do if (np->n_key == key) + { + if (deltap) + *deltap = 0.; return (np); ! } ! else parent = np; while (np = (key < np->n_key ? np->n_left : np->n_right)); ! if (np = (key < parent->n_key ? parent->n_prev : parent)) ! { ! if (deltap) ! *deltap = key - np->n_key; ! return (np); ! } ! else return (0); ! } ! ! /* Returns the smallest node >= key, if any (may return null). ! If deltap is not null, it will hold the abs diff (node.n_key - key). */ ! t_qnode *qtree_closestover(t_qtree *tree, double key, double *deltap) ! { ! t_qnode *np, *parent; ! if (!(np = tree->t_root)) ! return (0); ! do ! if (np->n_key == key) ! { ! if (deltap) ! *deltap = 0.; ! return (np); ! } ! else parent = np; ! while (np = (key < np->n_key ? np->n_left : np->n_right)); ! if (np = (key > parent->n_key ? parent->n_next : parent)) ! { ! if (deltap) ! *deltap = np->n_key - key; ! return (np); ! } ! else return (0); ! } ! ! /* Returns the smallest node >= key or the greatest node <= key, whichever ! makes the smallest abs diff, |key - node.n_key|. Returns null only for ! an empty tree. If deltap is not null, it will hold the signed diff ! (negative for an undernode, i.e. when node < key). */ ! t_qnode *qtree_closest(t_qtree *tree, double key, double *deltap) ! { ! t_qnode *np, *parent; ! if (!(np = tree->t_root)) ! return (0); ! do ! if (np->n_key == key) ! { ! if (deltap) ! *deltap = 0.; ! return (np); ! } ! else parent = np; ! while (np = (key < np->n_key ? np->n_left : np->n_right)); ! if (key > parent->n_key) ! { ! if (np = parent->n_next) ! { ! double delta1 = key - parent->n_key; ! double delta2 = np->n_key - key; ! if (delta1 < delta2) ! { ! if (deltap) ! *deltap = -delta1; ! return (parent); ! } ! else ! { ! if (deltap) ! *deltap = delta2; ! return (np); ! } ! } ! else ! { ! if (deltap) ! *deltap = parent->n_key - key; ! return (parent); ! } ! } else ! { ! if (np = parent->n_prev) ! { ! double delta1 = key - np->n_key; ! double delta2 = parent->n_key - key; ! if (delta1 < delta2) ! { ! if (deltap) ! *deltap = -delta1; ! return (np); ! } ! else ! { ! if (deltap) ! *deltap = delta2; ! return (parent); ! } ! } ! else ! { ! if (deltap) ! *deltap = parent->n_key - key; ! return (parent); ! } ! } }
! t_qnode *qtree_insert(t_qtree *tree, double key, ! t_qnode *preexisting, int *foundp) { ! int found; ! return (qtree_doinsert(tree, key, preexisting, 0, ! (foundp ? foundp : &found))); }
! t_qnode *qtree_multiinsert(t_qtree *tree, double key, ! t_qnode *preexisting, int fifoflag) { int found; ! return (qtree_doinsert(tree, key, preexisting, ! (fifoflag ? ! qtree_postinserthook : ! qtree_preinserthook), &found)); ! } ! ! t_qnode *qtree_override(t_qtree *tree, t_qnode *oldnode, t_qnode *newnode) ! { ! if (tree->t_nodesize) ! { ! loudbug_bug("qtree_override 1"); ! return (0); ! } ! else ! { ! newnode->n_key = oldnode->n_key; ! newnode->n_black = oldnode->n_black; ! if (newnode->n_left = oldnode->n_left) ! newnode->n_left->n_parent = newnode; ! if (newnode->n_right = oldnode->n_right) ! newnode->n_right->n_parent = newnode; ! if (newnode->n_parent = oldnode->n_parent) ! { ! if (oldnode == newnode->n_parent->n_left) ! newnode->n_parent->n_left = newnode; ! else if (oldnode == newnode->n_parent->n_right) ! newnode->n_parent->n_right = newnode; ! else ! loudbug_bug("qtree_override 2"); ! } ! if (newnode->n_prev = oldnode->n_prev) ! newnode->n_prev->n_next = newnode; ! if (newnode->n_next = oldnode->n_next) ! newnode->n_next->n_prev = newnode; ! if (tree->t_root == oldnode) ! tree->t_root = newnode; ! if (tree->t_first == oldnode) ! tree->t_first = newnode; ! if (tree->t_last == oldnode) ! tree->t_last = newnode; ! return (newnode); ! } }
*************** *** 673,677 **** { int found; ! t_qnode *np = qtree_doinsert(tree, key, 0, &found); if (np && (!found || replaceflag)) { --- 835,839 ---- { int found; ! t_qnode *np = qtree_doinsert(tree, key, 0, 0, &found); if (np && (!found || replaceflag)) { *************** *** 696,700 **** { int found; ! t_qnode *np = qtree_doinsert(tree, key, 0, &found); if (np && (!found || replaceflag)) { --- 858,862 ---- { int found; ! t_qnode *np = qtree_doinsert(tree, key, 0, 0, &found); if (np && (!found || replaceflag)) { *************** *** 719,723 **** { int found; ! t_qnode *np = qtree_doinsert(tree, key, 0, &found); if (np && (!found || replaceflag)) { --- 881,885 ---- { int found; ! t_qnode *np = qtree_doinsert(tree, key, 0, 0, &found); if (np && (!found || replaceflag)) { *************** *** 772,780 **** { t_qnode *np, *next = tree->t_first; ! while (next) { - np = next; next = next->n_next; ! freebytes(np, tree->t_nodesize); } qtree_doinit(tree, tree->t_valuetype, tree->t_nodesize, 0); --- 934,942 ---- { t_qnode *np, *next = tree->t_first; ! while (np = next) { next = next->n_next; ! if (tree->t_nodesize) ! freebytes(np, tree->t_nodesize); } qtree_doinit(tree, tree->t_valuetype, tree->t_nodesize, 0);
Index: os.c =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/common/os.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** os.c 27 Jan 2005 14:42:53 -0000 1.1 --- os.c 21 Nov 2005 22:16:37 -0000 1.2 *************** *** 7,10 **** --- 7,11 ---- #else #include <unistd.h> + #include <dirent.h> #endif #include <stdlib.h> *************** *** 234,235 **** --- 235,334 ---- return (fopen(path, (textmode ? "w" : "wb"))); } + + /* FIXME add MSW */ + + struct _osdir + { + #ifndef MSW + DIR *dir_handle; + struct dirent *dir_entry; + #endif + int dir_flags; + }; + + /* returns 0 on error, a caller is then expected to call + loud_syserror(owner, "cannot open "%s"", dirname) */ + t_osdir *osdir_open(char *dirname) + { + #ifndef MSW + DIR *handle = opendir(dirname); + if (handle) + { + #endif + t_osdir *dp = getbytes(sizeof(*dp)); + #ifndef MSW + dp->dir_handle = handle; + dp->dir_entry = 0; + #endif + dp->dir_flags = 0; + return (dp); + #ifndef MSW + } + else return (0); + #endif + } + + void osdir_setmode(t_osdir *dp, int flags) + { + if (dp) + dp->dir_flags = flags; + } + + void osdir_close(t_osdir *dp) + { + if (dp) + { + #ifndef MSW + closedir(dp->dir_handle); + #endif + freebytes(dp, sizeof(*dp)); + } + } + + void osdir_rewind(t_osdir *dp) + { + if (dp) + { + #ifndef MSW + rewinddir(dp->dir_handle); + dp->dir_entry = 0; + #endif + } + } + + char *osdir_next(t_osdir *dp) + { + #ifndef MSW + if (dp) + { + while (dp->dir_entry = readdir(dp->dir_handle)) + { + if (!dp->dir_flags || + (dp->dir_entry->d_type == DT_REG + && (dp->dir_flags & OSDIR_FILEMODE)) || + (dp->dir_entry->d_type == DT_DIR + && (dp->dir_flags & OSDIR_DIRMODE))) + return (dp->dir_entry->d_name); + } + } + #endif + return (0); + } + + int osdir_isfile(t_osdir *dp) + { + #ifndef MSW + return (dp && dp->dir_entry && dp->dir_entry->d_type == DT_REG); + #else + return (0); + #endif + } + + int osdir_isdir(t_osdir *dp) + { + #ifndef MSW + return (dp && dp->dir_entry && dp->dir_entry->d_type == DT_DIR); + #else + return (0); + #endif + }
--- NEW FILE: messtree.h --- /* 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. */
#ifndef __MESSTREE_H__ #define __MESSTREE_H__
typedef int (*t_messcall)(t_pd *, t_symbol *, int, t_atom *); typedef char *t_messarg;
typedef struct _messslot { char *ms_name; t_messcall ms_call; char *ms_argument; int ms_flags; struct _messnode *ms_subnode; } t_messslot;
typedef struct _messnode /* a parser's symbol definition, sort of... */ { t_messslot *mn_table; int mn_nslots; int mn_index; } t_messnode;
EXTERN_STRUCT _messtree; #define t_messtree struct _messtree
#define MESSTREE_NSLOTS(slots) (sizeof(slots)/sizeof(*(slots)))
enum { MESSTREE_OK, /* done current message parsing, parse next */ MESSTREE_CONTINUE, /* continue current message parsing */ MESSTREE_UNKNOWN, /* current message unknown, parse next */ MESSTREE_CORRUPT, /* current message corrupt, parse next */ MESSTREE_FATAL /* exit parsing */ };
#define MESSTREE_NONEXCLUSIVE 1
t_messtree *messtree_new(t_symbol *selector); void messtree_add(t_messtree *mt, t_messnode *rootnode); t_messtree *messtree_build(t_messslot *rootslot); int messtree_doit(t_messtree *mt, t_messslot **msp, int *nargp, t_pd *target, t_symbol *s, int ac, t_atom *av);
#endif