[PD-cvs] externals/miXed/shared/common messtree.c, NONE, 1.1 messtree.h, NONE, 1.1 Makefile.sources, 1.7, 1.8 fitter.c, 1.2, 1.3 fitter.h, 1.2, 1.3 loud.c, 1.7, 1.8 loud.h, 1.6, 1.7 os.c, 1.1, 1.2 os.h, 1.1, 1.2 port.c, 1.17, 1.18 qtree.c, 1.2, 1.3 qtree.h, 1.1, 1.2

Krzysztof Czaja krzyszcz at users.sourceforge.net
Mon Nov 21 23:16:39 CET 2005


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





More information about the Pd-cvs mailing list