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