aboutsummaryrefslogtreecommitdiff
path: root/externals/grill
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2007-01-20 14:27:39 +0000
committerThomas Grill <xovo@users.sourceforge.net>2007-01-20 14:27:39 +0000
commit968dba3204a1420d4ffc2a775392cccbc0d1932b (patch)
tree71acfe2c36850e2d79845c15d98931f63f21e68c /externals/grill
parent6efe6563a57bc3f946deaecff67653f9d21ea99d (diff)
implemented output sorting (ogetall, ogetrec, ogetsub), see bug #154
Fixed bug #148. added success/error reporting for file operations implemented UTF-8 conversion for OSX Additionally XML files are now encoded with UTF-8. changed obviously buggy pool name registering some assertions sorting fixes and optimizations svn path=/trunk/; revision=7371
Diffstat (limited to 'externals/grill')
-rw-r--r--externals/grill/pool/pool-help.pd597
-rw-r--r--externals/grill/pool/readme.txt3
-rw-r--r--externals/grill/pool/source/data.cpp2
-rw-r--r--externals/grill/pool/source/main.cpp376
-rw-r--r--externals/grill/pool/source/pool.cpp282
5 files changed, 816 insertions, 444 deletions
diff --git a/externals/grill/pool/pool-help.pd b/externals/grill/pool/pool-help.pd
index 2b4a35c3..83286db3 100644
--- a/externals/grill/pool/pool-help.pd
+++ b/externals/grill/pool/pool-help.pd
@@ -1,281 +1,316 @@
-#N canvas 29 115 955 725 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 obj 336 576 print C;
-#X text 408 576 command;
-#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 424 635 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 716 496 pd dirs;
-#X text 713 470 directory operations;
-#N canvas 0 22 837 529 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 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 717 551 pd file;
-#X text 715 528 file operations;
-#X text 715 585 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 716 606 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 715 638 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 717 659 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 272 13 a hierarchical storage object \, (C)2002-2006 Thomas
-Grill;
-#X connect 0 0 69 0;
-#X connect 2 0 69 0;
-#X connect 3 0 69 0;
-#X connect 6 0 69 0;
-#X connect 7 0 69 0;
-#X connect 8 0 69 0;
-#X connect 9 0 69 0;
-#X connect 10 0 69 0;
-#X connect 11 0 69 0;
-#X connect 12 0 11 0;
-#X connect 13 0 14 0;
-#X connect 14 0 69 0;
-#X connect 22 0 69 0;
-#X connect 23 0 69 0;
-#X connect 25 0 69 0;
-#X connect 27 0 69 0;
-#X connect 32 0 69 0;
-#X connect 33 0 69 0;
-#X connect 44 0 69 0;
-#X connect 47 0 69 0;
-#X connect 49 0 69 0;
-#X connect 59 0 69 0;
-#X connect 64 0 69 0;
-#X connect 65 0 69 0;
-#X connect 66 0 69 0;
-#X connect 67 0 69 0;
-#X connect 68 0 69 0;
-#X connect 69 0 4 0;
-#X connect 69 1 1 0;
-#X connect 69 2 5 0;
-#X connect 69 3 17 0;
-#X connect 69 4 62 0;
-#X connect 72 0 69 0;
-#X connect 73 0 69 0;
-#X connect 74 0 69 0;
-#X connect 79 0 69 0;
-#X connect 81 0 79 0;
-#X connect 84 0 69 0;
-#X connect 86 0 69 0;
+#N canvas 24 27 960 781 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 440 651 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 841 533 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 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+37 1e+37 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 272 13 a hierarchical storage object \, (C)2002-2006 Thomas
+Grill;
+#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 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 92 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 92 0 93 0;
+#X connect 92 1 90 0;
diff --git a/externals/grill/pool/readme.txt b/externals/grill/pool/readme.txt
index 080125b9..f4905980 100644
--- a/externals/grill/pool/readme.txt
+++ b/externals/grill/pool/readme.txt
@@ -84,6 +84,9 @@ Version history:
- 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)
0.2.1:
- fixed "cntsub"... directories in current directory have been forgotten
diff --git a/externals/grill/pool/source/data.cpp b/externals/grill/pool/source/data.cpp
index 3729738c..decfc436 100644
--- a/externals/grill/pool/source/data.cpp
+++ b/externals/grill/pool/source/data.cpp
@@ -195,7 +195,7 @@ BL pooldata::SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir)
Atoms tmp;
if(absdir) tmp = d;
if(file.good()) {
- file << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl;
+ file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
file << "<!DOCTYPE pool SYSTEM \"http://grrrr.org/ext/pool/pool-0.2.dtd\">" << endl;
file << "<pool>" << endl;
BL ret = pd->SvDirXML(file,depth,tmp);
diff --git a/externals/grill/pool/source/main.cpp b/externals/grill/pool/source/main.cpp
index b8aa4f7d..02d617b7 100644
--- a/externals/grill/pool/source/main.cpp
+++ b/externals/grill/pool/source/main.cpp
@@ -77,7 +77,7 @@ protected:
V m_getall(); // only values
V m_getrec(I argc,const A *argv); // also subdirectories
V m_getsub(I argc,const A *argv); // only subdirectories
- V m_ogetall(); // only values (ordered)
+ V m_ogetall(int argc,const A *argv); // only values (ordered)
V m_ogetrec(I argc,const A *argv); // also subdirectories (ordered)
V m_ogetsub(I argc,const A *argv); // only subdirectories (ordered)
V m_cntall(); // only values
@@ -131,8 +131,8 @@ private:
V set(I argc,const A *argv,BL over);
V getdir(const S *tag);
- I getrec(const S *tag,I level,BL order,get_t how /*= get_norm*/,const AtomList &rdir);
- I getsub(const S *tag,I level,BL order,get_t how /*= get_norm*/,const AtomList &rdir);
+ int getrec(const S *tag,int level,int order,bool rev,get_t how /*= get_norm*/,const AtomList &rdir);
+ int getsub(const S *tag,int level,int order,bool rev,get_t how /*= get_norm*/,const AtomList &rdir);
V paste(const S *tag,I argc,const A *argv,BL repl);
V copy(const S *tag,I argc,const A *argv,BL cut);
@@ -204,7 +204,7 @@ private:
FLEXT_CALLBACK(m_getall)
FLEXT_CALLBACK_V(m_getrec)
FLEXT_CALLBACK_V(m_getsub)
- FLEXT_CALLBACK(m_ogetall)
+ FLEXT_CALLBACK_V(m_ogetall)
FLEXT_CALLBACK_V(m_ogetrec)
FLEXT_CALLBACK_V(m_ogetsub)
FLEXT_CALLBACK(m_cntall)
@@ -637,50 +637,136 @@ V pool::m_geti(I ix)
echodir();
}
-I pool::getrec(const t_symbol *tag,I level,BL order,get_t how,const AtomList &rdir)
+
+// ---- some sorting stuff ----------------------------------
+
+inline bool smaller(const A &a,const A &b,int index) { return a < b; }
+inline void swap(A &a,A &b) { A c = a; a = b; b = c; }
+
+inline bool smaller(const A *a,const A *b,int index) { return *a < *b; }
+inline void swap(A *a,A *b) { A *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 <typename T1,typename T2>
+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 <typename T1,typename T2>
+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 <typename T1,typename T2>
+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);
- I ret = 0;
+ int ret = 0;
switch(how) {
- case get_cnt:
- ret = pl->CntAll(gldir);
- break;
- case get_print:
- ret = pl->PrintAll(gldir);
- break;
- case get_norm: {
- A *k;
- Atoms *r;
- I cnt = pl->GetAll(gldir,k,r);
- if(!k)
- post("%s - %s: error retrieving values",thisName(),GetString(tag));
- else {
- for(I 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;
- }
+ case get_cnt:
+ ret = pl->CntAll(gldir);
+ break;
+ case get_print:
+ ret = pl->PrintAll(gldir);
+ break;
+ case get_norm: {
+ A *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 A **r;
- I cnt = pl->GetSub(gldir,r);
+ int cnt = pl->GetSub(gldir,r);
if(!r)
post("%s - %s: error retrieving directories",thisName(),GetString(tag));
else {
- I lv = level > 0?level-1:-1;
- for(I i = 0; i < cnt; ++i) {
+ 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,how,l);
+ ret += getrec(tag,lv,order,rev,how,l);
}
delete[] r;
}
@@ -692,16 +778,37 @@ I pool::getrec(const t_symbol *tag,I level,BL order,get_t how,const AtomList &rd
V pool::m_getall()
{
AtomList l;
- getrec(thisTag(),0,false,get_norm,l);
+ getrec(thisTag(),0,-1,false,get_norm,l);
ToSysBang(3);
echodir();
}
-V pool::m_ogetall()
+V pool::m_ogetall(I argc,const A *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,true,get_norm,l);
+ getrec(thisTag(),0,index,rev,get_norm,l);
ToSysBang(3);
echodir();
@@ -709,19 +816,20 @@ V pool::m_ogetall()
V pool::m_getrec(I argc,const A *argv)
{
- I 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]);
+ 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);
}
- else
- post("%s - %s: invalid level specification - set to infinite",thisName(),GetString(thisTag()));
+ --argc,++argv;
}
+ if(argc)
+ post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag()));
+
AtomList l;
- getrec(thisTag(),lvls,false,get_norm,l);
+ getrec(thisTag(),lvls,-1,false,get_norm,l);
ToSysBang(3);
echodir();
@@ -730,40 +838,62 @@ V pool::m_getrec(I argc,const A *argv)
V pool::m_ogetrec(I argc,const A *argv)
{
- I 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]);
+ 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);
}
- else
- post("%s - %s: invalid level specification - set to infinite",thisName(),GetString(thisTag()));
+ --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,true,get_norm,l);
+ getrec(thisTag(),lvls,index,rev,get_norm,l);
ToSysBang(3);
echodir();
}
-I pool::getsub(const S *tag,I level,BL order,get_t how,const AtomList &rdir)
+int pool::getsub(const S *tag,int level,int order,bool rev,get_t how,const AtomList &rdir)
{
Atoms gldir(curdir);
gldir.Append(rdir);
- I ret = 0;
+ int ret = 0;
const A **r = NULL;
// CntSub is not used here because it doesn't allow checking for valid directory
- I cnt = pl->GetSub(gldir,r);
+ int cnt = pl->GetSub(gldir,r);
if(!r)
post("%s - %s: error retrieving directories",thisName(),GetString(tag));
else {
- I lv = level > 0?level-1:-1;
- for(I i = 0; i < cnt; ++i) {
+ 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;
@@ -777,7 +907,7 @@ I pool::getsub(const S *tag,I level,BL order,get_t how,const AtomList &rdir)
if(level != 0) {
AtomList l(rdir); l.Append(*r[i]);
- ret += getsub(tag,lv,order,how,l);
+ ret += getsub(tag,lv,order,rev,how,l);
}
}
delete[] r;
@@ -786,42 +916,62 @@ I pool::getsub(const S *tag,I level,BL order,get_t how,const AtomList &rdir)
return ret;
}
-V pool::m_getsub(I argc,const A *argv)
+V pool::m_getsub(int argc,const A *argv)
{
- I lvls = 0;
- if(argc > 0) {
- if(CanbeInt(argv[0])) {
- if(argc > 1)
- post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag()));
- lvls = GetAInt(argv[0]);
+ 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);
}
- else
- post("%s - %s: invalid level specification - set to 0",thisName(),GetString(thisTag()));
+ --argc,++argv;
}
+
+ if(argc)
+ post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag()));
AtomList l;
- getsub(thisTag(),lvls,false,get_norm,l);
+ getsub(thisTag(),lvls,-1,false,get_norm,l);
ToSysBang(3);
echodir();
}
-V pool::m_ogetsub(I argc,const A *argv)
+V pool::m_ogetsub(int argc,const A *argv)
{
- I lvls = 0;
- if(argc > 0) {
- if(CanbeInt(argv[0])) {
- if(argc > 1)
- post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag()));
- lvls = GetAInt(argv[0]);
+ 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);
}
- else
- post("%s - %s: invalid level specification - set to 0",thisName(),GetString(thisTag()));
+ --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,true,get_norm,l);
+ getsub(thisTag(),lvls,index,rev,get_norm,l);
ToSysBang(3);
echodir();
@@ -831,7 +981,7 @@ V pool::m_ogetsub(I argc,const A *argv)
V pool::m_cntall()
{
AtomList l;
- I cnt = getrec(thisTag(),0,false,get_cnt,l);
+ I cnt = getrec(thisTag(),0,-1,false,get_cnt,l);
ToSysSymbol(3,thisTag());
ToSysBang(2);
ToSysBang(1);
@@ -840,21 +990,22 @@ V pool::m_cntall()
echodir();
}
-V pool::m_cntrec(I argc,const A *argv)
+V pool::m_cntrec(int argc,const A *argv)
{
- I 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]);
+ 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);
}
- else
- post("%s - %s: invalid level specification - set to infinite",thisName(),GetString(thisTag()));
+ --argc,++argv;
}
+
+ if(argc)
+ post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag()));
AtomList l;
- I cnt = getrec(thisTag(),lvls,false,get_cnt,l);
+ I cnt = getrec(thisTag(),lvls,-1,false,get_cnt,l);
ToSysSymbol(3,thisTag());
ToSysBang(2);
ToSysBang(1);
@@ -866,19 +1017,20 @@ V pool::m_cntrec(I argc,const A *argv)
V pool::m_cntsub(I argc,const A *argv)
{
- I lvls = 0;
- if(argc > 0) {
- if(CanbeInt(argv[0])) {
- if(argc > 1)
- post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag()));
- lvls = GetAInt(argv[0]);
+ 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);
}
- else
- post("%s - %s: invalid level specification - set to 0",thisName(),GetString(thisTag()));
+ --argc,++argv;
}
+ if(argc)
+ post("%s - %s: superfluous arguments ignored",thisName(),GetString(thisTag()));
+
AtomList l;
- I cnt = getsub(thisTag(),lvls,false,get_cnt,l);
+ I cnt = getsub(thisTag(),lvls,-1,false,get_cnt,l);
ToSysSymbol(3,thisTag());
ToSysBang(2);
ToSysBang(1);
@@ -890,29 +1042,31 @@ V pool::m_cntsub(I argc,const A *argv)
V pool::m_printall()
{
AtomList l;
- I cnt = getrec(thisTag(),0,false,get_print,l);
+ I cnt = getrec(thisTag(),0,-1,false,get_print,l);
post("");
}
V pool::m_printrec(I argc,const A *argv,BL fromroot)
{
const S *tag = thisTag();
- I 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]);
+ 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);
}
- else
- post("%s - %s: invalid level specification - set to infinite",thisName(),GetString(tag));
+ --argc,++argv;
}
+ if(argc)
+ post("%s - %s: superfluous arguments ignored",thisName(),GetString(tag));
+
Atoms svdir(curdir);
if(fromroot) curdir.Clear();
AtomList l;
- I cnt = getrec(tag,lvls,false,get_print,l);
+ I cnt = getrec(tag,lvls,-1,false,get_print,l);
post("");
curdir = svdir;
diff --git a/externals/grill/pool/source/pool.cpp b/externals/grill/pool/source/pool.cpp
index 163cae0c..078fa3d9 100644
--- a/externals/grill/pool/source/pool.cpp
+++ b/externals/grill/pool/source/pool.cpp
@@ -15,9 +15,105 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <stdlib.h>
#include <fstream>
+#if FLEXT_OS == FLEXT_OS_WIN
+#include <windows.h> // for charset conversion functions
+#elif FLEXT_OS == FLEXT_OS_MAC
+#include <Carbon/Carbon.h>
+#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 I compare(I a,I b) { return a == b?0:(a < b?-1:1); }
inline I compare(F a,F b) { return a == b?0:(a < b?-1:1); }
@@ -487,11 +583,12 @@ BL pooldir::Copy(pooldir *p,I depth,BL cut)
return ok;
}
+static bool _isspace(char c) { return c > 0 && isspace(c); }
-static const char *ReadAtom(const char *c,A &a)
+static const char *ReadAtom(const char *c,A &a,bool utf8)
{
- // skip leading whitespace
- while(*c && isspace(*c)) ++c;
+ // skip leading whitespace (NON-ASCII character are < 0)
+ while(*c && _isspace(*c)) ++c;
if(!*c) return NULL;
char tmp[1024];
@@ -518,11 +615,11 @@ static const char *ReadAtom(const char *c,A &a)
else if(*c == '"' && issymbol && !escaped) {
// end of string
++c;
- FLEXT_ASSERT(!*c || isspace(*c));
+ FLEXT_ASSERT(!*c || _isspace(*c));
*m = 0;
break;
}
- else if(!*c || (isspace(*c) && !escaped)) {
+ else if(!*c || (_isspace(*c) && !escaped)) {
*m = 0;
break;
}
@@ -550,69 +647,152 @@ static const char *ReadAtom(const char *c,A &a)
flext::SetFloat(a,fres);
}
// no, it's a symbol
- else
- flext::SetString(a,tmp);
+ 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 false;
+ err = WideCharToMultiByte(CP_ACP,0,wtmp,err,tmp,1024,NULL,FALSE);
+ if(!err) return false;
+ 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 false;
+
+ 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 false;
+#else
+ wchar_t wtmp[1024];
+ size_t len = mbstowcs(wtmp,tmp,1024);
+ if(len < 0) return false;
+ if(!WCStoUTF8(tmp,wtmp,sizeof(tmp))) return false;
+ c = tmp;
+#endif
+ }
+ else
+ c = tmp;
+ flext::SetString(a,c);
+ }
return c;
}
-static BL ParseAtoms(C *tmp,flext::AtomList &l)
+static BL ParseAtoms(C *tmp,flext::AtomList &l,bool utf8)
{
const int MAXATOMS = 1024;
int cnt = 0;
t_atom atoms[MAXATOMS];
for(const char *t = tmp; *t && cnt < MAXATOMS; ++cnt) {
- t = ReadAtom(t,atoms[cnt]);
+ t = ReadAtom(t,atoms[cnt],utf8);
if(!t) break;
}
l(cnt,atoms);
return true;
}
-static BL ParseAtoms(string &s,flext::AtomList &l)
+static BL ParseAtoms(string &s,flext::AtomList &l,bool utf8)
{
- return ParseAtoms((C *)s.c_str(),l);
+ return ParseAtoms((C *)s.c_str(),l,utf8);
}
-static BL ReadAtoms(istream &is,flext::AtomList &l,C del)
+static bool ReadAtoms(istream &is,flext::AtomList &l,C del,bool utf8)
{
- C tmp[1024];
+ char tmp[1024];
is.getline(tmp,sizeof tmp,del);
if(is.eof() || !is.good())
return false;
else
- return ParseAtoms(tmp,l);
+ return ParseAtoms(tmp,l,utf8);
}
-static V WriteAtom(ostream &os,const A &a)
+static bool WriteAtom(ostream &os,const A &a,bool utf8)
{
- switch(a.a_type) {
- case A_FLOAT:
- os << a.a_w.w_float;
- break;
-#if FLEXT_SYS == FLEXT_SYS_MAX
- case A_LONG:
- os << a.a_w.w_long;
- break;
+ 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
- case A_SYMBOL: {
- const char *c = flext::GetString(flext::GetSymbol(a));
+ }
+
os << '"';
for(; *c; ++c) {
- if(isspace(*c) || *c == '\\' || *c == ',' || *c == '"')
+ // escape some special characters
+ if(_isspace(*c) || *c == '\\' || *c == ',' || *c == '"')
os << '\\';
os << *c;
}
os << '"';
- break;
}
- }
+ else
+ FLEXT_ASSERT(false);
+ return true;
}
-static V WriteAtoms(ostream &os,const flext::AtomList &l)
+static void WriteAtoms(ostream &os,const flext::AtomList &l,bool utf8)
{
for(I i = 0; i < l.Count(); ++i) {
- WriteAtom(os,l[i]);
+ WriteAtom(os,l[i],utf8);
if(i < l.Count()-1) os << ' ';
}
}
@@ -622,9 +802,9 @@ BL pooldir::LdDir(istream &is,I depth,BL mkdir)
for(I i = 1; !is.eof(); ++i) {
Atoms d,k,*v = new Atoms;
BL r =
- ReadAtoms(is,d,',') &&
- ReadAtoms(is,k,',') &&
- ReadAtoms(is,*v,'\n');
+ ReadAtoms(is,d,',',false) &&
+ ReadAtoms(is,k,',',false) &&
+ ReadAtoms(is,*v,'\n',false);
if(r) {
if(depth < 0 || d.Count() <= depth) {
@@ -655,18 +835,18 @@ BL pooldir::SvDir(ostream &os,I depth,const AtomList &dir)
I cnt = 0;
for(I vi = 0; vi < vsize; ++vi) {
for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
- WriteAtoms(os,dir);
+ WriteAtoms(os,dir,false);
os << " , ";
- WriteAtom(os,ix->key);
+ WriteAtom(os,ix->key,false);
os << " , ";
- WriteAtoms(os,*ix->data);
+ WriteAtoms(os,*ix->data,false);
os << endl;
++cnt;
}
}
if(!cnt) {
// no key/value pairs present -> force empty directory
- WriteAtoms(os,dir);
+ WriteAtoms(os,dir,false);
os << " , ," << endl;
}
if(depth) {
@@ -706,7 +886,7 @@ static bool gettag(istream &is,xmltag &tag)
for(;;) {
// eat whitespace
- while(isspace(is.peek())) is.get();
+ while(_isspace(is.peek())) is.get();
// no tag begin -> break
if(is.peek() != '<') break;
@@ -753,17 +933,17 @@ static bool gettag(istream &is,xmltag &tag)
char *tb = tmp,*te = t-1,*tf;
- for(; isspace(*tb); ++tb) {}
+ for(; _isspace(*tb); ++tb) {}
if(*tb == '/') {
// slash at the beginning -> end tag
tag.type = xmltag::t_end;
- for(++tb; isspace(*tb); ++tb) {}
+ for(++tb; _isspace(*tb); ++tb) {}
}
else {
- for(; isspace(*te); --te) {}
+ for(; _isspace(*te); --te) {}
if(*te == '/') {
// slash at the end -> empty tag
- for(--te; isspace(*te); --te) {}
+ for(--te; _isspace(*te); --te) {}
tag.type = xmltag::t_empty;
}
else
@@ -772,9 +952,9 @@ static bool gettag(istream &is,xmltag &tag)
}
// copy tag text without slashes
- for(tf = tb; tf <= te && *tf && !isspace(*tf); ++tf) {}
+ for(tf = tb; tf <= te && *tf && !_isspace(*tf); ++tf) {}
tag.tag.assign(tb,tf-tb);
- while(isspace(*tf)) ++tf;
+ while(_isspace(*tf)) ++tf;
tag.attr.assign(tf,te-tf+1);
return true;
@@ -824,14 +1004,14 @@ BL pooldir::LdDirXMLRec(istream &is,I depth,BL mkdir,AtomList &d)
if(v.Count())
post("pool - XML load: value data already given, ignoring new data");
else
- ret = ParseAtoms(s,v);
+ 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);
+ ret = ParseAtoms(s,k,true);
}
else {
t_atom &dkey = d[d.Count()-1];
@@ -841,7 +1021,7 @@ BL pooldir::LdDirXMLRec(istream &is,I depth,BL mkdir,AtomList &d)
if(*ds)
post("pool - XML load: dir key already given, ignoring new key");
else
- ReadAtom(s.c_str(),dkey);
+ ReadAtom(s.c_str(),dkey,true);
ret = true;
}
@@ -893,7 +1073,7 @@ BL pooldir::LdDirXMLRec(istream &is,I depth,BL mkdir,AtomList &d)
if(fnd == d.Count()-1)
post("pool - XML load: dir key must be given prior to values");
- // else: one directoy level has been left unintialized, ignore items
+ // else: one directory level has been left unintialized, ignore items
}
else {
// only use first word of key
@@ -981,7 +1161,7 @@ BL pooldir::SvDirXML(ostream &os,I depth,const AtomList &dir,I ind)
os << "<dir>" << endl;
indent(os,ind+i+1);
os << "<key>";
- WriteAtom(os,dir[ind+i]);
+ WriteAtom(os,dir[ind+i],true);
os << "</key>" << endl;
}
@@ -989,9 +1169,9 @@ BL pooldir::SvDirXML(ostream &os,I depth,const AtomList &dir,I ind)
for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
indent(os,ind+lvls);
os << "<value><key>";
- WriteAtom(os,ix->key);
+ WriteAtom(os,ix->key,true);
os << "</key><data>";
- WriteAtoms(os,*ix->data);
+ WriteAtoms(os,*ix->data,true);
os << "</data></value>" << endl;
}
}