Changeset 307

Show
Ignore:
Timestamp:
04/28/2005 11:40:03 AM (3 years ago)
Author:
moo
Message:

user defined variable, compute on parsing: string+string, int+int, array+array, var+=expression.
"include" sub configuration file.
closed #11.

Location:
trunk
Files:
3 added
11 modified

Legend:

Unmodified
Added
Removed
  • trunk/doc/configuration.txt

    r240 r307  
    2727A BNF like notation: :: 
    2828 
    29   option   : NAME = VARIABLE 
     29  option   : NAME = VALUE 
     30  merge    : NAME += VALUE 
    3031  NAME     : modulename.key 
    31   VARIABLE : ( <string> | <integer> | <boolean> | <array> ) 
     32  VALUE    : ( <string> | <integer> | <boolean> | <array> | VALUE [ + VALUE ]*) 
    3233  <string> : "text" 
    3334  <integer>: digit* 
    3435  <boolean>: ( "enable" | "disable" ) 
    35   <array>  : "(" [ <string> "=>" ] <variable> [, [ <string> "=>" ] <variable> ]* ")" 
     36  <array>  : "(" [ <string> "=>" ] <value> [, [ <string> "=>" ] <value> ]* ")" 
     37  INCLUDE  : "include" VALUE 
    3638   
    3739Example 
     
    5153  # enable directory listings 
    5254  server.dir-listing = "enable" 
    53   
     55 
     56  # variables, computed when config is read. 
     57  var.mymodule = "foo" 
     58  server.modules += ( "mod_" + var.mymodule ) 
     59 
     60  # include, relative to dirname of main config file 
     61  include "mime.types.conf" 
    5462 
    5563 
  • trunk/doc/lighttpd.conf

    r293 r307  
    282282#setenv.add-response-header = ( "X-Secret-Message" => "42" ) 
    283283 
     284#### variable usage: 
     285## variable name without "." is auto prefixed by "var." and becomes "var.bar" 
     286#bar = 1 
     287#var.mystring = "foo" 
     288 
     289## integer add 
     290#bar += 1 
     291## string concat, with integer cast as string, result: "www.foo1.com" 
     292#server.name = "www." + mystring + var.bar + ".com" 
     293## array merge 
     294#index-file.names = (foo + ".php") + index-file.names 
     295#index-file.names += (foo + ".php") 
     296 
     297#### include 
     298#include /etc/lighttpd/lighttpd-inc.conf 
     299## same as above if you run: "lighttpd -f /etc/lighttpd/lighttpd.conf" 
     300#include "lighttpd-inc.conf" 
  • trunk/src/configfile-glue.c

    r298 r307  
    164164         
    165165        /* check parent first */ 
    166         if (dc->parent) { 
     166        if (dc->parent && dc->parent->context_ndx) { 
    167167                if (con->conf.log_condition_handling) { 
    168168                        log_error_write(srv, __FILE__, __LINE__,  "sb", "go parent", dc->parent->string); 
  • trunk/src/configfile.c

    r298 r307  
    296296        int bar; 
    297297         
    298         char *input; 
     298        buffer *file; 
     299        stream s; 
     300        const char *input; 
    299301        size_t offset; 
    300302        size_t size; 
     
    307309        int in_cond; 
    308310} tokenizer_t; 
     311 
     312static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) { 
     313        if (buffer_is_empty(basedir) && 
     314                        (fn[0] == '/' || fn[0] == '\\') && 
     315                        (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) { 
     316                t->file = buffer_init_string(fn); 
     317        } 
     318        else { 
     319                t->file = buffer_init_buffer(basedir); 
     320                buffer_append_string(t->file, fn); 
     321        } 
     322 
     323        if (0 != stream_open(&(t->s), t->file)) { 
     324                log_error_write(srv, __FILE__, __LINE__, "sbss",  
     325                                "opening configfile ", t->file, "failed:", strerror(errno)); 
     326                buffer_free(t->file); 
     327                return -1; 
     328        } 
     329 
     330        t->input = t->s.start; 
     331        t->offset = 0; 
     332        t->size = t->s.size; 
     333        t->line = 1; 
     334        t->line_pos = 1; 
     335         
     336        t->in_key = 1; 
     337        t->in_brace = 0; 
     338        t->in_cond = 0; 
     339        return 0; 
     340} 
     341 
     342static int tokenizer_close(server *srv, tokenizer_t *t) { 
     343        UNUSED(srv); 
     344 
     345        buffer_free(t->file); 
     346        return stream_close(&(t->s)); 
     347} 
    309348 
    310349static int config_skip_newline(tokenizer_t *t) { 
     
    335374        for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) { 
    336375                char c = t->input[t->offset]; 
    337                 char *start = NULL; 
     376                const char *start = NULL; 
    338377                 
    339378                switch (c) { 
     
    347386                                        tid = TK_ARRAY_ASSIGN; 
    348387                                } else { 
    349                                         log_error_write(srv, __FILE__, __LINE__, "sdsds",  
     388                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     389                                                        "file:", t->file, 
    350390                                                        "line:", t->line, "pos:", t->line_pos,  
    351391                                                        "use => for assignments in arrays"); 
     
    366406                                        tid = TK_MATCH; 
    367407                                } else { 
    368                                         log_error_write(srv, __FILE__, __LINE__, "sdsds",  
     408                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     409                                                        "file:", t->file, 
    369410                                                        "line:", t->line, "pos:", t->line_pos,  
    370411                                                        "only =~ and == are allow in the condition"); 
    371412                                        return -1; 
    372413                                } 
     414                                t->in_key = 1; 
     415                                t->in_cond = 0; 
    373416                        } else if (t->in_key) { 
    374417                                tid = TK_ASSIGN; 
     
    378421                                t->offset++; 
    379422                                t->line_pos++; 
    380                                 t->in_key = 0; 
    381423                        } else { 
    382                                 log_error_write(srv, __FILE__, __LINE__, "sdsds",  
     424                                log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     425                                                "file:", t->file, 
    383426                                                "line:", t->line, "pos:", t->line_pos,  
    384427                                                "unexpected equal-sign: ="); 
     
    402445                                        tid = TK_NOMATCH; 
    403446                                } else { 
    404                                         log_error_write(srv, __FILE__, __LINE__, "sdsds",  
     447                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     448                                                        "file:", t->file, 
    405449                                                        "line:", t->line, "pos:", t->line_pos,  
    406450                                                        "only !~ and != are allow in the condition"); 
    407451                                        return -1; 
    408452                                } 
     453                                t->in_key = 1; 
     454                                t->in_cond = 0; 
    409455                        } else { 
    410                                 log_error_write(srv, __FILE__, __LINE__, "sdsds",  
     456                                log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     457                                                "file:", t->file, 
    411458                                                "line:", t->line, "pos:", t->line_pos,  
    412459                                                "unexpected exclamation-marks: !"); 
     
    453500                                config_skip_newline(t); 
    454501                                t->line_pos = 1; 
    455                                 t->line++; 
     502                t->line++; 
    456503                        } 
    457504                        break; 
     
    497544                                /* ERROR */ 
    498545                                 
    499                                 log_error_write(srv, __FILE__, __LINE__, "sdsds",  
     546                                log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     547                                                "file:", t->file, 
    500548                                                "line:", t->line, "pos:", t->line_pos,  
    501549                                                "missing closing quote"); 
     
    534582                         
    535583                        break; 
     584 
     585                case '+': 
     586                        if (t->input[t->offset + 1] == '=') { 
     587                                t->offset += 2; 
     588                                buffer_copy_string(token, "+="); 
     589                                tid = TK_APPEND; 
     590                        } 
     591                        else { 
     592                                t->offset++; 
     593                                tid = TK_PLUS; 
     594                                buffer_copy_string(token, "+"); 
     595                        } 
     596                        break; 
     597 
    536598                case '|': 
    537599                        t->offset++; 
     
    544606                                 
    545607                        tid = TK_LCURLY; 
    546                         t->in_key = 1; 
    547                         t->in_cond = 0; 
    548608                                 
    549609                        buffer_copy_string(token, "{"); 
     
    582642                        break; 
    583643                default: 
    584                         if (t->in_key) { 
     644                        if (t->in_cond) { 
     645                                for (i = 0; t->input[t->offset + i] &&  
     646                                     (isalpha((unsigned char)t->input[t->offset + i]) 
     647                                      ); i++); 
     648                                 
     649                                if (i && t->input[t->offset + i]) { 
     650                                        tid = TK_SRVVARNAME; 
     651                                        buffer_copy_string_len(token, t->input + t->offset, i); 
     652                                         
     653                                        t->offset += i; 
     654                                        t->line_pos += i; 
     655                                } else { 
     656                                        /* ERROR */ 
     657                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     658                                                        "file:", t->file, 
     659                                                        "line:", t->line, "pos:", t->line_pos,  
     660                                                        "invalid character in condition"); 
     661                                        return -1; 
     662                                } 
     663                        } else if (isdigit((unsigned char)c)) { 
     664                                /* take all digits */ 
     665                                for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]);  i++); 
     666                                 
     667                                /* was there it least a digit ? */ 
     668                                if (i && t->input[t->offset + i]) { 
     669                                        tid = TK_INTEGER; 
     670                                         
     671                                        buffer_copy_string_len(token, t->input + t->offset, i); 
     672                                         
     673                                        t->offset += i; 
     674                                        t->line_pos += i; 
     675                                } else { 
     676                                        /* ERROR */ 
     677                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     678                                                        "file:", t->file, 
     679                                                        "line:", t->line, "pos:", t->line_pos,  
     680                                                        "unexpected EOF"); 
     681                                         
     682                                        return -1; 
     683                                } 
     684                        } 
     685                        else { 
    585686                                /* the key might consist of [-.0-9a-z] */ 
    586687                                for (i = 0; t->input[t->offset + i] &&  
     
    591692                                 
    592693                                if (i && t->input[t->offset + i]) { 
    593                                         tid = TK_LKEY; 
    594694                                        buffer_copy_string_len(token, t->input + t->offset, i); 
     695                                        if (strcmp(token->ptr, "include") == 0) { 
     696                                                tid = TK_INCLUDE; 
     697                                        } 
     698                                        else { 
     699                                                tid = TK_LKEY; 
     700                                        } 
    595701                                         
    596702                                        t->offset += i; 
     
    598704                                } else { 
    599705                                        /* ERROR */ 
    600                                         log_error_write(srv, __FILE__, __LINE__, "sdsds",  
     706                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
     707                                                        "file:", t->file, 
    601708                                                        "line:", t->line, "pos:", t->line_pos,  
    602                                                         "invalid character in lvalue"); 
     709                                                        "invalid character in variable name"); 
    603710                                        return -1; 
    604711                                } 
    605                         } else if (t->in_cond) { 
    606                                 for (i = 0; t->input[t->offset + i] &&  
    607                                      (isalpha((unsigned char)t->input[t->offset + i]) 
    608                                       ); i++); 
    609                                  
    610                                 if (i && t->input[t->offset + i]) { 
    611                                         tid = TK_SRVVARNAME; 
    612                                         buffer_copy_string_len(token, t->input + t->offset, i); 
    613                                          
    614                                         t->offset += i; 
    615                                         t->line_pos += i; 
    616                                 } else { 
    617                                         /* ERROR */ 
    618                                         log_error_write(srv, __FILE__, __LINE__, "sdsds",  
    619                                                         "line:", t->line, "pos:", t->line_pos,  
    620                                                         "invalid character in condition"); 
    621                                         return -1; 
    622                                 } 
    623                         } else { 
    624                                 if (isdigit((unsigned char)c)) { 
    625                                         /* take all digits */ 
    626                                         for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]);  i++); 
    627                                          
    628                                         /* was there it least a digit ? */ 
    629                                         if (i && t->input[t->offset + i]) { 
    630                                                 tid = TK_INTEGER; 
    631                                                  
    632                                                 buffer_copy_string_len(token, t->input + t->offset, i); 
    633                                                  
    634                                                 t->offset += i; 
    635                                                 t->line_pos += i; 
    636                                         } else { 
    637                                                 /* ERROR */ 
    638                                                 log_error_write(srv, __FILE__, __LINE__, "sdsds",  
    639                                                                 "line:", t->line, "pos:", t->line_pos,  
    640                                                                 "unexpected EOF"); 
    641                                                  
    642                                                 return -1; 
    643                                         } 
    644                                 } else { 
    645                                         /* ERROR */ 
    646                                         log_error_write(srv, __FILE__, __LINE__, "sdsds",  
    647                                                         "line:", t->line, "pos:", t->line_pos,  
    648                                                         "invalid value field"); 
    649                                          
    650                                         return -1; 
    651                                 } 
    652712                        } 
    653713                        break; 
     
    657717        if (tid) { 
    658718                *token_id = tid; 
     719#if 0 
     720                log_error_write(srv, __FILE__, __LINE__, "sbsdsdb",  
     721                                "file:", t->file, 
     722                                "line:", t->line, "pos:", t->line_pos, token); 
     723#endif 
    659724                 
    660725                return 1; 
     
    667732} 
    668733 
    669 int config_read(server *srv, const char *fn) { 
    670         stream s; 
     734int config_parse_file(server *srv, config_t *context, const char *fn) { 
    671735        tokenizer_t t; 
    672736        void *pParser; 
    673737        int token_id; 
    674         buffer *token; 
     738        buffer *token, *lasttoken; 
     739        int ret; 
     740 
     741        if (tokenizer_open(srv, &t, context->basedir, fn) == -1) { 
     742                return -1; 
     743        } 
     744         
     745        pParser = configparserAlloc( malloc ); 
     746        lasttoken = buffer_init(); 
     747        token = buffer_init(); 
     748        while((1 == (ret = config_tokenizer(srv, &t, &token_id, token))) && context->ok) { 
     749                buffer_copy_string_buffer(lasttoken, token); 
     750                configparser(pParser, token_id, token, context); 
     751                 
     752                token = buffer_init(); 
     753        } 
     754        if (ret != -1 && context->ok) { 
     755                /* add an EOL at EOF, better than say sorry */ 
     756                buffer_copy_string(token, "(EOL)"); 
     757                configparser(pParser, TK_EOL, token, context); 
     758                token = buffer_init_string("(END)"); 
     759                if (context->ok) { 
     760                        configparser(pParser, 0, token, context); 
     761                        token = buffer_init(); 
     762                } 
     763        } 
     764        configparserFree(pParser, free); 
     765        buffer_free(token); 
     766         
     767        if (ret == -1) { 
     768                log_error_write(srv, __FILE__, __LINE__, "sb",  
     769                                "configfile parser failed:", lasttoken); 
     770        } 
     771        else if (context->ok == 0) { 
     772                log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb",  
     773                                "file:", t.file, 
     774                                "line:", t.line, "pos:", t.line_pos,  
     775                                "parser failed somehow near here:", lasttoken); 
     776                ret = -1; 
     777        } 
     778        buffer_free(lasttoken); 
     779 
     780        tokenizer_close(srv, &t); 
     781        return ret == -1 ? -1 : 0; 
     782} 
     783 
     784static void context_init(server *srv, config_t *context) { 
     785        context->srv = srv; 
     786        context->ok = 1; 
     787        context->configs_stack = array_init(); 
     788        context->basedir = buffer_init(); 
     789} 
     790 
     791static void context_free(config_t *context) { 
     792        array_free(context->configs_stack); 
     793        buffer_free(context->basedir); 
     794} 
     795 
     796int config_read(server *srv, const char *fn) { 
    675797        config_t context; 
    676798        data_config *dc; 
    677799        int ret; 
    678         buffer *bfn = buffer_init_string(fn); 
    679          
    680         if (0 != stream_open(&s, bfn)) { 
    681                 buffer_free(bfn); 
    682                  
    683                 log_error_write(srv, __FILE__, __LINE__, "ssss",  
    684                                 "opening configfile ", fn, "failed:", strerror(errno)); 
    685                 return -1; 
    686         } 
    687          
    688         buffer_free(bfn); 
    689  
    690         t.input = s.start; 
    691         t.offset = 0; 
    692         t.size = s.size; 
    693         t.line = 1; 
    694         t.line_pos = 1; 
    695          
    696         t.in_key = 1; 
    697         t.in_brace = 0; 
    698         t.in_cond = 0; 
    699          
    700         context.ok = 1; 
     800        char *pos; 
     801 
     802        context_init(srv, &context); 
    701803        context.all_configs = srv->config_context; 
    702         context.configs_stack = array_init(); 
     804 
     805        pos = strrchr(fn, 
     806#ifdef __WIN32 
     807                        '\\' 
     808#else 
     809                        '/' 
     810#endif 
     811                        ); 
     812        if (pos) { 
     813                buffer_copy_string_len(context.basedir, fn, pos - fn + 1); 
     814                fn = pos + 1; 
     815        } 
    703816         
    704817        dc = data_config_init(); 
     
    709822        array_insert_unique(context.all_configs, (data_unset *)dc); 
    710823        context.current = dc; 
    711          
     824 
    712825        /* default context */ 
    713826        srv->config = dc->value; 
    714827         
    715         pParser = configparserAlloc( malloc ); 
    716         token = buffer_init(); 
    717         while((1 == (ret = config_tokenizer(srv, &t, &token_id, token))) && context.ok) { 
    718                 configparser(pParser, token_id, token, &context); 
    719                  
    720                 token = buffer_init(); 
    721         } 
    722         configparser(pParser, 0, token, &context); 
    723         configparserFree(pParser, free ); 
    724          
    725         buffer_free(token); 
    726          
    727         stream_close(&s); 
    728          
    729         if (ret == -1) { 
    730                 log_error_write(srv, __FILE__, __LINE__, "s",  
    731                                 "configfile parser failed"); 
    732                 return -1; 
    733         } 
    734          
    735         if (context.ok == 0) { 
    736                 log_error_write(srv, __FILE__, __LINE__, "sdsds",  
    737                                 "line:", t.line, "pos:", t.line_pos,  
    738                                 "parser failed somehow near here"); 
    739                 return -1; 
    740         } 
    741          
    742         assert(context.configs_stack->used == 0); 
    743         array_free(context.configs_stack); 
     828        ret = config_parse_file(srv, &context, fn); 
     829 
     830        assert(0 != ret || context.configs_stack->used == 0); 
     831        context_free(&context); 
     832 
     833        if (0 != ret) { 
     834                return ret; 
     835        } 
    744836 
    745837        if (0 != config_insert(srv)) { 
  • trunk/src/configfile.h

    r298 r307  
    44#include "array.h" 
    55#include "buffer.h" 
     6#include "server.h" 
    67 
    78typedef struct { 
     9        server *srv; 
    810        int     ok; 
    911        array  *all_configs; 
    1012        array  *configs_stack; /* to parse nested block */ 
    1113        data_config *current; /* current started with { */ 
     14        buffer *basedir; 
    1215} config_t; 
    1316