pool-master/0000755000175000017500000000000012504366625013563 5ustar zmoelnigzmoelnigpool-master/readme.txt0000644000175000017500000001204512504366625015563 0ustar zmoelnigzmoelnigpool - a hierarchical storage object for PD and Max/MSP Copyright (c) 2002-2008 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. Donations for further development of the package are highly appreciated. Visit https://www.paypal.com/xclick/business=gr%40grrrr.org&item_name=pool&no_note=1&tax=0¤cy_code=EUR ---------------------------------------------------------------------------- Goals/features of the package: - pool can store and retrieve key/value pairs, where a key can be any atom and the value can be any list of atoms - pool can manage folders. A folder name can be any atom. - pool objects can be named and then share their data space - clipboard operations are possible in a pool or among several pools - file operations can load/save data from disk ---------------------------------------------------------------------------- IMPORTANT INFORMATION for all PD users: Put the pd-msvc/pool.dll, pd-linux/pool.pd_linux or pd-darwin/pool.pd_darwin file into the extra folder of the PD installation, or use a -path or -lib option at PD startup to find the pool external. Put the help-pool.pd file into the doc\5.reference subfolder of your PD installation. ---------------------------------------------------------------------------- IMPORTANT INFORMATION for all Max/MSP users: For Mac OSX put the max-osx/pool.mxd file into the folder /Library/Application Support/Cycling '74/externals For Mac OS9 put the max-os9/pool.mxe file into the externals subfolder of your Max/MSP installation For Windows put the max-msvc\pool.mxe file into the folder C:\program files\common files\Cycling '74\externals (english version) Put the pool.help file into the max-help folder. ============================================================================ BUILDING from source -------------------- You will need the flext C++ layer for PD and Max/MSP externals to compile this. See http://grrrr.org/ext/flext Download, install and compile the package. Afterwards you can proceed with building this external. POSIX configure style --------------------- ./bootstrap.sh ./configure --enable-system=pd_OR_max --with-sysdir=PATH_TO_PD_OR_MAX_HEADER_FILES --libdir=WHERE_TO_PUT_THE_EXTERNAL make sudo make install pd/Max - Windows - Microsoft Visual C, Borland C++, MinGW: ---------------------------------------------------------- Start a command shell with your eventual build environment (e.g. run vcvars32.bat for Microsoft Visual Studio) then run ..\flext\build.bat (you would have to substitute ..\flext with the respective path to the flext package) pd/Max - OSX/Linux - GCC: ------------------------- From a shell run bash ../flext/build.sh (you would have to substitute ../flext with the respective path to the flext package) ============================================================================ Version history: 0.2.2: - fixed serious bug with clearing values and dirs. e.g. "clrall" and "clrrec" messages. - fixed double-free for clearing dirs and values - re-introduced a help message - fixed bug in nested-dir XML saving - changed printrec/printroot to display empty folders - new curdir attribute for getting/setting the current directory - changed pool name searching with STL code (more efficient) - added success/error reporting for file operations (through attribute outlet) - fixed handling of non-ASCII-characters - XML files are now encoded UTF-8 - implemented output sorting (ogetall, ogetrec, ogetsub) - fixed some potential buffer overrun problems 0.2.1: - fixed "cntsub"... directories in current directory have been forgotten - store/create also empty dirs with file I/O - more inlined functions and better symbol handling - added "seti" message to set elements at index - added "clri" message to erase elements at index - fixed bad bug: pool::priv was not initialized - enhanced and optimized atom parsing - escaped symbols (with \) for whitespace support on store and load - escape symbols also with "" to help the load routine - improved reading of legacy data by Frank Barknecht - use statically allocated lists where feasible - bug fix: [reset( didn't reset the current dir - file loading: fixed recognition of stringified directory names 0.2.0: - attributes (pool,private,echodir,absdir) - added "geti" message for retrieval of a value at an index - fixed bug in "get" message if key not present - adapted source to flext 0.4.1 - register methods at class creation - extensive use of hashing for keys and directories - database can be saved/loaded as XML data - fixed bug with stored numbers starting with - or + - relative file names will be based on the folder of the current patcher - added printall, printrec, printroot messages for console printout - added mkchdir, mkchsub to create and change to directories at once - change storage object only when name has changed 0.1.0: - first public release --------------------------------------------------------------------------- general: - what is output as value if it is key only? (Max->nothing!) - XML format ok? pool-master/pool-0.2.dtd0000644000175000017500000000021712504366625015526 0ustar zmoelnigzmoelnig pool-master/pool.vcproj0000644000175000017500000002620212504366625015763 0ustar zmoelnigzmoelnig pool-master/Makefile.am0000755000175000017500000000005212504366625015617 0ustar zmoelnigzmoelnig# # automake template # SUBDIRS = source pool-master/source/0000755000175000017500000000000012504366625015063 5ustar zmoelnigzmoelnigpool-master/source/pool.h0000644000175000017500000001445212504366625016213 0ustar zmoelnigzmoelnig/* pool - hierarchical storage object for PD and Max/MSP Copyright (c) 2002-2008 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. $LastChangedRevision: 26 $ $LastChangedDate$ $LastChangedBy$ */ #ifndef __POOL_H #define __POOL_H #define FLEXT_ATTRIBUTES 1 #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500) #error You need at least flext version 0.5.0 #endif #include using namespace std; typedef flext::AtomListStatic<8> Atoms; class poolval: public flext { public: poolval(const t_atom &key,AtomList *data); ~poolval(); poolval &Set(AtomList *data); poolval *Dup() const; t_atom key; AtomList *data; poolval *nxt; }; class pooldir: public flext { public: pooldir(const t_atom &dir,pooldir *parent,int vcnt,int dcnt); ~pooldir(); void Clear(bool rec,bool dironly = false); void Reset(bool realloc = true); bool Empty() const { return !dirs && !vals; } bool HasDirs() const { return dirs != NULL; } bool HasVals() const { return vals != NULL; } pooldir *GetDir(int argc,const t_atom *argv,bool cut = false); pooldir *GetDir(const AtomList &d,bool cut = false) { return GetDir(d.Count(),d.Atoms(),cut); } bool DelDir(int argc,const t_atom *argv); bool DelDir(const AtomList &d) { return DelDir(d.Count(),d.Atoms()); } pooldir *AddDir(int argc,const t_atom *argv,int vcnt = 0,int dcnt = 0); pooldir *AddDir(const AtomList &d,int vcnt = 0,int dcnt = 0) { return AddDir(d.Count(),d.Atoms(),vcnt,dcnt); } void SetVal(const t_atom &key,AtomList *data,bool over = true); bool SetVali(int ix,AtomList *data); void ClrVal(const t_atom &key) { SetVal(key,NULL); } bool ClrVali(int ix) { return SetVali(ix,NULL); } AtomList *PeekVal(const t_atom &key); AtomList *GetVal(const t_atom &key,bool cut = false); int CntAll() const; int GetAll(t_atom *&keys,Atoms *&lst,bool cut = false); int PrintAll(char *buf,int len) const; int GetKeys(AtomList &keys); int CntSub() const; int GetSub(const t_atom **&dirs); poolval *RefVal(const t_atom &key); poolval *RefVali(int ix); bool Paste(const pooldir *p,int depth,bool repl,bool mkdir); bool Copy(pooldir *p,int depth,bool cur); bool LdDir(istream &is,int depth,bool mkdir); bool LdDirXML(istream &is,int depth,bool mkdir); bool SvDir(ostream &os,int depth,const AtomList &dir = AtomList()); bool SvDirXML(ostream &os,int depth,const AtomList &dir = AtomList(),int ind = 0); int VSize() const { return vsize; } int DSize() const { return dsize; } protected: int VIdx(const t_atom &v) const { return FoldBits(AtomHash(v),vbits); } int DIdx(const t_atom &d) const { return FoldBits(AtomHash(d),dbits); } t_atom dir; pooldir *nxt; pooldir *parent; const int vbits,dbits,vsize,dsize; static unsigned int FoldBits(unsigned long h,int bits); static int Int2Bits(unsigned long n); struct valentry { int cnt; poolval *v; }; struct direntry { int cnt; pooldir *d; }; valentry *vals; direntry *dirs; private: bool LdDirXMLRec(istream &is,int depth,bool mkdir,AtomList &d); }; class pooldata: public flext { public: pooldata(const t_symbol *s = NULL,int vcnt = 0,int dcnt = 0); ~pooldata(); bool Private() const { return sym == NULL; } void Push() { ++refs; } bool Pop() { return --refs > 0; } void Reset() { root.Reset(); } bool MkDir(const AtomList &d,int vcnt = 0,int dcnt = 0) { root.AddDir(d,vcnt,dcnt); return true; } bool ChkDir(const AtomList &d) { return root.GetDir(d) != NULL; } bool RmDir(const AtomList &d) { return root.DelDir(d); } bool Set(const AtomList &d,const t_atom &key,AtomList *data,bool over = true) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->SetVal(key,data,over); return true; } bool Seti(const AtomList &d,int ix,AtomList *data) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->SetVali(ix,data); return true; } bool Clr(const AtomList &d,const t_atom &key) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->ClrVal(key); return true; } bool Clri(const AtomList &d,int ix) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->ClrVali(ix); return true; } bool ClrAll(const AtomList &d,bool rec,bool dironly = false) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->Clear(rec,dironly); return true; } AtomList *Peek(const AtomList &d,const t_atom &key) { pooldir *pd = root.GetDir(d); return pd?pd->PeekVal(key):NULL; } AtomList *Get(const AtomList &d,const t_atom &key) { pooldir *pd = root.GetDir(d); return pd?pd->GetVal(key):NULL; } poolval *Ref(const AtomList &d,const t_atom &key) { pooldir *pd = root.GetDir(d); return pd?pd->RefVal(key):NULL; } poolval *Refi(const AtomList &d,int ix) { pooldir *pd = root.GetDir(d); return pd?pd->RefVali(ix):NULL; } int CntAll(const AtomList &d) { pooldir *pd = root.GetDir(d); return pd?pd->CntAll():0; } int PrintAll(const AtomList &d); int GetAll(const AtomList &d,t_atom *&keys,Atoms *&lst); int CntSub(const AtomList &d) { pooldir *pd = root.GetDir(d); return pd?pd->CntSub():0; } int GetSub(const AtomList &d,const t_atom **&dirs); bool Paste(const AtomList &d,const pooldir *clip,int depth = -1,bool repl = true,bool mkdir = true); pooldir *Copy(const AtomList &d,const t_atom &key,bool cut); pooldir *CopyAll(const AtomList &d,int depth,bool cut); bool LdDir(const AtomList &d,const char *flnm,int depth,bool mkdir = true); bool SvDir(const AtomList &d,const char *flnm,int depth,bool absdir); bool Load(const char *flnm) { AtomList l; return LdDir(l,flnm,-1); } bool Save(const char *flnm) { AtomList l; return SvDir(l,flnm,-1,true); } bool LdDirXML(const AtomList &d,const char *flnm,int depth,bool mkdir = true); bool SvDirXML(const AtomList &d,const char *flnm,int depth,bool absdir); bool LoadXML(const char *flnm) { AtomList l; return LdDirXML(l,flnm,-1); } bool SaveXML(const char *flnm) { AtomList l; return SvDirXML(l,flnm,-1,true); } int refs; const t_symbol *sym; pooldata *nxt; pooldir root; private: static const t_atom nullatom; }; #endif pool-master/source/main.cpp0000644000175000017500000010620112504366625016513 0ustar zmoelnigzmoelnig/* pool - hierarchical storage object for PD and Max/MSP Copyright (c) 2002-2008 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. $LastChangedRevision: 26 $ $LastChangedDate$ $LastChangedBy$ */ #include "pool.h" #include #include #define POOL_VERSION "0.2.2pre" #define VCNT 32 #define DCNT 8 class pool: public flext_base { FLEXT_HEADER_S(pool,flext_base,setup) public: pool(int argc,const t_atom *argv); virtual ~pool(); static void setup(t_classid); virtual bool Init(); pooldata *Pool() { return pl; } protected: // switch to other pool void ms_pool(const AtomList &l); void mg_pool(AtomList &l); void mg_priv(bool &p) const { p = pl && pl->Private(); } // print some help message static void m_help() { post("pool " POOL_VERSION " - hierarchical storage object, (C)2002-2008 Thomas Grill"); } // clear all data in pool void m_reset(); // handle directories void m_getdir(); void m_mkdir(int argc,const t_atom *argv,bool abs = true,bool chg = false); // make (and change) to dir void m_mkchdir(int argc,const t_atom *argv) { m_mkdir(argc,argv,true,true); } // make and change to dir void m_chdir(int argc,const t_atom *argv,bool abs = true); // change to dir void m_rmdir(int argc,const t_atom *argv,bool abs = true); // remove dir void m_updir(int argc,const t_atom *argv); // one or more levels up void ms_curdir(const AtomList &l) { m_chdir(l.Count(),l.Atoms()); } void m_mksub(int argc,const t_atom *argv) { m_mkdir(argc,argv,false); } void m_mkchsub(int argc,const t_atom *argv) { m_mkdir(argc,argv,false,true); } void m_chsub(int argc,const t_atom *argv) { m_chdir(argc,argv,false); } void m_rmsub(int argc,const t_atom *argv) { m_rmdir(argc,argv,false); } // handle data void m_set(int argc,const t_atom *argv) { set(argc,argv,true); } void m_seti(int argc,const t_atom *argv); // set value at index void m_add(int argc,const t_atom *argv) { set(argc,argv,false); } void m_clr(int argc,const t_atom *argv); void m_clri(int ix); // clear value at index void m_clrall(); // only values void m_clrrec(); // also subdirectories void m_clrsub(); // only subdirectories void m_get(int argc,const t_atom *argv); void m_geti(int ix); // get value at index void m_getall(); // only values void m_getrec(int argc,const t_atom *argv); // also subdirectories void m_getsub(int argc,const t_atom *argv); // only subdirectories void m_ogetall(int argc,const t_atom *argv); // only values (ordered) void m_ogetrec(int argc,const t_atom *argv); // also subdirectories (ordered) void m_ogetsub(int argc,const t_atom *argv); // only subdirectories (ordered) void m_cntall(); // only values void m_cntrec(int argc,const t_atom *argv); // also subdirectories void m_cntsub(int argc,const t_atom *argv); // only subdirectories // print directories void m_printall(); // print values in current dir void m_printrec(int argc,const t_atom *argv,bool fromroot = false); // print values recursively void m_printroot() { m_printrec(0,NULL,true); } // print values recursively from root // cut/copy/paste void m_paste(int argc,const t_atom *argv) { paste(thisTag(),argc,argv,true); } // paste contents of clipboard void m_pasteadd(int argc,const t_atom *argv) { paste(thisTag(),argc,argv,false); } // paste but don't replace void m_clrclip(); // clear clipboard void m_cut(int argc,const t_atom *argv) { copy(thisTag(),argc,argv,true); } // cut value into clipboard void m_copy(int argc,const t_atom *argv) { copy(thisTag(),argc,argv,false); } // copy value into clipboard void m_cutall() { copyall(thisTag(),true,0); } // cut all values in current directory into clipboard void m_copyall() { copyall(thisTag(),false,0); } // copy all values in current directory into clipboard void m_cutrec(int argc,const t_atom *argv) { copyrec(thisTag(),argc,argv,true); } // cut directory (and subdirs) into clipboard void m_copyrec(int argc,const t_atom *argv) { copyrec(thisTag(),argc,argv,false); } // cut directory (and subdirs) into clipboard // load/save from/to file void m_load(int argc,const t_atom *argv) { load(argc,argv,false); } void m_save(int argc,const t_atom *argv) { save(argc,argv,false); } void m_loadx(int argc,const t_atom *argv) { load(argc,argv,true); } // XML void m_savex(int argc,const t_atom *argv) { save(argc,argv,true); } // XML // load directories void m_lddir(int argc,const t_atom *argv) { lddir(argc,argv,false); } // load values into current dir void m_ldrec(int argc,const t_atom *argv) { ldrec(argc,argv,false); } // load values recursively void m_ldxdir(int argc,const t_atom *argv) { lddir(argc,argv,true); } // load values into current dir (XML) void m_ldxrec(int argc,const t_atom *argv) { ldrec(argc,argv,true); } // load values recursively (XML) // save directories void m_svdir(int argc,const t_atom *argv) { svdir(argc,argv,false); } // save values in current dir void m_svrec(int argc,const t_atom *argv) { svrec(argc,argv,false); } // save values recursively void m_svxdir(int argc,const t_atom *argv) { svdir(argc,argv,true); } // save values in current dir (XML) void m_svxrec(int argc,const t_atom *argv) { svrec(argc,argv,true); } // save values recursively (XML) private: static bool KeyChk(const t_atom &a); static bool ValChk(int argc,const t_atom *argv); static bool ValChk(const AtomList &l) { return ValChk(l.Count(),l.Atoms()); } void ToOutAtom(int ix,const t_atom &a); static const t_symbol *sym_echo; static const t_symbol *sym_error; enum get_t { get_norm,get_cnt,get_print }; void set(int argc,const t_atom *argv,bool over); void getdir(const t_symbol *tag); int getrec(const t_symbol *tag,int level,int order,bool rev,get_t how /*= get_norm*/,const AtomList &rdir); int getsub(const t_symbol *tag,int level,int order,bool rev,get_t how /*= get_norm*/,const AtomList &rdir); void paste(const t_symbol *tag,int argc,const t_atom *argv,bool repl); void copy(const t_symbol *tag,int argc,const t_atom *argv,bool cut); void copyall(const t_symbol *tag,bool cut,int lvls); void copyrec(const t_symbol *tag,int argc,const t_atom *argv,bool cut); void load(int argc,const t_atom *argv,bool xml); void save(int argc,const t_atom *argv,bool xml); void lddir(int argc,const t_atom *argv,bool xml); // load values into current dir void ldrec(int argc,const t_atom *argv,bool xml); // load values recursively void svdir(int argc,const t_atom *argv,bool xml); // save values in current dir void svrec(int argc,const t_atom *argv,bool xml); // save values recursively void echodir() { if(echo) getdir(sym_echo); } bool absdir,echo; int vcnt,dcnt; pooldata *pl; Atoms curdir; pooldir *clip; static const t_symbol *holdname; // used during initialization of new object (between constructor and Init method) typedef std::map PoolMap; static PoolMap poolmap; void SetPool(const t_symbol *s); void FreePool(); static pooldata *GetPool(const t_symbol *s); static void RmvPool(pooldata *p); string MakeFilename(const char *fn) const; FLEXT_CALLVAR_V(mg_pool,ms_pool) FLEXT_ATTRGET_V(curdir) FLEXT_CALLSET_V(ms_curdir) FLEXT_ATTRVAR_B(absdir) FLEXT_ATTRVAR_B(echo) FLEXT_CALLGET_B(mg_priv) FLEXT_ATTRVAR_I(vcnt) FLEXT_ATTRVAR_I(dcnt) FLEXT_CALLBACK(m_help) FLEXT_CALLBACK(m_reset) FLEXT_CALLBACK(m_getdir) FLEXT_CALLBACK_V(m_mkdir) FLEXT_CALLBACK_V(m_chdir) FLEXT_CALLBACK_V(m_mkchdir) FLEXT_CALLBACK_V(m_updir) FLEXT_CALLBACK_V(m_rmdir) FLEXT_CALLBACK_V(m_mksub) FLEXT_CALLBACK_V(m_chsub) FLEXT_CALLBACK_V(m_mkchsub) FLEXT_CALLBACK_V(m_rmsub) FLEXT_CALLBACK_V(m_set) FLEXT_CALLBACK_V(m_seti) FLEXT_CALLBACK_V(m_add) FLEXT_CALLBACK_V(m_clr) FLEXT_CALLBACK_I(m_clri) FLEXT_CALLBACK(m_clrall) FLEXT_CALLBACK(m_clrrec) FLEXT_CALLBACK(m_clrsub) FLEXT_CALLBACK_V(m_get) FLEXT_CALLBACK_I(m_geti) FLEXT_CALLBACK(m_getall) FLEXT_CALLBACK_V(m_getrec) FLEXT_CALLBACK_V(m_getsub) FLEXT_CALLBACK_V(m_ogetall) FLEXT_CALLBACK_V(m_ogetrec) FLEXT_CALLBACK_V(m_ogetsub) FLEXT_CALLBACK(m_cntall) FLEXT_CALLBACK_V(m_cntrec) FLEXT_CALLBACK_V(m_cntsub) FLEXT_CALLBACK(m_printall) FLEXT_CALLBACK_V(m_printrec) FLEXT_CALLBACK(m_printroot) FLEXT_CALLBACK_V(m_paste) FLEXT_CALLBACK_V(m_pasteadd) FLEXT_CALLBACK(m_clrclip) FLEXT_CALLBACK_V(m_copy) FLEXT_CALLBACK_V(m_cut) FLEXT_CALLBACK(m_copyall) FLEXT_CALLBACK(m_cutall) FLEXT_CALLBACK_V(m_copyrec) FLEXT_CALLBACK_V(m_cutrec) FLEXT_CALLBACK_V(m_load) FLEXT_CALLBACK_V(m_save) FLEXT_CALLBACK_V(m_lddir) FLEXT_CALLBACK_V(m_ldrec) FLEXT_CALLBACK_V(m_svdir) FLEXT_CALLBACK_V(m_svrec) FLEXT_CALLBACK_V(m_loadx) FLEXT_CALLBACK_V(m_savex) FLEXT_CALLBACK_V(m_ldxdir) FLEXT_CALLBACK_V(m_ldxrec) FLEXT_CALLBACK_V(m_svxdir) FLEXT_CALLBACK_V(m_svxrec) }; FLEXT_NEW_V("pool",pool) pool::PoolMap pool::poolmap; const t_symbol *pool::sym_echo,*pool::sym_error; const t_symbol *pool::holdname; void pool::setup(t_classid c) { post(""); pool::m_help(); post(""); sym_echo = MakeSymbol("echo"); sym_error = MakeSymbol("error"); FLEXT_CADDATTR_VAR(c,"pool",mg_pool,ms_pool); FLEXT_CADDATTR_VAR(c,"curdir",curdir,ms_curdir); FLEXT_CADDATTR_VAR1(c,"absdir",absdir); FLEXT_CADDATTR_VAR1(c,"echodir",echo); FLEXT_CADDATTR_GET(c,"private",mg_priv); FLEXT_CADDATTR_VAR1(c,"valcnt",vcnt); FLEXT_CADDATTR_VAR1(c,"dircnt",dcnt); FLEXT_CADDMETHOD_(c,0,"help",m_help); FLEXT_CADDMETHOD_(c,0,"reset",m_reset); FLEXT_CADDMETHOD_(c,0,"getdir",m_getdir); FLEXT_CADDMETHOD_(c,0,"mkdir",m_mkdir); FLEXT_CADDMETHOD_(c,0,"chdir",m_chdir); FLEXT_CADDMETHOD_(c,0,"mkchdir",m_mkchdir); FLEXT_CADDMETHOD_(c,0,"rmdir",m_rmdir); FLEXT_CADDMETHOD_(c,0,"updir",m_updir); FLEXT_CADDMETHOD_(c,0,"mksub",m_mksub); FLEXT_CADDMETHOD_(c,0,"chsub",m_chsub); FLEXT_CADDMETHOD_(c,0,"mkchsub",m_mkchsub); FLEXT_CADDMETHOD_(c,0,"rmsub",m_rmsub); FLEXT_CADDMETHOD_(c,0,"set",m_set); FLEXT_CADDMETHOD_(c,0,"seti",m_seti); FLEXT_CADDMETHOD_(c,0,"add",m_add); FLEXT_CADDMETHOD_(c,0,"clr",m_clr); FLEXT_CADDMETHOD_(c,0,"clri",m_clri); FLEXT_CADDMETHOD_(c,0,"clrall",m_clrall); FLEXT_CADDMETHOD_(c,0,"clrrec",m_clrrec); FLEXT_CADDMETHOD_(c,0,"clrsub",m_clrsub); FLEXT_CADDMETHOD_(c,0,"get",m_get); FLEXT_CADDMETHOD_(c,0,"geti",m_geti); FLEXT_CADDMETHOD_(c,0,"getall",m_getall); FLEXT_CADDMETHOD_(c,0,"getrec",m_getrec); FLEXT_CADDMETHOD_(c,0,"getsub",m_getsub); FLEXT_CADDMETHOD_(c,0,"ogetall",m_ogetall); FLEXT_CADDMETHOD_(c,0,"ogetrec",m_ogetrec); FLEXT_CADDMETHOD_(c,0,"ogetsub",m_ogetsub); FLEXT_CADDMETHOD_(c,0,"cntall",m_cntall); FLEXT_CADDMETHOD_(c,0,"cntrec",m_cntrec); FLEXT_CADDMETHOD_(c,0,"cntsub",m_cntsub); FLEXT_CADDMETHOD_(c,0,"printall",m_printall); FLEXT_CADDMETHOD_(c,0,"printrec",m_printrec); FLEXT_CADDMETHOD_(c,0,"printroot",m_printroot); FLEXT_CADDMETHOD_(c,0,"paste",m_paste); FLEXT_CADDMETHOD_(c,0,"pasteadd",m_pasteadd); FLEXT_CADDMETHOD_(c,0,"clrclip",m_clrclip); FLEXT_CADDMETHOD_(c,0,"cut",m_cut); FLEXT_CADDMETHOD_(c,0,"copy",m_copy); FLEXT_CADDMETHOD_(c,0,"cutall",m_cutall); FLEXT_CADDMETHOD_(c,0,"copyall",m_copyall); FLEXT_CADDMETHOD_(c,0,"cutrec",m_cutrec); FLEXT_CADDMETHOD_(c,0,"copyrec",m_copyrec); FLEXT_CADDMETHOD_(c,0,"load",m_load); FLEXT_CADDMETHOD_(c,0,"save",m_save); FLEXT_CADDMETHOD_(c,0,"lddir",m_lddir); FLEXT_CADDMETHOD_(c,0,"ldrec",m_ldrec); FLEXT_CADDMETHOD_(c,0,"svdir",m_svdir); FLEXT_CADDMETHOD_(c,0,"svrec",m_svrec); FLEXT_CADDMETHOD_(c,0,"loadx",m_loadx); FLEXT_CADDMETHOD_(c,0,"savex",m_savex); FLEXT_CADDMETHOD_(c,0,"ldxdir",m_ldxdir); FLEXT_CADDMETHOD_(c,0,"ldxrec",m_ldxrec); FLEXT_CADDMETHOD_(c,0,"svxdir",m_svxdir); FLEXT_CADDMETHOD_(c,0,"svxrec",m_svxrec); } pool::pool(int argc,const t_atom *argv): absdir(true),echo(false), pl(NULL), clip(NULL), vcnt(VCNT),dcnt(DCNT) { holdname = argc >= 1 && IsSymbol(argv[0])?GetSymbol(argv[0]):NULL; AddInAnything("Commands in"); AddOutList(); AddOutAnything(); AddOutList(); AddOutAnything(); } pool::~pool() { FreePool(); } bool pool::Init() { if(flext_base::Init()) { SetPool(holdname); return true; } else return false; } void pool::SetPool(const t_symbol *s) { if(s) { if(pl) { // check if new symbol equals the current one if(pl->sym == s) return; else FreePool(); } pl = GetPool(s); } else { if(pl) { // if already private no need to allocate new storage if(pl->Private()) return; else FreePool(); } pl = new pooldata(NULL,vcnt,dcnt); } } void pool::FreePool() { curdir(); // reset current directory if(pl) { if(!pl->Private()) RmvPool(pl); else delete pl; pl = NULL; } if(clip) { delete clip; clip = NULL; } } void pool::ms_pool(const AtomList &l) { const t_symbol *s = NULL; if(l.Count()) { if(l.Count() > 1) post("%s - pool: superfluous arguments ignored",thisName()); s = GetASymbol(l[0]); if(!s) post("%s - pool: invalid pool name, pool set to private",thisName()); } SetPool(s); } void pool::mg_pool(AtomList &l) { if(!pl || pl->Private()) l(); else { l(1); SetSymbol(l[0],pl->sym); } } void pool::m_reset() { curdir(); pl->Reset(); } void pool::getdir(const t_symbol *tag) { ToSysAnything(3,tag,0,NULL); ToSysList(2,curdir); } void pool::m_getdir() { getdir(thisTag()); } void pool::m_mkdir(int argc,const t_atom *argv,bool abs,bool chg) { // const char *nm = chg?"mkchdir":"mkdir"; if(!ValChk(argc,argv)) post("%s - %s: invalid directory name",thisName(),GetString(thisTag())); else { Atoms ndir; if(abs) ndir(argc,argv); else (ndir = curdir).Append(argc,argv); if(!pl->MkDir(ndir,vcnt,dcnt)) { post("%s - %s: directory couldn't be created",thisName(),GetString(thisTag())); } else if(chg) // change to newly created directory curdir = ndir; } echodir(); } void pool::m_chdir(int argc,const t_atom *argv,bool abs) { if(!ValChk(argc,argv)) post("%s - %s: invalid directory name",thisName(),GetString(thisTag())); else { Atoms prv(curdir); if(abs) curdir(argc,argv); else curdir.Append(argc,argv); if(!pl->ChkDir(curdir)) { post("%s - %s: directory couldn't be changed",thisName(),GetString(thisTag())); curdir = prv; } } echodir(); } void pool::m_updir(int argc,const t_atom *argv) { int lvls = 1; if(argc > 0) { if(CanbeInt(argv[0])) { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); lvls = GetAInt(argv[0]); if(lvls < 0) post("%s - %s: invalid level specification - set to 1",thisName(),GetString(thisTag())); } else post("%s - %s: invalid level specification - set to 1",thisName(),GetString(thisTag())); } Atoms prv(curdir); if(lvls > curdir.Count()) { post("%s - %s: level exceeds directory depth - corrected",thisName(),GetString(thisTag())); curdir(); } else curdir.Part(0,curdir.Count()-lvls); if(!pl->ChkDir(curdir)) { post("%s - %s: directory couldn't be changed",thisName(),GetString(thisTag())); curdir = prv; } echodir(); } void pool::m_rmdir(int argc,const t_atom *argv,bool abs) { if(abs) curdir(argc,argv); else curdir.Append(argc,argv); if(!pl->RmDir(curdir)) post("%s - %s: directory couldn't be removed",thisName(),GetString(thisTag())); curdir(); echodir(); } void pool::set(int argc,const t_atom *argv,bool over) { if(!argc || !KeyChk(argv[0])) post("%s - %s: invalid key",thisName(),GetString(thisTag())); else if(!ValChk(argc-1,argv+1)) { post("%s - %s: invalid data values",thisName(),GetString(thisTag())); } else if(!pl->Set(curdir,argv[0],new AtomList(argc-1,argv+1),over)) post("%s - %s: value couldn't be set",thisName(),GetString(thisTag())); echodir(); } void pool::m_seti(int argc,const t_atom *argv) { if(!argc || !CanbeInt(argv[0])) post("%s - %s: invalid index",thisName(),GetString(thisTag())); else if(!ValChk(argc-1,argv+1)) { post("%s - %s: invalid data values",thisName(),GetString(thisTag())); } else if(!pl->Seti(curdir,GetAInt(argv[0]),new Atoms(argc-1,argv+1))) post("%s - %s: value couldn't be set",thisName(),GetString(thisTag())); echodir(); } void pool::m_clr(int argc,const t_atom *argv) { if(!argc || !KeyChk(argv[0])) post("%s - %s: invalid key",thisName(),GetString(thisTag())); else { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); if(!pl->Clr(curdir,argv[0])) post("%s - %s: value couldn't be cleared",thisName(),GetString(thisTag())); } echodir(); } void pool::m_clri(int ix) { if(ix < 0) post("%s - %s: invalid index",thisName(),GetString(thisTag())); else { if(!pl->Clri(curdir,ix)) post("%s - %s: value couldn't be cleared",thisName(),GetString(thisTag())); } echodir(); } void pool::m_clrall() { if(!pl->ClrAll(curdir,false)) post("%s - %s: values couldn't be cleared",thisName(),GetString(thisTag())); echodir(); } void pool::m_clrrec() { if(!pl->ClrAll(curdir,true)) post("%s - %s: values couldn't be cleared",thisName(),GetString(thisTag())); echodir(); } void pool::m_clrsub() { if(!pl->ClrAll(curdir,true,true)) post("%s - %s: directories couldn't be cleared",thisName(),GetString(thisTag())); echodir(); } void pool::m_get(int argc,const t_atom *argv) { if(!argc || !KeyChk(argv[0])) post("%s - %s: invalid key",thisName(),GetString(thisTag())); else { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); poolval *r = pl->Ref(curdir,argv[0]); ToSysAnything(3,thisTag(),0,NULL); if(absdir) ToSysList(2,curdir); else ToSysList(2,0,NULL); if(r) { ToOutAtom(1,r->key); ToSysList(0,*r->data); } else { ToSysBang(1); ToSysBang(0); } } echodir(); } void pool::m_geti(int ix) { if(ix < 0) post("%s - %s: invalid index",thisName(),GetString(thisTag())); else { poolval *r = pl->Refi(curdir,ix); ToSysAnything(3,thisTag(),0,NULL); if(absdir) ToSysList(2,curdir); else ToSysList(2,0,NULL); if(r) { ToOutAtom(1,r->key); ToSysList(0,*r->data); } else { ToSysBang(1); ToSysBang(0); } } echodir(); } // ---- some sorting stuff ---------------------------------- inline bool smaller(const t_atom &a,const t_atom &b,int index) { return a < b; } inline void swap(t_atom &a,t_atom &b) { t_atom c = a; a = b; b = c; } inline bool smaller(const t_atom *a,const t_atom *b,int index) { return *a < *b; } inline void swap(t_atom *a,t_atom *b) { t_atom *c = a; a = b; b = c; } inline bool smaller(const Atoms &a,const Atoms &b,int index) { if(a.Count()-1 < index) return true; else if(b.Count()-1 < index) return false; else return a[index] < b[index]; } inline void swap(Atoms &a,Atoms &b) { Atoms c(a); a = b; b = c; } inline bool smaller(const Atoms *a,const Atoms *b,int index) { return smaller(*a,*b,index); } inline void swap(Atoms *a,Atoms *b) { Atoms *c = a; a = b; b = c; } template void sift(T1 *a,T2 *b,int start,int count,int index,bool rev) { int root = start; // Point to a root node int child; while((child = root * 2 + 1) < count) { // While the root has child(ren) point to its left child // If the child has a sibling and the child's value is less than its sibling's... if(child < count-1 && smaller(a[child],a[child+1],index) != rev) child++; // ... point to the right child instead if(smaller(a[root],a[child],index) == rev) break; // If the value in root is less than in child... swap(a[root], a[child]); // ... swap the values in root and child and... if(b) swap(b[root], b[child]); root = child; // ... make root point to its child } } template void heapsort(T1 *a,T2 *b,int count,int index,bool rev) { int start = count/2-1; int end = count-1; for(; start >= 0; start--) sift(a, b, start, count, index, rev); for(; end > 0; --end) { swap(a[end], a[0]); if(b) swap(b[end], b[0]); sift(a, b, 0, end, index, rev); } } template static void orderpairs(T1 *keys,T2 *atoms,int count,int index,bool rev) { FLEXT_ASSERT(index >= 0); if(!count) return; if(index) heapsort(atoms,keys,count,index-1,rev); else heapsort(keys,atoms,count,0,rev); } // ---- sorting stuff ends ---------------------------------- int pool::getrec(const t_symbol *tag,int level,int order,bool rev,get_t how,const AtomList &rdir) { Atoms gldir(curdir); gldir.Append(rdir); int ret = 0; switch(how) { case get_cnt: ret = pl->CntAll(gldir); break; case get_print: ret = pl->PrintAll(gldir); break; case get_norm: { t_atom *k; Atoms *r; int cnt = pl->GetAll(gldir,k,r); if(!k) { FLEXT_ASSERT(!k); post("%s - %s: error retrieving values",thisName(),GetString(tag)); } else { FLEXT_ASSERT(r); if(order >= 0) orderpairs(k,r,cnt,order,rev); for(int i = 0; i < cnt; ++i) { ToSysAnything(3,tag,0,NULL); ToSysList(2,absdir?gldir:rdir); ToOutAtom(1,k[i]); ToSysList(0,r[i]); } delete[] k; delete[] r; } ret = cnt; } } if(level != 0) { const t_atom **r; int cnt = pl->GetSub(gldir,r); if(!r) post("%s - %s: error retrieving directories",thisName(),GetString(tag)); else { if(order >= 0) orderpairs(r,(Atoms *)NULL,cnt,order,rev); int lv = level > 0?level-1:-1; for(int i = 0; i < cnt; ++i) { Atoms l(rdir); l.Append(*r[i]); ret += getrec(tag,lv,order,rev,how,l); } delete[] r; } } return ret; } void pool::m_getall() { AtomList l; getrec(thisTag(),0,-1,false,get_norm,l); ToSysBang(3); echodir(); } void pool::m_ogetall(int argc,const t_atom *argv) { int index = 0; if(argc) { if(!CanbeInt(*argv) || (index = GetAInt(*argv)) < 0) { index = 0; post("%s - %s: invalid sort index specification - set to 0",thisName(),GetString(thisTag())); } --argc,++argv; } bool rev = false; if(argc) { if(!CanbeBool(*argv)) post("%s - %s: invalid sort direction specification - set to forward",thisName(),GetString(thisTag())); else rev = GetABool(*argv); --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); AtomList l; getrec(thisTag(),0,index,rev,get_norm,l); ToSysBang(3); echodir(); } void pool::m_getrec(int argc,const t_atom *argv) { int lvls = -1; if(argc) { if(!CanbeInt(*argv) || (lvls = GetAInt(*argv)) < -1) { lvls = -1; post("%s - %s: invalid level specification - set to %i",thisName(),GetString(thisTag()),lvls); } --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); AtomList l; getrec(thisTag(),lvls,-1,false,get_norm,l); ToSysBang(3); echodir(); } void pool::m_ogetrec(int argc,const t_atom *argv) { int lvls = -1; if(argc) { if(!CanbeInt(*argv) || (lvls = GetAInt(*argv)) < -1) { lvls = -1; post("%s - %s: invalid level specification - set to %i",thisName(),GetString(thisTag()),lvls); } --argc,++argv; } int index = 0; if(argc) { if(!CanbeInt(*argv) || (index = GetAInt(*argv)) < 0) { index = 0; post("%s - %s: invalid sort index specification - set to 0",thisName(),GetString(thisTag())); } --argc,++argv; } bool rev = false; if(argc) { if(!CanbeBool(*argv)) post("%s - %s: invalid sort direction specification - set to forward",thisName(),GetString(thisTag())); else rev = GetABool(*argv); --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); AtomList l; getrec(thisTag(),lvls,index,rev,get_norm,l); ToSysBang(3); echodir(); } int pool::getsub(const t_symbol *tag,int level,int order,bool rev,get_t how,const AtomList &rdir) { Atoms gldir(curdir); gldir.Append(rdir); int ret = 0; const t_atom **r = NULL; // CntSub is not used here because it doesn't allow checking for valid directory int cnt = pl->GetSub(gldir,r); if(!r) post("%s - %s: error retrieving directories",thisName(),GetString(tag)); else { if(order >= 0) orderpairs(r,(Atoms *)NULL,cnt,order,rev); int lv = level > 0?level-1:-1; for(int i = 0; i < cnt; ++i) { Atoms ndir(absdir?gldir:rdir); ndir.Append(*r[i]); ++ret; if(how == get_norm) { ToSysAnything(3,tag,0,NULL); ToSysList(2,curdir); ToSysList(1,ndir); ToSysBang(0); } if(level != 0) { AtomList l(rdir); l.Append(*r[i]); ret += getsub(tag,lv,order,rev,how,l); } } delete[] r; } return ret; } void pool::m_getsub(int argc,const t_atom *argv) { int lvls = 0; if(argc) { if(!CanbeInt(*argv) || (lvls = GetAInt(*argv)) < -1) { lvls = 0; post("%s - %s: invalid level specification - set to %i",thisName(),GetString(thisTag()),lvls); } --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); AtomList l; getsub(thisTag(),lvls,-1,false,get_norm,l); ToSysBang(3); echodir(); } void pool::m_ogetsub(int argc,const t_atom *argv) { int lvls = 0; if(argc) { if(!CanbeInt(*argv) || (lvls = GetAInt(*argv)) < -1) { lvls = 0; post("%s - %s: invalid level specification - set to %i",thisName(),GetString(thisTag()),lvls); } --argc,++argv; } int index = 0; if(argc) { if(!CanbeInt(*argv) || (index = GetAInt(*argv)) < 0) { index = 0; post("%s - %s: invalid sort index specification - set to 0",thisName(),GetString(thisTag())); } --argc,++argv; } bool rev = false; if(argc) { if(!CanbeBool(*argv)) post("%s - %s: invalid sort direction specification - set to forward",thisName(),GetString(thisTag())); else rev = GetABool(*argv); --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); AtomList l; getsub(thisTag(),lvls,index,rev,get_norm,l); ToSysBang(3); echodir(); } void pool::m_cntall() { AtomList l; int cnt = getrec(thisTag(),0,-1,false,get_cnt,l); ToSysSymbol(3,thisTag()); ToSysBang(2); ToSysBang(1); ToSysInt(0,cnt); echodir(); } void pool::m_cntrec(int argc,const t_atom *argv) { int lvls = -1; if(argc) { if(!CanbeInt(*argv) || (lvls = GetAInt(*argv)) < -1) { lvls = -1; post("%s - %s: invalid level specification - set to %i",thisName(),GetString(thisTag()),lvls); } --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); AtomList l; int cnt = getrec(thisTag(),lvls,-1,false,get_cnt,l); ToSysSymbol(3,thisTag()); ToSysBang(2); ToSysBang(1); ToSysInt(0,cnt); echodir(); } void pool::m_cntsub(int argc,const t_atom *argv) { int lvls = 0; if(argc) { if(!CanbeInt(*argv) || (lvls = GetAInt(*argv)) < -1) { lvls = 0; post("%s - %s: invalid level specification - set to %i",thisName(),GetString(thisTag()),lvls); } --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); AtomList l; int cnt = getsub(thisTag(),lvls,-1,false,get_cnt,l); ToSysSymbol(3,thisTag()); ToSysBang(2); ToSysBang(1); ToSysInt(0,cnt); echodir(); } void pool::m_printall() { AtomList l; int cnt = getrec(thisTag(),0,-1,false,get_print,l); post(""); } void pool::m_printrec(int argc,const t_atom *argv,bool fromroot) { const t_symbol *tag = thisTag(); int lvls = -1; if(argc) { if(!CanbeInt(*argv) || (lvls = GetAInt(*argv)) < -1) { lvls = 0; post("%s - %s: invalid level specification - set to %i",thisName(),GetString(tag),lvls); } --argc,++argv; } if(argc) post("%s - %s: superfluous arguments ignored",thisName(),GetString(tag)); Atoms svdir(curdir); if(fromroot) curdir.Clear(); AtomList l; int cnt = getrec(tag,lvls,-1,false,get_print,l); post(""); curdir = svdir; } void pool::paste(const t_symbol *tag,int argc,const t_atom *argv,bool repl) { if(clip) { bool mkdir = true; int depth = -1; if(argc >= 1) { if(CanbeInt(argv[0])) depth = GetAInt(argv[1]); else post("%s - %s: invalid depth argument - set to -1",thisName(),GetString(tag)); if(argc >= 2) { if(CanbeBool(argv[1])) mkdir = GetABool(argv[1]); else post("%s - %s: invalid mkdir argument - set to true",thisName(),GetString(tag)); if(argc > 2) post("%s - %s: superfluous arguments ignored",thisName(),GetString(tag)); } } pl->Paste(curdir,clip,depth,repl,mkdir); } else post("%s - %s: clipboard is empty",thisName(),GetString(tag)); echodir(); } void pool::m_clrclip() { if(clip) { delete clip; clip = NULL; } } void pool::copy(const t_symbol *tag,int argc,const t_atom *argv,bool cut) { if(!argc || !KeyChk(argv[0])) post("%s - %s: invalid key",thisName(),GetString(tag)); else { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(tag)); m_clrclip(); clip = pl->Copy(curdir,argv[0],cut); if(!clip) post("%s - %s: Copying into clipboard failed",thisName(),GetString(tag)); } echodir(); } void pool::copyall(const t_symbol *tag,bool cut,int depth) { m_clrclip(); clip = pl->CopyAll(curdir,depth,cut); if(!clip) post("%s - %s: Copying into clipboard failed",thisName(),GetString(tag)); echodir(); } void pool::copyrec(const t_symbol *tag,int argc,const t_atom *argv,bool cut) { int lvls = -1; if(argc > 0) { if(CanbeInt(argv[0])) { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(tag)); lvls = GetAInt(argv[0]); } else post("%s - %s: invalid level specification - set to infinite",thisName(),GetString(tag)); } copyall(tag,cut,lvls); } void pool::load(int argc,const t_atom *argv,bool xml) { const char *flnm = NULL; if(argc > 0) { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); if(IsString(argv[0])) flnm = GetString(argv[0]); } bool ok = false; if(!flnm) post("%s - %s: no filename given",thisName(),GetString(thisTag())); else { string file(MakeFilename(flnm)); ok = xml?pl->LoadXML(file.c_str()):pl->Load(file.c_str()); if(!ok) post("%s - %s: error loading data",thisName(),GetString(thisTag())); } t_atom at; SetBool(at,ok); ToOutAnything(GetOutAttr(),thisTag(),1,&at); echodir(); } void pool::save(int argc,const t_atom *argv,bool xml) { const char *flnm = NULL; if(argc > 0) { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); if(IsString(argv[0])) flnm = GetString(argv[0]); } bool ok = false; if(!flnm) post("%s - %s: no filename given",thisName(),GetString(thisTag())); else { string file(MakeFilename(flnm)); ok = xml?pl->SaveXML(file.c_str()):pl->Save(file.c_str()); if(!ok) post("%s - %s: error saving data",thisName(),GetString(thisTag())); } t_atom at; SetBool(at,ok); ToOutAnything(GetOutAttr(),thisTag(),1,&at); echodir(); } void pool::lddir(int argc,const t_atom *argv,bool xml) { const char *flnm = NULL; if(argc > 0) { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); if(IsString(argv[0])) flnm = GetString(argv[0]); } bool ok = false; if(!flnm) post("%s - %s: invalid filename",thisName(),GetString(thisTag())); else { string file(MakeFilename(flnm)); ok = xml?pl->LdDirXML(curdir,file.c_str(),0):pl->LdDir(curdir,file.c_str(),0); if(!ok) post("%s - %s: directory couldn't be loaded",thisName(),GetString(thisTag())); } t_atom at; SetBool(at,ok); ToOutAnything(GetOutAttr(),thisTag(),1,&at); echodir(); } void pool::ldrec(int argc,const t_atom *argv,bool xml) { const char *flnm = NULL; int depth = -1; bool mkdir = true; if(argc >= 1) { if(IsString(argv[0])) flnm = GetString(argv[0]); if(argc >= 2) { if(CanbeInt(argv[1])) depth = GetAInt(argv[1]); else post("%s - %s: invalid depth argument - set to -1",thisName(),GetString(thisTag())); if(argc >= 3) { if(CanbeBool(argv[2])) mkdir = GetABool(argv[2]); else post("%s - %s: invalid mkdir argument - set to true",thisName(),GetString(thisTag())); if(argc > 3) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); } } } bool ok = false; if(!flnm) post("%s - %s: invalid filename",thisName(),GetString(thisTag())); else { string file(MakeFilename(flnm)); ok = xml?pl->LdDirXML(curdir,file.c_str(),depth,mkdir):pl->LdDir(curdir,file.c_str(),depth,mkdir); if(!ok) post("%s - %s: directory couldn't be saved",thisName(),GetString(thisTag())); } t_atom at; SetBool(at,ok); ToOutAnything(GetOutAttr(),thisTag(),1,&at); echodir(); } void pool::svdir(int argc,const t_atom *argv,bool xml) { const char *flnm = NULL; if(argc > 0) { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); if(IsString(argv[0])) flnm = GetString(argv[0]); } bool ok = false; if(!flnm) post("%s - %s: invalid filename",thisName(),GetString(thisTag())); else { string file(MakeFilename(flnm)); ok = xml?pl->SvDirXML(curdir,file.c_str(),0,absdir):pl->SvDir(curdir,file.c_str(),0,absdir); if(!ok) post("%s - %s: directory couldn't be saved",thisName(),GetString(thisTag())); } t_atom at; SetBool(at,ok); ToOutAnything(GetOutAttr(),thisTag(),1,&at); echodir(); } void pool::svrec(int argc,const t_atom *argv,bool xml) { const char *flnm = NULL; if(argc > 0) { if(argc > 1) post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag())); if(IsString(argv[0])) flnm = GetString(argv[0]); } bool ok = false; if(!flnm) post("%s - %s: invalid filename",thisName(),GetString(thisTag())); else { string file(MakeFilename(flnm)); ok = xml?pl->SvDirXML(curdir,file.c_str(),-1,absdir):pl->SvDir(curdir,file.c_str(),-1,absdir); if(!ok) post("%s - %s: directory couldn't be saved",thisName(),GetString(thisTag())); } t_atom at; SetBool(at,ok); ToOutAnything(GetOutAttr(),thisTag(),1,&at); echodir(); } bool pool::KeyChk(const t_atom &a) { return IsSymbol(a) || IsFloat(a) || IsInt(a); } bool pool::ValChk(int argc,const t_atom *argv) { for(int i = 0; i < argc; ++i) { const t_atom &a = argv[i]; if(!IsSymbol(a) && !IsFloat(a) && !IsInt(a)) return false; } return true; } void pool::ToOutAtom(int ix,const t_atom &a) { if(IsSymbol(a)) ToSysSymbol(ix,GetSymbol(a)); else if(IsFloat(a)) ToSysFloat(ix,GetFloat(a)); else if(IsInt(a)) ToSysInt(ix,GetInt(a)); else post("%s - %s type not supported!",thisName(),GetString(thisTag())); } pooldata *pool::GetPool(const t_symbol *s) { PoolMap::iterator it = poolmap.find(s); pooldata *p; if(it != poolmap.end()) p = it->second; else poolmap[s] = p = new pooldata(s); p->Push(); return p; } void pool::RmvPool(pooldata *p) { FLEXT_ASSERT(p->sym); PoolMap::iterator it = poolmap.find(p->sym); FLEXT_ASSERT(it != poolmap.end()); FLEXT_ASSERT(p == it->second); if(!p->Pop()) { poolmap.erase(it); delete p; } } string pool::MakeFilename(const char *fn) const { #if FLEXT_SYS == FLEXT_SYS_PD // / and \ must not be mixed! // (char *) type casts for BorlandC++ char *sl = strchr((char *)fn,'/'); if(!sl) sl = strchr((char *)fn,'\\'); if(!sl || (sl != fn #if FLEXT_OS == FLEXT_OS_WIN && sl[-1] != ':' // look for drive specification with ":/" or ":\\" #endif )) { // prepend absolute canvas path if filename has no absolute path const char *p = GetString(canvas_getdir(thisCanvas())); return string(p)+'/'+fn; } else return fn; #else #pragma message("Relative file paths not implemented") return fn; #endif } pool-master/source/pool.cpp0000644000175000017500000007276612504366625016562 0ustar zmoelnigzmoelnig/* pool - hierarchical storage object for PD and Max/MSP Copyright (c) 2002-2008 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. $LastChangedRevision: 26 $ $LastChangedDate$ $LastChangedBy$ */ #include "pool.h" #include #include #include #include #include #if FLEXT_OS == FLEXT_OS_WIN #include // for charset conversion functions #elif FLEXT_OS == FLEXT_OS_MAC #include #else static bool WCStoUTF8(char *sdst,const wchar_t *src,int dstlen) { unsigned char *dst = (unsigned char *)sdst; unsigned char *max = dst+dstlen; for(;;) { wchar_t ud = *(src++); if(ud < 128) { if(dst+1 >= max) return false; *(dst++) = (unsigned char)ud; } else if(ud < 2048) { if(dst+2 >= max) return false; *(dst++) = 192+(unsigned char)(ud/64); *(dst++) = 128+(unsigned char)(ud%64); } else if(ud < 65535) { if(dst+3 >= max) return false; *(dst++) = 224+(unsigned char)(ud/4096); *(dst++) = 128+(unsigned char)((ud/64)%64); *(dst++) = 128+(unsigned char)(ud%64); } else if(ud < 2097151) { if(dst+4 >= max) return false; *(dst++) = 240+(unsigned char)(ud/262144); *(dst++) = 128+(unsigned char)((ud/4096)%64); *(dst++) = 128+(unsigned char)((ud/64)%64); *(dst++) = 128+(unsigned char)(ud%64); } else if(ud < 67108863) { if(dst+5 >= max) return false; *(dst++) = 248+(unsigned char)(ud/16777216); *(dst++) = 128+(unsigned char)((ud/262144)%64); *(dst++) = 128+(unsigned char)((ud/4096)%64); *(dst++) = 128+(unsigned char)((ud/64)%64); *(dst++) = 128+(unsigned char)(ud%64); } else { if(dst+6 >= max) return false; *(dst++) = 252+(unsigned char)(ud/1073741824); *(dst++) = 128+(unsigned char)((ud/16777216)%64); *(dst++) = 128+(unsigned char)((ud/262144)%64); *(dst++) = 128+(unsigned char)((ud/4096)%64); *(dst++) = 128+(unsigned char)((ud/64)%64); *(dst++) = 128+(unsigned char)(ud%64); } if(!ud) break; } return true; } static bool UTF8toWCS(wchar_t *dst,const char *ssrc,int dstlen) { const unsigned char *src = (const unsigned char *)ssrc; wchar_t *max = dst+dstlen; for(;;) { if(*src < 128) { *dst = *(src++); if(!*dst) break; } else if(*src < 224) { *dst = wchar_t(src[0]-192)*64+wchar_t(src[1]-128); src += 2; } else if(*src < 240) { *dst = wchar_t(src[0]-224)*4096+wchar_t(src[1]-128)*64+wchar_t(src[2]-128); src += 3; } else if(*src < 248) { *dst = wchar_t(src[0]-240)*262144+wchar_t(src[1]-128)*4096+wchar_t(src[2]-128)*64+wchar_t(src[3]-128); src += 4; } else if(*src < 252) { *dst = wchar_t(src[0]-248)*16777216+wchar_t(src[1]-128)*262144+wchar_t(src[2]-128)*4096+wchar_t(src[3]-128)*64+wchar_t(src[4]-128); src += 5; } else if(*src < 254) { *dst = wchar_t(src[0]-252)*1073741824+wchar_t(src[1]-128)*16777216+wchar_t(src[2]-128)*262144+wchar_t(src[3]-128)*4096+wchar_t(src[4]-128)*64+wchar_t(src[5]-128); src += 6; } else // invalid string return false; if(++dst >= max) return false; } return true; } #endif using namespace std; inline int compare(int a,int b) { return a == b?0:(a < b?-1:1); } inline int compare(float a,float b) { return a == b?0:(a < b?-1:1); } static int compare(const t_symbol *a,const t_symbol *b) { if(a == b) return 0; else return strcmp(flext::GetString(a),flext::GetString(b)); } static int compare(const t_atom &a,const t_atom &b) { if(flext::GetType(a) == flext::GetType(b)) { switch(flext::GetType(a)) { case A_FLOAT: return compare(flext::GetFloat(a),flext::GetFloat(b)); #if FLEXT_SYS == FLEXT_SYS_MAX case A_LONG: return compare(flext::GetInt(a),flext::GetInt(b)); #endif case A_SYMBOL: return compare(flext::GetSymbol(a),flext::GetSymbol(b)); #if FLEXT_SYS == FLEXT_SYS_PD case A_POINTER: return flext::GetPointer(a) == flext::GetPointer(b)?0:(flext::GetPointer(a) < flext::GetPointer(b)?-1:1); #endif default: FLEXT_LOG("pool - atom comparison: type not handled"); return -1; } } else return flext::GetType(a) < flext::GetType(b)?-1:1; } poolval::poolval(const t_atom &k,AtomList *d): data(d),nxt(NULL) { SetAtom(key,k); } poolval::~poolval() { if(data) delete data; FLEXT_ASSERT(nxt == NULL); } poolval &poolval::Set(AtomList *d) { if(data) delete data; data = d; return *this; } poolval *poolval::Dup() const { return new poolval(key,data?new Atoms(*data):NULL); } pooldir::pooldir(const t_atom &d,pooldir *p,int vcnt,int dcnt): parent(p),nxt(NULL),vals(NULL),dirs(NULL), vbits(Int2Bits(vcnt)),dbits(Int2Bits(dcnt)), vsize(1<nxt; d->nxt = NULL; delete d; } while((d = d1) != NULL); dirs[i].d = NULL; dirs[i].cnt = 0; } } } if(!dironly && vals) { for(int i = 0; i < vsize; ++i) { poolval *v = vals[i].v,*v1; if(v) { do { v1 = v->nxt; v->nxt = NULL; delete v; } while((v = v1) != NULL); vals[i].v = NULL; vals[i].cnt = 0; } } } } void pooldir::Reset(bool realloc) { Clear(true,false); if(dirs) delete[] dirs; if(vals) delete[] vals; if(realloc) { dirs = new direntry[dsize]; ZeroMem(dirs,dsize*sizeof *dirs); vals = new valentry[vsize]; ZeroMem(vals,vsize*sizeof *vals); } else dirs = NULL,vals = NULL; } pooldir *pooldir::AddDir(int argc,const t_atom *argv,int vcnt,int dcnt) { if(!argc) return this; int c = 1,dix = DIdx(argv[0]); pooldir *prv = NULL,*ix = dirs[dix].d; for(; ix; prv = ix,ix = ix->nxt) { c = compare(argv[0],ix->dir); if(c <= 0) break; } if(c || !ix) { pooldir *nd = new pooldir(argv[0],this,vcnt,dcnt); nd->nxt = ix; if(prv) prv->nxt = nd; else dirs[dix].d = nd; dirs[dix].cnt++; ix = nd; } return ix->AddDir(argc-1,argv+1); } pooldir *pooldir::GetDir(int argc,const t_atom *argv,bool rmv) { if(!argc) return this; int c = 1,dix = DIdx(argv[0]); pooldir *prv = NULL,*ix = dirs[dix].d; for(; ix; prv = ix,ix = ix->nxt) { c = compare(argv[0],ix->dir); if(c <= 0) break; } if(c || !ix) return NULL; else { if(argc > 1) return ix->GetDir(argc-1,argv+1,rmv); else if(rmv) { pooldir *nd = ix->nxt; if(prv) prv->nxt = nd; else dirs[dix].d = nd; dirs[dix].cnt--; ix->nxt = NULL; return ix; } else return ix; } } bool pooldir::DelDir(int argc,const t_atom *argv) { pooldir *pd = GetDir(argc,argv,true); if(pd && pd != this) { delete pd; return true; } else return false; } void pooldir::SetVal(const t_atom &key,AtomList *data,bool over) { int c = 1,vix = VIdx(key); poolval *prv = NULL,*ix = vals[vix].v; for(; ix; prv = ix,ix = ix->nxt) { c = compare(key,ix->key); if(c <= 0) break; } if(c || !ix) { // no existing data found if(data) { poolval *nv = new poolval(key,data); nv->nxt = ix; if(prv) prv->nxt = nv; else vals[vix].v = nv; vals[vix].cnt++; } } else if(over) { // data exists... only set if overwriting enabled if(data) ix->Set(data); else { // delete key poolval *nv = ix->nxt; if(prv) prv->nxt = nv; else vals[vix].v = nv; vals[vix].cnt--; ix->nxt = NULL; delete ix; } } } bool pooldir::SetVali(int rix,AtomList *data) { poolval *prv = NULL,*ix = NULL; int vix; for(vix = 0; vix < vsize; ++vix) if(rix > vals[vix].cnt) rix -= vals[vix].cnt; else { ix = vals[vix].v; for(; ix && rix; prv = ix,ix = ix->nxt) --rix; if(ix && !rix) break; } if(ix) { // data exists... overwrite it if(data) ix->Set(data); else { // delete key poolval *nv = ix->nxt; if(prv) prv->nxt = nv; else vals[vix].v = nv; vals[vix].cnt--; ix->nxt = NULL; delete ix; } return true; } else return false; } poolval *pooldir::RefVal(const t_atom &key) { int c = 1,vix = VIdx(key); poolval *ix = vals[vix].v; for(; ix; ix = ix->nxt) { c = compare(key,ix->key); if(c <= 0) break; } return c || !ix?NULL:ix; } poolval *pooldir::RefVali(int rix) { for(int vix = 0; vix < vsize; ++vix) if(rix > vals[vix].cnt) rix -= vals[vix].cnt; else { poolval *ix = vals[vix].v; for(; ix && rix; ix = ix->nxt) --rix; if(ix && !rix) return ix; } return NULL; } flext::AtomList *pooldir::PeekVal(const t_atom &key) { poolval *ix = RefVal(key); return ix?ix->data:NULL; } flext::AtomList *pooldir::GetVal(const t_atom &key,bool cut) { int c = 1,vix = VIdx(key); poolval *prv = NULL,*ix = vals[vix].v; for(; ix; prv = ix,ix = ix->nxt) { c = compare(key,ix->key); if(c <= 0) break; } if(c || !ix) return NULL; else { AtomList *ret; if(cut) { poolval *nv = ix->nxt; if(prv) prv->nxt = nv; else vals[vix].v = nv; vals[vix].cnt--; ix->nxt = NULL; ret = ix->data; ix->data = NULL; delete ix; } else ret = new Atoms(*ix->data); return ret; } } int pooldir::CntAll() const { int cnt = 0; for(int vix = 0; vix < vsize; ++vix) cnt += vals[vix].cnt; return cnt; } int pooldir::PrintAll(char *buf,int len) const { int offs = strlen(buf); int cnt = 0; for(int vix = 0; vix < vsize; ++vix) { poolval *ix = vals[vix].v; for(int i = 0; ix; ++i,ix = ix->nxt) { PrintAtom(ix->key,buf+offs,len-offs); strcat(buf+offs," , "); int l = strlen(buf+offs)+offs; ix->data->Print(buf+l,len-l); post(buf); } cnt += vals[vix].cnt; } buf[offs] = 0; return cnt; } int pooldir::GetKeys(AtomList &keys) { int cnt = CntAll(); keys(cnt); for(int vix = 0; vix < vsize; ++vix) { poolval *ix = vals[vix].v; for(int i = 0; ix; ++i,ix = ix->nxt) SetAtom(keys[i],ix->key); } return cnt; } int pooldir::GetAll(t_atom *&keys,Atoms *&lst,bool cut) { int cnt = CntAll(); keys = new t_atom[cnt]; lst = new Atoms[cnt]; for(int i = 0,vix = 0; vix < vsize; ++vix) { poolval *ix = vals[vix].v; for(; ix; ++i) { SetAtom(keys[i],ix->key); lst[i] = *ix->data; if(cut) { poolval *t = ix; vals[vix].v = ix = ix->nxt; vals[vix].cnt--; t->nxt = NULL; delete t; } else ix = ix->nxt; } } return cnt; } int pooldir::CntSub() const { int cnt = 0; for(int dix = 0; dix < dsize; ++dix) cnt += dirs[dix].cnt; return cnt; } int pooldir::GetSub(const t_atom **&lst) { const int cnt = CntSub(); lst = new const t_atom *[cnt]; for(int i = 0,dix = 0; i < cnt; ++dix) { pooldir *ix = dirs[dix].d; for(; ix; ix = ix->nxt) lst[i++] = &ix->dir; } return cnt; } bool pooldir::Paste(const pooldir *p,int depth,bool repl,bool mkdir) { bool ok = true; for(int vi = 0; vi < p->vsize; ++vi) { for(poolval *ix = p->vals[vi].v; ix; ix = ix->nxt) { SetVal(ix->key,new Atoms(*ix->data),repl); } } if(ok && depth) { for(int di = 0; di < p->dsize; ++di) { for(pooldir *dix = p->dirs[di].d; ok && dix; dix = dix->nxt) { pooldir *ndir = mkdir?AddDir(1,&dix->dir):GetDir(1,&dix->dir); if(ndir) { ok = ndir->Paste(dix,depth > 0?depth-1:depth,repl,mkdir); } } } } return ok; } bool pooldir::Copy(pooldir *p,int depth,bool cut) { bool ok = true; if(cut) { for(int vi = 0; vi < vsize; ++vi) { for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) p->SetVal(ix->key,ix->data); vals[vi].cnt = 0; vals[vi].v = NULL; } } else { for(int vi = 0; vi < vsize; ++vi) { for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { p->SetVal(ix->key,new Atoms(*ix->data)); } } } if(ok && depth) { for(int di = 0; di < dsize; ++di) { for(pooldir *dix = dirs[di].d; ok && dix; dix = dix->nxt) { pooldir *ndir = p->AddDir(1,&dix->dir); if(ndir) ok = dix->Copy(ndir,depth > 0?depth-1:depth,cut); else ok = false; } } } return ok; } static bool _isspace(char c) { return c > 0 && isspace(c); } static const char *ReadAtom(const char *c,t_atom &a,bool utf8) { // skip leading whitespace (NON-ASCII character are < 0) while(*c && _isspace(*c)) ++c; if(!*c) return NULL; char tmp[1024]; char *m = tmp; // write position bool issymbol; if(*c == '"') { issymbol = true; ++c; } else issymbol = false; // go to next whitespace for(bool escaped = false;; ++c) if(*c == '\\') { if(escaped) { *m++ = *c; escaped = false; } else escaped = true; } else if(*c == '"' && issymbol && !escaped) { // end of string ++c; FLEXT_ASSERT(!*c || _isspace(*c)); *m = 0; break; } else if(!*c || (_isspace(*c) && !escaped)) { *m = 0; break; } else { *m++ = *c; escaped = false; } // save character and set delimiter float fres; // first try float #if 0 if(!issymbol && sscanf(tmp,"%f",&fres) == 1) { #else char *endp; // see if it's a float - thanks to Frank Barknecht fres = (float)strtod(tmp,&endp); if(!issymbol && !*endp && endp != tmp) { #endif int ires = (int)fres; // try a cast if(fres == ires) flext::SetInt(a,ires); else flext::SetFloat(a,fres); } // no, it's a symbol else { const char *c; if(utf8) { #if FLEXT_OS == FLEXT_OS_WIN wchar_t wtmp[1024]; int err = MultiByteToWideChar(CP_UTF8,0,tmp,strlen(tmp),wtmp,1024); if(!err) return NULL; err = WideCharToMultiByte(CP_ACP,0,wtmp,err,tmp,1024,NULL,FALSE); if(!err) return NULL; tmp[err] = 0; c = tmp; #elif FLEXT_OS == FLEXT_OS_MAC char ctmp[1024]; // is the output always MacRoman? TextEncoding inconv = CreateTextEncoding(kTextEncodingUnicodeDefault,kTextEncodingDefaultVariant,kUnicodeUTF8Format); TextEncoding outconv = CreateTextEncoding(kTextEncodingMacRoman,kTextEncodingDefaultVariant,kTextEncodingDefaultFormat); TECObjectRef converter; OSStatus status = TECCreateConverter(&converter,inconv,outconv); if(status) return NULL; ByteCount inlen,outlen; status = TECConvertText( converter, (ConstTextPtr)tmp,strlen(tmp),&inlen, (TextPtr)ctmp,sizeof(ctmp),&outlen ); ctmp[outlen] = 0; TECDisposeConverter(converter); c = ctmp; if(status) return NULL; #else wchar_t wtmp[1024]; size_t len = mbstowcs(wtmp,tmp,1024); if(len < 0) return NULL; if(!WCStoUTF8(tmp,wtmp,sizeof(tmp))) return NULL; c = tmp; #endif } else c = tmp; flext::SetString(a,c); } return c; } static bool ParseAtoms(const char *tmp,flext::AtomList &l,bool utf8) { FLEXT_ASSERT(tmp); vector atoms; while(*tmp) { t_atom at; tmp = ReadAtom(tmp,at,utf8); if(!tmp) break; atoms.push_back(at); } l(atoms.size(),&atoms[0]); return true; } static bool ParseAtoms(string &s,flext::AtomList &l,bool utf8) { return ParseAtoms((char *)s.c_str(),l,utf8); } static bool ReadAtoms(istream &is,flext::AtomList &l,char del,bool utf8) { vector tmp; for(;;) { char c = is.get(); if(is.eof() || c == del) break; tmp.push_back(c); } tmp.push_back(0); // end-of-string marker return is.good() && ParseAtoms(&tmp[0],l,utf8); } static bool WriteAtom(ostream &os,const t_atom &a,bool utf8) { if(flext::IsFloat(a)) os << flext::GetFloat(a); else if(flext::IsInt(a)) os << flext::GetInt(a); else if(flext::IsSymbol(a)) { const char *c = flext::GetString(a); if(utf8) { #if FLEXT_OS == FLEXT_OS_WIN char tmp[1024]; wchar_t wtmp[1024]; int err = MultiByteToWideChar(CP_ACP,0,c,strlen(c),wtmp,1024); if(!err) return false; err = WideCharToMultiByte(CP_UTF8,0,wtmp,err,tmp,1024,NULL,FALSE); if(!err) return false; tmp[err] = 0; c = tmp; #elif FLEXT_OS == FLEXT_OS_MAC char tmp[1024]; // is the input always MacRoman? TextEncoding inconv = CreateTextEncoding(kTextEncodingMacRoman,kTextEncodingDefaultVariant,kTextEncodingDefaultFormat); TextEncoding outconv = CreateTextEncoding(kTextEncodingUnicodeDefault,kTextEncodingDefaultVariant,kUnicodeUTF8Format); TECObjectRef converter; OSStatus status = TECCreateConverter(&converter,inconv,outconv); if(status) return false; ByteCount inlen,outlen; status = TECConvertText( converter, (ConstTextPtr)c,strlen(c),&inlen, (TextPtr)tmp,sizeof(tmp),&outlen ); tmp[outlen] = 0; TECDisposeConverter(converter); if(status) return false; c = tmp; #else char tmp[1024]; wchar_t wtmp[1024]; if(!UTF8toWCS(wtmp,c,1024)) return false; size_t len = wcstombs(tmp,wtmp,sizeof(tmp)); if(len < 0) return false; c = tmp; #endif } os << '"'; for(; *c; ++c) { // escape some special characters if(_isspace(*c) || *c == '\\' || *c == ',' || *c == '"') os << '\\'; os << *c; } os << '"'; } else FLEXT_ASSERT(false); return true; } static void WriteAtoms(ostream &os,const flext::AtomList &l,bool utf8) { for(int i = 0; i < l.Count(); ++i) { WriteAtom(os,l[i],utf8); if(i < l.Count()-1) os << ' '; } } bool pooldir::LdDir(istream &is,int depth,bool mkdir) { for(int i = 1; !is.eof(); ++i) { Atoms d,k,*v = new Atoms; bool r = ReadAtoms(is,d,',',false) && ReadAtoms(is,k,',',false) && ReadAtoms(is,*v,'\n',false); if(r) { if(depth < 0 || d.Count() <= depth) { pooldir *nd = mkdir?AddDir(d):GetDir(d); if(nd) { if(k.Count() == 1) { nd->SetVal(k[0],v); v = NULL; } else if(k.Count() > 1) post("pool - file format invalid: key must be a single word"); } #ifdef FLEXT_DEBUG else post("pool - directory was not found",i); #endif } } else if(!is.eof()) post("pool - format mismatch encountered, skipped line %i",i); if(v) delete v; } return true; } bool pooldir::SvDir(ostream &os,int depth,const AtomList &dir) { int cnt = 0; for(int vi = 0; vi < vsize; ++vi) { for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { WriteAtoms(os,dir,false); os << " , "; WriteAtom(os,ix->key,false); os << " , "; WriteAtoms(os,*ix->data,false); os << endl; ++cnt; } } if(!cnt) { // no key/value pairs present -> force empty directory WriteAtoms(os,dir,false); os << " , ," << endl; } if(depth) { // save sub-directories int nd = depth > 0?depth-1:-1; for(int di = 0; di < dsize; ++di) { for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) { ix->SvDir(os,nd,Atoms(dir).Append(ix->dir)); } } } return true; } class xmltag { public: string tag,attr; bool Ok() const { return tag.length() > 0; } bool operator ==(const char *t) const { return !tag.compare(t); } void Clear() { #if defined(_MSC_VER) && (_MSC_VER < 0x1200) // incomplete STL implementation tag = ""; attr = ""; #else tag.clear(); attr.clear(); #endif } enum { t_start,t_end,t_empty } type; }; static bool gettag(istream &is,xmltag &tag) { static const char *commstt = ""; for(;;) { // eat whitespace while(_isspace(is.peek())) is.get(); // no tag begin -> break if(is.peek() != '<') break; is.get(); // swallow < char tmp[1024],*t = tmp; // parse for comment start const char *c = commstt; while(*++c) { if(*c != is.peek()) break; *(t++) = is.get(); } if(!*c) { // is comment char cmp[2] = {0,0}; // set to some unusual initial value for(int ic = 0; ; ic = (++ic)%2) { char c = is.get(); if(c == '>') { // if third character is > then check also the former two int i; for(i = 0; i < 2 && cmp[(ic+i)%2] == commend[i]; ++i) {} if(i == 2) break; // match: comment end found! } else cmp[ic] = c; } } else { // parse until > with consideration of "s bool intx = false; for(;;) { *t = is.get(); if(*t == '"') intx = !intx; else if(*t == '>' && !intx) { *t = 0; break; } t++; } // look for tag slashes char *tb = tmp,*te = t-1,*tf; for(; _isspace(*tb); ++tb) {} if(*tb == '/') { // slash at the beginning -> end tag tag.type = xmltag::t_end; for(++tb; _isspace(*tb); ++tb) {} } else { for(; _isspace(*te); --te) {} if(*te == '/') { // slash at the end -> empty tag for(--te; _isspace(*te); --te) {} tag.type = xmltag::t_empty; } else // no slash -> begin tag tag.type = xmltag::t_start; } // copy tag text without slashes for(tf = tb; tf <= te && *tf && !_isspace(*tf); ++tf) {} tag.tag.assign(tb,tf-tb); while(_isspace(*tf)) ++tf; tag.attr.assign(tf,te-tf+1); return true; } } tag.Clear(); return false; } static void getvalue(istream &is,string &s) { char tmp[1024],*t = tmp; bool intx = false; for(;;) { char c = is.peek(); if(c == '"') intx = !intx; else if(c == '<' && !intx) break; *(t++) = is.get(); } *t = 0; s = tmp; } bool pooldir::LdDirXMLRec(istream &is,int depth,bool mkdir,AtomList &d) { Atoms k,v; bool inval = false,inkey = false,indata = false; int cntval = 0; while(!is.eof()) { xmltag tag; gettag(is,tag); if(!tag.Ok()) { // look for value string s; getvalue(is,s); if(s.length() && ( (!inval && inkey && d.Count()) || /* dir */ (inval && (inkey || indata)) /* value */ ) ) { bool ret = true; if(indata) { if(v.Count()) post("pool - XML load: value data already given, ignoring new data"); else ret = ParseAtoms(s,v,true); } else // inkey if(inval) { if(k.Count()) post("pool - XML load, value key already given, ignoring new key"); else ret = ParseAtoms(s,k,true); } else { t_atom &dkey = d[d.Count()-1]; FLEXT_ASSERT(IsSymbol(dkey)); const char *ds = GetString(dkey); FLEXT_ASSERT(ds); if(*ds) post("pool - XML load: dir key already given, ignoring new key"); else ReadAtom(s.c_str(),dkey,true); ret = true; } if(!ret) post("pool - error interpreting XML value (%s)",s.c_str()); } else post("pool - error reading XML data"); } else if(tag == "dir") { if(tag.type == xmltag::t_start) { // warn if last directory key was not given if(d.Count() && GetSymbol(d[d.Count()-1]) == sym__) post("pool - XML load: dir key must be given prior to subdirs, ignoring items"); Atoms dnext(d.Count()+1); // copy existing dir dnext.Set(d.Count(),d.Atoms(),0,false); // initialize current dir key as empty SetSymbol(dnext[d.Count()],sym__); // read next level LdDirXMLRec(is,depth,mkdir,dnext); } else if(tag.type == xmltag::t_end) { if(!cntval && mkdir) { // no values have been found in dir -> make empty dir AddDir(d); } // break tag loop break; } } else if(tag == "value") { if(tag.type == xmltag::t_start) { inval = true; ++cntval; k.Clear(); v.Clear(); } else if(tag.type == xmltag::t_end) { // set value after tag closing, but only if level <= depth if(depth < 0 || d.Count() <= depth) { int fnd; for(fnd = d.Count()-1; fnd >= 0; --fnd) if(GetSymbol(d[fnd]) == sym__) break; // look if last dir key has been given if(fnd >= 0) { if(fnd == d.Count()-1) post("pool - XML load: dir key must be given prior to values"); // else: one directory level has been left unintialized, ignore items } else { // only use first word of key if(k.Count() == 1) { pooldir *nd = mkdir?AddDir(d):GetDir(d); if(nd) nd->SetVal(k[0],new Atoms(v)); else post("pool - XML load: value key must be exactly one word, value not stored"); } } } inval = false; } } else if(tag == "key") { if(tag.type == xmltag::t_start) { inkey = true; } else if(tag.type == xmltag::t_end) { inkey = false; } } else if(tag == "data") { if(!inval) post("pool - XML tag not within "); if(tag.type == xmltag::t_start) { indata = true; } else if(tag.type == xmltag::t_end) { indata = false; } } else if(!d.Count() && tag == "pool" && tag.type == xmltag::t_end) { // break tag loop break; } #ifdef FLEXT_DEBUG else { post("pool - unknown XML tag '%s'",tag.tag.c_str()); } #endif } return true; } bool pooldir::LdDirXML(istream &is,int depth,bool mkdir) { while(!is.eof()) { xmltag tag; if(!gettag(is,tag)) break; if(tag == "pool") { if(tag.type == xmltag::t_start) { Atoms empty; // must be a separate definition for gcc LdDirXMLRec(is,depth,mkdir,empty); } else post("pool - pool not initialized yet"); } else if(tag == "!DOCTYPE") { // ignore } #ifdef FLEXT_DEBUG else { post("pool - unknown XML tag '%s'",tag.tag.c_str()); } #endif } return true; } static void indent(ostream &s,int cnt) { for(int i = 0; i < cnt; ++i) s << '\t'; } bool pooldir::SvDirXML(ostream &os,int depth,const AtomList &dir,int ind) { int i,lvls = ind?(dir.Count()?1:0):dir.Count(); for(i = 0; i < lvls; ++i) { indent(os,ind+i); os << "" << endl; indent(os,ind+i+1); os << ""; WriteAtom(os,dir[ind+i],true); os << "" << endl; } for(int vi = 0; vi < vsize; ++vi) { for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { indent(os,ind+lvls); os << ""; WriteAtom(os,ix->key,true); os << ""; WriteAtoms(os,*ix->data,true); os << "" << endl; } } if(depth) { int nd = depth > 0?depth-1:-1; for(int di = 0; di < dsize; ++di) { for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) { ix->SvDirXML(os,nd,Atoms(dir).Append(ix->dir),ind+lvls); } } } for(i = lvls-1; i >= 0; --i) { indent(os,ind+i); os << "" << endl; } return true; } unsigned int pooldir::FoldBits(unsigned long h,int bits) { if(!bits) return 0; const int hmax = (1<>i)&hmax; return ret; } int pooldir::Int2Bits(unsigned long n) { int b; for(b = 0; n; ++b) n >>= 1; return b; } pool-master/source/Makefile.am0000755000175000017500000000121712504366625017123 0ustar zmoelnigzmoelnig# # automake template # # shared library to be built lib_LTLIBRARIES = @PACKAGE_NAME@.la @PACKAGE_NAME@_la_SOURCES = pool.h main.cpp pool.cpp data.cpp @PACKAGE_NAME@_la_CXXFLAGS = @EXT_CFLAGS@ $(patsubst %,-I%,@INCLUDEDIRS@) # -module allows to avoid lib prefix for libraries # -shrext sets shared library extension as given by @EXTENSION@ # -avoid-version avoids the creation of symlinks to versions of a shared library @PACKAGE_NAME@_la_LDFLAGS = @EXT_LDFLAGS@ -no-undefined -module -shrext @EXTENSION@ -avoid-version $(patsubst %,-L%,@LIBDIRS@) $(patsubst %,-l%,@libs@) $(patsubst %,-framework %,@FRAMEWORKS@) #@PACKAGE_NAME@_la_LIBADD = @libs@ pool-master/source/data.cpp0000644000175000017500000001126112504366625016501 0ustar zmoelnigzmoelnig/* pool - hierarchical storage object for PD and Max/MSP Copyright (c) 2002-2008 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. $LastChangedRevision: 26 $ $LastChangedDate$ $LastChangedBy$ */ #include "pool.h" #include #include #include #include using namespace std; pooldata::pooldata(const t_symbol *s,int vcnt,int dcnt): sym(s),nxt(NULL),refs(0), root(nullatom,NULL,vcnt,dcnt) { FLEXT_LOG1("new pool %s",sym?flext_base::GetString(sym):""); } pooldata::~pooldata() { FLEXT_LOG1("free pool %s",sym?flext_base::GetString(sym):""); } const t_atom pooldata::nullatom = { A_NULL }; int pooldata::GetAll(const AtomList &d,t_atom *&keys,Atoms *&lst) { pooldir *pd = root.GetDir(d); if(pd) return pd->GetAll(keys,lst); else { keys = NULL; lst = NULL; return 0; } } int pooldata::PrintAll(const AtomList &d) { char tmp[1024]; d.Print(tmp,sizeof tmp); pooldir *pd = root.GetDir(d); strcat(tmp," , "); int cnt = pd?pd->PrintAll(tmp,sizeof tmp):0; if(!cnt) post(tmp); return cnt; } int pooldata::GetSub(const AtomList &d,const t_atom **&dirs) { pooldir *pd = root.GetDir(d); if(pd) return pd->GetSub(dirs); else { dirs = NULL; return 0; } } bool pooldata::Paste(const AtomList &d,const pooldir *clip,int depth,bool repl,bool mkdir) { pooldir *pd = root.GetDir(d); return pd && pd->Paste(clip,depth,repl,mkdir); } pooldir *pooldata::Copy(const AtomList &d,const t_atom &key,bool cut) { pooldir *pd = root.GetDir(d); if(pd) { AtomList *val = pd->GetVal(key,cut); if(val) { pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize()); ret->SetVal(key,val); return ret; } else return NULL; } else return NULL; } pooldir *pooldata::CopyAll(const AtomList &d,int depth,bool cut) { pooldir *pd = root.GetDir(d); if(pd) { // What sizes should we choose here? pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize()); if(pd->Copy(ret,depth,cut)) return ret; else { delete ret; return NULL; } } else return NULL; } static const char *CnvFlnm(char *dst,const char *src,int sz) { #if FLEXT_SYS == FLEXT_SYS_PD && FLEXT_OS == FLEXT_OS_WIN int i,cnt = strlen(src); if(cnt >= sz-1) return NULL; for(i = 0; i < cnt; ++i) dst[i] = src[i] != '/'?src[i]:'\\'; dst[i] = 0; return dst; #else return src; #endif } bool pooldata::LdDir(const AtomList &d,const char *flnm,int depth,bool mkdir) { pooldir *pd = root.GetDir(d); if(pd) { char tmp[1024]; // CnvFlnm checks for size of string buffer const char *t = CnvFlnm(tmp,flnm,sizeof tmp); if(t) { ifstream file(t); return file.good() && pd->LdDir(file,depth,mkdir); } else return false; } else return false; } bool pooldata::SvDir(const AtomList &d,const char *flnm,int depth,bool absdir) { pooldir *pd = root.GetDir(d); if(pd) { char tmp[1024]; // CnvFlnm checks for size of string buffer const char *t = CnvFlnm(tmp,flnm,sizeof tmp); if(t) { ofstream file(t); Atoms tmp; if(absdir) tmp = d; return file.good() && pd->SvDir(file,depth,tmp); } else return false; } else return false; } bool pooldata::LdDirXML(const AtomList &d,const char *flnm,int depth,bool mkdir) { pooldir *pd = root.GetDir(d); if(pd) { char tmp[1024]; // CnvFlnm checks for size of string buffer const char *t = CnvFlnm(tmp,flnm,sizeof tmp); if(t) { ifstream file(t); bool ret = file.good() != 0; if(ret) { file.getline(tmp,sizeof tmp); ret = !strncmp(tmp,"LdDirXML(file,depth,mkdir); return ret; } } return false; } bool pooldata::SvDirXML(const AtomList &d,const char *flnm,int depth,bool absdir) { pooldir *pd = root.GetDir(d); if(pd) { char tmp[1024]; // CnvFlnm checks for size of string buffer const char *t = CnvFlnm(tmp,flnm,sizeof tmp); if(t) { ofstream file(t); Atoms tmp; if(absdir) tmp = d; if(file.good()) { file << "" << endl; file << "" << endl; file << "" << endl; bool ret = pd->SvDirXML(file,depth,tmp); file << "" << endl; return ret; } } } return false; } pool-master/pool-help.pd0000644000175000017500000002443512504366625016017 0ustar zmoelnigzmoelnig#N canvas 24 27 968 789 12; #X msg 296 105 set 1 2 3; #X obj 238 631 print K; #X msg 607 211 getall; #X msg 296 134 set A k g; #X obj 189 660 print V; #X obj 287 605 print D; #X msg 296 164 set A l m; #X msg 297 195 set 2 34; #X msg 427 297 clr A; #X msg 429 105 get A; #X msg 429 130 get 2; #X msg 31 132 echodir \$1; #X obj 31 111 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 31 213 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 31 234 absdir \$1; #X text 426 277 clear value; #X text 425 83 get value; #X text 360 605 directory (abs or rel to current); #X text 264 661 data value; #X text 310 631 data key; #X msg 32 314 pool pool1; #X msg 33 343 pool; #X text 77 343 set to private; #X msg 33 405 reset; #X text 32 384 clear all pool data; #X msg 608 111 clrall; #X text 599 89 clear all values in dir; #X text 607 190 get all values in dir; #X text 175 500 pool name can be given as argument; #X text 598 136 clear all values and dirs; #X msg 606 158 clrrec; #X msg 605 258 getrec; #X text 605 236 get all values in dir and subdirs; #X text 670 289 bang at EOL; #X text 673 208 bang at EOL; #X text 670 257 depth may be given; #X text 34 291 set pool name; #X text 30 89 at each command; #X text 30 73 echo current dir; #X text 295 82 set values; #X text 26 194 (default on); #X text 18 178 report absolute dirs; #X msg 34 452 help; #X text 77 453 get some info; #X text 670 274 default=-1 (= infinite); #X msg 609 340 cntall; #X text 675 338 count all values in dir; #X msg 609 366 cntrec; #X text 677 364 ... and subdirs; #X text 673 378 (depth may be given); #N canvas 472 45 444 655 dirs 0; #X msg 111 40 mkdir fld1; #X msg 113 135 chdir; #X msg 109 331 updir; #X msg 110 468 getsub -1; #X text 112 20 make absolute dir; #X text 111 64 make relative dir; #X msg 112 85 mksub fld2; #X text 111 117 change to absolute dir; #X msg 112 178 chsub fld2; #X text 110 159 change to relative dir; #X text 105 312 change to upper dir; #X text 106 364 remove absolute dir; #X msg 107 383 rmdir fld1; #X msg 109 422 rmsub fld2; #X text 108 403 remove relative dir; #X text 108 450 get subdirs; #X text 250 494 -1 ... infinite; #X text 166 327 depth may be given; #X text 167 343 default=1; #X text 208 463 depth may be given; #X text 206 479 default=1; #X text 107 491 count subdirs; #X msg 110 512 cntsub -1; #X msg 110 572 getdir; #X text 109 552 get current dir; #X text 175 572 always absolute; #X obj 13 252 s \$0-pool; #X msg 111 231 mkchdir fld1; #X text 112 211 make and change to absolute dir; #X msg 109 276 mkchsub fld2; #X text 110 256 make and change to relative dir; #X connect 0 0 26 0; #X connect 1 0 26 0; #X connect 2 0 26 0; #X connect 3 0 26 0; #X connect 6 0 26 0; #X connect 8 0 26 0; #X connect 12 0 26 0; #X connect 13 0 26 0; #X connect 22 0 26 0; #X connect 23 0 26 0; #X connect 27 0 26 0; #X connect 29 0 26 0; #X restore 715 490 pd dirs; #X text 714 469 directory operations; #N canvas 0 22 845 610 file 0; #X text 117 207 save dir and subdirs; #X text 117 165 save data in current dir; #X text 117 253 load data into current dir; #X text 115 300 load data into current dir and below; #X text 132 340 depth (default -1) and; #X text 134 356 mkdir flag (default 1) can be given; #X text 117 37 save all; #X text 117 81 load all (add to existing data); #X text 22 12 file operations; #X obj 22 188 s \$0-pool; #X text 473 209 save dir and subdirs; #X text 473 167 save data in current dir; #X text 473 255 load data into current dir; #X text 471 302 load data into current dir and below; #X text 488 342 depth (default -1) and; #X text 490 358 mkdir flag (default 1) can be given; #X text 473 39 save all; #X text 473 83 load all (add to existing data); #X obj 378 190 s \$0-pool; #X text 444 12 XML format; #X msg 120 54 save pool.dat; #X msg 118 100 load pool.dat; #X msg 117 184 svdir pool.dat; #X msg 117 226 svrec pool.dat; #X msg 116 272 lddir pool.dat; #X msg 116 319 ldrec pool.dat; #X msg 476 56 savex pool.xml; #X msg 474 102 loadx pool.xml; #X msg 473 186 svxdir pool.xml; #X msg 473 228 svxrec pool.xml; #X msg 472 274 ldxdir pool.xml; #X msg 472 321 ldxrec pool.xml; #X text 26 398 If the file name is given without a path specification the folder containing the current patcher will be used.; #X text 27 451 The attribute outlet reports if file saving/loading has been successful \, by outputting the message tag and a boolean flag.; #X text 29 517 Please note: the absdir flag is also used for paths written into the files. With absdir=1 absolute paths are written \, absdir=0 means relative paths.; #X connect 20 0 9 0; #X connect 21 0 9 0; #X connect 22 0 9 0; #X connect 23 0 9 0; #X connect 24 0 9 0; #X connect 25 0 9 0; #X connect 26 0 18 0; #X connect 27 0 18 0; #X connect 28 0 18 0; #X connect 29 0 18 0; #X connect 30 0 18 0; #X connect 31 0 18 0; #X restore 715 600 pd file; #X text 713 577 file operations; #X text 713 634 clipboard operations; #N canvas 0 22 545 593 clip 0; #X text 97 56 copy value associated to key into clipboard; #X msg 100 77 copy A; #X msg 98 119 cut B; #X text 96 101 cut value associated to key into clipboard; #X msg 96 401 paste; #X msg 98 179 copyall; #X text 95 158 copy all values in current dir into clipboard; #X msg 97 221 cutall; #X text 95 201 cut all values in current dir into clipboard; #X text 94 263 copy all values in current dir into clipboard; #X text 94 306 cut all values in current dir into clipboard; #X msg 97 284 copyrec; #X text 194 285 depth may be given (default=-1); #X text 193 326 depth may be given (default=-1); #X msg 96 326 cutrec 1; #X text 194 345 1..only with first level subdirs; #X text 96 379 paste clipboard contents into current directory; #X text 167 397 depth (default -1) and; #X text 169 413 mkdir flag (default 1) can be given; #X text 183 448 depth (default -1) and; #X text 185 466 mkdir flag (default 1) can be given; #X msg 95 453 pasteadd; #X text 95 431 paste but don't replace; #X msg 94 521 clrclip; #X text 171 520 clear clipboard (free memory); #X text 22 12 clipboard operations (this is an internal clipboard...) ; #X obj 4 193 s \$0-pool; #X connect 1 0 26 0; #X connect 2 0 26 0; #X connect 4 0 26 0; #X connect 5 0 26 0; #X connect 7 0 26 0; #X connect 11 0 26 0; #X connect 14 0 26 0; #X connect 21 0 26 0; #X connect 23 0 26 0; #X restore 714 655 pd clip; #X text 715 439 more commands:; #X obj 237 444 r \$0-pool; #X text 174 517 data is shared among pool objects with the same name ; #X obj 26 10 cnv 15 850 45 empty empty pool 10 22 0 24 -260818 -1 0 ; #X obj 386 553 print A; #X text 458 552 attributes; #X msg 34 490 getattributes; #X msg 139 132 getechodir; #X msg 130 234 getabsdir; #X msg 141 314 getpool; #X msg 297 345 add 2 14; #X obj 260 478 pool @valcnt 10 @dircnt 5; #X text 330 425 expected value and directory counts; #X text 330 440 can be given for optimal performance; #X msg 429 155 get 3; #X msg 295 222 set 3 -1 1; #X msg 32 518 getmethods; #X text 328 454 (see attributes in properties dialog); #X text 713 687 console printout; #N canvas 0 22 612 291 print 0; #X obj 21 231 s \$0-pool; #X msg 109 80 printall; #X msg 109 132 printrec; #X text 110 60 print all values in dir; #X text 109 112 print values in dir and subdirs; #X text 190 133 (depth may be given); #X text 22 12 print-to-console operations; #X text 201 183 (depth may be given); #X msg 109 181 printroot; #X text 109 161 print values in dir and subdirs (starting from root) ; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 8 0 0 0; #X restore 715 708 pd print; #X text 272 33 http://grrrr.org; #X msg 428 225 geti \$1; #X text 426 185 get indexed element; #X obj 427 205 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10 -262144 -1 -1 0 256; #X text 297 323 set but don't replace; #X text 294 256 set value at index; #X msg 295 276 seti 3 Uhu; #X text 424 343 clear value at index; #X msg 425 363 clri 2; #X text 713 523 output ordering; #N canvas 285 155 534 455 ordered 0; #X obj 24 284 s \$0-pool; #X msg 112 191 ogetall; #X msg 110 287 ogetrec; #X text 113 171 get all values in dir (ordered); #X text 109 244 get all values in dir und subdirs; #X text 185 311 bang at EOL; #X text 107 262 (ordered); #X text 109 365 get subdirs (ordered); #X msg 110 389 ogetsub; #X text 385 400 (-1..infinite); #X text 183 189 index \, direction may be given; #X text 28 10 ordered output sorts by key or value ascending or descending ; #X text 28 71 index > 0 sort by atom \, at indexed position; #X text 28 53 index = 0 sort by key (default); #X text 30 100 direction = 0... ascending (default); #X text 30 118 direction != 0... descending; #X text 183 290 depth default to -1 (= infinite); #X text 183 273 depth \, index \, direction may be given; #X text 208 381 depth \, index \, direction may be given; #X text 206 401 depth defaults to 1; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 8 0 0 0; #X restore 714 544 pd ordered; #X text 35 699 NOTE: pool is currently not reentrant! This means that you should not input data as a direct reaction upon output.; #X text 32 733 (this only applies to pools of the same name); #X obj 340 579 print C; #X text 412 579 command; #X obj 294 552 route bang; #X obj 499 666 print ------------; #X text 503 646 separator on bang; #X text 272 13 a hierarchical storage object \, (C)2002-2008 Thomas Grill; #X connect 0 0 67 0; #X connect 2 0 67 0; #X connect 3 0 67 0; #X connect 6 0 67 0; #X connect 7 0 67 0; #X connect 8 0 67 0; #X connect 9 0 67 0; #X connect 10 0 67 0; #X connect 11 0 67 0; #X connect 12 0 11 0; #X connect 13 0 14 0; #X connect 14 0 67 0; #X connect 20 0 67 0; #X connect 21 0 67 0; #X connect 23 0 67 0; #X connect 25 0 67 0; #X connect 30 0 67 0; #X connect 31 0 67 0; #X connect 42 0 67 0; #X connect 45 0 67 0; #X connect 47 0 67 0; #X connect 57 0 67 0; #X connect 62 0 67 0; #X connect 63 0 67 0; #X connect 64 0 67 0; #X connect 65 0 67 0; #X connect 66 0 67 0; #X connect 67 0 4 0; #X connect 67 1 1 0; #X connect 67 2 5 0; #X connect 67 3 91 0; #X connect 67 4 60 0; #X connect 70 0 67 0; #X connect 71 0 67 0; #X connect 72 0 67 0; #X connect 77 0 67 0; #X connect 79 0 77 0; #X connect 82 0 67 0; #X connect 84 0 67 0; #X connect 91 0 92 0; #X connect 91 1 89 0; pool-master/bootstrap.sh0000755000175000017500000000060012504366625016133 0ustar zmoelnigzmoelnig#! /bin/sh ( ( ( test -x "$(which libtoolize)" && libtoolize --force ) || ( # MacOS has no libtoolize... use glibtoolize instead test -x "$(which glibtoolize)" && glibtoolize --force ) ) && aclocal && automake --foreign --add-missing && autoconf ) || ( echo Bootstrapping failed false ) pool-master/gpl.txt0000644000175000017500000004313112504366625015110 0ustar zmoelnigzmoelnig GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pool-master/pool.mcp0000755000175000017500000061277412504366625015261 0ustar zmoelnigzmoelnigcool(T|CodeWarrior Project   %&' !"#()*+,-.U\Y^_]VZX`abcdefghijklmnop[qTWrstuvwxz~{}y|}~|0749:8153;<=>?@ABCDEFGHIJK6L/2MNOPQRSH !"#$%G&I'()JKLM*+,N-./O0123465789:;<=?>@ABCDE  F   $ !"#$%&'()* +,-./013:7<=;486>?@ABCDEFGHIJKLMN9O25PQRSTUV    X_\ab`Y][cdefghijklmnopqrs^tWZuvwxyz{MSL RuntimeAltiVec.LibVector_Example.cpMSL C++.PPC.LibInterfaceLibMathLibMSL C.PPC.LibMSL SIOUX.PPC.LibxAltiVec Example:a.outLib Import PPCBalloon HelpMW C/C++ PPCRezPPCAsmXCOFF Import PPCPEF Import PPCMacOS PPC LinkerSource TreesAccess PathsDebugger RuntimeTarget SettingsFile MappingsBuild ExtrasDebugger TargetCustom KeywordsC/C++ CompilerC/C++ WarningsOutput FlagsPackager PanelPPC CodeGenPPC DisassemblerPPC Global OptimizerPPC LinkerPPC PEFPPC ProjectPPCAsm PanelRez Compiler:AltiVec Exampleflext.outMaxLibMax External:Max External:delay~delay.cppdelay.hMaxAudioLib:delay1~delay-d~First Segmentdelay~:delay-d~flext-d.outidelay-d~idelay~:idelay~:idelay-d~testext~:testext~testext-d~:testext-d~main.cppMSL AppRuntime.LibMSL RuntimePPC.LibMSL StdCRuntimeAltiVec.LibMSL MPWCRuntimeAltiVec.LibMSL ShLibRuntime.LibMSL C.Carbon.LibMSL SIOUX_WASTE.PPC.Libflext_d.outtestext:testextThreadsLibwmangle:wmangleWindowsLibdeljoin:deljoinpool:poolpool.cpppool.hconsole.stubs.cdata.cppMax OS9:max-os9:poolMax OSXflextCycling74MaxLib.stubCycling74 OSXMaxAudioLib.stubCarbonLib:max-osx:poolMax OS9 debugMSL_Runtime_PPC.LibMSL_C_PPC.LibMSL_C++_PPC.LibMSL_C_Carbon.LibProperty ListUnicodeConverterUnicodeUtilitiesCoreLibUnicodeUtilitiesLibTextEncodingConverterTextensionTextCommonmax-osx/pool.mxdlnl7]%DP`8#<P  !"#$ %e&    VX` 3 "#%&()*+,-.3     3") &40,N98+V^PH=;K ]SY[T1-.3M2X5'F67 >*U_Wk/\(Z?DB@CEAbca` OQR !"#$d %G<:jhiIefgLJ.JavaClasses.jarZIP MWZP( Ah JavaClasses.jarZIP MWZP,-( Ah  1( Ah ROOTFILEFILEFILE#FILE GRUPMax OS9FILE(FILE%FILE)FILE*FILE+FILE,FILE.FILE3GRUPMax OSXFILE(FILE0FILE)FILE*FILE+GRUP Mac LibrariesFILE/FILE-FILE1LE1FILE" "#%&()*+,-.3 :` Merge Out????APPLDLGXckidProjWSPCmcvscast?@A'BBC]DrEFGHIJKLMNOPQRS TU$V,W:XBYHZR[^\l]}^_`abcdefgh1iGjRk]lVWT* ?Xl>G`QT* > flcwmax-x.h flcwmax-x.h a.out????APPLX????__startMacOS:Applications (Mac OS 9):audio:Max4/MSP2:MaxMSP 4.1999 :` Merge Out????APPLDLGXckidProjWSPCmcvscast,?L@eABCDEF G(HJIbJwKLMNOP Q 9R [S sT U V W X Y Z [ 1\ G] \^ u_ ` a b c d e f 1g Jh ei {j k l m n o p q 0r Fs ^t su v w x y z { | 2} I~ ^ r 2L_s&5H\p%<Wq3Gc{+A\{0On 7L`x,D^s  5L`y 9Pf!8Ti.BSh~    + @Xp "=Wq  $!A"Y#s$%&'()*+6,P-g./01234536K7a8v9:;<=>?@)A?BZCnDEFGHIJ K +L >M NN bO wP Q R S T U! V!W!1X!FY![Z!t[!\!]!^!_!`!a"b"'c">d"Pe"jf"g"h"i"j"k"l# m#"n#6o#Op#lq#r#s#t#u#v#w#x$y$.z$K{$^|$r}$~$$$$$%%%%9%Q%h%%%%%%&&&7&L&c&w&&&&&&''%'9'R'o''''''((('(<(N(_(t((((((())%)<)N)b)s)))))))* **0*J*d*t******+ +#+8+L+d+{+++++,,,0,J,_,v,,,,,,- -!-8-L-e------. .!.7.L.d.y......//0/D/Y/q/////000$080M 0b 0y 0 0 00011"1=1\1z111122"2?2\2t22 2!2"3#3$$3D%3_&3|'3(3)3*3+4,4!-4<.4W/4t0414243445 55&65=75d8595:5;5<5=6>6?6*@6QA6lB6C6D6E6F6G7H7I7JJ7kK7L7M7N7O8 P@::max-os9:Y@:MSL:@:MacOS Support:@:MAX includes:Z@:MSP includes:Z@:source:Y@ MacOS PPC LinkerMax OS9:MacOS PPC LinkerAPPL`Appl`MMLBLib Import PPCMPLFLib Import PPCMWCD`RSRC`TEXT.arrTEXT.bhBalloon HelpBalloon HelpTEXT.cMW C/C++ PPCC/C++TEXT.c++MW C/C++ PPCC/C++TEXT.ccMW C/C++ PPCC/C++TEXT.cpMW C/C++ PPCC/C++TEXT.cppMW C/C++ PPCC/C++TEXT.expTEXT.hMW C/C++ PPCC/C++TEXT.pchMW C/C++ PPCC/C++TEXT.pch++MW C/C++ PPCC/C++TEXT.rRezRezTEXT.sPPCAsmBalloon HelpXCOFXCOFF Import PPCdocu`rsrc`shlbPEF Import PPCstubPEF Import PPC.docP.oXCOFF Import PPC.ppob`.rsrc`NoneMMPr@Java Linker RSRCTEXT.htmlJavaTEXT.javaMW JavaJavaTEXT.mfJavarsrc.auJAR Importer@.classMW Java.gifJAR Importer@.jarMW Java.zipMW JavaMacOS 68K LinkerAPPL`Appl`MMLBLib Import 68KMPLFLib Import 68KMWCD`OBJ MPW Import 68KPLob`RSRC`TEXT.cMW C/C++ 68KTEXT.c++MW C/C++ 68KTEXT.ccMW C/C++ 68KTEXT.cpMW C/C++ 68KTEXT.cppMW C/C++ 68KTEXT.expTEXT.hMW C/C++ 68KTEXT.pchMW C/C++ 68KTEXT.pch++MW C/C++ 68KTEXT.rRezRezTEXT.segdocu`rsrc`shlbPEF Import 68KstubPEF Import 68K.docP.oMPW Import 68K.ppob`.rsrc`MacOS MergeAPPL`Appl`RSRC`TEXT.rRezRezappe`rsrc`shlbMach-O PPC LinkerAPPL`Appl`MLIBLib Import Mach-OMMLBLib Import Mach-OMPLFLib Import Mach-OMWCD`RSRC`TEXT.cMW C/C++ MachPPCC/C++TEXT.c++MW C/C++ MachPPCC/C++TEXT.ccMW C/C++ MachPPCC/C++TEXT.cpMW C/C++ MachPPCC/C++TEXT.cppMW C/C++ MachPPCC/C++TEXT.expTEXT.hMW C/C++ MachPPCC/C++TEXT.pchMW C/C++ MachPPCC/C++TEXT.pch++MW C/C++ MachPPCC/C++TEXT.rRezRezdocu`rsrc`.docPWin32 x86 LinkerTEXT.cMW C/C++ x86C/C++TEXT.c++MW C/C++ x86C/C++TEXT.ccMW C/C++ x86C/C++TEXT.cpMW C/C++ x86C/C++TEXT.cppMW C/C++ x86C/C++TEXT.defTEXT.hMW C/C++ x86C/C++TEXT.h++MW C/C++ x86C/C++TEXT.hppMW C/C++ x86C/C++TEXT.ordTEXT.pchMW C/C++ x86C/C++TEXT.pch++MW C/C++ x86C/C++TEXT.rcMW WinRCBalloon HelpiLIBLib Import x86iOBJObj Import x86.aLib Import x86.docP.libLib Import x86.oObj Import x86.objObj Import x86.resWinRes ImportMacOS X PPC Linker-APPL`Appl`MDYLMachO ImporterC/C++MLIBMachO ImporterC/C++MMLBMachO ImporterC/C++MPLFMachO ImporterC/C++MWCD`RSRC`TEXT.arrTEXT.axpTEXT.cMW C/C++ PPC Mac OS XC/C++TEXT.c++MW C/C++ PPC Mac OS XC/C++TEXT.ccMW C/C++ PPC Mac OS XC/C++TEXT.cpMW C/C++ PPC Mac OS XC/C++TEXT.cppMW C/C++ PPC Mac OS XC/C++TEXT.expTEXT.hMW C/C++ PPC Mac OS XC/C++TEXT.h++MW C/C++ PPC Mac OS XC/C++TEXT.hppMW C/C++ PPC Mac OS XC/C++TEXT.lcfTEXT.mMW C/C++ PPC Mac OS XC/C++TEXT.mmMW C/C++ PPC Mac OS XC/C++TEXT.pchMW C/C++ PPC Mac OS XC/C++TEXT.pch++MW C/C++ PPC Mac OS XC/C++TEXT.pchmMW C/C++ PPC Mac OS XC/C++TEXT.pchmmMW C/C++ PPC Mac OS XC/C++TEXT.plcProperty List CompilerProperty ListTEXT.plocProperty List CompilerProperty ListTEXT.rRezRezTEXT.wkedocu`rsrc`.aMachO ImporterC/C++.docP.dylibMachO ImporterC/C++.gifCopy To PackageP.icnsCopy To PackageP.jpgCopy To PackageP.libMachO ImporterC/C++.nibCopy To PackageP.plistCopy To Package.ppob`.rsrc`.stringsCopy To Package.tiffCopy To PackagePtorNSLFreeTypedDataPtrOSAExecutepQDSaveRegionBitsDisposeHRURLToFSSpecUPPCreateCheckGroupBoxControlGetDataBrowserListViewHeaderBtnHeight-SetPortTextSizeGetHardDiskTimeout2PMSessionDefaultPageFormatGetMenuTitleIconNavTranslateFileDisposeControlUserPaneActivateUPPSPMSessionPrintDialogInit^InvokeSpeechPhonemeUPPNavDialogDisposeInstallXTimeTaskGetEventKindtFMDisposeFontIteratorSetMenuTitleIconFInvokeQDTxMeasUPP:ICSetCurrentProfilepTSMSetInlineInputRegion%GetrNamMacHeaders.cMacOS_Carbon_C++_Macros.hFSD MacOS:Applications (Mac OS 9):audio:Max4/MSP2:Max/MSP 4.0.5mainolAsync< ~P U1cP'CODE' 'DATA' 'PICT'@ noname.exe?R S#U(()[*]+^-c/a0d1T0E#U$(    @::max-osx:Y@:MSL:@:MacOS Support:@:msp-includes:\@:max-includes:\@:source:Y@MacOS:Applications (Mac OS 9):audio:Max4/MSP2:MaxMSP 4.1999 MacOS PPC LinkerachOLibMax OSX:MacOS PPC LinkerAPPL`Appl`MMLBLib Import PPCMPLFLib Import PPCMWCD`RSRC`TEXT.arrTEXT.bhBalloon HelpBalloon HelpTEXT.cMW C/C++ PPCC/C++TEXT.c++MW C/C++ PPCC/C++TEXT.ccMW C/C++ PPCC/C++TEXT.cpMW C/C++ PPCC/C++TEXT.cppMW C/C++ PPCC/C++TEXT.expTEXT.hMW C/C++ PPCC/C++TEXT.pchMW C/C++ PPCC/C++TEXT.pch++MW C/C++ PPCC/C++TEXT.rRezRezTEXT.sPPCAsmBalloon HelpXCOFXCOFF Import PPCdocu`rsrc`shlbPEF Import PPCstubPEF Import PPC.docP.oXCOFF Import PPC.ppob`.rsrc`NoneMMPr@Java Linker RSRCTEXT.htmlJavaTEXT.javaMW JavaJavaTEXT.mfJavarsrc.auJAR Importer@.classMW Java.gifJAR Importer@.jarMW Java.zipMW JavaMacOS 68K LinkerAPPL`Appl`MMLBLib Import 68KMPLFLib Import 68KMWCD`OBJ MPW Import 68KPLob`RSRC`TEXT.cMW C/C++ 68KTEXT.c++MW C/C++ 68KTEXT.ccMW C/C++ 68KTEXT.cpMW C/C++ 68KTEXT.cppMW C/C++ 68KTEXT.expTEXT.hMW C/C++ 68KTEXT.pchMW C/C++ 68KTEXT.pch++MW C/C++ 68KTEXT.rRezRezTEXT.segdocu`rsrc`shlbPEF Import 68KstubPEF Import 68K.docP.oMPW Import 68K.ppob`.rsrc`MacOS MergeAPPL`Appl`RSRC`TEXT.rRezRezappe`rsrc`shlbMach-O PPC LinkerAPPL`Appl`MLIBLib Import Mach-OMMLBLib Import Mach-OMPLFLib Import Mach-OMWCD`RSRC`TEXT.cMW C/C++ MachPPCC/C++TEXT.c++MW C/C++ MachPPCC/C++TEXT.ccMW C/C++ MachPPCC/C++TEXT.cpMW C/C++ MachPPCC/C++TEXT.cppMW C/C++ MachPPCC/C++TEXT.expTEXT.hMW C/C++ MachPPCC/C++TEXT.pchMW C/C++ MachPPCC/C++TEXT.pch++MW C/C++ MachPPCC/C++TEXT.rRezRezdocu`rsrc`.docPWin32 x86 LinkerTEXT.cMW C/C++ x86C/C++TEXT.c++MW C/C++ x86C/C++TEXT.ccMW C/C++ x86C/C++TEXT.cpMW C/C++ x86C/C++TEXT.cppMW C/C++ x86C/C++TEXT.defTEXT.hMW C/C++ x86C/C++TEXT.h++MW C/C++ x86C/C++TEXT.hppMW C/C++ x86C/C++TEXT.ordTEXT.pchMW C/C++ x86C/C++TEXT.pch++MW C/C++ x86C/C++TEXT.rcMW WinRCBalloon HelpiLIBLib Import x86iOBJObj Import x86.aLib Import x86.docP.libLib Import x86.oObj Import x86.objObj Import x86.resWinRes ImportMacOS X PPC Linker-APPL`Appl`MDYLMachO ImporterC/C++MLIBMachO ImporterC/C++MMLBMachO ImporterC/C++MPLFMachO ImporterC/C++MWCD`RSRC`TEXT.arrTEXT.axpTEXT.cMW C/C++ PPC Mac OS XC/C++TEXT.c++MW C/C++ PPC Mac OS XC/C++TEXT.ccMW C/C++ PPC Mac OS XC/C++TEXT.cpMW C/C++ PPC Mac OS XC/C++TEXT.cppMW C/C++ PPC Mac OS XC/C++TEXT.expTEXT.hMW C/C++ PPC Mac OS XC/C++TEXT.h++MW C/C++ PPC Mac OS XC/C++TEXT.hppMW C/C++ PPC Mac OS XC/C++TEXT.lcfTEXT.mMW C/C++ PPC Mac OS XC/C++TEXT.mmMW C/C++ PPC Mac OS XC/C++TEXT.pchMW C/C++ PPC Mac OS XC/C++TEXT.pch++MW C/C++ PPC Mac OS XC/C++TEXT.pchmMW C/C++ PPC Mac OS XC/C++TEXT.pchmmMW C/C++ PPC Mac OS XC/C++TEXT.plcProperty List CompilerProperty ListTEXT.plocProperty List CompilerProperty ListTEXT.rRezRezTEXT.wkedocu`rsrc`.aMachO ImporterC/C++.docP.dylibMachO ImporterC/C++.gifCopy To PackageP.icnsCopy To PackageP.jpgCopy To PackageP.libMachO ImporterC/C++.nibCopy To PackageP.plistCopy To Package.ppob`.rsrc`.stringsCopy To Package.tiffCopy To PackagePachOLibMax OSXMacHeaders.cMacOS_Carbon_C++_Macros.hD MacOS:Applications (Mac OS 9):audio:Max4/MSP2:Max/MSP 4.0.5mainolAsync< ~P U1P'CODE' 'DATA' 'PICT'@ noname.exestartstart?R S"T#U%b&c(()0*)+,-a.f3k2j "#%&()*+,-.@::max-os9:Y@:MSL:@:MacOS Support:@:MAX includes:Z@:MSP includes:Z@:source:Y@MacOS:Applications (Mac OS 9):audio:Max4/MSP2:MaxMSP 4.1999 MacOS PPC LinkerMax OS9 debug:MacOS PPC LinkerAPPL`Appl`MMLBLib Import PPCMPLFLib Import PPCMWCD`RSRC`TEXT.arrTEXT.bhBalloon HelpBalloon HelpTEXT.cMW C/C++ PPCC/C++TEXT.c++MW C/C++ PPCC/C++TEXT.ccMW C/C++ PPCC/C++TEXT.cpMW C/C++ PPCC/C++TEXT.cppMW C/C++ PPCC/C++TEXT.expTEXT.hMW C/C++ PPCC/C++TEXT.pchMW C/C++ PPCC/C++TEXT.pch++MW C/C++ PPCC/C++TEXT.rRezRezTEXT.sPPCAsmBalloon HelpXCOFXCOFF Import PPCdocu`rsrc`shlbPEF Import PPCstubPEF Import PPC.docP.oXCOFF Import PPC.ppob`.rsrc`NoneMMPr@Java Linker RSRCTEXT.htmlJavaTEXT.javaMW JavaJavaTEXT.mfJavarsrc.auJAR Importer@.classMW Java.gifJAR Importer@.jarMW Java.zipMW JavaMacOS 68K LinkerAPPL`Appl`MMLBLib Import 68KMPLFLib Import 68KMWCD`OBJ MPW Import 68KPLob`RSRC`TEXT.cMW C/C++ 68KTEXT.c++MW C/C++ 68KTEXT.ccMW C/C++ 68KTEXT.cpMW C/C++ 68KTEXT.cppMW C/C++ 68KTEXT.expTEXT.hMW C/C++ 68KTEXT.pchMW C/C++ 68KTEXT.pch++MW C/C++ 68KTEXT.rRezRezTEXT.segdocu`rsrc`shlbPEF Import 68KstubPEF Import 68K.docP.oMPW Import 68K.ppob`.rsrc`MacOS MergeAPPL`Appl`RSRC`TEXT.rRezRezappe`rsrc`shlbMach-O PPC LinkerAPPL`Appl`MLIBLib Import Mach-OMMLBLib Import Mach-OMPLFLib Import Mach-OMWCD`RSRC`TEXT.cMW C/C++ MachPPCC/C++TEXT.c++MW C/C++ MachPPCC/C++TEXT.ccMW C/C++ MachPPCC/C++TEXT.cpMW C/C++ MachPPCC/C++TEXT.cppMW C/C++ MachPPCC/C++TEXT.expTEXT.hMW C/C++ MachPPCC/C++TEXT.pchMW C/C++ MachPPCC/C++TEXT.pch++MW C/C++ MachPPCC/C++TEXT.rRezRezdocu`rsrc`.docPWin32 x86 LinkerTEXT.cMW C/C++ x86C/C++TEXT.c++MW C/C++ x86C/C++TEXT.ccMW C/C++ x86C/C++TEXT.cpMW C/C++ x86C/C++TEXT.cppMW C/C++ x86C/C++TEXT.defTEXT.hMW C/C++ x86C/C++TEXT.h++MW C/C++ x86C/C++TEXT.hppMW C/C++ x86C/C++TEXT.ordTEXT.pchMW C/C++ x86C/C++TEXT.pch++MW C/C++ x86C/C++TEXT.rcMW WinRCBalloon HelpiLIBLib Import x86iOBJObj Import x86.aLib Import x86.docP.libLib Import x86.oObj Import x86.objObj Import x86.resWinRes ImportMacOS X PPC Linker-APPL`Appl`MDYLMachO ImporterC/C++MLIBMachO ImporterC/C++MMLBMachO ImporterC/C++MPLFMachO ImporterC/C++MWCD`RSRC`TEXT.arrTEXT.axpTEXT.cMW C/C++ PPC Mac OS XC/C++TEXT.c++MW C/C++ PPC Mac OS XC/C++TEXT.ccMW C/C++ PPC Mac OS XC/C++TEXT.cpMW C/C++ PPC Mac OS XC/C++TEXT.cppMW C/C++ PPC Mac OS XC/C++TEXT.expTEXT.hMW C/C++ PPC Mac OS XC/C++TEXT.h++MW C/C++ PPC Mac OS XC/C++TEXT.hppMW C/C++ PPC Mac OS XC/C++TEXT.lcfTEXT.mMW C/C++ PPC Mac OS XC/C++TEXT.mmMW C/C++ PPC Mac OS XC/C++TEXT.pchMW C/C++ PPC Mac OS XC/C++TEXT.pch++MW C/C++ PPC Mac OS XC/C++TEXT.pchmMW C/C++ PPC Mac OS XC/C++TEXT.pchmmMW C/C++ PPC Mac OS XC/C++TEXT.plcProperty List CompilerProperty ListTEXT.plocProperty List CompilerProperty ListTEXT.rRezRezTEXT.wkedocu`rsrc`.aMachO ImporterC/C++.docP.dylibMachO ImporterC/C++.gifCopy To PackageP.icnsCopy To PackageP.jpgCopy To PackageP.libMachO ImporterC/C++.nibCopy To PackageP.plistCopy To Package.ppob`.rsrc`.stringsCopy To Package.tiffCopy To PackagePMax OS9 debugMacHeaders.cMacOS_Carbon_C++_Macros.hD MacOS:Applications (Mac OS 9):audio:Max4/MSP2:Max/MSP 4.0.5mainolAsync< <=kd Jn04>>4(?<?$>$?d-?L?$-n ?;?t?L; ?.??t.n???n@G ??G n@,l@?l@T:@<@>@|x@d@<xn@=TAE @0E @ C A0AX AAtnAAD~@B8nB8BpSTDLGXckidProjWSPC :` Merge Out????APPLDLGXckidProjWSPCmcvscast~P U1P'CODE' 'DATA' 'PICT'@ noname.exeMain-ClassAuto-GeneratedesMPDeallocateTaskStorageIndexCreatePushButtonControlDisposeHRWasCFURLVisitedUPPACMGetPartialProfileElementHFSCloseIteratorzNewHMControlContentUPPTXNTerminateTextensionNSLStartNeighborhoodLookupENewSoundConverterFillBufferDataUPPGetMenuTypeNHRGoToAnchorCFStringTextToPhonemesKCAddInternetPasswordWithPathDisposeCMProfileAccessUPP"DisposeDrawHookUPP'TECGetAvailableTextEncodingsNewTimerUPPGetEventDispatcherTargetTXNZoomWindowInvokeIconActionUPPTECClearConvstart Executable????MEXE@Executable.rsrc:./Astarta.exe????MEXE@a.rsrc:./SGDispoJqJetNoProxyURLJSGSetVideoBottlenecks/SpriteMediaCountImagesUnsignedFixMulDivVDGetVideoDefaults QTVRGetMouseOverTracking QTSPrefsAddProxySettingMoviesTaskMusicGetInstrumentKnobDescriptionObsoleteQTVREnableHoInfo.plistMusicOfflineDataUPPMediaTrackPropertyAtomChanged_AddMediaSampleReferences64IQTGetFileNameExtension_SGGetChannelBoundsMediaSetNonPrimarySourceDataXQTSStreamBufferDataInfo`GetTrackEditRateMusicGetDrumKnobDescriptionCurveInsertIntoPath:DisposeICMCompletionUPPSGGetChannelDeviceListMediaGetURLLinkCDSequenceInvalidate3MovieExportGetShortFileTypeStringImageCodecGetSettings^MusicGetInstrumentNamesDataHSetDataRefWithAnchorRTPMPIdle,GetMediaTimeScaleSCDef:ltPictFileSettingsgSetDSequenceSrcRectMediaTargetRefConsEqual(InvalidateSpriteWorldInvokeQTVRInterceptUPP MusicStartOfflineBGetCSequenceDataRateParamsNewImageCodecTimeTriggerUPPInvokeImageCodecMPDrawBandUPPNVDDoneQTVideoOutputSetEchoPortQTVRBeginUpdateStreamVDSetInputStandardeGDGetScaleNImageCodecBandCompressImageCodecGetMaxCompressionSizeCGetTrackClipRgnTransformPoints{VDGrabOneFrameAsyncmQTSPrefsFindProxyByTypeERemoveImageDescriptionExtensionGetMediaQuplst,NewUserDataFromHandle|SGSetSettingsQTNewTweendSetTimeBaseMasterClock]QTVRSetAnimationSettingMediaGetMediaInfoGetSoundDescriptionExtensionNAGetControllerSGHandleUpdateEvent/GraphicsExportSetInputFileSCSetTestImagePixMapRemoveM@Main-ClassAuto-Generated0\?x ?n?n?T??@4@x@@`@00@Hn$@<@0@0B@0@ A@nA0ADD Executable????MEXE@Executable.rsrc:./Aa.exe????MEXE@a.rsrc:./  J*   ¼ (œt 0 800 |  n ?(n  Info.plist    $(0(  D T T $T          <t $tn d  L $ n   t L n   tn Q,  Q,n:x  xn,\ \nT<n|d<ndn   nnddn(, D0 nnnplstnn ,\0,|LT\T  plstnn ,\0,|LT\T  @Main-ClassAuto-GeneratedЀp4ЀhЀ1_1q (0 l шnѠ \Ѹ(11mfdr0nVlҰ1 Ҙ18exsi0Pnth"$8vwbyҀ8gsen 8cflc8oldr1tstart Executable????MEXE@Executable.rsrc:./Astarta.exe????MEXE@a.rsrc:./u@Jnunà ,,,L,40nWdInfo.plist|L44V+0+ , <Xnp\΄@,, @28T0:: L2,:< ,T4n4n+@V0V0 Lndplst|nXV|VhPTVD0VD  <no+@?R S"T#U%b&c(()0*)+,-a.f3k2j:<mstrvmstl( mstn mstrmstl{mstn0bpref 0v pref 0 prefi0pref0pref1pref#$Lmtgl(motiPLst%+,,mpsi(msti(msti3zmallmapl3prefI܋&9^prefI':LprefIE( mtslmtplmtps;mtpiKpref $pref Opref z.@pref rFipref Npref udpref d.npref opref 36pref p pref $Dpref "X&pref 38pref '~pref 1"pref ? pref ! pref u-pref .^pref ۗ/vpref 36Fpref ?7T pref :,"pref Npref +lpref BX>pref $ pref 9`pref }9pref } mtsl=mtplBmtpsmtpi0mtlopref CNpref R pref Wpref -].Apref Ջ"pref 4  pref !,pref $pref 6#pref -X@pref :=pref z<pref pref .pref pref 6pref hʮ pref 2pref QF&pref 0$pref lpref X"pref R{ pref ʜz pref  pref JLpref adpref `4pref P B pref | "pref , pref 3 pref Q pref   pref ]/pref 'GNpref z mtsl|mtplmtpsmtpipref %0tFpref BuZpref R 66pref B!l pref "pref #&pref w$*pref d%pref &"pref ' pref HZ(0V pref k):pref =*pref +pref ,pref B- pref ."pref c/(pref .0Fpref 1^pref 29 pref '3xpref V_4pref K(5pref M6pref 7$"pref f8F\pref 9pref ::lpref y;pref <pref M=2pref 6>pref B?(pref |@9"pref "cA\pref hB0pref ]Czlpref vjDpref )$Epref F92pref GRpref Hppref .Ix"pref RJ\pref pKpref k{Llpref @MNpref N:pref ܘOJ2pref JJPpool-master/pool.help0000755000175000017500000001654712504366625015426 0ustar zmoelnigzmoelnigpmaxqv2r#NsvpatcherU1~t#PuoriginP]tvwindowwsetfontxSans Serif$Atyhiddenznewex~c) {s0-ptyzc) {tyz}z) {tyz) }rtv~linecountRtyzG( pcontroltv~Qtyz!! 1t1opentv~RrsvNty1inlet_Ptvwx$@At1commentYZ 1Unfortunately1Jitter1includes1an1example1file1that1is1named1"pool"1and1which1 could1!be1"found11#loaded1$prior1%to1&the1'external1("pool".t1Y/ 1)In1*case1+this11,a1-problem1.for1/you10,11just12rename1&13jitter-examples/other/pool.pat1%14some15other16name...17there118no19harm1:done101;since18151on1?it.t1@popty1Anewobjs0 1Bp1Ctroublest1gX 1Dclear1Evalue1Fat1Gindextv~Qt1U 1Hset1E1F1Gt1Imessage)" 1JgetiRt1If# 1KclriStv~Rt1]$ 1Lkey1Monlytv~Qt1I^ 1H1NBtv~St1[ 1,1Obang11Poutput1.1&1E1Qof1Rundefined1Skeystv~Qt1I0 1Tadd1N1Ytv~Rt1N 1H1E1Ubut1Vdon't1Woverwritetv~Qt1I   1Xget1YAt1I 1X1Zut1 1X1E1[(associated1%1\key)t1I 1X1Nt1IG 1]clr1Yt1I0 1H1ZTUt1I/ 1^setiR1Nt1Il< 1H1Y1_yesRt1IY1 1HQRSt1/P 1D1`pool1adatat1I-  1bresett1H{ 1H1cvalues1d(key11edata)t1I 1fredefine1Etv~Rt1Gd 1D1E1[1%1\tv~Qt1)X 1X1E1F1Gt1IND 1ggetmethodstz 1hprintt1jR 1iordered1jversiont1I64 1kogetrecRt1^R 1i1jt1I6' 1logetallt1Vb 1m....t1IaA 1ngetattributest1M!0 1oprivate?t1I 7 1pgetprivatet1I&2 1qgetabsdirt1= D 1X1`1rnamet1I ( 1sgetpoolt1I&U7 1tgetechodirt1j7 1uattributest1I 1`t1 1vcut1wall1c11xsubdirst1w 1ycopy1w1c11xt1 1zdepth1{(default=-1)1|may1!1}givent1s 1~paste1U1V1replacet1 1~1clipboard1into1current1dirt1 1D11(free1memory)t1I# 1clrclipt1I- 1pasteaddt1Z 1v1w1c1in11t1I  1~tv~Rt1 1z1{11mkdir1flag1(default11)1|1!1}tv~Qt1I- 1cutrecQt1Iv, 1copyrect1IY! 1cutallt1F 1y1w1c111t1IE( 1copyallt1(k 1v1E1%1t1I& 1v1Ztv~Rt1  1y1E1[1%1\1%1tv~Qt1I ' 1y1Yt1Q| 1(optional1z1argument)t1Cl 1count1xt1IF- 1cntsubRt1dTl 1default=-1...infinitet1I6F- 1cntrecRtv~Rt1[*_ 1O1F1right1outlet1signals1end1Q1listtv~Qt1I6)! 1cntallt1cFl 11z1|1!1}tvwx$@At1 1,1E11,11Q1atomst1 1,1L11one1atomtvwx$At1IZ 1ldrec1data.txtRPtv~Rt1 1z1{111111|1!1}t1{ 1load1a11111xtv~Qt1IH 11t1y 11a111t1IF 1lddir1t17 1Et17 1Lt17 1directorytv~Rt1cq 1save1a1Q1111xtv~Qt1IgK 1svrec1t1Uq 11a1Q11t1IUI 1svdir1tv~Rt1#{ 1z1|1!1}1(default=1)101-1..infinitetv~Qt1I7 1rmsub1fld2t1z 1remove1relative1subdirt1I" 1rmdirt1 q 11absolute1t1I6 1chsub1fld1t1z 1change1%11t1I3 1getsubt1_ 11%1parent1t1I 1updirt1I 1chdirt1I`7 1mksub1t1_i 1make11t1IN7 11t1 O[ 111t1q 11%11t1l 1X1xt1/9P 1X141infot1I7 1helpt1 ;l 1(always1absolute)t1 -l 1X11t1I,# 1getdirt1dl 1t1I6- 1getrecRtv~Rt1\_ 1O1F11111Q1tv~Qt1I7# 1tv~Rt17q 1X1w1c11111xtv~Qt1I6x! 1getallt16h 1X1w1c111t1I6K# 1clrrectv~Rt1ZF[ 1D1w1c11xtv~Qt1I70  1clrallt1>W 1111`t1I=C 11t1-P 11`1%1t1I,F 11t1I 1`t1I= 1`1mypoolt1I&|3 1absdir1$1t1toggle|_Ptv~Rt1dx 1report11directories1(default)tv~Qt1I&E7 1echodir1Št1E_Pt1IN 1Ot1I\ 1Ot1Ij 1t1I@ Prs(7-tvwx$AtzO 11Htz< 1prepend1Ht1_Pt1+_Ptz< 11Htzox< 11HtzD`< 11Htz$K< 11Ht1_Pt1m_Pt1H_Pt1#_Pt1*_Pt1o+_Pt1H-_Pt1%-_Pt1connect_PTPt1XPTPt1PPXPt1QPYPt1_PUPt1YPUPt1_PVPt1ZPVPt1RPZPt1SP[Pt1[PWPt1_PWPt1\P^Pt1^P]Pt1SP_Pt1@t1A@C 1B1Htvwx$`Atz@yB1`1#B1color^tvwx$At1]W=1`1-1,1hierarchical1storage1object101(C)2002-20081Thomas1Grilltvwx$Atv~Rt1-d 1echo111F1every1commandt1 1H1`1r1(data11shared1among1`1objects)tv~Qt12P 1or1H1%1privatetvwx$@Atv~St1 1101L11a1c1|1consist1Q1any1atoms:1symbols101integers11floatstvwx$Atv~Rt1Z)[ 1D1w1c111t1^w_ 1O1F11111Q1tv~Qt1cl 11z1|1!1}tv~Rt1d 1z1|1!1}1tv~Qt17 1ؠtv~Rt1 d 1R1levels1deep11V1create1dirst1y 1r1Q1`1|1!1}1as1argument1(see1`1attribute)tvwx$@Atv~Qt1 1,11path11,11Q1tvwx$At16d 11ctv~St1d 1+11also1used1.1saving1Q11names!1see11functionst1user1panel 1#X1brgb11frgbPPP11borderP11roundedP11shadowP11:t1backgroundtvwx$ At1 1w1&1file-op1messages1are2available2with2appended2x2(like2savex)1.2XML2formatt11(ؠ1111PPP11P11P11P11:tvwx$Atv~Qt1$z 1`2has182 inlets/outlets?11^t1$d 2 CLICK2 HERE11^t12 ubutton"zuPPt11(91111PPP11P11P11P11:t1t11\11̠11PPP11P11P11P11:t1t11)T1111PPP11P11P11P11:t1t11])|T1111PPP11P11P11P11:t1t113)81111PPP11P11P11P11:t1t1 P!Pt1#P$Pty1PPty1PPty1PPty1PPty1PPty1PPty1PPty1PPty1PPty1PPty1PPty1PPty1PPty1!PPty1xPPty1$PPty1{PPty1%PPty1&PPty1yPPty1|PPty18PPty1PPty1~PPt2 fastenTvP99t1PPty1PPt1PPt1PPt1QQt1QPt1RRt1RPt1SSt1SPt1TTty1+PPty1-PPty1/PPty1PPty11PPty13PPty1PPty15PPty1=PPty1?PPty1@PPty1EPPty1APPty1GPPty1IPPty1CPPty1_PPty1[PPty1]PPty1UPPty1PPty1PPty1'PPty1)PPty1KPPty1MPPty1RPPty1TPPty1WPPty1bPPty1dPPty1fPPty1hPPty1iPPty1jPPty1nPPty1oPPt1@pool-master/package.txt0000644000175000017500000000014112504366625015713 0ustar zmoelnigzmoelnigNAME=pool SRCDIR=source PRECOMPILE=pool.h SRCS= main.cpp data.cpp pool.cpp HDRS= pool.h pool-master/license.txt0000644000175000017500000000373612504366625015757 0ustar zmoelnigzmoelnigpool - a hierarchical storage object for PD and MaxMSP Copyright (C) 2002-2003 Thomas Grill 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. In the official pool distribution, the GNU General Public License is in the file gpl.txt --------------------------------------------------------- OTHER COPYRIGHT NOTICES --------------------------------------------------------- This package uses the flext C++ layer - See its license text below: --- flext ---------------------------------------------- flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (C) 2001-2003 Thomas Grill 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. In the official flext distribution, the GNU General Public License is in the file gpl.txt pool-master/configure.ac0000755000175000017500000001273112504366625016060 0ustar zmoelnigzmoelnigthreads_default=no AC_INIT([pool],[0.0.0],[gr@grrrr.org]) ########################################################### AM_INIT_AUTOMAKE AC_SUBST(SYSTEM) AC_SUBST(INCLUDEDIRS) AC_SUBST(LIBDIRS) AC_SUBST(libs) AC_SUBST(FRAMEWORKS) AC_SUBST(EXT_CFLAGS) AC_SUBST(EXT_LDFLAGS) AC_SUBST(EXTENSION) # configure options AC_ARG_ENABLE(system, AC_HELP_STRING(--enable-system,[realtime system [default=pd]]), [SYSTEM=$enableval], [SYSTEM=pd] ) AC_ARG_WITH(sysdir, AC_HELP_STRING(--with-sysdir,[path to pd or max headers]), [sysdir=$withval], AC_MSG_ERROR([path to system headers is required]) ) AC_ARG_WITH(flext-headers, AC_HELP_STRING(--with-flext-headers,[path to the flext headers [default=/usr/local/include/flext]]), [flext_headers=$withval], [flext_headers="/usr/local/include/flext"] ) AC_ARG_WITH(flext-libs, AC_HELP_STRING(--with-flext-libs,[path to the flext libraries [default=/usr/local/lib]]), [flext_libs=$withval], [flext_libs="/usr/local/lib"] ) AC_ARG_ENABLE(dynamic, AC_HELP_STRING(--enable-dynamic,[link dynamically to flext [default=no]]), [dynamic=$enableval], [dynamic=no] ) AC_ARG_ENABLE(debug, AC_HELP_STRING(--enable-debug,[enables debug build [default=no]]), [debug=$enableval], [debug=no] ) AC_ARG_ENABLE(threads, AC_HELP_STRING(--enable-threads,[enables threaded build [default=$threads_default]]), [threads=$enableval], [threads=$threads_default], ) AC_ARG_ENABLE(optimize, AC_HELP_STRING(--enable-optimize,[enables optimized builds for: pentium4, pentium3, G4, G5, etc.]), [optimize=$enableval] ) # if CFLAGS aren't set by the user, set them to an empty string # otherwise AC_PROG_CC sets them to "-O2 -g" test ".$CFLAGS" = "." && CFLAGS=" " test ".$CXXFLAGS" = "." && CXXFLAGS=" " # disable static library building (must be before AC_PROG_LIBTOOL) AC_DISABLE_STATIC # needed to build win32 dlls AC_LIBTOOL_WIN32_DLL # Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_MAKE_SET # Language use for checks AC_LANG(C++) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_STRUCT_TM # Checks for libraries. INCLUDEDIRS="$INCLUDEDIRS $flext_headers" LIBDIRS="$LIBDIRS $flext_libs" if test $SYSTEM == pd; then AC_DEFINE(FLEXT_SYS,2) # check for g_canvas.h in pd folder AC_CHECK_FILE([$sysdir/g_canvas.h],,AC_MSG_ERROR([Cannot find $sysdir/g_canvas.h])) INCLUDEDIRS="$INCLUDEDIRS $sysdir" libs="$libs pd" if test $(uname -s) == Linux; then EXTENSION=.pd_linux elif test $(uname -s) == Darwin; then EXT_LDFLAGS="-flat_namespace -undefined suppress" EXTENSION=.pd_darwin elif ( test $(uname -s) == CYGWIN_NT-5.0 ) || ( test $(uname -s) == CYGWIN_NT-5.1 ) || ( test $(uname -s) == MINGW32_NT-5.1 ) ; then EXTENSION=.dll AC_DEFINE(NT) fi elif test $SYSTEM == max; then AC_DEFINE(FLEXT_SYS,1) # check for MaxAPI.h in pd folder AC_CHECK_FILE([$sysdir/max-includes/MaxAPI.h],,AC_MSG_ERROR([Cannot find $sysdir/max-includes/MaxAPI.h])) AC_CHECK_FILE([$sysdir/max-includes/MaxAudioAPI.h],,AC_MSG_ERROR([Cannot find $sysdir/max-includes/MaxAudioAPI.h])) INCLUDEDIRS="$INCLUDEDIRS $sysdir/max-includes $sysdir/msp-includes" else AC_MSG_ERROR([system must be pd or max]) fi if test ".$dynamic" == ".yes"; then AC_DEFINE(FLEXT_SHARED) LIBNAME=flext-${SYSTEM} if test ".$debug" == ".yes"; then LIBNAME=${LIBNAME}_d fi else LIBNAME=flext-${SYSTEM}_ if test ".$threaded" == ".yes"; then AC_DEFINE(FLEXT_THREADS) LIBNAME=${LIBNAME}t else LIBNAME=${LIBNAME}s fi if test ".$debug" == ".yes"; then LIBNAME=${LIBNAME}d fi fi libs="$libs $LIBNAME" # Checks are complicated because flext references symbols from pd or Max #AC_CHECK_LIB([$LIBNAME], # buf_class, # check for variable "buf_class"" # true, # AC_MSG_ERROR([cannot find flext library $flext_libs/$LIBNAME]) #) # test for existence of library file AC_MSG_CHECKING([for $flext_libs/lib$LIBNAME.*]) if test ".$(ls $flext_libs/lib$LIBNAME.*)" == "."; then AC_MSG_ERROR([cannot find flext library $flext_libs/$LIBNAME]) else AC_MSG_RESULT(yes) fi # we ought to check flext header files: #AC_CHECK_HEADERS([$flext_headers/flext.h], # but we rather check for pure existence since we are dependent on the pd/Max/pthreads etc. headers AC_CHECK_FILE([$flext_headers/flext.h], , AC_MSG_ERROR([cannot find $flext_headers/flext.h]) ) if test $(uname -s) == Linux; then true elif test $(uname -s) == Darwin; then FRAMEWORKS="$FRAMEWORKS ApplicationServices vecLib" elif ( test $(uname -s) == CYGWIN_NT-5.0 ) || ( test $(uname -s) == CYGWIN_NT-5.1 ) || ( test $(uname -s) == MINGW32_NT-5.1 ) ; then EXT_CFLAGS="$EXT_CFLAGS -mms-bitfields -mno-cygwin" EXT_LDFLAGS="$EXT_LDFLAGS -mno-cygwin" fi # set compilation flags if test ".$debug" == ".yes"; then AC_DEFINE(FLEXT_DEBUG) EXT_CFLAGS="$EXT_CFLAGS -g" else EXT_CFLAGS="$EXT_CFLAGS -O2" fi if test ".$optimize" == ".yes"; then OPT_FLAGS="$OPT_FLAGS -mtune=$optimize" case $optimize in pentium | pentium2 | athlon | pentium-mmx) EXT_CFLAGS="$EXT_CFLAGS -march=$optimize";; pentium3 | pentium3m | pentium4 | pentium4m | pentium-m | prescott | nocona | athlon-xp | athlon-mp | athlon64 | opteron) EXT_CFLAGS="$EXT_CFLAGS -march=$optimize -mfpmath=sse"; AC_DEFINE(FLEXT_USE_SIMD);; G3) EXT_CFLAGS="$EXT_CFLAGS -mcpu=$optimize";; G5 | G4) EXT_CFLAGS="$EXT_CFLAGS -mcpu=$optimize -faltivec"; AC_DEFINE(FLEXT_USE_SIMD);; *) ;; esac fi ########################################################### AC_OUTPUT([ Makefile source/Makefile ])