Changeset 38
- Timestamp:
- 04/28/08 18:40:14 (8 months ago)
- Files:
-
- trunk/doc/3rdPartyBug.txt (added)
- trunk/doc/util/config/todo.txt (modified) (1 diff)
- trunk/doc/util/serializer/todo.txt (modified) (1 diff)
- trunk/doost/api/Common.d (modified) (1 diff)
- trunk/doost/core/Any.d (modified) (2 diffs)
- trunk/doost/database (added)
- trunk/doost/database/Column.d (added)
- trunk/doost/database/DbiAdapter.d (added)
- trunk/doost/database/Expression.d (added)
- trunk/doost/database/Recordset.d (added)
- trunk/doost/database/Schema.d (added)
- trunk/doost/database/Sql.d (added)
- trunk/doost/database/SqlCreate.d (added)
- trunk/doost/database/SqlSelect.d (added)
- trunk/doost/database/Table.d (added)
- trunk/doost/database/Visitor.d (added)
- trunk/doost/storage/FileStorage.d (modified) (1 diff)
- trunk/doost/storage/Storage.d (modified) (7 diffs)
- trunk/doost/sys/Environment.d (modified) (1 diff)
- trunk/doost/text/Escaper.d (modified) (6 diffs)
- trunk/doost/text/Scanner.d (modified) (16 diffs)
- trunk/doost/util/DUnit.d (modified) (2 diffs)
- trunk/doost/util/config/ConfigFileStorage.d (modified) (1 diff)
- trunk/doost/util/config/PoTextArchive.d (added)
- trunk/doost/util/config/ProgramOptions.d (modified) (1 diff)
- trunk/doost/util/config/Utils.d (modified) (1 diff)
- trunk/doost/util/config/Value.d (modified) (15 diffs)
- trunk/doost/util/serializer/Registry.d (modified) (3 diffs)
- trunk/doost/util/serializer/Serializer.d (modified) (21 diffs)
- trunk/doost/util/serializer/archive/JsonArchive.d (modified) (39 diffs)
- trunk/doost/util/serializer/archive/TextArchive.d (modified) (39 diffs)
- trunk/dsss.conf (added)
- trunk/examples/database (added)
- trunk/examples/database/PackageTest.d (added)
- trunk/examples/database/TestSchema.d (added)
- trunk/examples/database/TestSchema.schema (added)
- trunk/examples/database/database.cbp (added)
- trunk/examples/storage (added)
- trunk/examples/storage/PackageTest.d (added)
- trunk/examples/storage/storage.cbp (added)
- trunk/examples/util/config/FunctionTest.d (modified) (25 diffs)
- trunk/examples/util/config/util_config.cbp (modified) (3 diffs)
- trunk/examples/util/serializer/FunctionTest.d (modified) (16 diffs)
- trunk/examples/util/serializer/FunctionTest1.d (modified) (4 diffs)
- trunk/examples/util/serializer/util_serializer.cbp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/doc/util/config/todo.txt
r30 r38 39 39 - compile time checking for configuration of PO and definition of options? 40 40 41 -------------------------------------------------------------------------------42 POSSIBLE D LANGUAGE / LIBRARY IMPROVEMENTS43 -------------------------------------------------------------------------------44 - referencing member objects in destructor (to allow automatic synchronization on destruction)45 - typeof(this) in member classes should be of current type, not base type (would allow to remove template mixins)46 - additional syntax for assert(bool condition, Exception e); When condition is not fulfiled exception e is thrown47 - templated constructors (initialization of Any, putting many options set into storages constructors...)48 - exiting from delegates with break / continue; probably also from other functions returning int;49 special enum for returning from loops? enum Loop {BREAK, CONTINUE) ?50 - assigning to array of Type should try also opAssign from Type. Currently it doesn't work51 - Tango: currently it is not possible to check if variable exists in environment variables as not exists and empty is indistinguishable;52 there should be additional method bool exists(char[] name)53 - function: void addOption(Option opt) on interface should be satisfied by derivatives of Option in interface implementation54 - creating automatic http:// links for tokens: 'See:' and 'See_also:' in DDoc55 - Tango: class String should encapsulate three forms of D strings: char[], wchar[], dchar[]56 - Tango: some templates from Variant should go to module traits57 trunk/doc/util/serializer/todo.txt
r30 r38 10 10 - 11 11 12 -------------------------------------------------------------------------------13 POSSIBLE D LANGUAGE / LIBRARY IMPROVEMENTS14 -------------------------------------------------------------------------------15 - implicit conversion from fixed arrays literals to dynamic literals16 (will be solved by polysemous values?)17 - it is not possible to send to function by ref literals like:18 'new SimpleTextArchive' or '[5,7,8].dup'. Why, if I don't care about value?19 - std.string - parse() should return struct{true/false, result} or tuple20 there are many usecases when it is expected situation when nothing is parsed21 eg. parsing array literal which can be empty or parse last element of such an22 array.23 - in the following case IFTI doesn't work: void describe(alias T)(T variable) {}24 - no struct constructors!!!trunk/doost/api/Common.d
r28 r38 18 18 debug public import std.stdio; 19 19 public import doost.util.DUnit; 20 version(Tango) public import std.compat; trunk/doost/core/Any.d
r32 r38 18 18 module doost.core.Any; 19 19 20 import doost.api.Common; 20 21 import doost.util.DUnit; 21 22 … … 213 214 214 215 unittest { 215 testSuite. start("Any");216 testSuite.begin("Any"); 216 217 } 217 218 trunk/doost/storage/FileStorage.d
r37 r38 16 16 module doost.storage.FileStorage; 17 17 18 import std.stdio; 18 19 import std.stream; 20 21 import doost.core.Traits; 19 22 import doost.storage.Storage; 20 23 21 24 //------------------------------------------------------------------------------ 22 25 23 class FileStorage(T) : Storage!(T) { 24 static typeof(this) init() { 25 return new typeof(this); 26 class FileStorage(ELEMENTTYPE) : Storage!(ELEMENTTYPE) { 27 alias ELEMENTTYPE[] STORAGETYPE; 28 29 public: 30 this(string filename) { 31 this.filename = filename; 26 32 } 27 33 28 //TODO: finish? 34 ~this() { 35 //ENH: should work 36 //close(); 37 } 29 38 30 39 //read functions 31 bool eos(uint pos = 0) { 40 override bool eos(uint pos = 0) { 41 //writefln("readBuffer.length: ", readBuffer.length); 42 if (pos + 1 < readBuffer.length) return false; 43 //if (!file.available) return true; 32 44 45 //writefln(pos); 46 //writefln(readBuffer); 47 48 49 auto len = pos - readBuffer.length; 50 len = 1024; 51 52 ubyte[] buf; 53 buf.length = len * ELEMENTTYPE.sizeof; 54 auto readed = file.read(buf); 55 readBuffer ~= cast(STORAGETYPE)buf[0 .. readed * ELEMENTTYPE.sizeof]; 56 57 if (readBuffer.length < pos + 1) return true; 58 59 return false; 33 60 } 34 61 35 T get(uint no = 1) {36 if (eos(no )) throw new Exception("There is no more data in the file");37 Tresult = readBuffer[0..no];62 override STORAGETYPE get(uint no) { 63 if (eos(no-1)) throw new Exception("There is no more data in the file (from get)"); 64 STORAGETYPE result = readBuffer[0..no]; 38 65 readBuffer = readBuffer[no..$]; 39 66 return result; 40 67 } 41 68 42 T peek(uint pos = 0, uint rep = 1) { 43 if (eos(pos + rep)) throw new Exception("There is no more data in the file"); 69 override ELEMENTTYPE get() { 70 if (eos(0)) throw new Exception("There is no more data in the file (from get)"); 71 scope(exit) readBuffer = readBuffer[1..$]; 72 return readBuffer[0]; 73 } 74 75 override ELEMENTTYPE peek(uint pos=0) { 76 if (eos(pos)) throw new Exception("There is no more data in the file (from peek)"); 77 return readBuffer[pos]; 78 } 79 80 override STORAGETYPE peek(uint pos, uint rep) { 81 if (eos(pos + rep-1)) throw new Exception("There is no more data in the file (from peek)"); 44 82 return readBuffer[pos..pos+rep]; 45 83 } 46 84 47 void buffer(T arr) {48 re adBuffer = arr ~readBuffer;85 override STORAGETYPE* frame() { 86 return &readBuffer; 49 87 } 50 88 51 89 //write functions 52 void put(Tsequence) {90 override void put(STORAGETYPE sequence) { 53 91 writeBuffer ~= sequence; 92 93 if (writeBuffer.length<1024) return; 94 //BUG: why write writes with length???? should be write<->writeString 95 file.writeString(writeBuffer); 96 writeBuffer=writeBuffer.init; 54 97 } 55 98 56 void put(StorageElementType!(T)element) {99 override void put(ELEMENTTYPE element) { 57 100 writeBuffer ~= element; 101 102 if (writeBuffer.length<1024) return; 103 file.writeString(writeBuffer); 104 writeBuffer=writeBuffer.init; 105 } 106 107 void open() { 108 file = new File(filename, FileMode.In | FileMode.Out); 109 } 110 111 void close() { 112 if (writeBuffer.length>0) file.writeString(writeBuffer); 113 file.close; 58 114 } 59 115 60 116 //-------------------------------------------------------------------------- 61 62 string fileName; 63 T readBuffer; 64 T writeBuffer; 117 private: 118 STORAGETYPE readBuffer; 119 STORAGETYPE writeBuffer; 120 uint cursor; 121 string filename; 65 122 66 123 File file; trunk/doost/storage/Storage.d
r37 r38 16 16 module doost.storage.Storage; 17 17 18 import doost.api.Common; 18 19 import doost.core.Traits; 20 import doost.util.DUnit; 19 21 20 22 … … 63 65 Params: array = any array 64 66 ******************************************************************************/ 65 void buffer(T)(ref T array, T buf) { 66 static assert(isArray!(T), onlyArrays); 67 //TODO: will not work for static arrays 68 array = buf ~ array; 67 T* frame(T)(ref T array) { 68 static assert(isArray!(T), onlyArrays); 69 return &array; 69 70 } 70 71 … … 75 76 Returns: no of elements from beginning of array 76 77 ******************************************************************************/ 77 T get(T)(ref T array, uint no = 1) { 78 StorageElementType!(T) get(T)(ref T array) { 79 static assert(isArray!(T), onlyArrays); 80 assert(array.length>0, arrayToShort); 81 StorageElementType!(T) result = array[0]; 82 array = array[1..$]; 83 return result; 84 } 85 86 T get(T)(ref T array, uint no) { 78 87 static assert(isArray!(T), onlyArrays); 79 88 assert(no <= array.length, arrayToShort); 80 T res = array[0..no];89 T result = array[0..no]; 81 90 array = array[no..$]; 82 return res ;91 return result; 83 92 } 84 93 … … 90 99 element = element of array 91 100 ******************************************************************************/ 101 //BUG: not possible to define it for one element (compiler can not resolve it) 92 102 void put(T, S)(ref T array, S sequence) { 93 103 static assert(isArray!(T), onlyArrays); … … 101 111 pos = starting postion to looka at 102 112 ******************************************************************************/ 103 T peek(T)(ref T array, uint pos = 0, uint rep = 1) { 113 StorageElementType!(T) peek(T)(T array, uint pos = 0) 114 in { 115 static assert(isArray!(T), onlyArrays); 116 assert(pos < array.length, arrayToShort); 117 } 118 body { 119 return array[pos]; 120 } 121 122 T peek(T)(T array, uint pos, uint rep) { 104 123 static assert(isArray!(T), onlyArrays); 105 124 assert(pos + rep <= array.length, arrayToShort); … … 109 128 //------------------------------------------------------------------------------ 110 129 111 interface Storage(T) { 130 interface Storage(ELEMENTTYPE) { 131 alias ELEMENTTYPE[] STORAGETYPE; 132 112 133 bool eos(uint pos = 0); 113 T get(uint no = 1); 114 void put(T sequence); 115 void put(StorageElementType!(T) element); 116 T peek(uint pos = 0, uint rep = 1); 117 void buffer(T arr); 118 static typeof(this) init(); 134 135 ELEMENTTYPE get(); 136 STORAGETYPE get(uint no); 137 138 void put(ELEMENTTYPE element); 139 void put(STORAGETYPE sequence); 140 141 ELEMENTTYPE peek(uint pos=0); 142 STORAGETYPE peek(uint pos, uint rep); 143 144 //BUG-DMD: not possible to return reference 145 STORAGETYPE* frame(); 119 146 } 120 147 … … 126 153 Params: T = array type being the base of this storage 127 154 ******************************************************************************/ 128 class DummyStorage(T) : Storage!(T) { 155 class DummyStorage(ELEMENTTYPE) : Storage!(ELEMENTTYPE) { 156 alias ELEMENTTYPE[] STORAGETYPE; 157 129 158 public: 130 131 static typeof(this) init() { 132 return new typeof(this); 133 } 134 135 bool eos(uint pos = 0) { 159 override bool eos(uint pos = 0) { 136 160 if (pos>=input.length) return true; 137 161 return false; 138 162 } 139 163 140 T get(uint no = 1) {141 Tresult = input[0..no];164 override STORAGETYPE get(uint no) { 165 STORAGETYPE result = input[0..no]; 142 166 input = input[no..$]; 143 167 return result; 144 168 } 145 169 146 void put(T sequence) { 170 override ELEMENTTYPE get() { 171 scope(exit) input = input[1..$]; 172 return input[0]; 173 } 174 175 override void put(STORAGETYPE sequence) { 147 176 output ~= sequence; 148 177 } 149 178 150 void put(StorageElementType!(T)element) {179 override void put(ELEMENTTYPE element) { 151 180 output ~= element; 152 181 } 153 182 154 T peek(uint pos = 0, uint rep = 1) { 183 override ELEMENTTYPE peek(uint pos=0) { 184 assert(pos < input.length); 185 return input[pos]; 186 } 187 188 override STORAGETYPE peek(uint pos = 0, uint rep = 1) { 155 189 assert(pos + rep <= input.length); 156 190 return input[pos..pos + rep]; 157 191 } 158 192 159 void buffer(T arr) { 160 input ~= arr; 161 } 162 163 T input; 164 T output; 165 } 193 override STORAGETYPE* frame() { 194 return &input; 195 } 196 197 STORAGETYPE input; 198 STORAGETYPE output; 199 } 200 201 //------------------------------------------------------------------------------ 202 203 unittest { 204 testSuite.timing.width(100).repeat(1).begin("Storage module"); 205 } 206 207 //------------------------------------------------------------------------------ 208 209 unittest { testCase.execute("Stream interface for strings - speed", { 210 string tst = "test string"; 211 char c; 212 213 for(int i=0; i<1000; i++) 214 c = tst.peek(); 215 216 });} 217 218 //------------------------------------------------------------------------------ 219 220 unittest { testCase.execute("Traditional access to strings - speed", { 221 string tst = "test string"; 222 char c; 223 224 for(int i=0; i<1000; i++) 225 c = tst[0]; 226 });} 227 228 //------------------------------------------------------------------------------ 229 230 unittest { 231 testSuite.finish; 232 } 233 trunk/doost/sys/Environment.d
r20 r38 298 298 foreach (key, value; Environment.get) 299 299 writefln(key, "=", value); 300 301 302 } 303 } 304 300 } 301 } 302 trunk/doost/text/Escaper.d
r37 r38 18 18 import std.stdio; 19 19 20 import doost.api.Common; 20 21 import doost.util.DUnit; 21 22 import doost.core.Traits; … … 127 128 //------------------------------------------------------------------------------ 128 129 129 unittest { testCase.repeat(1).execute("basic old implementation escape characters", {130 unittest { testCase.repeat(1).execute("basic escape characters old implementation", { 130 131 assert(escapeOld("\""[]) == "\\\""); 131 132 assert(escapeOld("\?"[]) == "\\?"); … … 154 155 uint code = c; 155 156 if (code >= 0x61) code -= 0x57; 157 else 156 158 if (code >= 0x41) code -= 0x37; 159 else 157 160 if (code >= 0x30) code -= 0x30; 158 161 return code; … … 163 166 /******************************************************************************* 164 167 ******************************************************************************/ 165 // TODO: speed optimalization168 //BUG-DMD: speed optimization of functions with ref parameters 166 169 T unescape(T)(T input) { 167 170 // static assert(isString!(T), "Only unicode strings allowed"); … … 286 289 //------------------------------------------------------------------------------ 287 290 288 unittest { testCase.repeat(1).execute("unescape stream wrapper", {289 DummyStorage!(string) storage;290 291 //storage.input = "\\\\"; assert(unescape(storage).output == "\\");292 assert(unescape("\\\""[]) == "\"");293 assert(unescape("\\?"[]) == "\?");294 assert(unescape("\\a"[]) == "\a");295 assert(unescape("\\b"[]) == "\b");296 assert(unescape("\\f"[]) == "\f");297 assert(unescape("\\n"[]) == "\n");298 assert(unescape("\\r"[]) == "\r");299 assert(unescape("\\t"[]) == "\t");300 assert(unescape("\\v"[]) == "\v");301 302 assert(unescape(r"\\\\\\\\ abc \\t\\n\\t \\t"[]) == r"\\\\ abc \t\n\t \t");303 });}304 305 //------------------------------------------------------------------------------306 307 291 unittest { testCase.repeat(1).execute("unescape basic characters old implementation", { 308 292 assert(unescapeOld("\\\\"[]) == "\\"); … … 322 306 //------------------------------------------------------------------------------ 323 307 308 unittest { testCase.repeat(1).execute("unescape stream wrapper", { 309 DummyStorage!(string) storage; 310 311 //storage.input = "\\\\"; assert(unescape(storage).output == "\\"); 312 assert(unescape("\\\""[]) == "\""); 313 assert(unescape("\\?"[]) == "\?"); 314 assert(unescape("\\a"[]) == "\a"); 315 assert(unescape("\\b"[]) == "\b"); 316 assert(unescape("\\f"[]) == "\f"); 317 assert(unescape("\\n"[]) == "\n"); 318 assert(unescape("\\r"[]) == "\r"); 319 assert(unescape("\\t"[]) == "\t"); 320 assert(unescape("\\v"[]) == "\v"); 321 322 assert(unescape(r"\\\\\\\\ abc \\t\\n\\t \\t"[]) == r"\\\\ abc \t\n\t \t"); 323 });} 324 325 //------------------------------------------------------------------------------ 326 324 327 unittest { testCase.execute("unescape extended characters", { 325 328 // 2 characters hexadecimal test (\x) trunk/doost/text/Scanner.d
r37 r38 265 265 {l:0x27, r:0x27} 266 266 ]}, 267 separator = {parts: [ 268 {l:',', r:','}, 269 {l:';', r:';'} 270 ]}, 267 271 digit = {parts: [ 268 272 {l:0x30, r:0x39} … … 468 472 parts ~= cp; 469 473 } 474 475 470 476 } 471 477 … … 619 625 620 626 //TODO: case insensitive matches? 621 622 627 Array matching(Matcher m) { 623 628 assert(m.index < parts.length, "Index of out bounds of SequenceSet"); … … 709 714 if (input.eos(pos)) return Matcher(pos, Matcher.missing_input); 710 715 //FIXME: dla char, peek nie powinien braÄ tylko jednego char'a ale caÅy code unit 711 if (!cc.matches(input.peek(pos) [0])) return Matcher(pos, Matcher.mismatch);716 if (!cc.matches(input.peek(pos))) return Matcher(pos, Matcher.mismatch); 712 717 ++pos; 713 718 return Matcher(pos, Matcher.matched); … … 792 797 //pragma(msg, "scanElement: " ~ T.stringof ~ ", " ~ S.stringof) 793 798 if (input.eos(pos)) return Matcher(pos, Matcher.missing_input); 794 if (input.peek(pos) [0]!= element) return Matcher(pos, Matcher.mismatch);799 if (input.peek(pos) != element) return Matcher(pos, Matcher.mismatch); 795 800 return Matcher(pos+1, Matcher.matched); 796 801 } … … 819 824 ******************************************************************************/ 820 825 Matcher scanSequence(T, S)(T input, S[] sequence, uint pos = 0) { 821 //pragma(msg, "scanSequence: " ~ T.stringof ~ ", " ~ (S[]).stringof)826 pragma(msg, "scanSequence: " ~ T.stringof ~ ", " ~ (S[]).stringof) 822 827 for(uint i=0; i < sequence.length; i++) { 823 828 if (input.eos(pos)) return Matcher(pos, Matcher.missing_input); 824 if (input.peek(pos) != sequence.peek(i)) return Matcher(pos, i == 0 ? Matcher.mismatch : Matcher.syntax_error); 829 if (input.peek(pos) != sequence.peek(i)) 830 return Matcher(pos, i == 0 ? Matcher.mismatch : Matcher.syntax_error); 825 831 ++pos; 826 832 } … … 864 870 } 865 871 866 if (re.find(aview) == pos) {872 if (re.find(aview) == 0) { 867 873 return Matcher(re.match(0).length + pos, Matcher.matched); 868 874 } … … 897 903 bool matched = false; 898 904 uint cnt = rep; 905 pragma(msg, T.stringof ~ S.stringof ); 899 906 900 907 while(cnt > 0) { … … 912 919 } else 913 920 static if (isArray!(S)) { 914 //pragma(msg, typeof(input).stringof ~ "" ~ typeof(condition).stringof);921 pragma(msg, typeof(input).stringof ~ " ?? " ~ typeof(condition).stringof); 915 922 m = scanSequence(input, condition, pos); 923 pragma(msg, "After scan sequence"); 916 924 } else 917 925 static if (is(S == StorageElementType!(T))) { … … 921 929 } 922 930 923 if (cast(bool)m) { 931 pragma(msg, "before if"); 932 if (!m.status) { 924 933 pos = m.position; 925 934 --cnt; … … 935 944 break; 936 945 } 946 pragma(msg, "after if"); 937 947 } 938 948 … … 949 959 Returns: number of skipped charactes 950 960 ******************************************************************************/ 961 //BUG-DMD: w ctfe nie moÅŒna robiÄ cast() nawet jeÅŒeli jest zdefiniowany operator cast 962 //BUG-DMD: Internal error: ..\ztc\cgcod.c 1817 951 963 uint skip(T, S)(ref T input, S condition, uint rep=1) { 952 964 uint pos=0; 953 965 auto mp = scan(input, condition, pos, rep); 954 if (cast(bool)mp) { 966 pragma(msg, "after auto"); 967 if (!mp.status) { 968 pragma(msg, "in if"); 955 969 if (mp.position) { 956 970 static if (isArray!(T)) { … … 960 974 } 961 975 } 976 pragma(msg, "before return"); 962 977 return mp.position; 963 978 } 964 return 0 ;979 return 0u; 965 980 } 966 981 … … 981 996 static if (is(S == Matcher)) { 982 997 StorageType!(T) result; 983 if ( cast(bool)condition&& condition.position) {998 if (!condition.status && condition.position) { 984 999 static if (isArray!(T)) { 985 1000 result = input[0 .. condition.position + pos]; … … 1001 1016 Matcher scanEscapeSequence(T)(T input, uint pos=0) { 1002 1017 if (input.eos(pos)) return Matcher(pos, Matcher.missing_input); 1003 if (input.peek(pos) [0]!= '\\') return Matcher(pos, Matcher.mismatch);1018 if (input.peek(pos) != '\\') return Matcher(pos, Matcher.mismatch); 1004 1019 1005 1020 ++pos; 1006 1021 if (input.eos(pos)) return Matcher(pos, Matcher.missing_input); 1007 auto c = input.peek(pos) [0];1022 auto c = input.peek(pos); 1008 1023 1009 1024 ++pos; … … 1115 1130 //Check for characters which can be only in middle 1116 1131 m = scan(input, midchars, pos); 1132 //writefln("scanString0: ", cast(bool)m); 1117 1133 if (cast(bool)m) return Matcher(pos, Matcher.mismatch); 1118 1134 1119 1135 //Characters which can be on any position (they should include midchars) 1120 1136 m = scan(input, allchars, pos, uint.max); 1137 //writefln("scanString1: ", input.peek(pos, m.position)); 1138 // foreach(r; allchars.parts) { 1139 // writefln(cast(int)r.l, "-", cast(int)r.r); 1140 // } 1121 1141 1122 1142 return m; trunk/doost/util/DUnit.d
r37 r38 301 301 m_number = m_owner.m_tccounter; 302 302 try { 303 long starttime = rdtsc;303 ulong starttime = rdtsc; 304 304 for(uint i = 0; i<m_repeat; i++) { 305 305 if (m_setup !is null) m_setup(); … … 390 390 bool m_dotraces; 391 391 392 long m_elapsedtime;392 ulong m_elapsedtime; 393 393 uint m_number; 394 394 TestSuite m_owner; trunk/doost/util/config/ConfigFileStorage.d
r22 r38 28 28 import doost.util.config.Formatter; 29 29 import doost.util.config.Exception; 30 import doost.util.config.Converter;31 30 32 31 //------------------------------------------------------------------------------ trunk/doost/util/config/ProgramOptions.d
r28 r38 22 22 23 23 import doost.core.Any; 24 25 import doost.util.serializer.Serializer; 26 24 27 import doost.util.config.Value; 25 import doost.util.config.Converter;26 28 import doost.util.config.Formatter; 27 29 import doost.util.config.Utils; 30 import doost.util.config.PoTextArchive; 28 31 29 32 public import doost.util.config.Value : define, boolSwitch; 30 33 public import doost.util.config.Option; 31 34 public import doost.util.config.Exception; 35 36 alias Serializer!(PoTextArchive, string) PoSerializer; 32 37 33 38 //------------------------------------------------------------------------------ trunk/doost/util/config/Utils.d
r28 r38 38 38 } 39 39 40 /*******************************************************************************41 Tokenizes string using given delimiters and skipping given characters.42 It recognize string literals enclosed in '' or "". String literals are43 taken as they are - nothing is changed in there.44 45 Params: str = string to tokenize46 delim = delimiter47 skip = characters to be skipped48 ******************************************************************************/49 char[][] tokenizer(char[] str, char[] delim=" \t\n", char[] skip="\r") {50 char[][] result;51 52 char[] token;53 bool isString = false;54 char sDelim='\x00';55 char c;56 57 for(uint i=0; i< str.length; i++) {58 c = str[i];59 60 if (c == '\'' || c == '"') {61 if (isString == true) {62 if (sDelim != c) {63 token~= c;64 continue;65 }66 isString = false;67 sDelim='\x00';68 token~= c;69 result~=token;70 token="";71 } else {72 isString = true;73 token = "";74 token~= c;75 sDelim=c;76 }77 continue;78 }79 80 if (isString == false) {81 if (find(delim, c) != -1) {82 if (token!= "") result~=token;83 token="";84 continue;85 }86 if (find(skip, c) != -1)87 continue;88 }89 90 token~= c;91 }92 93 if (isString) throw new InvalidOptionValueException(str);94 if (token!= "") result~=token;95 96 return result;97 }98 99 40 //------------------------------------------------------------------------------ 100 41 trunk/doost/util/config/Value.d
r28 r38 20 20 import std.string; 21 21 import std.stdio; 22 import std.regexp; 22 23 import doost.core.Any; 23 import doost.util.config.ProgramOptions; 24 import doost.util.config.Converter; 24 import doost.core.Traits; 25 import doost.text.Scanner; 26 import doost.text.Escaper; 27 import doost.util.serializer.Serializer; 28 import doost.util.config.PoTextArchive; 25 29 import doost.util.config.Exception; 26 30 27 31 //------------------------------------------------------------------------------ 32 33 alias Serializer!(PoTextArchive, string) PoSerializer; 34 35 PoSerializer serializer; 36 37 static this() { 38 serializer = new PoSerializer; 39 serializer.global().defString.p_midchars = CharClass!(char).emptyset; 40 serializer.global().defString.p_allchars = CharClass!(char).any_char; 41 serializer.global().defString.p_allchars.subtract(serializer.global().defSkip.p_skip); 42 } 28 43 29 44 const char[] arg = "arg"; … … 81 96 82 97 /******************************************************************************* 83 Evaluates to true if type of T is known (parsers and stringizers are84 available)85 ******************************************************************************/86 template isKnownType(T) {87 static if (isCommonArray!(T) || isAtomicType!(T) || is(T == char[]) || is(T == wchar[]) || is(T == dchar[])) {88 const isKnownType=true;89 } else {90 const isKnownType=false;91 }92 }93 94 //------------------------------------------------------------------------------95 96 /*******************************************************************************97 98 Interface which specifies how the option's value is to be parsed 98 99 and converted into D types. … … 263 264 m_pattern=pattern; 264 265 m_composing=false; 265 266 267 //FIXME: Would be very nice to have __traits(compile) 268 //to make better guesses for user defined type 269 //m_parser and m_stringizer should be null only if there is no match 270 //for templates 271 272 static if(!isKnownType!(T)) { 273 m_parser = null; 274 m_stringizer = null; 275 } else { 276 m_parser = &parseValue!(T); 277 m_stringizer = &stringizeValue!(T); 278 } 279 280 281 static if(isCommonArray!(T)) { 282 pragma(msg, "common array: " ~ T.stringof); 283 static if(isKnownType!(arrayElementType!(T))) { 284 m_elementSemantic = new TypedValue!(arrayElementType!(T)); 285 } 286 } else 287 static if(is(T == char[]) || is(T == wchar[]) || is(T == dchar[])) { 288 pragma(msg, "text type: " ~ T.stringof); 289 } else 290 static if(isAtomicType!(T)) { 291 pragma(msg, "atomic type: " ~ T.stringof); 292 } else 293 static if(is (T == bool)) { 294 pragma(msg, "bool: " ~ T.stringof); 295 m_pattern = "on|yes|1|true"; 296 } else { 297 } 298 266 m_parser = null; 267 m_stringizer = null; 268 archive = serializer.archive; 299 269 } 300 270 … … 310 280 result.m_zero_tokens = m_zero_tokens; 311 281 312 static if (isCommonArray!(T)) { 313 result.m_sep = m_sep; 314 result.m_skip = m_skip; 315 } 282 result.archive = archive.dup_info; 316 283 317 284 return result; … … 372 339 override void parse(Any value, char[] token) 373 340 in { 374 assert(m_parser);341 //assert(m_parser); 375 342 } 376 343 body { 344 static if (is(T == bool)) { 345 if (token.length == 0 && m_zero_tokens) { 346 //bool switch 347 return !(m_default_value.as!(bool)); 348 } 349 } 350 351 if (!value.empty && !m_composing) throw new MultipleOccurrencesException("multiple_occurrences"); 352 if (token.length == 0) throw new InvalidOptionValueException; 353 354 //TODO: dodaÄ validatory na typy zamiast patternów 355 356 static if (isCommonArray!(T) || isAssocArray!(T)) { 357 //Top level arrays can have omitted beginning and end delimiters 358 if (token[0] != '[') 359 token = '[' ~ token ~ ']'; 360 } 361 377 362 T result; 378 363 364 if (m_pattern.length > 0) { 365 //writefln(m_pattern, " - ", T.stringof); 366 auto re = std.regexp.search(token, m_pattern); 367 if (!(re !is null && re.match(0) == token)) 368 throw new InvalidOptionValueException; 369 } 370 371 //writefln(token, " - ", T.stringof); 379 372 static if (isCommonArray!(T)) { 380 //TODO: sprawdzenie czy jest composing, jeÅŒeli nie to throw381 373 if (!value.empty) result = value.as!(T); 382 result ~= m_parser(this, token);374 result ~= serializer.load!(T)(token, archive); 383 375 } else { 384 if (!value.empty) throw new MultipleOccurrencesException("multiple_occurrences"); 385 //FIXME: jest róŌnica pomiÄdzy null i ""; co poniÅŒej powinno byÄ? 386 if (!isZeroTokens && token is null) throw new InvalidOptionValueException; 387 388 result = m_parser(this, token); 376 result = serializer.load!(T)(token, archive); 389 377 } 390 378 … … 398 386 Returns: string value of argument 399 387 **************************************************************************/ 400 override char[] stringize(Any value) 401 in { 402 assert(m_stringizer); 403 } 404 body { 405 return m_stringizer(this, value); 388 override char[] stringize(Any value) { 389 return serializer.dump(value.as!(T)); 406 390 } 407 391 … … 441 425 /*************************************************************************** 442 426 **************************************************************************/ 443 TypedValue parser(T function( TypedValue,char[]) parser) {427 TypedValue parser(T
