I have implemented a string type for Pure Data as well as a [str] object that uses it. For it to work, pd needs to be patched. The [str] is contained in a separate file but the infrastructural changes are part of pd. I have attached a patch file for anyone interested. If it is acceptable, where should I put it? I could check str.c into externals, but it won't build unless the source is patched... The str object can join, split, load, save, drip, compare and convert strings to other types. It should be useful for formatting arbitrary strings for communication via byte-oriented objects such as [comport] and [tcpserver], which can then talk to external hardware (e.g. serial LCD or lanbox), for example terminating strings with CR LF instead of semicolons. Other potential applications of the string type that I haven't yet implemented are math using very long integers and row-by-row image processing. Martin
Index: pd/src/g_text.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/g_text.c,v retrieving revision 1.15 diff -u -w -r1.15 g_text.c --- pd/src/g_text.c 4 Oct 2006 19:35:06 -0000 1.15 +++ pd/src/g_text.c 18 Jan 2007 00:13:03 -0000 @@ -276,6 +276,11 @@ outlet_symbol(x->mr_outlet, s); }
+static void messresponder_string(t_messresponder *x, t_string *st) +{ /* MP 20070107 string type */ + outlet_string(x->mr_outlet, st); +} + static void messresponder_list(t_messresponder *x, t_symbol *s, int argc, t_atom *argv) { @@ -307,6 +312,13 @@ binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at); }
+static void message_string(t_message *x, t_string *st) +{ + t_atom at; + SETSTRING(&at, st); + binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at); +} + static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv) { binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, argc, argv); @@ -1333,6 +1345,7 @@ class_addbang(message_class, message_bang); class_addfloat(message_class, message_float); class_addsymbol(message_class, message_symbol); + class_addstring(message_class, message_string); class_addlist(message_class, message_list); class_addanything(message_class, message_list);
Index: pd/src/m_atom.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_atom.c,v retrieving revision 1.4 diff -u -w -r1.4 m_atom.c --- pd/src/m_atom.c 11 Aug 2006 20:09:07 -0000 1.4 +++ pd/src/m_atom.c 18 Jan 2007 00:13:03 -0000 @@ -28,6 +28,14 @@ else return (&s_float); }
+t_string *atom_getstring(t_atom *a) /* MP 20070108 */ +{ + static unsigned char c = 0;/* a default string to avoid null pointers. This should be somewhere else...? */ + static t_string st = {1L, &c}; + if (a->a_type == A_STRING) return (a->a_w.w_string); + else return (&st); +} + t_symbol *atom_gensym(t_atom *a) /* this works better for graph labels */ { char buf[30]; Index: pd/src/m_binbuf.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_binbuf.c,v retrieving revision 1.13 diff -u -w -r1.13 m_binbuf.c --- pd/src/m_binbuf.c 4 Oct 2006 19:35:06 -0000 1.13 +++ pd/src/m_binbuf.c 18 Jan 2007 00:13:03 -0000 @@ -672,6 +672,10 @@ case A_SYMBOL: typedmess(target, stackwas->a_w.w_symbol, nargs-1, stackwas+1); break; + case A_STRING: /* MP 20070106 string type */ + if (nargs == 1) pd_string(target, stackwas->a_w.w_string); + else pd_list(target, 0, nargs, stackwas); + break; case A_FLOAT: if (nargs == 1) pd_float(target, stackwas->a_w.w_float); else pd_list(target, 0, nargs, stackwas); Index: pd/src/m_class.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_class.c,v retrieving revision 1.7 diff -u -w -r1.7 m_class.c --- pd/src/m_class.c 15 Aug 2006 04:54:15 -0000 1.7 +++ pd/src/m_class.c 18 Jan 2007 00:13:03 -0000 @@ -20,6 +20,7 @@
static t_symbol *class_loadsym; /* name under which an extern is invoked */ static void pd_defaultfloat(t_pd *x, t_float f); +static void pd_defaultstring(t_pd *x, t_string *st); /* MP20061226 string type */ static void pd_defaultlist(t_pd *x, t_symbol *s, int argc, t_atom *argv); t_pd pd_objectmaker; /* factory for creating "object" boxes */ t_pd pd_canvasmaker; /* factory for creating canvases */ @@ -38,6 +39,11 @@ else (*(*x)->c_anymethod)(x, &s_bang, 0, 0); }
+static void pd_defaultstring(t_pd *x, t_string *st) /* MP 20061226 string type */ +{ /* for now just reject it, later convert to symbol/float/list */ + pd_error(x, "%s: no method for string so far...", (*x)->c_name->s_name); +} + static void pd_defaultpointer(t_pd *x, t_gpointer *gp) { if (*(*x)->c_listmethod != pd_defaultlist) @@ -205,6 +211,7 @@ c->c_pointermethod = pd_defaultpointer; c->c_floatmethod = pd_defaultfloat; c->c_symbolmethod = pd_defaultsymbol; + c->c_stringmethod = pd_defaultstring; /* MP 20061226 string type */ c->c_listmethod = pd_defaultlist; c->c_anymethod = pd_defaultanything; c->c_wb = (typeflag == CLASS_PATCHABLE ? &text_widgetbehavior : 0); @@ -288,6 +295,12 @@ if (argtype != A_SYMBOL || va_arg(ap, t_atomtype)) goto phooey; class_addsymbol(c, fn); } + else if (sel == &s_string) /* MP 20070106 string type */ + { + post("class_addmethod: %p", fn); + if (argtype != A_STRING || va_arg(ap, t_atomtype)) goto phooey; + class_addstring(c, fn); + } else if (sel == &s_list) { if (argtype != A_GIMME) goto phooey; @@ -346,6 +359,11 @@ c->c_symbolmethod = (t_symbolmethod)fn; }
+void class_addstring(t_class *c, t_method fn) /* MP 20061226 string type */ +{ + c->c_stringmethod = (t_stringmethod)fn; +} + void class_addlist(t_class *c, t_method fn) { c->c_listmethod = (t_listmethod)fn; @@ -564,9 +582,10 @@ t_symbol s_x = {"x", 0, 0}; t_symbol s_y = {"y", 0, 0}; t_symbol s_ = {"", 0, 0}; +t_symbol s_string = {"string", 0, 0}; /* MP 20061223 string type */
static t_symbol *symlist[] = { &s_pointer, &s_float, &s_symbol, &s_bang, - &s_list, &s_anything, &s_signal, &s__N, &s__X, &s_x, &s_y, &s_}; + &s_list, &s_anything, &s_signal, &s__N, &s__X, &s_x, &s_y, &s_, &s_string}; /* MP 20061223 added s_string */
void mess_init(void) { @@ -654,6 +673,13 @@ (*c->c_symbolmethod)(x, &s_); return; } + if (s == &s_string) /* MP 20061226 string type */ + { + /*post("pd_typedmess argc = %d\n", argc);*//* MP 20061226 debug */ + if (argc == 1) (*c->c_stringmethod)(x, argv->a_w.w_string); + else goto badarg; + return; + } for (i = c->c_nmethod, m = c->c_methods; i--; m++) if (m->me_name == s) { @@ -698,6 +724,19 @@ } dp++; break; + case A_STRING:/* MP 20070106 string type */ + /*post("pd_typedmess A_STRING");*/ + if (!argc) goto badarg; + if (argv->a_type == A_STRING) + { + /*post("argv->a_type == A_STRING, argc = %d, narg= %d", argc, narg);*/ + *ap = (t_int)(argv->a_w.w_string); + } + argc--; + argv++; + narg++; + ap++; + break; case A_SYMBOL: if (!argc) goto badarg; case A_DEFSYM: @@ -772,6 +811,10 @@ { case 'f': SETFLOAT(at, va_arg(ap, double)); break; case 's': SETSYMBOL(at, va_arg(ap, t_symbol *)); break; + case 't': + SETSTRING(at, va_arg(ap, t_string *)); + /*post("pd_vmess: arg[0].a_w.w_string = %p", arg[0].a_w.w_string);*/ + break; /* MP 20061226 string type */ case 'i': SETFLOAT(at, va_arg(ap, t_int)); break; case 'p': SETPOINTER(at, va_arg(ap, t_gpointer *)); break; default: goto done; Index: pd/src/m_imp.h =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_imp.h,v retrieving revision 1.4 diff -u -w -r1.4 m_imp.h --- pd/src/m_imp.h 19 Aug 2005 23:28:03 -0000 1.4 +++ pd/src/m_imp.h 18 Jan 2007 00:13:03 -0000 @@ -25,6 +25,7 @@ typedef void (*t_pointermethod)(t_pd *x, t_gpointer *gp); typedef void (*t_floatmethod)(t_pd *x, t_float f); typedef void (*t_symbolmethod)(t_pd *x, t_symbol *s); +typedef void (*t_stringmethod)(t_pd *x, t_string *st); /* MP20061226 string type */ typedef void (*t_listmethod)(t_pd *x, t_symbol *s, int argc, t_atom *argv); typedef void (*t_anymethod)(t_pd *x, t_symbol *s, int argc, t_atom *argv);
@@ -41,6 +42,7 @@ t_pointermethod c_pointermethod; t_floatmethod c_floatmethod; t_symbolmethod c_symbolmethod; + t_stringmethod c_stringmethod; /* MP20061226 string type */ t_listmethod c_listmethod; t_anymethod c_anymethod; struct _widgetbehavior *c_wb; /* "gobjs" only */ Index: pd/src/m_obj.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_obj.c,v retrieving revision 1.4 diff -u -w -r1.4 m_obj.c --- pd/src/m_obj.c 18 May 2005 04:28:51 -0000 1.4 +++ pd/src/m_obj.c 18 Jan 2007 00:13:03 -0000 @@ -15,6 +15,7 @@ t_gpointer *iu_pointerslot; t_float *iu_floatslot; t_symbol **iu_symslot; + t_string **iu_stringslot; /* MP 20061226 string type */ t_sample iu_floatsignalvalue; };
@@ -32,9 +33,10 @@ #define i_pointerslot i_un.iu_pointerslot #define i_floatslot i_un.iu_floatslot #define i_symslot i_un.iu_symslot +#define i_stringslot i_un.iu_stringslot /* MP 20061226 string type */
static t_class *inlet_class, *pointerinlet_class, *floatinlet_class, - *symbolinlet_class; + *symbolinlet_class, *stringinlet_class; /* MP 20061226 added stringinlet_class */
#define ISINLET(pd) ((*(pd) == inlet_class) || \ (*(pd) == pointerinlet_class) || \ @@ -111,6 +113,26 @@ else inlet_wrong(x, &s_symbol); }
+static void inlet_string(t_inlet *x, t_string *st) /* MP20061226 string type */ +{ + /*post("inlet_string (%p): st %p", &inlet_string, st);*/ + if (x->i_symfrom == &s_string) + { + /*post("inlet_string calling pd_vmess");*/ + pd_vmess(x->i_dest, x->i_symto, "t", st); + } + else if (!x->i_symfrom) + { + /*post("inlet_string calling pd_string");*/ + pd_string(x->i_dest, st); + } + else + { + /*post("inlet_string calling inlet_wrong");*/ + inlet_wrong(x, &s_string); + } +} + static void inlet_list(t_inlet *x, t_symbol *s, int argc, t_atom *argv) { t_atom at; @@ -192,6 +214,23 @@ return (x); }
+t_inlet *stringinlet_new(t_object *owner, t_string **stp) /* MP 20061226 string type */ +{ + t_inlet *x = (t_inlet *)pd_new(stringinlet_class), *y, *y2; + x->i_owner = owner; + x->i_dest = 0; + x->i_symfrom = &s_string; + x->i_stringslot = stp; + x->i_next = 0; + if (y = owner->ob_inlet) + { + while (y2 = y->i_next) y = y2; + y->i_next = x; + } + else owner->ob_inlet = x; + return (x); +} + static void symbolinlet_symbol(t_inlet *x, t_symbol *s) { *(x->i_symslot) = s; @@ -244,6 +283,7 @@ class_addpointer(inlet_class, inlet_pointer); class_addfloat(inlet_class, inlet_float); class_addsymbol(inlet_class, inlet_symbol); + class_addstring(inlet_class, inlet_string); /* MP 20061226 string type */ class_addlist(inlet_class, inlet_list); class_addanything(inlet_class, inlet_anything);
@@ -366,6 +406,18 @@ --stackcount; }
+void outlet_string(t_outlet *x, t_string *st) /* MP 20061226 string type */ +{ + /*post("outlet_string %p %lu", st, st->s_length);*/ + t_outconnect *oc; + if(++stackcount >= STACKITER) + outlet_stackerror(x); + else + for (oc = x->o_connections; oc; oc = oc->oc_next) + pd_string(oc->oc_to, st); + --stackcount; +} + void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv) { t_outconnect *oc; Index: pd/src/m_pd.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_pd.c,v retrieving revision 1.4 diff -u -w -r1.4 m_pd.c --- pd/src/m_pd.c 28 Nov 2004 21:20:42 -0000 1.4 +++ pd/src/m_pd.c 18 Jan 2007 00:13:03 -0000 @@ -284,6 +284,12 @@ (*(*x)->c_symbolmethod)(x, s); }
+void pd_string(t_pd *x, t_string *st) /* MP20061226 string type */ +{ + /*post("pd_string: st %p length %lu (*x)->c_stringmethod %p", st, st->s_length, (*x)->c_stringmethod);*/ + (*(*x)->c_stringmethod)(x, st); +} + void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv) { (*(*x)->c_listmethod)(x, &s_list, argc, argv); Index: pd/src/m_pd.h =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_pd.h,v retrieving revision 1.17 diff -u -w -r1.17 m_pd.h --- pd/src/m_pd.h 22 Oct 2006 21:46:11 -0000 1.17 +++ pd/src/m_pd.h 18 Jan 2007 00:13:03 -0000 @@ -102,6 +102,15 @@ t_gstub *gp_stub; /* stub which points to glist/array */ } t_gpointer;
+/* MP20061223 string type: */ +typedef struct _string /* pointer to a string */ +{ + unsigned long s_length; /* length of string in bytes */ + unsigned char *s_data; /* pointer to 1st byte of string */ +} t_string; +/* ...MP20061223 string type */ + + typedef union word { t_float w_float; @@ -110,6 +119,7 @@ t_array *w_array; struct _glist *w_list; int w_index; + t_string *w_string; /* MP20061223 string type */ } t_word;
typedef enum @@ -125,7 +135,8 @@ A_DOLLAR, A_DOLLSYM, A_GIMME, - A_CANT + A_CANT, + A_STRING /* MP20061223 string type */ } t_atomtype;
#define A_DEFSYMBOL A_DEFSYM /* better name for this */ @@ -212,6 +223,7 @@ EXTERN t_symbol s_pointer; EXTERN t_symbol s_float; EXTERN t_symbol s_symbol; +EXTERN t_symbol s_string; EXTERN t_symbol s_bang; EXTERN t_symbol s_list; EXTERN t_symbol s_anything; @@ -255,6 +267,7 @@ #define SETFLOAT(atom, f) ((atom)->a_type = A_FLOAT, (atom)->a_w.w_float = (f)) #define SETSYMBOL(atom, s) ((atom)->a_type = A_SYMBOL, \ (atom)->a_w.w_symbol = (s)) +#define SETSTRING(atom, st) ((atom)->a_type = A_STRING, (atom)->a_w.w_string = (st)) /* MP 20061226 string type */ #define SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \ (atom)->a_w.w_index = (n)) #define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \ @@ -263,6 +276,7 @@ EXTERN t_float atom_getfloat(t_atom *a); EXTERN t_int atom_getint(t_atom *a); EXTERN t_symbol *atom_getsymbol(t_atom *a); +EXTERN t_string *atom_getstring(t_atom *a);/* MP 20070108 sring type */ EXTERN t_symbol *atom_gensym(t_atom *a); EXTERN t_float atom_getfloatarg(int which, int argc, t_atom *argv); EXTERN t_int atom_getintarg(int which, int argc, t_atom *argv); @@ -326,6 +340,7 @@ EXTERN void pd_pointer(t_pd *x, t_gpointer *gp); EXTERN void pd_float(t_pd *x, t_float f); EXTERN void pd_symbol(t_pd *x, t_symbol *s); +EXTERN void pd_string(t_pd *x, t_string *st); /* MP 20061226 string type */ EXTERN void pd_list(t_pd *x, t_symbol *s, int argc, t_atom *argv); EXTERN void pd_anything(t_pd *x, t_symbol *s, int argc, t_atom *argv); #define pd_class(x) (*(x)) @@ -350,6 +365,7 @@ EXTERN void outlet_pointer(t_outlet *x, t_gpointer *gp); EXTERN void outlet_float(t_outlet *x, t_float f); EXTERN void outlet_symbol(t_outlet *x, t_symbol *s); +EXTERN void outlet_string(t_outlet *x, t_string *st); /* MP 20061226 string type */ EXTERN void outlet_list(t_outlet *x, t_symbol *s, int argc, t_atom *argv); EXTERN void outlet_anything(t_outlet *x, t_symbol *s, int argc, t_atom *argv); EXTERN t_symbol *outlet_getsymbol(t_outlet *x); @@ -404,6 +420,7 @@ EXTERN void class_addpointer(t_class *c, t_method fn); EXTERN void class_doaddfloat(t_class *c, t_method fn); EXTERN void class_addsymbol(t_class *c, t_method fn); +EXTERN void class_addstring(t_class *c, t_method fn);/* MP 20061226 string type */ EXTERN void class_addlist(t_class *c, t_method fn); EXTERN void class_addanything(t_class *c, t_method fn); EXTERN void class_sethelpsymbol(t_class *c, t_symbol *s); @@ -432,6 +449,7 @@ #define class_addpointer(x, y) class_addpointer((x), (t_method)(y)) #define class_addfloat(x, y) class_doaddfloat((x), (t_method)(y)) #define class_addsymbol(x, y) class_addsymbol((x), (t_method)(y)) +#define class_addstring(x, y) class_addstring((x), (t_method)(y)) /* MP20061226 string type */ #define class_addlist(x, y) class_addlist((x), (t_method)(y)) #define class_addanything(x, y) class_addanything((x), (t_method)(y)) #endif
Hi Martin, many thanks for your initiative, it is greatly appreciated! It would be extremely useful to also define some API for string handling right from the start, to be able to use the string type in externals... all those functionality that seems to be contained in your str object.
best greetings, Thomas
PS. It would be good to submit the patch to the sourceforge PD project.
Am 27.01.2007 um 17:53 schrieb Martin Peach:
I have implemented a string type for Pure Data as well as a [str] object that uses it. For it to work, pd needs to be patched. The [str] is contained in a separate file but the infrastructural changes are part of pd. I have attached a patch file for anyone interested. If it is acceptable, where should I put it? I could check str.c into externals, but it won't build unless the source is patched... The str object can join, split, load, save, drip, compare and convert strings to other types. It should be useful for formatting arbitrary strings for communication via byte-oriented objects such as [comport] and [tcpserver], which can then talk to external hardware (e.g. serial LCD or lanbox), for example terminating strings with CR LF instead of semicolons. Other potential applications of the string type that I haven't yet implemented are math using very long integers and row-by-row image processing.
Yeah, sounds cool indeed. If you want to try it in the Pd-extended builds, add the patch to packages/patches with a descriptive name and the version of Pd is was diffed from. (just don't add it to the 0.39.2 release branch ;)
Those patches are automatically applied as part of the build system. Your patch will have to play nice with the patches that are there.
.hc
On Jan 27, 2007, at 12:44 PM, Thomas Grill wrote:
Hi Martin, many thanks for your initiative, it is greatly appreciated! It would be extremely useful to also define some API for string handling right from the start, to be able to use the string type in externals... all those functionality that seems to be contained in your str object.
best greetings, Thomas
PS. It would be good to submit the patch to the sourceforge PD project.
Am 27.01.2007 um 17:53 schrieb Martin Peach:
I have implemented a string type for Pure Data as well as a [str] object that uses it. For it to work, pd needs to be patched. The [str] is contained in a separate file but the infrastructural changes are part of pd. I have attached a patch file for anyone interested. If it is acceptable, where should I put it? I could check str.c into externals, but it won't build unless the source is patched... The str object can join, split, load, save, drip, compare and convert strings to other types. It should be useful for formatting arbitrary strings for communication via byte-oriented objects such as [comport] and [tcpserver], which can then talk to external hardware (e.g. serial LCD or lanbox), for example terminating strings with CR LF instead of semicolons. Other potential applications of the string type that I haven't yet implemented are math using very long integers and row-by-row image processing.
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
------------------------------------------------------------------------
News is what people want to keep hidden and everything else is publicity. - Bill Moyers
Thomas Grill wrote:
Hi Martin, many thanks for your initiative, it is greatly appreciated! It would be extremely useful to also define some API for string handling right from the start, to be able to use the string type in externals... all those functionality that seems to be contained in your str object.
:) Part of the patch adds lines to m_pd.h to give a basic API:
A t_string is defined: typedef struct _string /* pointer to a string */ { unsigned long s_length; /* length of string in bytes */ unsigned char *s_data; /* pointer to 1st byte of string */ } t_string;
...and a w_string is added to t_word:
t_string *w_string; } t_word;
t_atomtype is extended with A_STRING: A_STRING } t_atomtype;
and the public functions are prototyped: EXTERN t_symbol s_string; #define SETSTRING(atom, st) ((atom)->a_type = A_STRING, (atom)->a_w.w_string = (st)) EXTERN t_string *atom_getstring(t_atom *a); EXTERN void pd_string(t_pd *x, t_string *st); EXTERN void outlet_string(t_outlet *x, t_string *st); EXTERN void class_addstring(t_class *c, t_method fn); #define class_addstring(x, y) class_addstring((x), (t_method)(y))
The [str] object contains the other functions, you can see them in str.c in /externals/mrpeach/str. Should they be public? I was thinking of an object like [list] which has selectors for various functions. Of course, any external can use t_strings once they are supported by pd. Some other issues are lying around, such as what is the largest possible string. I used MAXPDSTRING but I think that there should be no limit -- string objects should be ready to handle strings that are longer than they have memory for, without crashing. In the str object the s_length field holds the available memory and a separate private field holds the current length, but when passed as an atom through an outlet, s_length contains the true length of the string.
Martin
Martin Peach wrote:
Thomas Grill wrote:
Hi Martin, many thanks for your initiative, it is greatly appreciated!
yes, me too!
The [str] object contains the other functions, you can see them in str.c in /externals/mrpeach/str.
i think that if pd provides the infrastructure, then it also should provide the objects. (e.g. when miller has to accept a patch anyhow, then there should also be a direct benefit to core pd)
Should they be public? I was thinking of an object like [list] which has selectors for various functions.
please don't! why?
apart from that: looking forward to look at it! great.
mfg.adr IOhannes
The [str] object contains the other functions, you can see them in str.c in /externals/mrpeach/str. Should they be public? I was thinking of an object like [list] which has selectors for various functions. Of course, any external can use t_strings once they are supported by pd.
Most important would be the functions to construct and destroy strings out of C strings, since there is some memory allocation involved. That must be part of core pd, so that they are consistent. I'll yet have to look into your str object to see how all of this is actually used.
Some other issues are lying around, such as what is the largest possible string. I used MAXPDSTRING but I think that there should be no limit -- string objects should be ready to handle strings that are longer than they have memory for, without crashing.
Yes, i wouldn't restrict that either.
greetings, Thomas
-- Thomas Grill http://grrrr.org
morning Martin, morning list,
just a note: I've patched the pd-0.40-2 source & re-compiled here (separate build, not related to my flext problems mentioned in another thread;-)), and I'm still triggering the #error at line 11 of str.c (apparently induced because !defined(t_string)), despite the fact that my (patched) m_pd.h (which is being properly (#include)d does in fact include the relevant typedef.
I'm running gcc-4.1.2 on debian-unstable/x86, and it seems that here, "typedef...t_string" does *not* in fact #define t_string in the preprocessor sense (a small test program confirms this). [str] builds fine if I comment out the #ifndef...#endif, but I hereby humbly suggest finding a better method to test for pd-internal string support (either a "real" preprocessor macro defined with #define in the patched m_pd.h or an autoconf-style test compile, which is probably way overboard, but at least wouldn't require a new patch)...
at any rate, a thousand thanks for your work, and I'm looking forward to playing with real strings in pd!
marmosets, Bryan
On 2007-01-27 17:53:19, Martin Peach martin.peach@sympatico.ca appears to have written:
I have implemented a string type for Pure Data as well as a [str] object that uses it.
[snip]
Bryan Jurish wrote:
morning Martin, morning list,
just a note: I've patched the pd-0.40-2 source & re-compiled here (separate build, not related to my flext problems mentioned in another thread;-)), and I'm still triggering the #error at line 11 of str.c (apparently induced because !defined(t_string)), despite the fact that my (patched) m_pd.h (which is being properly (#include)d does in fact include the relevant typedef.
Yes, I threw that in at the last moment without really _testing_ it. I can see now that it wouldn't work although it seemed to at the time... It would probably be better to #define PD_STRING_VERSION or something similar in m_pd.h.
I'm running gcc-4.1.2 on debian-unstable/x86, and it seems that here, "typedef...t_string" does *not* in fact #define t_string in the preprocessor sense (a small test program confirms this). [str] builds fine if I comment out the #ifndef...#endif, but I hereby humbly suggest finding a better method to test for pd-internal string support (either a "real" preprocessor macro defined with #define in the patched m_pd.h or an autoconf-style test compile, which is probably way overboard, but at least wouldn't require a new patch)...
at any rate, a thousand thanks for your work, and I'm looking forward to playing with real strings in pd!
Good to know I've done something useful for once! I guess my question now is whether it's best to have a single [str] object with lots of selectors for different functions a la [list] as I did in str.c, or a bunch of objects like [str_join] [str_split] all in a str library, or individual objects in "flatspace".
Martin
marmosets, Bryan
On 2007-01-27 17:53:19, Martin Peach martin.peach@sympatico.ca appears to have written:
I have implemented a string type for Pure Data as well as a [str] object that uses it.
[snip]
moin Martin,
On 2007-02-04 00:40:03, Martin Peach martin.peach@sympatico.ca appears to have written:
Bryan Jurish wrote:
at any rate, a thousand thanks for your work, and I'm looking forward to playing with real strings in pd!
Good to know I've done something useful for once! I guess my question now is whether it's best to have a single [str] object with lots of selectors for different functions a la [list] as I did in str.c, or a bunch of objects like [str_join] [str_split] all in a str library, or individual objects in "flatspace".
I myself am partial to multiple objects, for semantic and coding-aesthetic reasons, but I can see that the parallel to [list] could be a motivation for the single-object approach. As to the question of library vs. a flat collection of single-object externals, I suppose the question is just how much of a common codebase would the various objects need? you could also even make multiple build targets (ext13 style) for the library and the flat collection, leaving the choice up to the user...
marmosets, Bryan
Bryan Jurish wrote:
moin Martin,
On 2007-02-04 00:40:03, Martin Peach martin.peach@sympatico.ca appears to have written:
Bryan Jurish wrote:
at any rate, a thousand thanks for your work, and I'm looking forward to playing with real strings in pd!
Good to know I've done something useful for once! I guess my question now is whether it's best to have a single [str] object with lots of selectors for different functions a la [list] as I did in str.c, or a bunch of objects like [str_join] [str_split] all in a str library, or individual objects in "flatspace".
I myself am partial to multiple objects, for semantic and coding-aesthetic reasons, but I can see that the parallel to [list] could be a motivation for the single-object approach. As to the question of library vs. a flat collection of single-object externals, I suppose the question is just how much of a common codebase would the various objects need? you could also even make multiple build targets (ext13 style) for the library and the flat collection, leaving the choice up to the user...
The only common codebase is what's exposed in m_pd.h and implemented in the patch, which is the minimum that enables pd to pass strings through inlets and outlets. How you allocate and destroy string space and how big the strings are is up to you, so you need to take that into account when processing string messages. IOW the string atom itself only contains a pointer to the string data, pd doesn't know anything about the data itself. In the [str] object I found it easier to use a common set of functions for the various selectors than to repeat them once for each type, but I think it would be too constraining to force everyone to use those (basically just the allocation and freeing of the string data). I also experimented with dynamically resizing the strings using resizebytes, but found that it would inevitably crash pd, so I settled on allocating a large block for each string and using a private variable to hold the current length of the string. Martin
On Feb 3, 2007, at 6:40 PM, Martin Peach wrote:
Bryan Jurish wrote:
morning Martin, morning list,
just a note: I've patched the pd-0.40-2 source & re-compiled here (separate build, not related to my flext problems mentioned in another thread;-)), and I'm still triggering the #error at line 11 of str.c (apparently induced because !defined(t_string)), despite the fact that my (patched) m_pd.h (which is being properly (#include)d does in fact include the relevant typedef.
Yes, I threw that in at the last moment without really _testing_ it. I can see now that it wouldn't work although it seemed to at the time... It would probably be better to #define PD_STRING_VERSION or something similar in m_pd.h.
I'm running gcc-4.1.2 on debian-unstable/x86, and it seems that here, "typedef...t_string" does *not* in fact #define t_string in the preprocessor sense (a small test program confirms this). [str] builds fine if I comment out the #ifndef...#endif, but I hereby humbly suggest finding a better method to test for pd-internal string support (either a "real" preprocessor macro defined with #define in the patched m_pd.h or an autoconf-style test compile, which is probably way overboard, but at least wouldn't require a new patch)...
at any rate, a thousand thanks for your work, and I'm looking forward to playing with real strings in pd!
Good to know I've done something useful for once! I guess my question now is whether it's best to have a single [str] object with lots of selectors for different functions a la [list] as I did in str.c, or a bunch of objects like [str_join] [str_split] all in a str library, or individual objects in "flatspace".
I think these should be in their own library called "string", then each of the objects would in individual objects in that library: [string/join], [string/split], etc. "flatspace" is not the place for it, that's for backwards compatibility. I think that the syntax of [list] is inconsistent without adding anything useful. Everywhere else in the core of Pd, the object class is always is the first name, and the rest are arguments.
.hc
Martin
marmosets, Bryan
On 2007-01-27 17:53:19, Martin Peach martin.peach@sympatico.ca appears to have written:
I have implemented a string type for Pure Data as well as a [str] object that uses it.
[snip]
PD-dev mailing list PD-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
------------------------------------------------------------------------
Computer science is no more related to the computer than astronomy is related to the telescope. -Edsger Dykstra