From d2eec74a4d8c21aad495ba61539486b24d7ab8dc Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Wed, 9 Oct 2002 10:19:04 +0000 Subject: moved from zexy/zexy to zexy svn path=/trunk/externals/zexy/; revision=169 --- src/z_index.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 src/z_index.c (limited to 'src/z_index.c') diff --git a/src/z_index.c b/src/z_index.c new file mode 100644 index 0000000..a2a96eb --- /dev/null +++ b/src/z_index.c @@ -0,0 +1,203 @@ +/* + (c) 2005:forum::für::umläute:2000 + + "index" simulates an associative index :: that is : convert a symbol to an index + +*/ + +#include "zexy.h" + +#include +#include + +#define MAXKEYLEN 16 + +/* ----------------------- index --------------------- */ + +static t_class *index_class; + +typedef struct _index +{ + t_object x_obj; + + int entries, maxentries; + int auto_mode; /* 1--add if key doesn't already exist; 0--do not add; */ + + char **names; +} t_index; + +static int find_last(char **names, int maxentries) +{ /* returns the index of the last entry (0..(maxentries-1)) */ + while (maxentries--) if (names[maxentries]) return maxentries; + return 0; +} + +static int find_item(const char *key, char **names, int maxentries) +{ /* returns index (0..[maxentries-1?]) on success; -1 if the item could not be found */ + int i=-1; + int max = find_last(names, maxentries); + + while (++i<=max) + if (names[i]) + if (!strcmp(key, names[i])) return i; + + return -1; +} + +static int find_free(char **names, int maxentries) +{ + int i=0; + + while (i 0) && (index <= x->maxentries) && (x->names[index-1])) post("index[%d] = %s", index, x->names[index-1]); +} + +static void index_auto(t_index *x, t_float automod) +{ + x->auto_mode = !(!automod); +} + + +static void index_add(t_index *x, t_symbol *s) +{ + int newentry; + int ok = 0; + + if (! (find_item(s->s_name, x->names, x->maxentries)+1) ) { + if ( x->entries < x->maxentries ) { + newentry=find_free(x->names, x->maxentries); + if (newentry + 1) { + char *buf = (char *)getbytes(sizeof(char) * MAXKEYLEN); + x->entries++; + strcpy(buf, s->s_name); + x->names[newentry]=buf; + + ok=1; + + outlet_float(x->x_obj.ob_outlet, (t_float)newentry+1); + + } else post("index :: couldn't find any place for new entry"); + } else post("index :: max number of elements (%d) reached !", x->maxentries); + } else post("index :: element already exists"); + + if (!ok) outlet_float(x->x_obj.ob_outlet, -1.f); +} + +static void index_delete(t_index *x, t_symbol *s) +{ + int element; + t_float r = -1.f; + + if ( (element = find_item(s->s_name,x->names, x->maxentries))+1 ) { + freebytes(x->names[element], sizeof(char) * MAXKEYLEN); + x->names[element]=0; + r = 0.f; + x->entries--; + } else post("index :: couldn't find element"); + + outlet_float(x->x_obj.ob_outlet, r); +} + +static void index_reset(t_index *x) +{ + int i=x->maxentries; + + while (i--) + if (x->names[i]) { + freebytes(x->names[i], sizeof(char) * MAXKEYLEN); + x->names[i]=0; + } + + x->entries=0; + + outlet_float(x->x_obj.ob_outlet, 0.f); +} + +static void index_symbol(t_index *x, t_symbol *s) +{ + int element; + if ( (element = find_item(s->s_name, x->names, x->maxentries)+1) ) + outlet_float(x->x_obj.ob_outlet, (t_float)element); + else if (x->auto_mode) + index_add(x, s); + else outlet_float(x->x_obj.ob_outlet, 0.f); +} + +static void *index_new(t_symbol *s, int argc, t_atom *argv) +{ + t_index *x = (t_index *)pd_new(index_class); + char** buf; + + int maxentries = 0, automod=0; + int i; + + if (argc--) { + maxentries = (int)atom_getfloat(argv++); + if (argc) automod = (int)atom_getfloat(argv++); + } + + if (!maxentries) maxentries=128; + + buf = (char **)getbytes(sizeof(char *) * maxentries); + + i = maxentries; + while (i--) buf[i]=0; + + x->entries = 0; + x->maxentries = maxentries; + x->names = buf; + x->auto_mode = !(!automod); + + outlet_new(&x->x_obj, &s_float); + + return (x); +} + +static void index_free(t_index *x) +{ + index_reset(x); + freebytes(x->names, sizeof(char *) * x->maxentries); +} + + +static void helper(t_index *x) +{ + post("\n%c index :: index symbols to indices", HEARTSYMBOL); + post("\t : look up the in the index and return it's index\n" + "'add '\t: add a new symbol to the index\n" + "'delete ' : delete a symbol from the index\n" + "'reset'\t\t : delete the whole index\n" + "'auto <1/0>\t : if auto is 1 and a yet unknown symbol is looked up it is\n\t\t\t automatically added to the index\n" + "'help'\t\t : view this" + "\noutlet : \t : index of the "); + post("\ncreation:\"index [ []]\": creates a sized index"); +} + +void z_index_setup(void) +{ + index_class = class_new(gensym("index"), + (t_newmethod)index_new, (t_method)index_free, + sizeof(t_index), 0, A_GIMME, 0); + + class_addsymbol(index_class, index_symbol); + + class_addmethod(index_class, (t_method)index_reset, gensym("reset"), 0); + class_addmethod(index_class, (t_method)index_delete, gensym("delete"), A_SYMBOL, 0); + class_addmethod(index_class, (t_method)index_add, gensym("add"), A_SYMBOL, 0); + + class_addmethod(index_class, (t_method)index_auto, gensym("auto"), A_FLOAT, 0); + + class_addfloat(index_class, (t_method)index_float); + + class_addmethod(index_class, (t_method)helper, gensym("help"), 0); + class_sethelpsymbol(index_class, gensym("zexy/index")); +} -- cgit v1.2.1