Changeset 102

Show
Ignore:
Timestamp:
06/02/05 00:02:29 (4 years ago)
Author:
pragma
Message:

6/01/05
- added reset() override to DSPResponse and DSPRequest (eliminated buggy behavior)
- refactored the expression parser to use less code (dumped split() function)
- refactored workspace slightly to use /lib instead of /runtime compiler now looks to dsp root for the 'runtime'
- fixed bugs with pushWriter and popWriter
- added dsp:import and dspconf page
- added dsp:capture and dspconf page
- added dsp:attribute and dspconf page

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/doc/dsp-reference/tags.html

    r97 r102  
    267267        <h3>Description:</h3> 
    268268        <p> 
    269             The dsp:argument tag is used when the servlet is invoked as a 
     269            The dsp:attribute tag is used when the servlet is invoked as a 
    270270            <a href='tags.html#custom'>custom tag</a> in another servlet. It defines a variable to hold the 
    271271            value of the passed attribute, when the servlet is invoked in this manner. 
  • trunk/dsp/DSPGrammar.d

    r100 r102  
    3939    public static char[] newline = "\n"; 
    4040 
    41     public static char[] standardInclude = "import dsp.servlet.IDSPResponse,dsp.servlet.IDSPRequest,std.string,std.boxer,mango.io.model.IWriter";    
    4241    public static char[] servletPrefix = "__servlet_"; 
    4342    public static char[] servletDecl = "(IDSPRequest request, IDSPResponse response)"; 
    4443    public static char[] outputVarDecl = "IWriter __writer = response.getWriter()"; 
    4544     
     45    public static char[] writer = "__writer"; 
    4646    public static char[] outputFunc = "__writer.put"; 
    4747    public static char[] replaceFunc = "std.string.replace"; 
    4848    public static char[] toStringFunc = "std.string.toString"; 
    4949 
     50    public static char[] standardImports =  
     51        "dsp.servlet.IDSPResponse," 
     52        "dsp.servlet.IDSPRequest," 
     53        "dsp.servlet.DSPAttributes," 
     54        "dsp.Runtime," 
     55        "std.string," 
     56        "std.boxer," 
     57        "mango.io.model.IWriter" 
     58        ;    
    5059 
    5160    public static char[] pathToNamespace(char[] path){ 
     
    91100    } 
    92101     
     102    public static char[] runtimeFromString(char[] target,char[] source){ 
     103        return "fromString(" ~ target ~ "," ~ source ~ ")"; 
     104    } 
     105     
    93106    /* 
    94107    public static char[] expressionEscape(char[] from,char[] to){ 
     
    110123    } 
    111124 
    112     public static char[] servletHeader(char[] name,char[] modulePath){ 
    113     //TODO: rework to use servlet name instead of 'default' 
     125    public static char[] servletHeader(char[] name,char[] modulePath,char[][] servletImports){ 
     126        char[] imports = "import " ~ standardImports; 
     127        foreach(char[] imp; servletImports){ 
     128            imports ~= ("," ~ imp); 
     129        } 
     130     
     131        //TODO: rework to use servlet name instead of 'default' 
    114132        return  
    115133            "module " ~ pathToNamespace(modulePath) ~ ";" ~ newline ~    
    116             standardInclude ~ ";" ~ newline ~ 
     134            imports ~ ";" ~ newline ~ 
    117135            `alias void function` ~ servletDecl ~ ` ServletHandle; 
    118136             
  • trunk/dsp/DSPProcessor.d

    r100 r102  
    4040class DSPProcessor : SimpleConsumer{ 
    4141    ServletCompilationContext context; 
     42    char[] content; 
    4243 
    4344    public this(ServletCompilationContext context){ 
  • trunk/dsp/ServletCompiler.d

    r99 r102  
    3131private import dsp.ServletGenerator; 
    3232private import dsp.ServletCompilationContext; 
     33private import dsp.DSPException; 
    3334 
    3435private import xml.utf8all; 
     
    6263        context.parser = parser; 
    6364         
    64         parser.parse(new DSPProcessor(context), provider, source); 
    65         std.file.write( 
    66             context.requestConfig.dSourceFilename, 
    67             context.generator.getServletSource( 
    68                 context.requestConfig.requestModule, 
    69                 context.requestConfig.ext 
    70             ) 
    71         ); 
     65        try{ 
     66            parser.parse(new DSPProcessor(context), provider, source); 
     67            std.file.write( 
     68                context.requestConfig.dSourceFilename, 
     69                context.generator.getServletSource( 
     70                    context.requestConfig.requestModule, 
     71                    context.requestConfig.ext 
     72                ) 
     73            ); 
     74        } 
     75        catch(DSPException e){ 
     76            Position pos = parser.getPosition(); 
     77            throw new Exception(std.string.format("%s %s:<br />\n%s",context.requestConfig.name,pos.toString(),e.toString())); 
     78        } 
    7279    } 
    7380     
    7481    private void RunCompiler(ServletCompilationContext context){ 
    75         char[] commandline = 
    76             "dmd " ~ context.requestConfig.dSourceFilename ~  
    77             " " ~ context.requestConfig.options ~ 
    78             " -op" ~ 
    79             " -od" ~ context.requestConfig.tempDirectory ~  
    80             " -of" ~ context.requestConfig.destServletFilename ~ 
    81             " mango.lib" ~ 
    82             " " ~ context.requestConfig.runtimeDirectory ~ "DllStub.obj" ~ 
    83             " " ~ context.requestConfig.runtimeDirectory ~ "IDSPRequest.obj" ~ 
    84             " " ~ context.requestConfig.runtimeDirectory ~ "IDSPResponse.obj" ~          
    85             " " ~ context.requestConfig.runtimeDirectory ~ "servlet.def" ~ 
    86             " -version=dsp" ~ 
    87             " > " ~ context.requestConfig.tempDirectory ~ context.requestConfig.name ~ "_output.txt" 
    88             ; 
    89              
    90     /* //TODO: fix this so 'build' works correctly 
    91         char[] commandline = 
    92             "build " ~ context.requestConfig.dSourceFilename ~  
    93             " -op" ~ 
    94             " -od" ~ context.requestConfig.tempDirectory ~  
    95             " -of" ~ context.requestConfig.destServletFilename ~ 
    96             " mango.lib" ~ 
    97             " servlet.def" ~ 
    98             " -version=dsp" ~ 
    99             " > " ~ context.tempDirectory ~ context.requestConfig.name ~ "_output.txt" 
    100             ;    
    101     */ 
    102             debug writefln("command: %s",commandline); 
    103          
    104         if(std.process.system(commandline) != 0){ 
    105             throw new Exception(cast(char[])std.file.read(context.requestConfig.tempDirectory ~ context.requestConfig.name ~ "_output.txt")); 
     82        with(context){ 
     83            char[] commandline = 
     84                "dmd " ~ requestConfig.dSourceFilename ~  
     85                " " ~ requestConfig.options ~ 
     86                " -op" ~ 
     87                " -od" ~ requestConfig.tempDirectory ~  
     88                " -of" ~ requestConfig.destServletFilename ~ 
     89                " mango.lib" ~ 
     90                " -I" ~ requestConfig.runtimeDirectory ~ 
     91                " " ~ requestConfig.runtimeDirectory ~ "lib/DllStub.obj" ~ 
     92                " " ~ requestConfig.runtimeDirectory ~ "lib/IDSPRequest.obj" ~ 
     93                " " ~ requestConfig.runtimeDirectory ~ "lib/IDSPResponse.obj" ~          
     94                " " ~ requestConfig.runtimeDirectory ~ "lib/DSPAttributes.obj" ~ 
     95                " " ~ requestConfig.runtimeDirectory ~ "lib/Runtime.obj" ~   
     96                " " ~ requestConfig.runtimeDirectory ~ "lib/servlet.def" ~ 
     97                " -version=dsp" ~ 
     98                " > " ~ requestConfig.tempDirectory ~ requestConfig.name ~ "_output.txt" 
     99                ; 
     100 
     101        /* //TODO: fix this so 'build' works correctly 
     102            char[] commandline = 
     103                "build " ~ requestConfig.dSourceFilename ~  
     104                " -op" ~ 
     105                " -od" ~ requestConfig.tempDirectory ~  
     106                " -of" ~ requestConfig.destServletFilename ~ 
     107                " mango.lib" ~ 
     108                " servlet.def" ~ 
     109                " -version=dsp" ~ 
     110                " > " ~ tempDirectory ~ requestConfig.name ~ "_output.txt" 
     111                ;    
     112        */ 
     113                debug writefln("command: %s",commandline); 
     114 
     115            if(std.process.system(commandline) != 0){ 
     116                throw new Exception(cast(char[])std.file.read(requestConfig.tempDirectory ~ requestConfig.name ~ "_output.txt")); 
     117            } 
    106118        } 
    107119    } 
  • trunk/dsp/ServletGenerator.d

    r100 r102  
    3131private import dsp.Register; 
    3232 
     33private import std.boxer; 
     34 
     35/* 
     36    Shim to workaround template resolution issue in DMD 0.125. 
     37    Calls to template functions will not work due to a regression in this compiler version 
     38    The workaround here, using a struct template, allows for an alternate solution to the std.boxer.unbox template. 
     39*/ 
     40struct unboxer(T){ 
     41    T opCall(Box value) 
     42    { 
     43        assert (value.type !== null); 
     44         
     45        if (typeid(T) is value.type) 
     46            return *cast(T*) value.data; 
     47        throw new UnboxException(value, typeid(T)); 
     48    } 
     49} 
     50 
     51unboxer!(Register) registerUnboxer; 
     52unboxer!(char[]) stringUnboxer; 
     53 
    3354class ServletGenerator : RegisterSet{ 
    3455    char[] servletCPIn; 
     
    3758    char[] servletName; 
    3859    char[] servletDependencies; 
     60    char[][] servletImports; 
     61     
     62    Box[] stack; 
    3963     
    4064    int contentMode; 
     
    119143    } 
    120144     
     145    public void pushRegister(Register ptr){ 
     146        stack ~= box(ptr); 
     147    } 
     148     
     149    public Register popRegister(){ 
     150        Register ptr = registerUnboxer(stack[$-1]); 
     151        stack.length = stack.length - 1; 
     152        return ptr; 
     153    } 
     154 
     155    public void pushString(char[] ptr){ 
     156        stack ~= box(ptr); 
     157    } 
     158     
     159    public char[] popString(){ 
     160        char[] ptr = stringUnboxer(stack[$-1]); 
     161        stack.length = stack.length - 1; 
     162        return ptr; 
     163    } 
     164     
    121165     
    122166    // parse and append expression-based bits 
     
    125169    public Register evaluateExpression(char[] value,bit render=true){ 
    126170        Register expr; 
    127          
    128171        expr.home = this; 
    129172         
     
    133176        } 
    134177     
    135         char[][] parts = value.split(DSPGrammar.escapeStr); 
    136178        int pos = 0; 
    137179        bit isText = true; 
    138180        char[] expression = "``"; 
    139          
    140         // optimize for non-escaped value 
    141         if(parts.length == 1){ 
    142             expr.appendText(value); 
    143             goto evalEnd; 
    144         } 
    145          
    146         while(pos < parts.length){ 
    147             char[] thisPart = parts[pos]; 
     181        char[] thisPart; 
     182        uint delimPos; 
     183        uint nextPos; 
     184         
     185        while(pos < value.length){ 
     186            delimPos = find(value[pos..value.length],DSPGrammar.escapeStr);  
     187            if(delimPos == 0){ 
     188                thisPart = value[pos..pos+DSPGrammar.escapeStr.length]; 
     189            } 
     190            else if(delimPos == -1){ 
     191                thisPart = value[pos..value.length]; 
     192            } 
     193            else{ 
     194                thisPart = value[pos..pos+delimPos]; 
     195            } 
     196             
     197            debug printf("thispart: %.*s\n",thisPart); 
    148198             
    149199            // plain-text portion of expression 
    150200            if(isText){ 
    151201                if(thisPart == DSPGrammar.escapeStr){ 
    152                     if(pos+1 < parts.length && parts[pos+1] == DSPGrammar.escapeStr){ 
     202                    if(pos+1+DSPGrammar.escapeStr.length < value.length && value[pos+1..pos+1+DSPGrammar.escapeStr.length] == DSPGrammar.escapeStr){ 
    153203                        expr.appendText(DSPGrammar.escapeStr); 
    154                         pos++; 
     204                        pos+=DSPGrammar.escapeStr.length; // extra advance for the additional escape token 
    155205                    } 
    156206                    else{ 
     
    166216            else{ 
    167217                if(thisPart == DSPGrammar.escapeStr){ 
    168                     if(pos+1 < parts.length && parts[pos+1] == DSPGrammar.escapeStr){ 
     218                    if(pos+1+DSPGrammar.escapeStr.length < value.length && value[pos+1..pos+1+DSPGrammar.escapeStr.length] == DSPGrammar.escapeStr){ 
    169219                        throw new DSPException("Double-escape not allowed here."); 
    170220                    } 
     
    177227                }        
    178228            } 
    179             pos++
     229            pos+=thisPart.length
    180230        } 
    181231         
     
    184234        } 
    185235         
    186     evalEnd:            
     236    evalEnd: 
    187237        if(render) appendBody(expr.render()); 
    188238        return expr; 
     
    193243    } 
    194244     
     245    public void addImport(char[] namespace){ 
     246        servletImports ~= namespace; 
     247    } 
     248     
    195249    public char[] getServletSource(char[] modulePath,char[] fileExtension){ 
    196250        return  
    197             DSPGrammar.servletHeader(servletName,modulePath) ~  
     251            DSPGrammar.servletHeader(servletName,modulePath,servletImports) ~  
    198252            DSPGrammar.dependenciesSection(servletDependencies,"/" ~ modulePath ~ "." ~ fileExtension) ~ 
    199253            DSPGrammar.servletFunction(renderRegisterSet(),servletName,servletCPIn,servletBody,servletCPOut) 
  • trunk/dsp/StandardTagLibrary.d

    r97 r102  
    4242        tags["servlet"] = new Servlet(); 
    4343        tags["include"] = new Include(); 
     44        tags["import"] = new Import(); 
     45        tags["capture"] = new Capture(); 
     46        tags["attribute"] = new Attribute(); 
    4447    } 
    4548} 
  • trunk/dsp/Util.d

    r99 r102  
    3838} 
    3939 
    40 char[][] split(char[] src,char[] delim){ 
    41     char[][] result; 
    42     int lastPos = 0; 
    43     int pos = 0; 
    44      
    45     debug printf("split: %.*s\n",src); 
    46     debug printf("src: '%*.s'\n",src); 
    47     while(lastPos < src.length){ 
    48         pos = find(src[lastPos..$],delim); 
    49         if(pos == -1){ 
    50             result ~= src[lastPos..$]; 
    51             break; 
    52         } 
    53         else{ 
    54             pos += lastPos; 
    55             debug printf("last %d, pos: %d\n",lastPos,pos); 
    56             if(pos == 0) result ~= ""; 
    57             else result ~= src[lastPos..pos]; // get segment 
    58             result ~= src[pos..pos + delim.length]; // keep the delimiter 
    59             lastPos = pos + delim.length; // advance 
    60         } 
    61     } 
    62     printf("\n"); 
    63     return result; 
    64 } 
    65  
    6640class CompleteBufferReader: Scanner{ 
    6741    IBuffer buffer; 
  • trunk/dsp/servlet/DSPAttributes.d

    r98 r102  
    3939    return output; 
    4040} 
     41 
     42Box get(DSPAttributes attribs,char[] name,Box defaultValue){ 
     43    if(name in attribs){ 
     44        return attribs[name]; 
     45    } 
     46    return defaultValue; 
     47} 
  • trunk/dsp/servlet/DSPLibrary.d

    r99 r102  
    4747    public DSPLibrary next,last; 
    4848    public char[] key; 
     49     
     50    public bit isLoaded(){ 
     51        return lib && lib.isLoaded; 
     52    } 
    4953 
    5054    public void unload(){ 
  • trunk/dsp/servlet/DSPRequest.d

    r97 r102  
    4444    } 
    4545     
     46    public void reset(){ 
     47        attribs = null; 
     48        contentData = null; 
     49        super.reset(); 
     50    } 
     51     
    4652    DSPAttributes attributes(){ 
    4753        return attribs;  
  • trunk/dsp/servlet/DSPResponse.d

    r99 r102  
    5353    } 
    5454     
     55    void reset(){ 
     56        writerStack.length = 0; 
     57        dspWriter = null; 
     58        customTagScopeStack.length = 0; 
     59        customTagScopeStack.length = 1; 
     60        tagStack.length = 0; 
     61        servlet = null; 
     62        super.reset(); 
     63    } 
     64     
    5565    void setServlet(DSPServlet servlet){ 
    5666        this.servlet = servlet; 
     
    7686    //* save the current writer and use a new one in its place 
    7787    void pushWriter(){ 
    78         HttpWriter newWriter = new HttpWriter(new Buffer()); 
    79         writerStack ~= newWriter; 
     88        HttpWriter newWriter = new HttpWriter(new GrowableBuffer(256)); 
     89        writerStack ~= dspWriter; 
    8090        dspWriter = newWriter; 
    8191    } 
     
    90100         
    91101        char[] data = cast(char[])dspWriter.getBuffer().getContent(); 
     102        printf("popWriter: [%.*s]\n",data); 
    92103        dspWriter = oldWriter; 
    93104         
  • trunk/dsp/servlet/DSPServlet.d

    r99 r102  
    213213            if(lib){ 
    214214                lib.service(dspRequest,dspResponse); 
     215                 
     216                if(dspResponse.isExceptionSet){ 
     217                    throw new Exception(dspResponse.getException()); 
     218                } 
    215219            } 
    216220            else{ 
  • trunk/dsp/tags/Include.d

    r100 r102  
    7272 
    7373            case "dsp": 
     74                //TODO: insert a #line pragma at the end of the filedata to reset the current file line 
    7475                parser.insertText(filedata); 
    7576                break; 
  • trunk/dsp/tags/all.d

    r97 r102  
    3232import dsp.tags.Servlet; 
    3333import dsp.tags.Include; 
     34import dsp.tags.Import; 
     35import dsp.tags.Capture; 
     36import dsp.tags.Attribute; 
  • trunk/dspconf/config.xml

    r75 r102  
    44    <temp-directory value="_temp\"/> 
    55    <cache-size value="2"/> 
    6     <runtime-directory value=".\runtime\"/> 
     6    <runtime-directory value=""/> 
    77    <build-options value="-inline -release"/> 
    88</config> 
  • trunk/dspconf/index.dsp

    r100 r102  
    55    <h2>DSP Tag unittests</h2> 
    66    <ul> 
    7         <?dsp char[] filename = "dsp_include.dsp"; ?> 
    8         <li><a href='#filename#'>dsp:include</a></li> 
     7        <li><a href='dsp_include.dsp'>dsp:include</a></li> 
     8        <li><a href='dsp_import.dsp'>dsp:import</a></li> 
     9        <li><a href='dsp_capture.dsp'>dsp:capture</a></li> 
     10        <li><a href='dsp_attribute.dsp'>dsp:attribute</a></li> 
    911    </ul> 
    1012</body>