Changeset 38

Show
Ignore:
Timestamp:
04/28/08 18:40:14 (8 months ago)
Author:
aarti_pl
Message:

- new module: storage
- new module: database (very early alpha)
- Tokenizer renamed to Scanner.d
- ProgramOptions works with Serializer
- updates for Serializer.d

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/doc/util/config/todo.txt

    r30 r38  
    3939    - compile time checking for configuration of PO and definition of options? 
    4040 
    41 -------------------------------------------------------------------------------  
    42                         POSSIBLE D LANGUAGE / LIBRARY IMPROVEMENTS 
    43 -------------------------------------------------------------------------------  
    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 thrown 
    47     - 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 work 
    51     - 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 implementation 
    54     - creating automatic http:// links for tokens: 'See:' and 'See_also:' in DDoc 
    55     - Tango: class String should encapsulate three forms of D strings: char[], wchar[], dchar[] 
    56     - Tango: some templates from Variant should go to module traits 
    57      
  • trunk/doc/util/serializer/todo.txt

    r30 r38  
    1010    - 
    1111 
    12 ------------------------------------------------------------------------------- 
    13                         POSSIBLE D LANGUAGE / LIBRARY IMPROVEMENTS 
    14 ------------------------------------------------------------------------------- 
    15     -   implicit conversion from fixed arrays literals to dynamic literals 
    16         (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 tuple 
    20         there are many usecases when it is expected situation when nothing is parsed 
    21         eg. parsing array literal which can be empty or parse last element of such an 
    22         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  
    1818debug public import std.stdio; 
    1919public import doost.util.DUnit; 
     20version(Tango) public import std.compat; 
  • trunk/doost/core/Any.d

    r32 r38  
    1818module doost.core.Any; 
    1919 
     20import doost.api.Common; 
    2021import doost.util.DUnit; 
    2122 
     
    213214 
    214215unittest { 
    215     testSuite.start("Any"); 
     216    testSuite.begin("Any"); 
    216217} 
    217218 
  • trunk/doost/storage/FileStorage.d

    r37 r38  
    1616module doost.storage.FileStorage; 
    1717 
     18import std.stdio; 
    1819import std.stream; 
     20 
     21import doost.core.Traits; 
    1922import doost.storage.Storage; 
    2023 
    2124//------------------------------------------------------------------------------ 
    2225 
    23 class FileStorage(T) : Storage!(T) { 
    24     static typeof(this) init() { 
    25         return new typeof(this); 
     26class FileStorage(ELEMENTTYPE) : Storage!(ELEMENTTYPE) { 
     27    alias ELEMENTTYPE[] STORAGETYPE; 
     28 
     29public: 
     30    this(string filename) { 
     31        this.filename = filename; 
    2632    } 
    2733 
    28     //TODO: finish? 
     34    ~this() { 
     35        //ENH: should work 
     36        //close(); 
     37    } 
    2938 
    3039    //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; 
    3244 
     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; 
    3360    } 
    3461 
    35     T get(uint no = 1) { 
    36         if (eos(no)) throw new Exception("There is no more data in the file"); 
    37         T result = 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]; 
    3865        readBuffer = readBuffer[no..$]; 
    3966        return result; 
    4067    } 
    4168 
    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)"); 
    4482        return readBuffer[pos..pos+rep]; 
    4583    } 
    4684 
    47     void buffer(T arr) { 
    48         readBuffer = arr ~ readBuffer; 
     85    override STORAGETYPE* frame() { 
     86        return &readBuffer; 
    4987    } 
    5088 
    5189    //write functions 
    52     void put(T sequence) { 
     90    override void put(STORAGETYPE sequence) { 
    5391        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; 
    5497    } 
    5598 
    56     void put(StorageElementType!(T) element) { 
     99    override void put(ELEMENTTYPE element) { 
    57100        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; 
    58114    } 
    59115 
    60116    //-------------------------------------------------------------------------- 
    61  
    62     string fileName; 
    63     T readBuffer; 
    64     T writeBuffer; 
     117private: 
     118    STORAGETYPE readBuffer; 
     119    STORAGETYPE writeBuffer; 
     120    uint cursor; 
     121    string filename; 
    65122 
    66123    File file; 
  • trunk/doost/storage/Storage.d

    r37 r38  
    1616module doost.storage.Storage; 
    1717 
     18import doost.api.Common; 
    1819import doost.core.Traits; 
     20import doost.util.DUnit; 
    1921 
    2022 
     
    6365    Params: array = any array 
    6466 ******************************************************************************/ 
    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; 
     67T* frame(T)(ref T array) { 
     68    static assert(isArray!(T), onlyArrays); 
     69    return &array; 
    6970} 
    7071 
     
    7576    Returns: no of elements from beginning of array 
    7677 ******************************************************************************/ 
    77 T get(T)(ref T array, uint no = 1) { 
     78StorageElementType!(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 
     86T get(T)(ref T array, uint no) { 
    7887    static assert(isArray!(T), onlyArrays); 
    7988    assert(no <= array.length, arrayToShort); 
    80     T res = array[0..no]; 
     89    T result = array[0..no]; 
    8190    array = array[no..$]; 
    82     return res
     91    return result
    8392} 
    8493 
     
    9099            element = element of array 
    91100 ******************************************************************************/ 
     101 //BUG: not possible to define it for one element (compiler can not resolve it) 
    92102void put(T, S)(ref T array, S sequence) { 
    93103    static assert(isArray!(T), onlyArrays); 
     
    101111            pos = starting postion to looka at 
    102112 ******************************************************************************/ 
    103 T peek(T)(ref T array, uint pos = 0, uint rep = 1) { 
     113StorageElementType!(T) peek(T)(T array, uint pos = 0) 
     114in { 
     115    static assert(isArray!(T), onlyArrays); 
     116    assert(pos < array.length, arrayToShort); 
     117
     118body { 
     119    return array[pos]; 
     120
     121 
     122T peek(T)(T array, uint pos, uint rep) { 
    104123    static assert(isArray!(T), onlyArrays); 
    105124    assert(pos + rep <= array.length, arrayToShort); 
     
    109128//------------------------------------------------------------------------------ 
    110129 
    111 interface Storage(T) { 
     130interface Storage(ELEMENTTYPE) { 
     131    alias ELEMENTTYPE[] STORAGETYPE; 
     132 
    112133    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(); 
    119146} 
    120147 
     
    126153    Params: T = array type being the base of this storage 
    127154 ******************************************************************************/ 
    128 class DummyStorage(T) : Storage!(T) { 
     155class DummyStorage(ELEMENTTYPE) : Storage!(ELEMENTTYPE) { 
     156    alias ELEMENTTYPE[] STORAGETYPE; 
     157 
    129158public: 
    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) { 
    136160        if (pos>=input.length) return true; 
    137161        return false; 
    138162    } 
    139163 
    140     T get(uint no = 1) { 
    141         T result = input[0..no]; 
     164    override STORAGETYPE get(uint no) { 
     165        STORAGETYPE result = input[0..no]; 
    142166        input = input[no..$]; 
    143167        return result; 
    144168    } 
    145169 
    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) { 
    147176        output ~= sequence; 
    148177    } 
    149178 
    150     void put(StorageElementType!(T) element) { 
     179    override void put(ELEMENTTYPE element) { 
    151180        output ~= element; 
    152181    } 
    153182 
    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) { 
    155189        assert(pos + rep <= input.length); 
    156190        return input[pos..pos + rep]; 
    157191    } 
    158192 
    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 
     203unittest { 
     204    testSuite.timing.width(100).repeat(1).begin("Storage module"); 
     205
     206 
     207//------------------------------------------------------------------------------ 
     208 
     209unittest { 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 
     220unittest { 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 
     230unittest { 
     231    testSuite.finish; 
     232
     233 
  • trunk/doost/sys/Environment.d

    r20 r38  
    298298        foreach (key, value; Environment.get) 
    299299                 writefln(key, "=", value); 
    300  
    301  
    302         } 
    303 
    304  
     300        } 
     301
     302 
  • trunk/doost/text/Escaper.d

    r37 r38  
    1818import std.stdio; 
    1919 
     20import doost.api.Common; 
    2021import doost.util.DUnit; 
    2122import doost.core.Traits; 
     
    127128//------------------------------------------------------------------------------ 
    128129 
    129 unittest { testCase.repeat(1).execute("basic old implementation escape characters", { 
     130unittest { testCase.repeat(1).execute("basic escape characters old implementation", { 
    130131    assert(escapeOld("\""[]) == "\\\""); 
    131132    assert(escapeOld("\?"[]) == "\\?"); 
     
    154155    uint code = c; 
    155156    if (code >= 0x61) code -= 0x57; 
     157        else 
    156158    if (code >= 0x41) code -= 0x37; 
     159        else 
    157160    if (code >= 0x30) code -= 0x30; 
    158161    return code; 
     
    163166/******************************************************************************* 
    164167 ******************************************************************************/ 
    165 //TODO: speed optimalization 
     168//BUG-DMD: speed optimization of functions with ref parameters 
    166169T unescape(T)(T input) { 
    167170//  static assert(isString!(T), "Only unicode strings allowed"); 
     
    286289//------------------------------------------------------------------------------ 
    287290 
    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  
    307291unittest { testCase.repeat(1).execute("unescape basic characters old implementation", { 
    308292    assert(unescapeOld("\\\\"[]) == "\\"); 
     
    322306//------------------------------------------------------------------------------ 
    323307 
     308unittest { 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 
    324327unittest { testCase.execute("unescape extended characters", { 
    325328    // 2 characters hexadecimal test (\x) 
  • trunk/doost/text/Scanner.d

    r37 r38  
    265265            {l:0x27, r:0x27} 
    266266        ]}, 
     267        separator = {parts: [ 
     268            {l:',', r:','}, 
     269            {l:';', r:';'} 
     270        ]}, 
    267271        digit = {parts: [ 
    268272            {l:0x30, r:0x39} 
     
    468472        parts ~= cp; 
    469473    } 
     474 
     475 
    470476} 
    471477 
     
    619625 
    620626    //TODO: case insensitive matches? 
    621  
    622627    Array matching(Matcher m) { 
    623628        assert(m.index < parts.length, "Index of out bounds of SequenceSet"); 
     
    709714    if (input.eos(pos)) return Matcher(pos, Matcher.missing_input); 
    710715    //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); 
    712717    ++pos; 
    713718    return Matcher(pos, Matcher.matched); 
     
    792797    //pragma(msg, "scanElement: " ~ T.stringof ~ ", " ~ S.stringof) 
    793798    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); 
    795800    return Matcher(pos+1, Matcher.matched); 
    796801} 
     
    819824 ******************************************************************************/ 
    820825Matcher 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) 
    822827    for(uint i=0; i < sequence.length; i++) { 
    823828        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); 
    825831        ++pos; 
    826832    } 
     
    864870    } 
    865871 
    866     if (re.find(aview) == pos) { 
     872    if (re.find(aview) == 0) { 
    867873        return Matcher(re.match(0).length + pos, Matcher.matched); 
    868874    } 
     
    897903    bool matched = false; 
    898904    uint cnt = rep; 
     905    pragma(msg, T.stringof ~ S.stringof ); 
    899906 
    900907    while(cnt > 0) { 
     
    912919        } else 
    913920        static if (isArray!(S)) { 
    914             //pragma(msg, typeof(input).stringof ~ " " ~ typeof(condition).stringof); 
     921            pragma(msg, typeof(input).stringof ~ " ?? " ~ typeof(condition).stringof); 
    915922            m = scanSequence(input, condition, pos); 
     923            pragma(msg, "After scan sequence"); 
    916924        } else 
    917925        static if (is(S == StorageElementType!(T))) { 
     
    921929        } 
    922930 
    923         if (cast(bool)m) { 
     931        pragma(msg, "before if"); 
     932        if (!m.status) { 
    924933            pos = m.position; 
    925934            --cnt; 
     
    935944            break; 
    936945        } 
     946        pragma(msg, "after if"); 
    937947    } 
    938948 
     
    949959    Returns: number of skipped charactes 
    950960 ******************************************************************************/ 
     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 
    951963uint skip(T, S)(ref T input, S condition, uint rep=1) { 
    952964    uint pos=0; 
    953965    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"); 
    955969        if (mp.position) { 
    956970            static if (isArray!(T)) { 
     
    960974            } 
    961975        } 
     976        pragma(msg, "before return"); 
    962977        return mp.position; 
    963978    } 
    964     return 0
     979    return 0u
    965980} 
    966981 
     
    981996    static if (is(S == Matcher)) { 
    982997        StorageType!(T) result; 
    983         if (cast(bool)condition && condition.position) { 
     998        if (!condition.status && condition.position) { 
    984999            static if (isArray!(T)) { 
    9851000                result = input[0 .. condition.position + pos]; 
     
    10011016Matcher scanEscapeSequence(T)(T input, uint pos=0) { 
    10021017    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); 
    10041019 
    10051020    ++pos; 
    10061021    if (input.eos(pos)) return Matcher(pos, Matcher.missing_input); 
    1007     auto c = input.peek(pos)[0]
     1022    auto c = input.peek(pos)
    10081023 
    10091024    ++pos; 
     
    11151130    //Check for characters which can be only in middle 
    11161131    m = scan(input, midchars, pos); 
     1132    //writefln("scanString0: ", cast(bool)m); 
    11171133    if (cast(bool)m) return Matcher(pos, Matcher.mismatch); 
    11181134 
    11191135    //Characters which can be on any position (they should include midchars) 
    11201136    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//    } 
    11211141 
    11221142    return m; 
  • trunk/doost/util/DUnit.d

    r37 r38  
    301301            m_number = m_owner.m_tccounter; 
    302302            try { 
    303                 long starttime = rdtsc; 
     303                ulong starttime = rdtsc; 
    304304                for(uint i = 0; i<m_repeat; i++) { 
    305305                    if (m_setup !is null) m_setup(); 
     
    390390    bool m_dotraces; 
    391391 
    392     long m_elapsedtime; 
     392    ulong m_elapsedtime; 
    393393    uint m_number; 
    394394    TestSuite m_owner; 
  • trunk/doost/util/config/ConfigFileStorage.d

    r22 r38  
    2828import doost.util.config.Formatter; 
    2929import doost.util.config.Exception; 
    30 import doost.util.config.Converter; 
    3130 
    3231//------------------------------------------------------------------------------ 
  • trunk/doost/util/config/ProgramOptions.d

    r28 r38  
    2222 
    2323import doost.core.Any; 
     24 
     25import doost.util.serializer.Serializer; 
     26 
    2427import doost.util.config.Value; 
    25 import doost.util.config.Converter; 
    2628import doost.util.config.Formatter; 
    2729import doost.util.config.Utils; 
     30import doost.util.config.PoTextArchive; 
    2831 
    2932public import doost.util.config.Value : define, boolSwitch; 
    3033public import doost.util.config.Option; 
    3134public import doost.util.config.Exception; 
     35 
     36alias Serializer!(PoTextArchive, string) PoSerializer; 
    3237 
    3338//------------------------------------------------------------------------------ 
  • trunk/doost/util/config/Utils.d

    r28 r38  
    3838} 
    3939 
    40 /******************************************************************************* 
    41     Tokenizes string using given delimiters and skipping given characters. 
    42     It recognize string literals enclosed in '' or "". String literals are 
    43     taken as they are - nothing is changed in there. 
    44  
    45     Params: str     = string to tokenize 
    46             delim   = delimiter 
    47             skip    = characters to be skipped 
    48  ******************************************************************************/ 
    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  
    9940//------------------------------------------------------------------------------ 
    10041 
  • trunk/doost/util/config/Value.d

    r28 r38  
    2020import std.string; 
    2121import std.stdio; 
     22import std.regexp; 
    2223import doost.core.Any; 
    23 import doost.util.config.ProgramOptions; 
    24 import doost.util.config.Converter; 
     24import doost.core.Traits; 
     25import doost.text.Scanner; 
     26import doost.text.Escaper; 
     27import doost.util.serializer.Serializer; 
     28import doost.util.config.PoTextArchive; 
    2529import doost.util.config.Exception; 
    2630 
    2731//------------------------------------------------------------------------------ 
     32 
     33alias Serializer!(PoTextArchive, string) PoSerializer; 
     34 
     35PoSerializer serializer; 
     36 
     37static 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} 
    2843 
    2944const char[] arg = "arg"; 
     
    8196 
    8297/******************************************************************************* 
    83     Evaluates to true if type of T is known (parsers and stringizers are 
    84     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 /******************************************************************************* 
    9798    Interface which specifies how the option's value is to be parsed 
    9899    and converted into D types. 
     
    263264        m_pattern=pattern; 
    264265        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; 
    299269    } 
    300270 
     
    310280        result.m_zero_tokens = m_zero_tokens; 
    311281 
    312     static if (isCommonArray!(T)) { 
    313         result.m_sep = m_sep; 
    314         result.m_skip = m_skip; 
    315     } 
     282        result.archive = archive.dup_info; 
    316283 
    317284        return result; 
     
    372339    override void parse(Any value, char[] token) 
    373340    in { 
    374         assert(m_parser); 
     341        //assert(m_parser); 
    375342    } 
    376343    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 
    377362        T result; 
    378363 
     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); 
    379372        static if (isCommonArray!(T)) { 
    380             //TODO: sprawdzenie czy jest composing, jeÅŒeli nie to throw 
    381373            if (!value.empty) result = value.as!(T); 
    382             result ~= m_parser(this, token); 
     374            result ~= serializer.load!(T)(token, archive); 
    383375        } 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); 
    389377        } 
    390378 
     
    398386        Returns: string value of argument 
    399387     **************************************************************************/ 
    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)); 
    406390    } 
    407391 
     
    441425    /*************************************************************************** 
    442426     **************************************************************************/ 
    443     TypedValue parser(T function(TypedValue, char[]) parser) { 
     427    TypedValue parser(T