Changeset 307
- Timestamp:
- 04/28/2005 11:40:03 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 11 modified
-
doc/configuration.txt (modified) (2 diffs)
-
doc/lighttpd.conf (modified) (1 diff)
-
src/configfile-glue.c (modified) (1 diff)
-
src/configfile.c (modified) (17 diffs)
-
src/configfile.h (modified) (2 diffs)
-
src/configparser.y (modified) (13 diffs)
-
src/server.c (modified) (1 diff)
-
tests/Makefile.am (modified) (1 diff)
-
tests/condition.conf (modified) (4 diffs)
-
tests/core-condition.t (modified) (5 diffs)
-
tests/core-var-include.t (added)
-
tests/docroot/www/Makefile.am (modified) (1 diff)
-
tests/var-include-sub.conf (added)
-
tests/var-include.conf (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/configuration.txt
r240 r307 27 27 A BNF like notation: :: 28 28 29 option : NAME = VARIABLE 29 option : NAME = VALUE 30 merge : NAME += VALUE 30 31 NAME : modulename.key 31 VA RIABLE : ( <string> | <integer> | <boolean> | <array>)32 VALUE : ( <string> | <integer> | <boolean> | <array> | VALUE [ + VALUE ]*) 32 33 <string> : "text" 33 34 <integer>: digit* 34 35 <boolean>: ( "enable" | "disable" ) 35 <array> : "(" [ <string> "=>" ] <variable> [, [ <string> "=>" ] <variable> ]* ")" 36 <array> : "(" [ <string> "=>" ] <value> [, [ <string> "=>" ] <value> ]* ")" 37 INCLUDE : "include" VALUE 36 38 37 39 Example … … 51 53 # enable directory listings 52 54 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" 54 62 55 63 -
trunk/doc/lighttpd.conf
r293 r307 282 282 #setenv.add-response-header = ( "X-Secret-Message" => "42" ) 283 283 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 164 164 165 165 /* check parent first */ 166 if (dc->parent ) {166 if (dc->parent && dc->parent->context_ndx) { 167 167 if (con->conf.log_condition_handling) { 168 168 log_error_write(srv, __FILE__, __LINE__, "sb", "go parent", dc->parent->string); -
trunk/src/configfile.c
r298 r307 296 296 int bar; 297 297 298 char *input; 298 buffer *file; 299 stream s; 300 const char *input; 299 301 size_t offset; 300 302 size_t size; … … 307 309 int in_cond; 308 310 } tokenizer_t; 311 312 static 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 342 static int tokenizer_close(server *srv, tokenizer_t *t) { 343 UNUSED(srv); 344 345 buffer_free(t->file); 346 return stream_close(&(t->s)); 347 } 309 348 310 349 static int config_skip_newline(tokenizer_t *t) { … … 335 374 for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) { 336 375 char c = t->input[t->offset]; 337 c har *start = NULL;376 const char *start = NULL; 338 377 339 378 switch (c) { … … 347 386 tid = TK_ARRAY_ASSIGN; 348 387 } else { 349 log_error_write(srv, __FILE__, __LINE__, "sdsds", 388 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 389 "file:", t->file, 350 390 "line:", t->line, "pos:", t->line_pos, 351 391 "use => for assignments in arrays"); … … 366 406 tid = TK_MATCH; 367 407 } else { 368 log_error_write(srv, __FILE__, __LINE__, "sdsds", 408 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 409 "file:", t->file, 369 410 "line:", t->line, "pos:", t->line_pos, 370 411 "only =~ and == are allow in the condition"); 371 412 return -1; 372 413 } 414 t->in_key = 1; 415 t->in_cond = 0; 373 416 } else if (t->in_key) { 374 417 tid = TK_ASSIGN; … … 378 421 t->offset++; 379 422 t->line_pos++; 380 t->in_key = 0;381 423 } else { 382 log_error_write(srv, __FILE__, __LINE__, "sdsds", 424 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 425 "file:", t->file, 383 426 "line:", t->line, "pos:", t->line_pos, 384 427 "unexpected equal-sign: ="); … … 402 445 tid = TK_NOMATCH; 403 446 } else { 404 log_error_write(srv, __FILE__, __LINE__, "sdsds", 447 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 448 "file:", t->file, 405 449 "line:", t->line, "pos:", t->line_pos, 406 450 "only !~ and != are allow in the condition"); 407 451 return -1; 408 452 } 453 t->in_key = 1; 454 t->in_cond = 0; 409 455 } else { 410 log_error_write(srv, __FILE__, __LINE__, "sdsds", 456 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 457 "file:", t->file, 411 458 "line:", t->line, "pos:", t->line_pos, 412 459 "unexpected exclamation-marks: !"); … … 453 500 config_skip_newline(t); 454 501 t->line_pos = 1; 455 t->line++;502 t->line++; 456 503 } 457 504 break; … … 497 544 /* ERROR */ 498 545 499 log_error_write(srv, __FILE__, __LINE__, "sdsds", 546 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 547 "file:", t->file, 500 548 "line:", t->line, "pos:", t->line_pos, 501 549 "missing closing quote"); … … 534 582 535 583 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 536 598 case '|': 537 599 t->offset++; … … 544 606 545 607 tid = TK_LCURLY; 546 t->in_key = 1;547 t->in_cond = 0;548 608 549 609 buffer_copy_string(token, "{"); … … 582 642 break; 583 643 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 { 585 686 /* the key might consist of [-.0-9a-z] */ 586 687 for (i = 0; t->input[t->offset + i] && … … 591 692 592 693 if (i && t->input[t->offset + i]) { 593 tid = TK_LKEY;594 694 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 } 595 701 596 702 t->offset += i; … … 598 704 } else { 599 705 /* ERROR */ 600 log_error_write(srv, __FILE__, __LINE__, "sdsds", 706 log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 707 "file:", t->file, 601 708 "line:", t->line, "pos:", t->line_pos, 602 "invalid character in lvalue");709 "invalid character in variable name"); 603 710 return -1; 604 711 } 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 }652 712 } 653 713 break; … … 657 717 if (tid) { 658 718 *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 659 724 660 725 return 1; … … 667 732 } 668 733 669 int config_read(server *srv, const char *fn) { 670 stream s; 734 int config_parse_file(server *srv, config_t *context, const char *fn) { 671 735 tokenizer_t t; 672 736 void *pParser; 673 737 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 784 static 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 791 static void context_free(config_t *context) { 792 array_free(context->configs_stack); 793 buffer_free(context->basedir); 794 } 795 796 int config_read(server *srv, const char *fn) { 675 797 config_t context; 676 798 data_config *dc; 677 799 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); 701 803 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 } 703 816 704 817 dc = data_config_init(); … … 709 822 array_insert_unique(context.all_configs, (data_unset *)dc); 710 823 context.current = dc; 711 824 712 825 /* default context */ 713 826 srv->config = dc->value; 714 827 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 } 744 836 745 837 if (0 != config_insert(srv)) { -
trunk/src/configfile.h
r298 r307 4 4 #include "array.h" 5 5 #include "buffer.h" 6 #include "server.h" 6 7 7 8 typedef struct { 9 server *srv; 8 10 int ok; 9 11 array *all_configs; 10 12 array *configs_stack; /* to parse nested block */ 11 13 data_config *current; /* current started with { */ 14 buffer *basedir; 12 15 } config_t; 13 16 …
