From c605308c3b3d09273dc52148083b25d251bc3a78 Mon Sep 17 00:00:00 2001 From: jasch Date: Sun, 15 Jul 2007 22:49:14 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r8093, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/jasch_lib/; revision=8094 --- detoxk/detox-help.pd | 108 +++++++++ detoxk/detox.c | 1 + detoxk/m_pd.h | 635 +++++++++++++++++++++++++++++++++++++++++++++++++++ detoxk/makefile | 92 ++++++++ 4 files changed, 836 insertions(+) create mode 100644 detoxk/detox-help.pd create mode 100644 detoxk/detox.c create mode 100644 detoxk/m_pd.h create mode 100644 detoxk/makefile diff --git a/detoxk/detox-help.pd b/detoxk/detox-help.pd new file mode 100644 index 0000000..247c0d2 --- /dev/null +++ b/detoxk/detox-help.pd @@ -0,0 +1,108 @@ +#N canvas 0 22 814 758 10; +#X msg 58 114 ; +#X obj 274 400 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 274 417 mode \$1; +#X msg 72 133 ; +#X obj 59 363 tosymbol; +#X msg 120 400 reset; +#X msg 85 152 ; +#X msg 353 314 Alan +Turing; +#X obj 225 603 prepend set; +#X msg 225 622 anchovi -56; +#X obj 225 645 prepend set; +#X msg 225 663 name margherita; +#X text 348 414 1: all attribute:value pairs; +#X text 164 399 reset tag-tree; +#X floatatom 227 469 8 0 0 0 - - -; +#X obj 226 545 prepend set; +#X msg 226 563 toxine class dish pizza item; +#X text 406 463 0 invalid tag; +#X text 406 478 1 closed tag; +#X text 406 493 2 opening tag; +#X text 406 508 3 closing tag; +#X text 406 523 4 meta tag; +#X msg 97 171 ; +#X msg 110 223 anchovi \$1; +#X floatatom 110 208 5 0 0 0 - - -; +#X msg 115 244 ; +#X msg 114 263 ; +#X msg 114 281 ; +#X msg 115 299 ; +#X msg 115 318 ; +#X text 348 399 0: first attribute:value pair; +#X text 296 399 mode:; +#X obj 59 437 detox 1; +#X text 462 559 -1 when unmatched closing tag; +#X msg 187 318 ; +#X text 405 545 returns: 0 when tree is empty; +#X obj 61 598 print tag_type; +#X obj 61 616 print tag_tree; +#X obj 61 634 print tag_content; +#X obj 61 652 print attribute:value; +#X obj 352 150 openpanel; +#X obj 351 248 textfile; +#X obj 364 222 bng 15 250 50 0 empty empty empty 0 -6 0 8 -150892 -1 +-1; +#X obj 352 133 bng 15 250 50 0 empty empty empty 0 -6 0 8 -166441 -1 +-1; +#X msg 364 204 rewind; +#X msg 352 168 read \$1 cr; +#X text 433 199 go to start of file; +#X text 433 214 step through file; +#X obj 351 266 print input_line; +#X text 375 132 open wellformed xml-file; +#X msg 110 190 ; +#X text 354 298 closed tag w/ multiple attributes; +#X obj -14 13 cnv 15 780 40 empty empty detox 20 12 0 24 -237236 -66577 +0; +#X text 85 21 extract values \, contents \, attributes from xml-tag +structures; +#X text 85 35 argument (optional): mode 0/1; +#X text 666 18 jasch 05/2006; +#X text 624 34 http://www.jasch.ch; +#X obj 310 465 cnv 15 90 20 empty empty tag_type: 10 10 0 10 -233017 +-66577 0; +#X obj 312 542 cnv 15 90 20 empty empty tag_tree: 10 10 0 10 -233017 +-66577 0; +#X obj 312 600 cnv 15 90 20 empty empty tag_content: 10 10 0 10 -233017 +-66577 0; +#X obj 311 643 cnv 15 200 18 empty empty attribute/value_pairs: 10 +10 0 10 -233017 -66577 0; +#X connect 0 0 4 0; +#X connect 1 0 2 0; +#X connect 2 0 32 0; +#X connect 3 0 4 0; +#X connect 4 0 32 0; +#X connect 5 0 32 0; +#X connect 6 0 4 0; +#X connect 7 0 4 0; +#X connect 8 0 9 0; +#X connect 10 0 11 0; +#X connect 15 0 16 0; +#X connect 22 0 4 0; +#X connect 23 0 4 0; +#X connect 24 0 23 0; +#X connect 25 0 4 0; +#X connect 26 0 4 0; +#X connect 27 0 4 0; +#X connect 28 0 4 0; +#X connect 29 0 4 0; +#X connect 32 0 10 0; +#X connect 32 0 39 0; +#X connect 32 1 8 0; +#X connect 32 1 38 0; +#X connect 32 2 15 0; +#X connect 32 2 37 0; +#X connect 32 3 14 0; +#X connect 32 3 36 0; +#X connect 34 0 4 0; +#X connect 40 0 45 0; +#X connect 41 0 4 0; +#X connect 41 0 48 0; +#X connect 42 0 41 0; +#X connect 43 0 40 0; +#X connect 44 0 41 0; +#X connect 45 0 41 0; +#X connect 50 0 4 0; diff --git a/detoxk/detox.c b/detoxk/detox.c new file mode 100644 index 0000000..9889e45 --- /dev/null +++ b/detoxk/detox.c @@ -0,0 +1 @@ +/*__________________________________________________________________________ detox á extract value/content from tag-structured symbol Copyright (C) 2003 - 2006 jan schacher This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA pd-port 20060517 revised tree output 20040712 initial build 20030502 ____________________________________________________________________________*/ #include "m_pd.h" #include #include #include #include #include #define VERSION "1.3" #define CLIP(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x) #define MAXLENGTH 4096 typedef struct _detox { t_object ob; t_atom t_tree[257], t_attrpair[2]; t_atom t_comp, t_blip; t_atom t_checkat[2]; char t_charbuf[MAXLENGTH]; long t_treecount; short t_debug; short t_mode; void *s_outlet, *s_outlet2, *s_outlet3, *s_outlet4; } t_detox; t_symbol *ps_nothing; void *detox_class; void *detox_new(t_symbol *s, short argc, t_atom *argv); void detox_bang(t_detox *x); void detox_float(t_detox *x, t_float f); void detox_list(t_detox *x, t_symbol *s, short argc, t_atom *argv); void detox_anything(t_detox *x, t_symbol *s, short argc, t_atom *argv); void detox_free(t_detox *x); void detox_reset(t_detox *x); void detox_debug(t_detox *x, float f); void detox_mode(t_detox *x, float f); void detox_anything(t_detox *x, t_symbol *s, short argc, t_atom *argv); void detox_action(t_detox *x); void detox_fixsymbol(t_detox *x); void version(t_detox *x); void detox_setup(void) { detox_class = class_new(gensym("detox"), (t_newmethod)detox_new, (t_method)detox_free, sizeof(t_detox), 0, A_GIMME, 0); class_addsymbol(detox_class, (t_method)detox_anything); class_addmethod(detox_class, (t_method)detox_list, gensym("list"), A_GIMME,0); class_addmethod(detox_class, (t_method)detox_debug, gensym("debug"), A_FLOAT, 0); class_addmethod(detox_class, (t_method)detox_mode, gensym("mode"), A_FLOAT, 0); class_addmethod(detox_class, (t_method)detox_reset, gensym("reset"), 0); class_addmethod(detox_class, (t_method)version, gensym("version"), 0); post("- detox - jasch - "__DATE__" "); ps_nothing = gensym(""); } void *detox_new(t_symbol *s, short argc, t_atom *argv) { t_detox *x = (t_detox *)pd_new(detox_class); x->s_outlet = outlet_new(&x->ob, NULL); x->s_outlet2 = outlet_new(&x->ob, NULL); x->s_outlet3 = outlet_new(&x->ob, NULL); x->s_outlet4 = outlet_new(&x->ob, gensym("float")); x->t_treecount = 0; x->t_debug = 0; if((argc >= 1)&&(argv[0].a_type == A_FLOAT)){ if(argv[0].a_w.w_float == 0){ x->t_mode = 0; }else{ x->t_mode = 1; } }else{ x->t_mode = 1; } x->t_debug = 0; if(x->t_debug) post("mode is %ld", x->t_mode); x->t_checkat[0].a_type = A_SYMBOL; x->t_checkat[0].a_w.w_symbol = gensym("none"); x->t_checkat[1].a_type = A_SYMBOL; x->t_checkat[1].a_w.w_symbol = gensym("none"); return (x); } void detox_free(t_detox *x) { // notify_free((t_object *)x); } void detox_bang(t_detox *x) { detox_action(x); } void detox_float(t_detox *x, t_float f) { sprintf(x->t_charbuf, "%.6f", f); detox_action(x); } void detox_list(t_detox *x, t_symbol *s, short argc, t_atom *argv) { long i; char temp[MAXLENGTH]; x->t_charbuf[0] = 0; for(i = 0; i < argc; i++){ if(i) strcat(x->t_charbuf, " "); temp[0] = 0; if(argv[i].a_type == A_FLOAT){ sprintf(temp, "%.6f", argv[i].a_w.w_float); }else if(argv[i].a_type == A_SYMBOL){ // check for whitespace in symbol and add back doublequotes if(strchr(argv[i].a_w.w_symbol->s_name, 32) == NULL) { // no whitespace : normal proc strcpy(temp, argv[i].a_w.w_symbol->s_name); } else { // with whitespace : fix it x->t_checkat[0] = argv[i]; detox_fixsymbol(x); strcpy(temp, x->t_checkat[1].a_w.w_symbol->s_name); } } if((strlen(x->t_charbuf) + strlen(temp)) < MAXLENGTH){ strcat(x->t_charbuf, temp); }else{ return; } } detox_action(x); } void detox_anything(t_detox *x, t_symbol *s, short argc, t_atom *argv) { long i; char temp[MAXLENGTH]; x->t_charbuf[0] = 0; strcpy(x->t_charbuf, s->s_name); for(i = 0; i < argc; i++){ strcat(x->t_charbuf, " "); temp[0] = 0; if(argv[i].a_type == A_FLOAT){ sprintf(temp, "%.6f", argv[i].a_w.w_float); }else if(argv[i].a_type == A_SYMBOL){ // check for whitespace in symbol and add back doublequotes if(strchr(argv[i].a_w.w_symbol->s_name, 32) == NULL) { // no whitespace : normal proc strcpy(temp, argv[i].a_w.w_symbol->s_name); } else { // with whitespace : fix it x->t_checkat[0] = argv[i]; detox_fixsymbol(x); strcpy(temp, x->t_checkat[1].a_w.w_symbol->s_name); } } // post("temp is %s", temp); if((strlen(x->t_charbuf) + strlen(temp)) < MAXLENGTH){ strcat(x->t_charbuf, temp); }else{ return; } } detox_action(x); return; } void detox_reset(t_detox *x) { short i; x->t_treecount = 0; for(i=0;i<256; i++) x->t_tree[i].a_w.w_symbol = ps_nothing; } void detox_debug(t_detox *x, float f) { if(f == 0.0){ x->t_debug = 0; }else if(f != 0){ x->t_debug = 1; } } void detox_mode(t_detox *x, float f) { if(f == 0.0){ x->t_mode = 0; }else if(f != 0){ x->t_mode = 1; } } void detox_action(t_detox *x) { t_atom *outlist, *attrpair; // *comp, char local[MAXLENGTH], local2[MAXLENGTH]; char temp[MAXLENGTH]; char tempstring[2]; // for strtok char *ptr1 = NULL, *ptr2 = NULL, *ptr3 = NULL; long i, j, k, last, len, tempcount = 0; short tagtype = 0; // 0 = closed, 1 = open, 2 = closing short outsize = 0; char quotetype[1]; short digitflag = 0; short punctflag = 0; short quoteflag = 0; // short attrpresent = 0; quotetype[0] = '\"'; // init to standard double quotes i = 0; strcpy(tempstring, " "); outlist = x->t_tree; attrpair = x->t_attrpair; x->t_attrpair[0].a_type = A_SYMBOL; x->t_attrpair[1].a_type = A_SYMBOL; // check type and recast on output strcpy(local2, x->t_charbuf); last = strlen(local2); // test for tag // if(x->t_debug) post("input is %s", x->t_charbuf); k = 0; while(isspace(local2[k])){ // remove whitespace/tab/cr/linefeed k++; } // if(x->t_debug) post("k is %ld, last is %ld", k, last); for(i=k, j=0; it_debug) post("tagtype 0"); goto content; } if((local[1] == '?') || (local[1] == '!')){ tagtype = 4; // this might be a metatag if(x->t_debug) post("tagtype 4"); goto content; } for(i = 0, ptr1 = NULL, quoteflag = 0; i < (long)(strlen(local) -1); i++) { if((local[i] == '\"') || (local[i] == '\'')){ quoteflag = !quoteflag; } if((local[i] == '/') && (quoteflag == 0)) { ptr1 = &local[i]; } } //ptr1 = strchr(local, '/'); // is it a closing tag ? // bug: if slash is within quotes: should ignore if(x->t_debug) post("ptr1 contains %s", x->t_charbuf); if(ptr1 == NULL){ // we have new open tag tagtype = 2; if(x->t_debug) post("tagtype 2"); }else if((local[1] == '/')){ // is it at beginning tagtype = 3; if(x->t_debug) post("tagtype 3"); }else if(local[1] != '/'){ // is it elsewhere if(x->t_debug) post("tagtype 1"); tagtype = 1; } switch(tagtype){ case 1: // closed tag :: add temporarily to tree ptr1 = strchr(local, '>'); ptr2 = strchr(local, ' '); if(ptr2 != NULL) *ptr2 = 0; if(ptr1 != NULL){ *ptr1 = 0; }else{ return; } len = strlen(local); ptr3 = (char *)memmove((local + 0),(local + 1), len-1); local[len-1] = 0; ptr3 = local; x->t_blip.a_type = A_SYMBOL; x->t_blip.a_w.w_symbol = gensym(ptr3); tempcount = 1; break; case 2: // opening tag :: add to tree, increment count ptr2 = strchr(local, ' '); if(ptr2 != NULL){ *ptr2 = 0; if(x->t_debug) post("inside opening tag w/ whitespace, %s", local); }else{ local[strlen(local) - 1] = 0; // local[strlen(ptr2) -1] = 0; if(x->t_debug) post("inside opening tag no whitespace, %s", local); // return; } len = strlen(local); ptr3 = (char *)memmove((local + 0),(local + 1), len-1); if(x->t_debug) post("ptr3 is %s", ptr3); local[len-1] = 0; ptr3 = local; SETSYMBOL(x->t_tree + x->t_treecount, gensym(ptr3)); x->t_treecount++; x->t_treecount = CLIP(x->t_treecount, 0, 255); break; case 3: // closing tag :: remove from tree, decrement count ptr2 = strchr(local, '>'); if(ptr2 != NULL){ *ptr2 = 0; }else{ return; } len = strlen(local); ptr3 = (char *)memmove((local + 0),(local + 2), len-2); local[len-2] = 0; ptr3 = local; x->t_comp.a_type = A_SYMBOL; x->t_comp.a_w.w_symbol = gensym(ptr3); if(x->t_comp.a_w.w_symbol->s_name == x->t_tree[x->t_treecount-1].a_w.w_symbol->s_name){ x->t_treecount -= 1; x->t_treecount = CLIP(x->t_treecount, 0, 255); }else{ outlet_float(x->s_outlet4, 3); outlet_float(x->s_outlet3, -1); return; } break; } content: outlet_float(x->s_outlet4, tagtype); if(tagtype == 0) return; // the tree if(x->t_treecount > 0){ if(tempcount){ outsize = x->t_treecount + 1; x->t_tree[outsize-1] = x->t_blip; }else{ outsize = x->t_treecount; } outlet_list(x->s_outlet3, 0L, outsize, outlist); // ouput tree }else if(x->t_treecount == 0){ if(tempcount){ outlet_anything(x->s_outlet3, x->t_blip.a_w.w_symbol, 0, 0L); // ouput tree }else{ outlet_float(x->s_outlet3, 0); // ouput tree } } strcpy(local, x->t_charbuf); ptr1 = strchr(local, '>'); // parse content between enclosing tags blah if(ptr1 == NULL) goto attributes; *ptr1 = 0; ++ptr1; ptr2 = strchr(ptr1, '<'); if(ptr2 == NULL) goto attributes; *ptr2 = 0; outlet_anything(x->s_outlet2, gensym(ptr1), 0, 0L); attributes: strcpy(local, x->t_charbuf); // retrieve full buffer again switch(x->t_mode) { // the old way of attribute parsing (mode 0) case 0: if(x->t_debug) post("content: before strtok %s", local); ptr1 = local; ptr2 = strchr(local, '>'); // find tag end ptr2++; // terminate local buffer after tag end ptr2[0] = 0; if(strcspn(ptr1, "=\"\'") == strlen(ptr1)) { // check for attributes inside tag break; // no attr-chars found, bail ouit } ptr1 = strchr(local, ' '); // find first whitespace if(ptr1 == NULL) { break; // no whitespace found bail } while((ptr1[0] == ' ') && (ptr1 != NULL)) { // find next non-whitespace char -> potential start of attr ptr1++; } ptr2 = ptr1; // setup second pointer from end of attr name while( !((ptr2[0] == ' ') || (ptr2[0] == '=')) && (ptr2 != NULL)) { // find next non-white or not equal-sign -> what if not well formed ?? ptr2++; } if(ptr2 == NULL) { error("detox: mode 0, attrloop ptr2 reached NULL looking for \" \" and \"=\""); return; } /*len = 0; len = strlen(ptr1) - strlen(ptr2); // determine length of attr name: name minus whitespace/equal sign for(i = 0; i < len; i++) { temp[i] = ptr1[i]; } temp[len] = 0; // terminate temp_buffer */ ptr1 = ptr2; // copy start pointer to position of end pointer -> remainder while(ptr1 != NULL) { // move start pointer until single or double quote if ((ptr1[0] == '\'') || (ptr1[0] == '\"')) { quotetype[0] = ptr1[0]; break; } ptr1++; } if(ptr1 == NULL) { // bail if no quotes found and end reached error("detox: mode 0, attrloop ptr1 reached NULL"); return; } // store quote char for later comparison if (x->t_debug) post("first quotetype found is %c", quotetype[0]); ptr2 = ++ptr1; // copy end pointer to pos of startpointer + 1, right after the quote while(ptr2 != NULL) { // looking for next quote of stored type if(ptr2[0] == quotetype[0]) { break; } ptr2++; } // post("quotetype is %c and ptr2 is %c", quotetype[0], ptr2[0]); if(ptr2 == NULL) { error("detox: mode 0, attrloop ptr2 reached NULL"); return; } len = 0; digitflag = 1; // reset check for long punctflag = 0; // reset check for float len = strlen(ptr1) - strlen(ptr2); // get the length of the attr content // post("ptr2 ends scan at %c", ptr2[0]); for(i = 0; i < len; i++) { // copy attr-content into temp-buffer temp[i] = ptr1[i]; punctflag += (temp[i] == '.'); // digitflag = digitflag && (isdigit(temp[i]) || ispunct(temp[i])); // are all digits? } temp[len] = 0; if (x->t_debug) post("temp is %s, digitflag is %ld, punctflag is %ld", temp, digitflag, punctflag); if(digitflag == 0){ attrpair[0].a_type = A_SYMBOL; // to do: check atom type and cast accordingly js 20061202 attrpair[0].a_w.w_symbol = gensym(temp); outlet_anything(x->s_outlet, x->t_attrpair[0].a_w.w_symbol, 0, 0L); } else if ((digitflag == 1)&&(punctflag == 0)){ attrpair[1].a_type = A_FLOAT; // to do: check atom type and cast accordingly js 20061202 attrpair[1].a_w.w_float = atoi(temp); outlet_float(x->s_outlet, x->t_attrpair[2].a_w.w_float); } else if ((digitflag == 1)&&(punctflag == 1)){ attrpair[1].a_type = A_FLOAT; // to do: check atom type and cast accordingly js 20061202 attrpair[1].a_w.w_float = atof(temp); outlet_float(x->s_outlet, x->t_attrpair[1].a_w.w_float); } break; case 1: // the new way of attribute parsing (mode 1) ¥¥¥¥ fixed 20070322 ptr1 = local; ptr2 = strchr(local, '>'); // find tag end ptr2++; // terminate local buffer after tag end ptr2[0] = 0; if(strcspn(ptr1, "=\"\'") == strlen(ptr1)) { // check for attributes inside tag break; // no attr-chars found, bail ouit } ptr1 = strchr(local, ' '); // find first whitespace if(ptr1 == NULL) { break; // no whitespace found bail } for(;;) { // ¥¥ attribute loop; example: while((ptr1[0] == ' ') && (ptr1 != NULL)) { // find next non-whitespace char -> potential start of attr ptr1++; } ptr2 = ptr1; // setup second pointer from end of attr name while( !((ptr2[0] == ' ') || (ptr2[0] == '=')) && (ptr2 != NULL)) { // find next non-white or not equal-sign -> what if not well formed ?? ptr2++; } if(ptr2 == NULL) { error("detox: mode 1, attrloop ptr2 reached NULL looking for \" \" and \"=\""); return; } len = 0; len = strlen(ptr1) - strlen(ptr2); // determine length of attr name: name minus whitespace/equal sign for(i = 0; i < len; i++) { temp[i] = ptr1[i]; } temp[len] = 0; // terminate temp_buffer attrpair[0].a_w.w_symbol = gensym(temp); // put tempbuffer into output symbol // ¥ done with the attr-name ptr1 = ptr2; // copy start pointer to position of end pointer -> remainder while(ptr1 != NULL) { // move start pointer until single or double quote if ((ptr1[0] == '\'') || (ptr1[0] == '\"')) { quotetype[0] = ptr1[0]; // store quote char for later comparison break; } ptr1++; } if(ptr1 == NULL) { // bail if no quotes found and end reached error("detox: mode 1, attrloop ptr1 reached NULL"); return; } if (x->t_debug) post("first quotetype found is %c", quotetype[0]); ptr2 = ++ptr1; // copy end pointer to pos of startpointer + 1, right after the quote while(ptr2 != NULL) { // looking for next quote of stored type if(ptr2[0] == quotetype[0]) { break; } ptr2++; } // post("quotetype is %c and ptr2 is %c", quotetype[0], ptr2[0]); if(ptr2 == NULL) { error("detox: mode 1, attrloop ptr2 reached NULL"); return; } len = 0; digitflag = 1; // reset check for long punctflag = 0; // reset check for float len = strlen(ptr1) - strlen(ptr2); // get the length of the attr content // post("ptr2 ends scan at %c", ptr2[0]); for(i = 0; i < len; i++) { // copy attr-content into temp-buffer temp[i] = ptr1[i]; punctflag += (temp[i] == '.'); // digitflag = digitflag && (isdigit(temp[i]) || ispunct(temp[i])); // are all digits? } temp[len] = 0; if (x->t_debug) post("temp is %s, digitflag is %ld, punctflag is %ld", temp, digitflag, punctflag); if(digitflag == 0){ attrpair[1].a_type = A_SYMBOL; // to do: check atom type and cast accordingly js 20061202 attrpair[1].a_w.w_symbol = gensym(temp); } else if ((digitflag == 1)&&(punctflag == 0)){ attrpair[1].a_type = A_FLOAT; // to do: check atom type and cast accordingly js 20061202 attrpair[1].a_w.w_float = atoi(temp); } else if ((digitflag == 1)&&(punctflag == 1)){ attrpair[1].a_type = A_FLOAT; // to do: check atom type and cast accordingly js 20061202 attrpair[1].a_w.w_float = atof(temp); } outlet_anything(x->s_outlet, x->t_attrpair[0].a_w.w_symbol, 1, &x->t_attrpair[1]); ptr1 = ++ptr2; // move start pointer to end of atrr-content while(ptr1 != NULL) { // find next non-whitespace char if (ptr1[0] != ' ') { break; } ptr1++; } if((ptr1[0] == '/') || (ptr1[0] == '>') || (ptr1[0] == '?') || (ptr1 == NULL)) { // if char is "/" or ">" or "?" or end of string finish up if (x->t_debug) post("ptr1 reached ending meta characters"); return; } if (x->t_debug) post("ptr1 reached loop point"); } break; } } void detox_fixsymbol(t_detox *x) // this is an ugly hack for max stripping double quotes from symbols with whitespace in them (language problem) { long i = 0; long len = 0; x->t_checkat[1].a_w.w_symbol->s_name[0] = '\"'; // first char in output is " len = strlen(x->t_checkat[0].a_w.w_symbol->s_name); len = CLIP(len, 0, (MAXLENGTH-3)); for(i = 0; i < len; i++) { if ((x->t_checkat[0].a_w.w_symbol->s_name[i] == '/') || (x->t_checkat[0].a_w.w_symbol->s_name[i] == '>')) { // check for syntax differences break; } x->t_checkat[1].a_w.w_symbol->s_name[i+1] = x->t_checkat[0].a_w.w_symbol->s_name[i]; } x->t_checkat[1].a_w.w_symbol->s_name[i+1] = '\"'; // last char in output is " x->t_checkat[1].a_w.w_symbol->s_name[i+2] = 0; // terminate string } void version(t_detox *x) { post("á detox á jasch á v. "VERSION" á compiled "__DATE__" - "__TIME__ ); } \ No newline at end of file diff --git a/detoxk/m_pd.h b/detoxk/m_pd.h new file mode 100644 index 0000000..41e0ffa --- /dev/null +++ b/detoxk/m_pd.h @@ -0,0 +1,635 @@ +/* Copyright (c) 1997-1999 Miller Puckette. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#ifndef __m_pd_h_ + +#if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus) +extern "C" { +#endif + +#define PD_MAJOR_VERSION 0 +#define PD_MINOR_VERSION 39 + +/* old name for "MSW" flag -- we have to take it for the sake of many old +"nmakefiles" for externs, which will define NT and not MSW */ +#if defined(NT) && !defined(MSW) +#define MSW +#endif + +#ifdef MSW +/* #pragma warning( disable : 4091 ) */ +#pragma warning( disable : 4305 ) /* uncast const double to float */ +#pragma warning( disable : 4244 ) /* uncast float/int conversion etc. */ +#pragma warning( disable : 4101 ) /* unused automatic variables */ +#endif /* MSW */ + + /* the external storage class is "extern" in UNIX; in MSW it's ugly. */ +#ifdef MSW +#ifdef PD_INTERNAL +#define EXTERN __declspec(dllexport) extern +#else +#define EXTERN __declspec(dllimport) extern +#endif /* PD_INTERNAL */ +#else +#define EXTERN extern +#endif /* MSW */ + + /* and depending on the compiler, hidden data structures are + declared differently: */ +#if defined( __GNUC__) || defined( __BORLANDC__ ) || defined( __MWERKS__ ) +#define EXTERN_STRUCT struct +#else +#define EXTERN_STRUCT extern struct +#endif + + +#if !defined(_SIZE_T) && !defined(_SIZE_T_) +#include /* just for size_t -- how lame! */ +#endif + +#define MAXPDSTRING 1000 /* use this for anything you want */ +#define MAXPDARG 5 /* max number of args we can typecheck today */ + +/* signed and unsigned integer types the size of a pointer: */ +/* GG: long is the size of a pointer */ +typedef long t_int; + +typedef float t_float; /* a floating-point number at most the same size */ +typedef float t_floatarg; /* floating-point type for function calls */ + +typedef struct _symbol +{ + char *s_name; + struct _class **s_thing; + struct _symbol *s_next; +} t_symbol; + +EXTERN_STRUCT _array; +#define t_array struct _array /* g_canvas.h */ + +/* pointers to glist and array elements go through a "stub" which sticks +around after the glist or array is freed. The stub itself is deleted when +both the glist/array is gone and the refcount is zero, ensuring that no +gpointers are pointing here. */ + +#define GP_NONE 0 /* the stub points nowhere (has been cut off) */ +#define GP_GLIST 1 /* the stub points to a glist element */ +#define GP_ARRAY 2 /* ... or array */ + +typedef struct _gstub +{ + union + { + struct _glist *gs_glist; /* glist we're in */ + struct _array *gs_array; /* array we're in */ + } gs_un; + int gs_which; /* GP_GLIST/GP_ARRAY */ + int gs_refcount; /* number of gpointers pointing here */ +} t_gstub; + +typedef struct _gpointer /* pointer to a gobj in a glist */ +{ + union + { + struct _scalar *gp_scalar; /* scalar we're in (if glist) */ + union word *gp_w; /* raw data (if array) */ + } gp_un; + int gp_valid; /* number which must match gpointee */ + t_gstub *gp_stub; /* stub which points to glist/array */ +} t_gpointer; + +typedef union word +{ + t_float w_float; + t_symbol *w_symbol; + t_gpointer *w_gpointer; + t_array *w_array; + struct _glist *w_list; + int w_index; +} t_word; + +typedef enum +{ + A_NULL, + A_FLOAT, + A_SYMBOL, + A_POINTER, + A_SEMI, + A_COMMA, + A_DEFFLOAT, + A_DEFSYM, + A_DOLLAR, + A_DOLLSYM, + A_GIMME, + A_CANT +} t_atomtype; + +#define A_DEFSYMBOL A_DEFSYM /* better name for this */ + +typedef struct _atom +{ + t_atomtype a_type; + union word a_w; +} t_atom; + +EXTERN_STRUCT _class; +#define t_class struct _class + +EXTERN_STRUCT _outlet; +#define t_outlet struct _outlet + +EXTERN_STRUCT _inlet; +#define t_inlet struct _inlet + +EXTERN_STRUCT _binbuf; +#define t_binbuf struct _binbuf + +EXTERN_STRUCT _clock; +#define t_clock struct _clock + +EXTERN_STRUCT _outconnect; +#define t_outconnect struct _outconnect + +EXTERN_STRUCT _glist; +#define t_glist struct _glist +#define t_canvas struct _glist /* LATER lose this */ + +typedef t_class *t_pd; /* pure datum: nothing but a class pointer */ + +typedef struct _gobj /* a graphical object */ +{ + t_pd g_pd; /* pure datum header (class) */ + struct _gobj *g_next; /* next in list */ +} t_gobj; + +typedef struct _scalar /* a graphical object holding data */ +{ + t_gobj sc_gobj; /* header for graphical object */ + t_symbol *sc_template; /* template name (LATER replace with pointer) */ + t_word sc_vec[1]; /* indeterminate-length array of words */ +} t_scalar; + +typedef struct _text /* patchable object - graphical, with text */ +{ + t_gobj te_g; /* header for graphical object */ + t_binbuf *te_binbuf; /* holder for the text */ + t_outlet *te_outlet; /* linked list of outlets */ + t_inlet *te_inlet; /* linked list of inlets */ + short te_xpix; /* x&y location (within the toplevel) */ + short te_ypix; + short te_width; /* requested width in chars, 0 if auto */ + unsigned int te_type:2; /* from defs below */ +} t_text; + +#define T_TEXT 0 /* just a textual comment */ +#define T_OBJECT 1 /* a MAX style patchable object */ +#define T_MESSAGE 2 /* a MAX stype message */ +#define T_ATOM 3 /* a cell to display a number or symbol */ + +#define te_pd te_g.g_pd + + /* t_object is synonym for t_text (LATER unify them) */ + +typedef struct _text t_object; + +#define ob_outlet te_outlet +#define ob_inlet te_inlet +#define ob_binbuf te_binbuf +#define ob_pd te_g.g_pd +#define ob_g te_g + +typedef void (*t_method)(void); +typedef void *(*t_newmethod)( void); +typedef void (*t_gotfn)(void *x, ...); + +/* ---------------- pre-defined objects and symbols --------------*/ +EXTERN t_pd pd_objectmaker; /* factory for creating "object" boxes */ +EXTERN t_pd pd_canvasmaker; /* factory for creating canvases */ +EXTERN t_symbol s_pointer; +EXTERN t_symbol s_float; +EXTERN t_symbol s_symbol; +EXTERN t_symbol s_bang; +EXTERN t_symbol s_list; +EXTERN t_symbol s_anything; +EXTERN t_symbol s_signal; +EXTERN t_symbol s__N; +EXTERN t_symbol s__X; +EXTERN t_symbol s_x; +EXTERN t_symbol s_y; +EXTERN t_symbol s_; + +/* --------- prototypes from the central message system ----------- */ +EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv); +EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv); +EXTERN t_symbol *gensym(char *s); +EXTERN t_gotfn getfn(t_pd *x, t_symbol *s); +EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s); +EXTERN void nullfn(void); +EXTERN void pd_vmess(t_pd *x, t_symbol *s, char *fmt, ...); +#define mess0(x, s) ((*getfn((x), (s)))((x))) +#define mess1(x, s, a) ((*getfn((x), (s)))((x), (a))) +#define mess2(x, s, a,b) ((*getfn((x), (s)))((x), (a),(b))) +#define mess3(x, s, a,b,c) ((*getfn((x), (s)))((x), (a),(b),(c))) +#define mess4(x, s, a,b,c,d) ((*getfn((x), (s)))((x), (a),(b),(c),(d))) +#define mess5(x, s, a,b,c,d,e) ((*getfn((x), (s)))((x), (a),(b),(c),(d),(e))) +EXTERN void obj_list(t_object *x, t_symbol *s, int argc, t_atom *argv); +EXTERN t_pd *pd_newest(void); + +/* --------------- memory management -------------------- */ +EXTERN void *getbytes(size_t nbytes); +EXTERN void *getzbytes(size_t nbytes); +EXTERN void *copybytes(void *src, size_t nbytes); +EXTERN void freebytes(void *x, size_t nbytes); +EXTERN void *resizebytes(void *x, size_t oldsize, size_t newsize); + +/* -------------------- atoms ----------------------------- */ + +#define SETSEMI(atom) ((atom)->a_type = A_SEMI, (atom)->a_w.w_index = 0) +#define SETCOMMA(atom) ((atom)->a_type = A_COMMA, (atom)->a_w.w_index = 0) +#define SETPOINTER(atom, gp) ((atom)->a_type = A_POINTER, \ + (atom)->a_w.w_gpointer = (gp)) +#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 SETDOLLAR(atom, n) ((atom)->a_type = A_DOLLAR, \ + (atom)->a_w.w_index = (n)) +#define SETDOLLSYM(atom, s) ((atom)->a_type = A_DOLLSYM, \ + (atom)->a_w.w_symbol= (s)) + +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_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); +EXTERN t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv); + +EXTERN void atom_string(t_atom *a, char *buf, unsigned int bufsize); + +/* ------------------ binbufs --------------- */ + +EXTERN t_binbuf *binbuf_new(void); +EXTERN void binbuf_free(t_binbuf *x); +EXTERN t_binbuf *binbuf_duplicate(t_binbuf *y); + +EXTERN void binbuf_text(t_binbuf *x, char *text, size_t size); +EXTERN void binbuf_gettext(t_binbuf *x, char **bufp, int *lengthp); +EXTERN void binbuf_clear(t_binbuf *x); +EXTERN void binbuf_add(t_binbuf *x, int argc, t_atom *argv); +EXTERN void binbuf_addv(t_binbuf *x, char *fmt, ...); +EXTERN void binbuf_addbinbuf(t_binbuf *x, t_binbuf *y); +EXTERN void binbuf_addsemi(t_binbuf *x); +EXTERN void binbuf_restore(t_binbuf *x, int argc, t_atom *argv); +EXTERN void binbuf_print(t_binbuf *x); +EXTERN int binbuf_getnatom(t_binbuf *x); +EXTERN t_atom *binbuf_getvec(t_binbuf *x); +EXTERN void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv); +EXTERN int binbuf_read(t_binbuf *b, char *filename, char *dirname, + int crflag); +EXTERN int binbuf_read_via_path(t_binbuf *b, char *filename, char *dirname, + int crflag); +EXTERN int binbuf_write(t_binbuf *x, char *filename, char *dir, + int crflag); +EXTERN void binbuf_evalfile(t_symbol *name, t_symbol *dir); +EXTERN t_symbol *binbuf_realizedollsym(t_symbol *s, int ac, t_atom *av, + int tonew); + +/* ------------------ clocks --------------- */ + +EXTERN t_clock *clock_new(void *owner, t_method fn); +EXTERN void clock_set(t_clock *x, double systime); +EXTERN void clock_delay(t_clock *x, double delaytime); +EXTERN void clock_unset(t_clock *x); +EXTERN double clock_getlogicaltime(void); +EXTERN double clock_getsystime(void); /* OBSOLETE; use clock_getlogicaltime() */ +EXTERN double clock_gettimesince(double prevsystime); +EXTERN double clock_getsystimeafter(double delaytime); +EXTERN void clock_free(t_clock *x); + +/* ----------------- pure data ---------------- */ +EXTERN t_pd *pd_new(t_class *cls); +EXTERN void pd_free(t_pd *x); +EXTERN void pd_bind(t_pd *x, t_symbol *s); +EXTERN void pd_unbind(t_pd *x, t_symbol *s); +EXTERN t_pd *pd_findbyclass(t_symbol *s, t_class *c); +EXTERN void pd_pushsym(t_pd *x); +EXTERN void pd_popsym(t_pd *x); +EXTERN t_symbol *pd_getfilename(void); +EXTERN t_symbol *pd_getdirname(void); +EXTERN void pd_bang(t_pd *x); +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_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)) + +/* ----------------- pointers ---------------- */ +EXTERN void gpointer_init(t_gpointer *gp); +EXTERN void gpointer_copy(const t_gpointer *gpfrom, t_gpointer *gpto); +EXTERN void gpointer_unset(t_gpointer *gp); +EXTERN int gpointer_check(const t_gpointer *gp, int headok); + +/* ----------------- patchable "objects" -------------- */ +EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1, + t_symbol *s2); +EXTERN t_inlet *pointerinlet_new(t_object *owner, t_gpointer *gp); +EXTERN t_inlet *floatinlet_new(t_object *owner, t_float *fp); +EXTERN t_inlet *symbolinlet_new(t_object *owner, t_symbol **sp); +EXTERN t_inlet *signalinlet_new(t_object *owner, t_float f); +EXTERN void inlet_free(t_inlet *x); + +EXTERN t_outlet *outlet_new(t_object *owner, t_symbol *s); +EXTERN void outlet_bang(t_outlet *x); +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_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); +EXTERN void outlet_free(t_outlet *x); +EXTERN t_object *pd_checkobject(t_pd *x); + + +/* -------------------- canvases -------------- */ + +EXTERN void glob_setfilename(void *dummy, t_symbol *name, t_symbol *dir); + +EXTERN void canvas_setargs(int argc, t_atom *argv); +EXTERN void canvas_getargs(int *argcp, t_atom **argvp); +EXTERN t_symbol *canvas_getcurrentdir(void); +EXTERN t_glist *canvas_getcurrent(void); +EXTERN void canvas_makefilename(t_glist *c, char *file, + char *result,int resultsize); +EXTERN t_symbol *canvas_getdir(t_glist *x); +EXTERN int sys_fontwidth(int fontsize); +EXTERN int sys_fontheight(int fontsize); +EXTERN void canvas_dataproperties(t_glist *x, t_scalar *sc, t_binbuf *b); + +/* ---------------- widget behaviors ---------------------- */ + +EXTERN_STRUCT _widgetbehavior; +#define t_widgetbehavior struct _widgetbehavior + +EXTERN_STRUCT _parentwidgetbehavior; +#define t_parentwidgetbehavior struct _parentwidgetbehavior +EXTERN t_parentwidgetbehavior *pd_getparentwidget(t_pd *x); + +/* -------------------- classes -------------- */ + +#define CLASS_DEFAULT 0 /* flags for new classes below */ +#define CLASS_PD 1 +#define CLASS_GOBJ 2 +#define CLASS_PATCHABLE 3 +#define CLASS_NOINLET 8 + +#define CLASS_TYPEMASK 3 + + +EXTERN t_class *class_new(t_symbol *name, t_newmethod newmethod, + t_method freemethod, size_t size, int flags, t_atomtype arg1, ...); +EXTERN void class_addcreator(t_newmethod newmethod, t_symbol *s, + t_atomtype type1, ...); +EXTERN void class_addmethod(t_class *c, t_method fn, t_symbol *sel, + t_atomtype arg1, ...); +EXTERN void class_addbang(t_class *c, t_method fn); +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_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); +EXTERN void class_setwidget(t_class *c, t_widgetbehavior *w); +EXTERN void class_setparentwidget(t_class *c, t_parentwidgetbehavior *w); +EXTERN t_parentwidgetbehavior *class_parentwidget(t_class *c); +EXTERN char *class_getname(t_class *c); +EXTERN char *class_gethelpname(t_class *c); +EXTERN void class_setdrawcommand(t_class *c); +EXTERN int class_isdrawcommand(t_class *c); +EXTERN void class_domainsignalin(t_class *c, int onset); +#define CLASS_MAINSIGNALIN(c, type, field) \ + class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0) + + /* prototype for functions to save Pd's to a binbuf */ +typedef void (*t_savefn)(t_gobj *x, t_binbuf *b); +EXTERN void class_setsavefn(t_class *c, t_savefn f); +EXTERN t_savefn class_getsavefn(t_class *c); + /* prototype for functions to open properties dialogs */ +typedef void (*t_propertiesfn)(t_gobj *x, struct _glist *glist); +EXTERN void class_setpropertiesfn(t_class *c, t_propertiesfn f); +EXTERN t_propertiesfn class_getpropertiesfn(t_class *c); + +#ifndef PD_CLASS_DEF +#define class_addbang(x, y) class_addbang((x), (t_method)(y)) +#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_addlist(x, y) class_addlist((x), (t_method)(y)) +#define class_addanything(x, y) class_addanything((x), (t_method)(y)) +#endif + +/* ------------ printing --------------------------------- */ +EXTERN void post(const char *fmt, ...); +EXTERN void startpost(const char *fmt, ...); +EXTERN void poststring(const char *s); +EXTERN void postfloat(float f); +EXTERN void postatom(int argc, t_atom *argv); +EXTERN void endpost(void); +EXTERN void error(const char *fmt, ...); +EXTERN void verbose(int level, const char *fmt, ...); +EXTERN void bug(const char *fmt, ...); +EXTERN void pd_error(void *object, const char *fmt, ...); +EXTERN void sys_logerror(const char *object, const char *s); +EXTERN void sys_unixerror(const char *object); +EXTERN void sys_ouch(void); + + +/* ------------ system interface routines ------------------- */ +EXTERN int sys_isreadablefile(const char *name); +EXTERN void sys_bashfilename(const char *from, char *to); +EXTERN void sys_unbashfilename(const char *from, char *to); +EXTERN int open_via_path(const char *name, const char *ext, const char *dir, + char *dirresult, char **nameresult, unsigned int size, int bin); +EXTERN int sched_geteventno(void); +EXTERN double sys_getrealtime(void); +EXTERN int (*sys_idlehook)(void); /* hook to add idle time computation */ + + +/* ------------ threading ------------------- */ +EXTERN void sys_lock(void); +EXTERN void sys_unlock(void); +EXTERN int sys_trylock(void); + + +/* --------------- signals ----------------------------------- */ + +typedef float t_sample; +#define MAXLOGSIG 32 +#define MAXSIGSIZE (1 << MAXLOGSIG) + +typedef struct _signal +{ + int s_n; /* number of points in the array */ + t_sample *s_vec; /* the array */ + float s_sr; /* sample rate */ + int s_refcount; /* number of times used */ + int s_isborrowed; /* whether we're going to borrow our array */ + struct _signal *s_borrowedfrom; /* signal to borrow it from */ + struct _signal *s_nextfree; /* next in freelist */ + struct _signal *s_nextused; /* next in used list */ +} t_signal; + + +typedef t_int *(*t_perfroutine)(t_int *args); + +EXTERN t_int *plus_perform(t_int *args); +EXTERN t_int *zero_perform(t_int *args); +EXTERN t_int *copy_perform(t_int *args); + +EXTERN void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n); +EXTERN void dsp_add_copy(t_sample *in, t_sample *out, int n); +EXTERN void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n); +EXTERN void dsp_add_zero(t_sample *out, int n); + +EXTERN int sys_getblksize(void); +EXTERN float sys_getsr(void); +EXTERN int sys_get_inchannels(void); +EXTERN int sys_get_outchannels(void); + +EXTERN void dsp_add(t_perfroutine f, int n, ...); +EXTERN void dsp_addv(t_perfroutine f, int n, t_int *vec); +EXTERN void pd_fft(float *buf, int npoints, int inverse); +EXTERN int ilog2(int n); + +EXTERN void mayer_fht(float *fz, int n); +EXTERN void mayer_fft(int n, float *real, float *imag); +EXTERN void mayer_ifft(int n, float *real, float *imag); +EXTERN void mayer_realfft(int n, float *real); +EXTERN void mayer_realifft(int n, float *real); + +EXTERN float *cos_table; +#define LOGCOSTABSIZE 9 +#define COSTABSIZE (1<