Update of /cvsroot/pure-data/externals/jasch_lib/detox In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29041
Modified Files: detox.c Log Message:
Index: detox.c =================================================================== RCS file: /cvsroot/pure-data/externals/jasch_lib/detox/detox.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** detox.c 18 May 2006 10:41:51 -0000 1.1.1.1 --- detox.c 18 May 2006 15:45:34 -0000 1.2 *************** *** 1 **** ! /*__________________________________________________________________________
detox á extract value/content from tag-structured symbol Copyright (C) 2003 jan schacher
thanks to tim place for inspiration and sample code
revised tree output 20040712 initial build 200300502
____________________________________________________________________________*/
#include "m_pd.h" #include <string.h> #include <stdlib.h> #include <ctype.h> #include <locale.h>
#define VERSION "1.2" #define CLIP(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x)
typedef struct _detox { t_object ob; t_atom t_tree[257], t_attrpair[2]; t_atom t_comp, t_blip; 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, long 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, long argc, t_atom *argv); long clip(long in, long min, long max); 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_anything, gensym("anything"), 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, long 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); return (x); }
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_anything(t_detox *x, t_symbol *s, long argc, t_atom *argv) { t_atom *outlist, *comp, *attrpair; char local[1024], local2[1024]; char temp[1024]; char tempstring[2]; char *ptr, *ptr2, *ptr3, *ptr4, *ptr5; long i, j, k, last, len, len2, tempcount = 0, pos = 0; short tagtype = 0; // 0 = closed, 1 = open, 2 = closing short outsize = 0; long quotetype = 0; short attrpresent = 0; 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; if(s->s_name == "debug"){ x->t_debug = CLIP(argv[0].a_w.w_float, 0, 1); return; } strcpy(local2, s->s_name); last = strlen(local2); // test for tag if(x->t_debug) post("input is %s", s->s_name); 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; i<last; i++, j++){ // remove whitespace/tab/cr/linefeed local[j] = local2[i]; } local[j] = 0; // terminate string if((local[0] != '<') || (local[j-1] != '>')){ tagtype = 0; // not a well formed tag if(x->t_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; } ptr = strchr(local, '/'); // is it a closing tag ? if(x->t_debug) post("ptr contains %s", s->s_name); if(ptr == 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 ptr = strchr(local, '>'); ptr2 = strchr(local, ' '); if(ptr2 != NULL) *ptr2 = 0; if(ptr != NULL){ *ptr = 0; }else{ return; } len = strlen(local); ptr5 = (char *)memmove((local + 0),(local + 1), len-1); local[len-1] = 0; ptr5 = local; x->t_blip.a_type = A_SYMBOL; x->t_blip.a_w.w_symbol = gensym(ptr5); 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); ptr5 = (char *)memmove((local + 0),(local + 1), len-1); if(x->t_debug) post("ptr5 is %s", ptr5); local[len-1] = 0; ptr5 = local; x->t_tree[x->t_treecount].a_type = A_SYMBOL; x->t_tree[x->t_treecount].a_w.w_symbol = gensym(ptr5); 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); ptr5 = (char *)memmove((local + 0),(local + 2), len-2); local[len-2] = 0; ptr5 = local; x->t_comp.a_type = A_SYMBOL; x->t_comp.a_w.w_symbol = gensym(ptr5); 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; 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, NULL); // ouput tree }else{ outlet_float(x->s_outlet3, 0); // ouput tree } } strcpy(local, s->s_name);
ptr = strchr(local, '>'); // parse content between enclosing tags <tag>blah</tag> if(ptr == NULL) goto onward; *ptr = 0; ++ptr; ptr2 = strchr(ptr, '<'); if(ptr2 == NULL) goto onward; *ptr2 = 0; outlet_anything(x->s_outlet2, gensym(ptr), 0, NULL);
onward: strcpy(local, s->s_name); // get full buffer again
switch(x->t_mode){ case 0: // the old way of attribute parsing (mode 0) if(x->t_debug) post("content: before strtok %s", local); ptr = strtok(local,tempstring); while (ptr != NULL){ ptr3 = strchr(ptr, '"'); if(ptr3 != NULL){ *ptr3 = 0; ++ptr3; ptr4 = strchr(ptr3, '"'); *ptr4 = 0; outlet_anything(x->s_outlet, gensym(ptr3), 0, NULL); if(x->t_debug) post("content: after strtok %s", ptr); } ptr = strtok(NULL, tempstring); } break; case 1: // the new way of attribute parsing (mode 1) ptr = local; if(strcspn(ptr, "="'") == strlen(ptr)) break; // no attr-chars found, bail ouit ptr = strchr(local, 32); // find first whitespace if(ptr == NULL) break; // no whitespace found bail attr_loop: while((ptr[0] == ' ') && (ptr != NULL)) ptr++; // find next non-whitespace char ptr2 = ptr; while(!((ptr2[0] == ' ')||(ptr2[0] == '=')) && (ptr2 != NULL)) ptr2++; // find next non-white or not equal-sign len = strlen(ptr) - strlen(ptr2); strncpy(temp, ptr, len); // copy into temp-buffer temp[len] = 0; // terminate temp_buffer attrpair[0].a_type = A_SYMBOL; attrpair[0].a_w.w_symbol = gensym(temp); // put into output symbol ptr = ptr2; while(!((ptr[0] == ''') || (ptr[0] == '"')) && (ptr != NULL)){ // move until single or double quote ptr++; quotetype = ptr[0]; } ptr2 = ++ptr; while((ptr2[0] != quotetype) && (ptr2 != NULL)) ptr2++; len = strlen(ptr) - strlen(ptr2); strncpy(temp, ptr, len); temp[len] = 0; attrpair[1].a_type = A_SYMBOL; attrpair[1].a_w.w_symbol = gensym(temp); outlet_anything(x->s_outlet, x->t_attrpair[0].a_w.w_symbol, 1, &x->t_attrpair[1]); ptr = ++ptr2; while((ptr[0] == ' ')&&(ptr != NULL)){ ptr++; } // find next non-whitespace char if((ptr[0] == '/') || (ptr[0] == '>') || (ptr[0] == '?') || (ptr == NULL)){ // if char is "/" or ">" or "?" bail out break; }else{ goto attr_loop; } break; } }
void detox_free(t_detox *x) { // notify_free((t_object *)x); }
long clip(long in, long min, long max) { return in < min? min: (in > max? max : in); }
void version(t_detox *x) { post("á detox á jasch - version " VERSION" compiled "__DATE__" "__TIME__ ); } \ No newline at end of file --- 1 ---- ! /*__________________________________________________________________________
detox á extract value/content from tag-structured symbol Copyright (C) 2003 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
revised tree output 20040712 initial build 200300502 pd-port 20060506
____________________________________________________________________________*/
#include "m_pd.h" #include <string.h> #include <stdlib.h> #include <ctype.h> #include <locale.h>
#define VERSION "1.2" #define CLIP(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x)
typedef struct _detox { t_object ob; t_atom t_tree[257], t_attrpair[2]; t_atom t_comp, t_blip; 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, long 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, long argc, t_atom *argv); long clip(long in, long min, long max); 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_anything, gensym("anything"), 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, long 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); return (x); }
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_anything(t_detox *x, t_symbol *s, long argc, t_atom *argv) { t_atom *outlist, *comp, *attrpair; char local[1024], local2[1024]; char temp[1024]; char tempstring[2]; char *ptr, *ptr2, *ptr3, *ptr4, *ptr5; long i, j, k, last, len, len2, tempcount = 0, pos = 0; short tagtype = 0; // 0 = closed, 1 = open, 2 = closing short outsize = 0; long quotetype = 0; short attrpresent = 0; 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; if(s->s_name == "debug"){ x->t_debug = CLIP(argv[0].a_w.w_float, 0, 1); return; } strcpy(local2, s->s_name); last = strlen(local2); // test for tag if(x->t_debug) post("input is %s", s->s_name); 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; i<last; i++, j++){ // remove whitespace/tab/cr/linefeed local[j] = local2[i]; } local[j] = 0; // terminate string if((local[0] != '<') || (local[j-1] != '>')){ tagtype = 0; // not a well formed tag if(x->t_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; } ptr = strchr(local, '/'); // is it a closing tag ? if(x->t_debug) post("ptr contains %s", s->s_name); if(ptr == 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 ptr = strchr(local, '>'); ptr2 = strchr(local, ' '); if(ptr2 != NULL) *ptr2 = 0; if(ptr != NULL){ *ptr = 0; }else{ return; } len = strlen(local); ptr5 = (char *)memmove((local + 0),(local + 1), len-1); local[len-1] = 0; ptr5 = local; x->t_blip.a_type = A_SYMBOL; x->t_blip.a_w.w_symbol = gensym(ptr5); 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); ptr5 = (char *)memmove((local + 0),(local + 1), len-1); if(x->t_debug) post("ptr5 is %s", ptr5); local[len-1] = 0; ptr5 = local; x->t_tree[x->t_treecount].a_type = A_SYMBOL; x->t_tree[x->t_treecount].a_w.w_symbol = gensym(ptr5); 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); ptr5 = (char *)memmove((local + 0),(local + 2), len-2); local[len-2] = 0; ptr5 = local; x->t_comp.a_type = A_SYMBOL; x->t_comp.a_w.w_symbol = gensym(ptr5); 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; 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, NULL); // ouput tree }else{ outlet_float(x->s_outlet3, 0); // ouput tree } } strcpy(local, s->s_name);
ptr = strchr(local, '>'); // parse content between enclosing tags <tag>blah</tag> if(ptr == NULL) goto onward; *ptr = 0; ++ptr; ptr2 = strchr(ptr, '<'); if(ptr2 == NULL) goto onward; *ptr2 = 0; outlet_anything(x->s_outlet2, gensym(ptr), 0, NULL);
onward: strcpy(local, s->s_name); // get full buffer again
switch(x->t_mode){ case 0: // the old way of attribute parsing (mode 0) if(x->t_debug) post("content: before strtok %s", local); ptr = strtok(local,tempstring); while (ptr != NULL){ ptr3 = strchr(ptr, '"'); if(ptr3 != NULL){ *ptr3 = 0; ++ptr3; ptr4 = strchr(ptr3, '"'); *ptr4 = 0; outlet_anything(x->s_outlet, gensym(ptr3), 0, NULL); if(x->t_debug) post("content: after strtok %s", ptr); } ptr = strtok(NULL, tempstring); } break; case 1: // the new way of attribute parsing (mode 1) ptr = local; if(strcspn(ptr, "="'") == strlen(ptr)) break; // no attr-chars found, bail ouit ptr = strchr(local, 32); // find first whitespace if(ptr == NULL) break; // no whitespace found bail attr_loop: while((ptr[0] == ' ') && (ptr != NULL)) ptr++; // find next non-whitespace char ptr2 = ptr; while(!((ptr2[0] == ' ')||(ptr2[0] == '=')) && (ptr2 != NULL)) ptr2++; // find next non-white or not equal-sign len = strlen(ptr) - strlen(ptr2); strncpy(temp, ptr, len); // copy into temp-buffer temp[len] = 0; // terminate temp_buffer attrpair[0].a_type = A_SYMBOL; attrpair[0].a_w.w_symbol = gensym(temp); // put into output symbol ptr = ptr2; while(!((ptr[0] == ''') || (ptr[0] == '"')) && (ptr != NULL)){ // move until single or double quote ptr++; quotetype = ptr[0]; } ptr2 = ++ptr; while((ptr2[0] != quotetype) && (ptr2 != NULL)) ptr2++; len = strlen(ptr) - strlen(ptr2); strncpy(temp, ptr, len); temp[len] = 0; attrpair[1].a_type = A_SYMBOL; attrpair[1].a_w.w_symbol = gensym(temp); outlet_anything(x->s_outlet, x->t_attrpair[0].a_w.w_symbol, 1, &x->t_attrpair[1]); ptr = ++ptr2; while((ptr[0] == ' ')&&(ptr != NULL)){ ptr++; } // find next non-whitespace char if((ptr[0] == '/') || (ptr[0] == '>') || (ptr[0] == '?') || (ptr == NULL)){ // if char is "/" or ">" or "?" bail out break; }else{ goto attr_loop; } break; } }
void detox_free(t_detox *x) { // notify_free((t_object *)x); }
long clip(long in, long min, long max) { return in < min? min: (in > max? max : in); }
void version(t_detox *x) { post("á detox á jasch - version " VERSION" compiled "__DATE__" "__TIME__ ); } \ No newline at end of file