Ignore:
Timestamp:
2006-07-21 21:43:56 (8 years ago)
Author:
Poul-Henning Kamp <phk@…>
Branches:
0.9, 2.0, 2.1, tags/varnish-2.0, tags/varnish-2.0-beta1, tags/varnish-2.0-beta1@3141, tags/varnish-2.0-beta2, tags/varnish-2.0-beta2@3221, tags/varnish-2.0-rc1, tags/varnish-2.0-rc1@3266, tags/varnish-2.0-tp1, tags/varnish-2.0-tp1@2734, tags/varnish-2.0-tp2, tags/varnish-2.0-tp2@2803, tags/varnish-2.0.1, tags/varnish-2.0.2, tags/varnish-2.0.3, tags/varnish-2.0.4, tags/varnish-2.0.5, tags/varnish-2.0.6, tags/varnish-2.1.0, tags/varnish-2.1.1, tags/varnish-2.1.2, tags/varnish-2.1.3, tags/varnish-2.1.4
Children:
379d3c
Parents:
a18165
git-author:
Poul-Henning Kamp <phk@…> (2006-07-21 21:43:56)
git-committer:
Poul-Henning Kamp <phk@…> (2006-07-21 21:43:56)
Message:

Automate generation of tables and prototypes for the objects which
VCL programs can manipulate.

git-svn-id:  http://www.varnish-cache.org/svn/trunk@545 d4fa192b-c00b-0410-8231-f00ffab90ce4

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/libvcl/vcc_obj.c

    ra18165 r454dc6  
    11/* 
    22 * $Id$ 
     3 * 
     4 * NB:  This file is machine generated, DO NOT EDIT! 
     5 * 
     6 * Edit vcc_gen_obj.tcl instead 
    37 */ 
    48 
    59#include <stdio.h> 
    6  
    710#include "vcc_compile.h" 
    811 
    912struct var vcc_be_vars[] = { 
    10         { "backend.host", 
    11                 HOSTNAME, 0,  NULL, "VRT_set_backend_hostname(backend, %s)" }, 
    12         { "backend.port", 
    13                 PORTNAME, 0,  NULL, "VRT_set_backend_portname(backend, %s)" }, 
     13        { "backend.host", HOSTNAME, 12, 
     14            "VRT_r_backend_host(backend)", 
     15            "VRT_l_backend_host(backend, ", 
     16        }, 
     17        { "backend.port", PORTNAME, 12, 
     18            "VRT_r_backend_port(backend)", 
     19            "VRT_l_backend_port(backend, ", 
     20        }, 
     21        { NULL } 
    1422}; 
    1523 
    16  
    1724struct var vcc_vars[] = { 
    18         { "req.request",                STRING,   0,  "VRT_GetReq(sp)"       }, 
    19         { "obj.valid",                  BOOL,     0,  "VRT_obj_valid(sp)"     }, 
    20         { "obj.cacheable",              BOOL,     0,  "VRT_obj_cacheable(sp)" }, 
    21         { "obj.backend",                BACKEND,  0,  "VRT_obj_backend(sp)"   }, 
    22         { "req.http.",                  HEADER,   0,  NULL }, 
    23 #if 0 
    24         { "req.ttlfactor",              FLOAT, 0,   "req->ttlfactor" }, 
    25         { "req.url.host",               STRING, 0,  "req->url.host" }, 
    26         { "req.url.path",               STRING, 0,  "req->url.path" }, 
    27         { "req.useragent",              STRING, 0,  "req->useragent" }, 
    28         { "req.backend",                BACKEND, 0, "req->backend"   }, 
    29         { "client.ip",                  IP, 0,      "client->ip"     }, 
    30         { "backend.response_time",      TIME, 0,    "backend->responsetime" }, 
    31         { "backend.down",               BOOL, 0,    "backend->down"  }, 
    32         { "backend.timeout",            TIME, 0,    "backend->timeout" }, 
    33         { "backend.bandwidth",          RATE, 0,    "backend->bandwidth" }, 
    34         { "obj.exist",                  BOOL, 0,    "obj->exists" }, 
    35         { "obj.ttl",                    TIME, 0,    "obj->ttl" }, 
    36         { "obj.result",                 INT, 0,     "obj->result" }, 
    37         { "obj.size",                   SIZE, 0,    "obj->size" }, 
    38         { "obj.usage",                  INT, 0,     "obj->usage" }, 
    39 #endif 
    40         { NULL,                         INT, 0,     "NULL" } 
     25        { "req.request", STRING, 11, 
     26            "VRT_r_req_request(sp)", 
     27            "VRT_l_req_request(sp, ", 
     28        }, 
     29        { "req.url", STRING, 7, 
     30            "VRT_r_req_url(sp)", 
     31            "VRT_l_req_url(sp, ", 
     32        }, 
     33        { "obj.valid", BOOL, 9, 
     34            "VRT_r_obj_valid(sp)", 
     35            "VRT_l_obj_valid(sp, ", 
     36        }, 
     37        { "obj.cacheable", BOOL, 13, 
     38            "VRT_r_obj_cacheable(sp)", 
     39            "VRT_l_obj_cacheable(sp, ", 
     40        }, 
     41        { "obj.backend", BACKEND, 11, 
     42            "VRT_r_obj_backend(sp)", 
     43            "VRT_l_obj_backend(sp, ", 
     44        }, 
     45        { "obj.ttl", TIME, 7, 
     46            "VRT_r_obj_ttl(sp)", 
     47            "VRT_l_obj_ttl(sp, ", 
     48        }, 
     49        { "req.http.", HEADER, 9, 
     50            "VRT_r_req_http_(sp)", 
     51            "VRT_l_req_http_(sp, ", 
     52        }, 
     53        { NULL } 
    4154}; 
    4255 
    43  
    44 #if 0 
    45  
    46 #include <sys/types.h> 
    47 #include <sys/socket.h> 
    48 #include <sys/stat.h> 
    49  
    50 #include <assert.h> 
    51 #include <ctype.h> 
    52 #include <errno.h> 
    53 #include <fcntl.h> 
    54 #include <netdb.h> 
    55 #include <stdio.h> 
    56 #include <printf.h> 
    57 #include <stdarg.h> 
    58 #include <sbuf.h> 
    59 #include <stdlib.h> 
    60 #include <string.h> 
    61 #include <queue.h> 
    62 #include <unistd.h> 
    63  
    64 #include "vcl_priv.h" 
    65 #include "vcl_returns.h" 
    66 #include "vcl_compile.h" 
    67  
    68 #include "libvcl.h" 
    69  
    70 #define ERRCHK(tl)      do { if ((tl)->err) return; } while (0) 
    71  
    72 #define INDENT          2 
    73  
    74 /*-------------------------------------------------------------------- 
    75  * Consistency check 
    76  */ 
    77  
    78 static struct method { 
    79         const char              *name; 
    80         const char              *defname; 
    81         unsigned                returns; 
    82 } method_tab[] = { 
    83 #define VCL_RET_MAC(a,b,c) 
    84 #define VCL_MET_MAC(a,b,c)      { "vcl_"#a, "default_vcl_"#a, c }, 
    85 #include "vcl_returns.h" 
    86 #undef VCL_MET_MAC 
    87 #undef VCL_RET_MAC 
    88         { NULL, 0U } 
    89 }; 
    90  
    91 struct proccall { 
    92         TAILQ_ENTRY(proccall)   list; 
    93         struct proc             *p; 
    94         struct token            *t; 
    95 }; 
    96  
    97 struct proc { 
    98         TAILQ_ENTRY(proc)       list; 
    99         TAILQ_HEAD(,proccall)   calls; 
    100         struct token            *name; 
    101         unsigned                returns; 
    102         unsigned                exists; 
    103         unsigned                called; 
    104         unsigned                active; 
    105         struct token            *returnt[VCL_RET_MAX]; 
    106 }; 
    107  
    108 /*--------------------------------------------------------------------*/ 
    109  
    110  
    111 static void Compound(struct tokenlist *tl); 
    112 static void Cond_0(struct tokenlist *tl); 
    113 static struct proc *AddProc(struct tokenlist *tl, struct token *t, int def); 
    114 static void AddCall(struct tokenlist *tl, struct token *t); 
    115 static const char *vcc_default_vcl_b, *vcc_default_vcl_e; 
    116  
    117 /*--------------------------------------------------------------------*/ 
    118  
    119 static void 
    120 ErrToken(struct tokenlist *tl, struct token *t) 
    121 { 
    122  
    123         if (t->tok == EOI) 
    124                 sbuf_printf(tl->sb, "end of input"); 
    125         else 
    126                 sbuf_printf(tl->sb, "'%T'", t); 
    127 } 
    128  
    129 static void 
    130 _ErrInternal(struct tokenlist *tl, const char *func, unsigned line) 
    131 { 
    132  
    133         sbuf_printf(tl->sb, "VCL compiler internal error at %s():%u\n", 
    134             func, line); 
    135         tl->err = 1; 
    136 } 
    137  
    138 #define ErrInternal(tl) _ErrInternal(tl, __func__, __LINE__) 
    139  
    140 static void 
    141 ErrWhere(struct tokenlist *tl, struct token *t) 
    142 { 
    143         unsigned lin, pos, x, y; 
    144         const char *p, *l, *f, *b, *e; 
    145          
    146         lin = 1; 
    147         pos = 0; 
    148         if (t->tok == METHOD) 
    149                 return; 
    150         if (t->b >= vcc_default_vcl_b && t->b < vcc_default_vcl_e) { 
    151                 f = "Default VCL code (compiled in)"; 
    152                 b = vcc_default_vcl_b; 
    153                 e = vcc_default_vcl_e; 
    154         } else { 
    155                 f = "VCL code"; 
    156                 b = tl->b; 
    157                 e = tl->e; 
    158         } 
    159         for (l = p = b; p < t->b; p++) { 
    160                 if (*p == '\n') { 
    161                         lin++; 
    162                         pos = 0; 
    163                         l = p + 1; 
    164                 } else if (*p == '\t') { 
    165                         pos &= ~7; 
    166                         pos += 8; 
    167                 } else 
    168                         pos++; 
    169         } 
    170         sbuf_printf(tl->sb, "In %s Line %d Pos %d\n", f, lin, pos); 
    171         x = y = 0; 
    172         for (p = l; p < e && *p != '\n'; p++) { 
    173                 if (*p == '\t') { 
    174                         y &= ~7; 
    175                         y += 8; 
    176                         while (x < y) { 
    177                                 sbuf_bcat(tl->sb, " ", 1); 
    178                                 x++; 
    179                         } 
    180                 } else { 
    181                         x++; 
    182                         y++; 
    183                         sbuf_bcat(tl->sb, p, 1); 
    184                 } 
    185         } 
    186         sbuf_cat(tl->sb, "\n"); 
    187         x = y = 0; 
    188         for (p = l; p < e && *p != '\n'; p++) { 
    189                 if (p >= t->b && p < t->e) { 
    190                         sbuf_bcat(tl->sb, "#", 1); 
    191                         x++; 
    192                         y++; 
    193                         continue; 
    194                 } 
    195                 if (*p == '\t') { 
    196                         y &= ~7; 
    197                         y += 8; 
    198                 } else 
    199                         y++; 
    200                 while (x < y) { 
    201                         sbuf_bcat(tl->sb, "-", 1); 
    202                         x++; 
    203                 } 
    204         } 
    205         sbuf_cat(tl->sb, "\n"); 
    206         tl->err = 1; 
    207 } 
    208  
    209 /*--------------------------------------------------------------------*/ 
    210  
    211 static void 
    212 NextToken(struct tokenlist *tl) 
    213 { 
    214         tl->t = TAILQ_NEXT(tl->t, list); 
    215         if (tl->t == NULL) { 
    216                 sbuf_printf(tl->sb, 
    217                     "Ran out of input, something is missing or" 
    218                     " maybe unbalanced (...) or {...}\n"); 
    219                 tl->err = 1; 
    220                 return; 
    221         } 
    222 } 
    223  
    224 static void 
    225 _Expect(struct tokenlist *tl, unsigned tok, int line) 
    226 { 
    227         if (tl->t->tok == tok) 
    228                 return; 
    229         sbuf_printf(tl->sb, "Expected %s got ", vcl_tnames[tok]); 
    230         ErrToken(tl, tl->t); 
    231         sbuf_printf(tl->sb, "\n(program line %u), at\n", line); 
    232         ErrWhere(tl, tl->t); 
    233 } 
    234  
    235 #define Expect(a, b) _Expect(a, b, __LINE__) 
    236 #define ExpectErr(a, b) do { _Expect(a, b, __LINE__); ERRCHK(a);} while (0) 
    237  
    238 #define L(tl, foo)      do {    \ 
    239         tl->indent += INDENT;   \ 
    240         foo;                    \ 
    241         tl->indent -= INDENT;   \ 
    242 } while (0) 
    243  
    244 #define C(tl, sep)      do {                            \ 
    245         Fc(tl, 1, "VRT_count(sp, %u)%s\n", ++tl->cnt, sep);     \ 
    246         tl->t->cnt = tl->cnt;                           \ 
    247 } while (0) 
    248          
    249 /*-------------------------------------------------------------------- 
    250  * Printf output to the two sbufs, possibly indented 
    251  */ 
    252  
    253 static void 
    254 Fh(struct tokenlist *tl, int indent, const char *fmt, ...) 
    255 { 
    256         va_list ap; 
    257  
    258         if (indent) 
    259                 sbuf_printf(tl->fh, "%*.*s", tl->indent, tl->indent, ""); 
    260         va_start(ap, fmt); 
    261         sbuf_vprintf(tl->fh, fmt, ap); 
    262         va_end(ap); 
    263 } 
    264  
    265 static void 
    266 Fc(struct tokenlist *tl, int indent, const char *fmt, ...) 
    267 { 
    268         va_list ap; 
    269  
    270         if (indent) 
    271                 sbuf_printf(tl->fc, "%*.*s", tl->indent, tl->indent, ""); 
    272         va_start(ap, fmt); 
    273         sbuf_vprintf(tl->fc, fmt, ap); 
    274         va_end(ap); 
    275 } 
    276  
    277 /*-------------------------------------------------------------------- 
    278  * Compare token to token 
    279  */ 
    280  
    281 static int 
    282 Teq(struct token *t1, struct token *t2) 
    283 { 
    284         if (t1->e - t1->b != t2->e - t2->b) 
    285                 return (0); 
    286         return (!memcmp(t1->b, t2->b, t1->e - t1->b)); 
    287 } 
    288  
    289 /*-------------------------------------------------------------------- 
    290  * Compare ID token to string, return true of match 
    291  */ 
    292  
    293 static int 
    294 IdIs(struct token *t, const char *p) 
    295 { 
    296         const char *q; 
    297  
    298         assert(t->tok == ID); 
    299         for (q = t->b; q < t->e && *p != '\0'; p++, q++) 
    300                 if (*q != *p) 
    301                         return (0); 
    302         if (q != t->e || *p != '\0') 
    303                 return (0); 
    304         return (1); 
    305 } 
    306  
    307 /*--------------------------------------------------------------------*/ 
    308  
    309 static char * 
    310 EncString(struct token *t) 
    311 { 
    312         char *p, *q; 
    313         const char *r; 
    314         unsigned u; 
    315  
    316         assert(t->tok == CSTR); 
    317         p = malloc(t->e - t->b); 
    318         assert(p != NULL); 
    319         q = p; 
    320         for (r = t->b + 1; r < t->e - 1; ) { 
    321                 if (*r != '\\') { 
    322                         *q++ = *r++; 
    323                         continue; 
    324                 } 
    325                 switch (r[1]) { 
    326                 case 'n':       *q++ = '\n';    r += 2; break; 
    327                 case 'r':       *q++ = '\r';    r += 2; break; 
    328                 case 'v':       *q++ = '\v';    r += 2; break; 
    329                 case 'f':       *q++ = '\f';    r += 2; break; 
    330                 case 't':       *q++ = '\t';    r += 2; break; 
    331                 case 'b':       *q++ = '\b';    r += 2; break; 
    332                 case '0': case '1': case '2': case '3': 
    333                 case '4': case '5': case '6': case '7': 
    334                         u = r[1] - '0'; 
    335                         r += 2; 
    336                         if (isdigit(r[0]) && (r[0] - '0') < 8) { 
    337                                 u <<= 3; 
    338                                 u |= r[0] - '0'; 
    339                                 r++; 
    340                                 if (isdigit(r[0]) && (r[0] - '0') < 8) { 
    341                                         u <<= 3; 
    342                                         u |= r[0] - '0'; 
    343                                         r++; 
    344                                 } 
    345                         } 
    346                         *q++ = u; 
    347                         break; 
    348                 default: 
    349                         *q++ = r[1];     
    350                         r += 2; 
    351                         break; 
    352                 } 
    353         } 
    354         *q = '\0'; 
    355         return (p); 
    356 } 
    357  
    358  
    359 /*-------------------------------------------------------------------- 
    360  * Keep track of definitions and references 
    361  */ 
    362  
    363 static struct ref * 
    364 FindRef(struct tokenlist *tl, struct token *t, enum ref_type type) 
    365 { 
    366         struct ref *r; 
    367  
    368         TAILQ_FOREACH(r, &tl->refs, list) { 
    369                 if (r->type != type) 
    370                         continue; 
    371                 if (Teq(r->name, t)) 
    372                         return (r); 
    373         } 
    374         r = calloc(sizeof *r, 1); 
    375         assert(r != NULL); 
    376         r->name = t; 
    377         r->type = type; 
    378         TAILQ_INSERT_TAIL(&tl->refs, r, list); 
    379         return (r); 
    380 } 
    381  
    382 static int 
    383 FindRefStr(struct tokenlist *tl, const char *s, enum ref_type type) 
    384 { 
    385         struct ref *r; 
    386  
    387         TAILQ_FOREACH(r, &tl->refs, list) { 
    388                 if (r->type != type) 
    389                         continue; 
    390                 if (IdIs(r->name, s)) 
    391                         return (1); 
    392         } 
    393         return (0); 
    394 } 
    395  
    396 static void 
    397 AddRef(struct tokenlist *tl, struct token *t, enum ref_type type) 
    398 { 
    399  
    400         FindRef(tl, t, type)->refcnt++; 
    401 } 
    402  
    403 static void 
    404 AddRefStr(struct tokenlist *tl, const char *s, enum ref_type type) 
    405 { 
    406         struct token *t; 
    407  
    408         t = calloc(sizeof *t, 1); 
    409         t->b = s; 
    410         t->e = strchr(s, '\0'); 
    411         t->tok = METHOD; 
    412         AddRef(tl, t, type); 
    413 } 
    414  
    415 static void 
    416 AddDef(struct tokenlist *tl, struct token *t, enum ref_type type) 
    417 { 
    418         struct ref *r; 
    419  
    420         r = FindRef(tl, t, type); 
    421         r->defcnt++; 
    422         r->name = t; 
    423 } 
    424  
    425 /*-------------------------------------------------------------------- 
    426  * Recognize and convert units of time, return seconds. 
    427  */ 
    428  
    429 static double 
    430 TimeUnit(struct tokenlist *tl) 
    431 { 
    432         double sc = 1.0; 
    433  
    434         assert(tl->t->tok == ID); 
    435         if (IdIs(tl->t, "ms")) 
    436                 sc = 1e-3; 
    437         else if (IdIs(tl->t, "s")) 
    438                 sc = 1.0; 
    439         else if (IdIs(tl->t, "m")) 
    440                 sc = 60.0; 
    441         else if (IdIs(tl->t, "h")) 
    442                 sc = 60.0 * 60.0; 
    443         else if (IdIs(tl->t, "d")) 
    444                 sc = 60.0 * 60.0 * 24.0; 
    445         else { 
    446                 sbuf_printf(tl->sb, "Unknown time unit "); 
    447                 ErrToken(tl, tl->t); 
    448                 sbuf_printf(tl->sb, ".  Legal are 's', 'm', 'h' and 'd'\n"); 
    449                 ErrWhere(tl, tl->t); 
    450                 return (1.0); 
    451         } 
    452         NextToken(tl); 
    453         return (sc); 
    454 } 
    455  
    456 /*-------------------------------------------------------------------- 
    457  * Recognize and convert units of size, return bytes. 
    458  */ 
    459  
    460 static double 
    461 SizeUnit(struct tokenlist *tl) 
    462 { 
    463         double sc = 1.0; 
    464  
    465         assert(tl->t->tok == ID); 
    466         if (IdIs(tl->t, "b")) 
    467                 sc = 1.0; 
    468         else if (IdIs(tl->t, "kb")) 
    469                 sc = 1024.0; 
    470         else if (IdIs(tl->t, "mb") || IdIs(tl->t, "Mb")) 
    471                 sc = 1024.0 * 1024.0; 
    472         else if (IdIs(tl->t, "gb") || IdIs(tl->t, "Gb")) 
    473                 sc = 1024.0 * 1024.0 * 1024.0; 
    474         else { 
    475                 sbuf_printf(tl->sb, "Unknown size unit "); 
    476                 ErrToken(tl, tl->t); 
    477                 sbuf_printf(tl->sb, ".  Legal are 'kb', 'mb' and 'gb'\n"); 
    478                 ErrWhere(tl, tl->t); 
    479                 return (1.0); 
    480         } 
    481         NextToken(tl); 
    482         return (sc); 
    483 } 
    484  
    485 /*-------------------------------------------------------------------- 
    486  * Recognize and convert units of rate as { space '/' time } 
    487  */ 
    488  
    489 static double 
    490 RateUnit(struct tokenlist *tl) 
    491 { 
    492         double sc = 1.0; 
    493  
    494         assert(tl->t->tok == ID); 
    495         sc = SizeUnit(tl); 
    496         Expect(tl, '/'); 
    497         NextToken(tl); 
    498         sc /= TimeUnit(tl); 
    499         return (sc); 
    500 } 
    501  
    502 /*-------------------------------------------------------------------- 
    503  * Recognize and convert { CNUM } to unsigned value 
    504  */ 
    505  
    506 static unsigned 
    507 UintVal(struct tokenlist *tl) 
    508 { 
    509         unsigned d = 0; 
    510         const char *p; 
    511  
    512         Expect(tl, CNUM); 
    513         for (p = tl->t->b; p < tl->t->e; p++) { 
    514                 d *= 10; 
    515                 d += *p - '0'; 
    516         } 
    517         NextToken(tl); 
    518         return (d); 
    519 } 
    520  
    521 /*-------------------------------------------------------------------- 
    522  * Recognize and convert { CNUM [ '.' [ CNUM ] ] } to double value 
    523  */ 
    524  
    525 static double 
    526 DoubleVal(struct tokenlist *tl) 
    527 { 
    528         double d = 0.0, e = 0.1; 
    529         const char *p; 
    530  
    531         Expect(tl, CNUM); 
    532         for (p = tl->t->b; p < tl->t->e; p++) { 
    533                 d *= 10; 
    534                 d += *p - '0'; 
    535         } 
    536         NextToken(tl); 
    537         if (tl->t->tok != '.')  
    538                 return (d); 
    539         NextToken(tl); 
    540         if (tl->t->tok != CNUM) 
    541                 return (d); 
    542         for (p = tl->t->b; p < tl->t->e; p++) { 
    543                 d += (*p - '0') * e; 
    544                 e *= 0.1; 
    545         } 
    546         NextToken(tl); 
    547         return (d); 
    548 } 
    549  
    550 /*--------------------------------------------------------------------*/ 
    551  
    552 static unsigned 
    553 IpVal(struct tokenlist *tl) 
    554 { 
    555         unsigned u, v; 
    556         struct token *t; 
    557  
    558         t = tl->t; 
    559         u = UintVal(tl); 
    560         if (u < 256) { 
    561                 v = u << 24; 
    562                 Expect(tl, '.'); 
    563                 NextToken(tl); 
    564                 t = tl->t; 
    565                 u = UintVal(tl); 
    566                 if (u < 256) { 
    567                         v |= u << 16; 
    568                         Expect(tl, '.'); 
    569                         NextToken(tl); 
    570                         t = tl->t; 
    571                         u = UintVal(tl); 
    572                         if (u < 256) { 
    573                                 v |= u << 8; 
    574                                 Expect(tl, '.'); 
    575                                 NextToken(tl); 
    576                                 t = tl->t; 
    577                                 u = UintVal(tl); 
    578                                 if (u < 256) { 
    579                                         v |= u; 
    580                                         return (v); 
    581                                 } 
    582                         } 
    583                 } 
    584         } 
    585         sbuf_printf(tl->sb, "Illegal octet in IP number\n"); 
    586         ErrWhere(tl, t); 
    587         return (0); 
    588 } 
    589  
    590 /*--------------------------------------------------------------------*/ 
    591  
    592 static struct var * 
    593 HeaderVar(struct tokenlist *tl __unused, struct token *t, struct var *vh) 
    594 { 
    595         char *p; 
    596         struct var *v; 
    597         int i; 
    598  
    599         v = calloc(sizeof *v, 1); 
    600         assert(v != NULL); 
    601         i = t->e - t->b; 
    602         p = malloc(i + 1); 
    603         assert(p != NULL); 
    604         memcpy(p, t->b, i); 
    605         p[i] = '\0'; 
    606         v->name = p; 
    607         v->fmt = STRING; 
    608         asprintf(&p, "VRT_GetHdr(sp, \"\\%03o%s:\")", 
    609             strlen(v->name + vh->len) + 1, v->name + vh->len); 
    610         assert(p != NULL); 
    611         v->rname = p; 
    612         return (v); 
    613 } 
    614  
    615 /*--------------------------------------------------------------------*/ 
    616  
    617 static struct var * 
    618 FindVar(struct tokenlist *tl, struct token *t, struct var *vl) 
    619 { 
    620         struct var *v; 
    621  
    622         for (v = vl; v->name != NULL; v++) { 
    623                 if (v->fmt == HEADER  && t->e - t->b <= v->len) 
    624                         continue; 
    625                 if (v->fmt != HEADER  && t->e - t->b != v->len) 
    626                         continue; 
    627                 if (memcmp(t->b, v->name, v->len)) 
    628                         continue; 
    629                 if (v->fmt != HEADER) 
    630                         return (v); 
    631                 return (HeaderVar(tl, t, v)); 
    632         } 
    633         sbuf_printf(tl->sb, "Unknown variable "); 
    634         ErrToken(tl, t); 
    635         sbuf_cat(tl->sb, "\nAt: "); 
    636         ErrWhere(tl, t); 
    637         return (NULL); 
    638 } 
    639  
    640  
    641 /*--------------------------------------------------------------------*/ 
    642  
    643 static void 
    644 TimeVal(struct tokenlist *tl) 
    645 { 
    646         double v, sc; 
    647  
    648         v = DoubleVal(tl); 
    649         ExpectErr(tl, ID); 
    650         sc = TimeUnit(tl); 
    651         Fc(tl, 0, "(%g * %g)", v, sc); 
    652 } 
    653  
    654 static void 
    655 SizeVal(struct tokenlist *tl) 
    656 { 
    657         double v, sc; 
    658  
    659         v = DoubleVal(tl); 
    660         ExpectErr(tl, ID); 
    661         sc = SizeUnit(tl); 
    662         Fc(tl, 0, "(%g * %g)", v, sc); 
    663 } 
    664  
    665 static void 
    666 RateVal(struct tokenlist *tl) 
    667 { 
    668         double v, sc; 
    669  
    670         v = DoubleVal(tl); 
    671         ExpectErr(tl, ID); 
    672         sc = RateUnit(tl); 
    673         Fc(tl, 0, "(%g * %g)", v, sc); 
    674 } 
    675  
    676 /*--------------------------------------------------------------------*/ 
    677  
    678 static void 
    679 Cond_Ip(struct var *vp, struct tokenlist *tl) 
    680 { 
    681         unsigned u; 
    682  
    683         switch (tl->t->tok) { 
    684         case '~': 
    685                 NextToken(tl); 
    686                 ExpectErr(tl, ID); 
    687                 AddRef(tl, tl->t, R_ACL); 
    688                 Fc(tl, 1, "ip_match(%s, acl_%T)\n", vp->rname, tl->t); 
    689                 NextToken(tl); 
    690                 break; 
    691         case T_EQ: 
    692         case T_NEQ: 
    693                 Fc(tl, 1, "%s %T ", vp->rname, tl->t); 
    694                 NextToken(tl); 
    695                 u = IpVal(tl); 
    696                 Fc(tl, 0, "%uU /* %u.%u.%u.%u */\n", u, 
    697                     (u >> 24) & 0xff, (u >> 16) & 0xff, 
    698                     (u >> 8) & 0xff, (u) & 0xff); 
    699                 break; 
    700         default: 
    701                 sbuf_printf(tl->sb, "Illegal condition "); 
    702                 ErrToken(tl, tl->t); 
    703                 sbuf_printf(tl->sb, " on IP number variable\n"); 
    704                 sbuf_printf(tl->sb, "  only '==', '!=' and '~' are legal\n"); 
    705                 ErrWhere(tl, tl->t); 
    706                 break; 
    707         } 
    708 } 
    709  
    710 static void 
    711 Cond_String(struct var *vp, struct tokenlist *tl) 
    712 { 
    713  
    714         switch (tl->t->tok) { 
    715         case '~': 
    716                 Fc(tl, 1, "string_match(%s, ", vp->rname); 
    717                 NextToken(tl); 
    718                 ExpectErr(tl, CSTR); 
    719                 Fc(tl, 0, "%T)\n", tl->t); 
    720                 NextToken(tl); 
    721                 break; 
    722         case T_EQ: 
    723         case T_NEQ: 
    724                 Fc(tl, 1, "%sstrcmp(%s, ", 
    725                     tl->t->tok == T_EQ ? "!" : "", vp->rname); 
    726                 NextToken(tl); 
    727                 ExpectErr(tl, CSTR); 
    728                 Fc(tl, 0, "%T)\n", tl->t); 
    729                 NextToken(tl); 
    730                 break; 
    731         default: 
    732                 Fc(tl, 1, "%s != (void*)0", vp->rname); 
    733                 break; 
    734         } 
    735 } 
    736  
    737 static void 
    738 Cond_Int(struct var *vp, struct tokenlist *tl) 
    739 { 
    740  
    741         Fc(tl, 1, "%s ", vp->rname); 
    742         switch (tl->t->tok) { 
    743         case T_EQ: 
    744         case T_NEQ: 
    745         case T_LEQ: 
    746         case T_GEQ: 
    747         case '>': 
    748         case '<': 
    749                 Fc(tl, 0, "%T ", tl->t); 
    750                 NextToken(tl); 
    751                 switch(vp->fmt) { 
    752                 case TIME: 
    753                         TimeVal(tl); 
    754                         break; 
    755                 case INT: 
    756                         ExpectErr(tl, CNUM); 
    757                         Fc(tl, 0, "%T ", tl->t); 
    758                         NextToken(tl); 
    759                         break; 
    760                 case SIZE: 
    761                         SizeVal(tl); 
    762                         break; 
    763                 default: 
    764                         sbuf_printf(tl->sb, 
    765                             "No conditions available for variable '%s'\n", 
    766                             vp->name); 
    767                         ErrWhere(tl, tl->t); 
    768                         return; 
    769                 } 
    770                 Fc(tl, 0, "\n"); 
    771                 break; 
    772         default: 
    773                 sbuf_printf(tl->sb, "Illegal condition "); 
    774                 ErrToken(tl, tl->t); 
    775                 sbuf_printf(tl->sb, " on integer variable\n"); 
    776                 sbuf_printf(tl->sb, 
    777                     "  only '==', '!=', '<', '>', '<=' and '>=' are legal\n"); 
    778                 ErrWhere(tl, tl->t); 
    779                 break; 
    780         } 
    781 } 
    782  
    783 static void 
    784 Cond_Bool(struct var *vp, struct tokenlist *tl) 
    785 { 
    786  
    787         Fc(tl, 1, "%s\n", vp->rname); 
    788 } 
    789  
    790 static void 
    791 Cond_2(struct tokenlist *tl) 
    792 { 
    793         struct var *vp; 
    794  
    795         C(tl, ","); 
    796         if (tl->t->tok == '!') { 
    797                 Fc(tl, 1, "!(\n"); 
    798                 NextToken(tl); 
    799         } else { 
    800                 Fc(tl, 1, "(\n"); 
    801         } 
    802         if (tl->t->tok == '(') { 
    803                 NextToken(tl); 
    804                 Cond_0(tl); 
    805                 ExpectErr(tl, ')'); 
    806                 NextToken(tl); 
    807         } else if (tl->t->tok == VAR) { 
    808                 vp = FindVar(tl, tl->t, vars); 
    809                 ERRCHK(tl); 
    810                 assert(vp != NULL); 
    811                 NextToken(tl); 
    812                 switch (vp->fmt) { 
    813                 case INT:       L(tl, Cond_Int(vp, tl)); break; 
    814                 case SIZE:      L(tl, Cond_Int(vp, tl)); break; 
    815                 case BOOL:      L(tl, Cond_Bool(vp, tl)); break; 
    816                 case IP:        L(tl, Cond_Ip(vp, tl)); break; 
    817                 case STRING:    L(tl, Cond_String(vp, tl)); break; 
    818                 case TIME:      L(tl, Cond_Int(vp, tl)); break; 
    819                 /* XXX backend == */ 
    820                 default:         
    821                         sbuf_printf(tl->sb, 
    822                             "Variable '%s'" 
    823                             " has no conditions that can be checked\n", 
    824                             vp->name); 
    825                         ErrWhere(tl, tl->t); 
    826                         return; 
    827                 } 
    828         } else { 
    829                 sbuf_printf(tl->sb, 
    830                     "Syntax error in condition, expected '(', '!' or" 
    831                     " variable name, found "); 
    832                 ErrToken(tl, tl->t); 
    833                 sbuf_printf(tl->sb, "\n"); 
    834                 ErrWhere(tl, tl->t); 
    835                 return; 
    836         } 
    837         Fc(tl, 1, ")\n"); 
    838 } 
    839  
    840 static void 
    841 Cond_1(struct tokenlist *tl) 
    842 { 
    843  
    844         Fc(tl, 1, "(\n"); 
    845         L(tl, Cond_2(tl)); 
    846         while (tl->t->tok == T_CAND) { 
    847                 NextToken(tl); 
    848                 Fc(tl, 1, ") && (\n"); 
    849                 L(tl, Cond_2(tl)); 
    850         } 
    851         Fc(tl, 1, ")\n"); 
    852 } 
    853  
    854 static void 
    855 Cond_0(struct tokenlist *tl) 
    856 { 
    857  
    858         Fc(tl, 1, "(\n"); 
    859         L(tl, Cond_1(tl)); 
    860         while (tl->t->tok == T_COR) { 
    861                 NextToken(tl); 
    862                 Fc(tl, 1, ") || (\n"); 
    863                 L(tl, Cond_1(tl)); 
    864         } 
    865         Fc(tl, 1, ")\n"); 
    866 } 
    867  
    868 static void 
    869 Conditional(struct tokenlist *tl) 
    870 { 
    871  
    872         ExpectErr(tl, '('); 
    873         NextToken(tl); 
    874         Fc(tl, 1, "(\n"); 
    875         L(tl, Cond_0(tl)); 
    876         ERRCHK(tl); 
    877         Fc(tl, 1, ")\n"); 
    878         ExpectErr(tl, ')'); 
    879         NextToken(tl); 
    880 } 
    881  
    882 /*--------------------------------------------------------------------*/ 
    883  
    884 static void 
    885 IfStmt(struct tokenlist *tl) 
    886 { 
    887  
    888         ExpectErr(tl, T_IF); 
    889         Fc(tl, 1, "if \n"); 
    890         NextToken(tl); 
    891         L(tl, Conditional(tl)); 
    892         ERRCHK(tl); 
    893         L(tl, Compound(tl)); 
    894         ERRCHK(tl); 
    895         while (1) { 
    896                 switch (tl->t->tok) { 
    897                 case T_ELSE: 
    898                         NextToken(tl); 
    899                         if (tl->t->tok != T_IF) { 
    900                                 Fc(tl, 1, "else \n"); 
    901                                 L(tl, Compound(tl)); 
    902                                 ERRCHK(tl); 
    903                                 return; 
    904                         } 
    905                         /* FALLTHROUGH */ 
    906                 case T_ELSEIF: 
    907                 case T_ELSIF: 
    908                         Fc(tl, 1, "else if \n"); 
    909                         NextToken(tl); 
    910                         L(tl, Conditional(tl)); 
    911                         ERRCHK(tl); 
    912                         L(tl, Compound(tl)); 
    913                         ERRCHK(tl); 
    914                         break; 
    915                 default: 
    916                         C(tl, ";"); 
    917                         return; 
    918                 } 
    919         } 
    920 } 
    921  
    922 /*--------------------------------------------------------------------*/ 
    923  
    924 static void 
    925 Action(struct tokenlist *tl) 
    926 { 
    927         unsigned a, u; 
    928         struct var *vp; 
    929         struct token *at; 
    930  
    931         at = tl->t; 
    932         NextToken(tl); 
    933         switch (at->tok) { 
    934         case T_NO_NEW_CACHE: 
    935                 Fc(tl, 1, "VCL_no_new_cache(sp);\n"); 
    936                 return; 
    937         case T_NO_CACHE: 
    938                 Fc(tl, 1, "VCL_no_cache(sp);\n"); 
    939                 return; 
    940 #define VCL_RET_MAC(a,b,c) case T_##b: \ 
    941                 Fc(tl, 1, "VRT_done(sp, VCL_RET_%s);\n", #b); \ 
    942                 tl->curproc->returns |= VCL_RET_##b; \ 
    943                 tl->curproc->returnt[c] = at; \ 
    944                 return; 
    945 #include "vcl_returns.h" 
    946 #undef VCL_RET_MAC 
    947         case T_ERROR: 
    948                 if (tl->t->tok == CNUM) 
    949                         a = UintVal(tl); 
    950                 else 
    951                         a = 0; 
    952                 Fc(tl, 1, "VRT_error(sp, %u, ", a); 
    953                 if (tl->t->tok == CSTR) { 
    954                         Fc(tl, 0, "%T);\n", tl->t); 
    955                         NextToken(tl); 
    956                 } else 
    957                         Fc(tl, 0, "(const char *)0);\n"); 
    958                 Fc(tl, 1, "VRT_done(sp, VCL_RET_ERROR);\n"); 
    959                 return; 
    960         case T_SWITCH_CONFIG: 
    961                 ExpectErr(tl, ID); 
    962                 Fc(tl, 1, "VCL_switch_config(\"%T\");\n", tl->t); 
    963                 NextToken(tl); 
    964                 return; 
    965         case T_CALL: 
    966                 ExpectErr(tl, ID); 
    967                 AddCall(tl, tl->t); 
    968                 AddRef(tl, tl->t, R_FUNC); 
    969                 Fc(tl, 1, "if (VGC_function_%T(sp))\n", tl->t); 
    970                 Fc(tl, 1, "\treturn (1);\n"); 
    971                 NextToken(tl); 
    972                 return; 
    973         case T_REWRITE: 
    974                 ExpectErr(tl, CSTR); 
    975                 Fc(tl, 1, "VCL_rewrite(%T", tl->t); 
    976                 NextToken(tl); 
    977                 ExpectErr(tl, CSTR); 
    978                 Fc(tl, 0, ", %T);\n", tl->t); 
    979                 NextToken(tl); 
    980                 return; 
    981         case T_SET: 
    982                 ExpectErr(tl, VAR); 
    983                 vp = FindVar(tl, tl->t, vars); 
    984                 ERRCHK(tl); 
    985                 assert(vp != NULL); 
    986                 Fc(tl, 1, "%s ", vp->rname); 
    987                 NextToken(tl); 
    988                 switch (vp->fmt) { 
    989                 case INT: 
    990                 case SIZE: 
    991                 case RATE: 
    992                 case TIME: 
    993                 case FLOAT: 
    994                         Fc(tl, 0, "%T ", tl->t); 
    995                         a = tl->t->tok; 
    996                         NextToken(tl); 
    997                         if (a == T_MUL || a == T_DIV) 
    998                                 Fc(tl, 0, "%g", DoubleVal(tl)); 
    999                         else if (vp->fmt == TIME) 
    1000                                 TimeVal(tl); 
    1001                         else if (vp->fmt == SIZE) 
    1002                                 SizeVal(tl); 
    1003                         else if (vp->fmt == RATE) 
    1004                                 RateVal(tl); 
    1005                         else  
    1006                                 Fc(tl, 0, "%g", DoubleVal(tl)); 
    1007                         Fc(tl, 0, ";\n"); 
    1008                         break; 
    1009                 case IP: 
    1010                         if (tl->t->tok == '=') { 
    1011                                 NextToken(tl); 
    1012                                 u = IpVal(tl); 
    1013                                 Fc(tl, 0, "= %uU; /* %u.%u.%u.%u */\n", 
    1014                                     u, 
    1015                                     (u >> 24) & 0xff, 
    1016                                     (u >> 16) & 0xff, 
    1017                                     (u >> 8) & 0xff, 
    1018                                     u & 0xff); 
    1019                                 break; 
    1020                         } 
    1021                         sbuf_printf(tl->sb, "Illegal assignment operator "); 
    1022                         ErrToken(tl, tl->t); 
    1023                         sbuf_printf(tl->sb, 
    1024                             " only '=' is legal for IP numbers\n"); 
    1025                         ErrWhere(tl, tl->t); 
    1026                         return; 
    1027                 case BACKEND: 
    1028                         if (tl->t->tok == '=') { 
    1029                                 NextToken(tl); 
    1030                                 AddRef(tl, tl->t, R_BACKEND); 
    1031                                 Fc(tl, 0, "= &VGC_backend_%T;\n", tl->t); 
    1032                                 NextToken(tl); 
    1033                                 break; 
    1034                         } 
    1035                         sbuf_printf(tl->sb, "Illegal assignment operator "); 
    1036                         ErrToken(tl, tl->t); 
    1037                         sbuf_printf(tl->sb, 
    1038                             " only '=' is legal for backend\n"); 
    1039                         ErrWhere(tl, tl->t); 
    1040                         return; 
    1041                 default: 
    1042                         sbuf_printf(tl->sb, 
    1043                             "Assignments not possible for '%s'\n", vp->name); 
    1044                         ErrWhere(tl, tl->t); 
    1045                         return; 
    1046                 } 
    1047                 return; 
    1048         default: 
    1049                 sbuf_printf(tl->sb, "Expected action, 'if' or '}'\n"); 
    1050                 ErrWhere(tl, at); 
    1051                 return; 
    1052         } 
    1053 } 
    1054  
    1055 /*--------------------------------------------------------------------*/ 
    1056  
    1057 static void 
    1058 Acl(struct tokenlist *tl) 
    1059 { 
    1060         unsigned u, m; 
    1061  
    1062         NextToken(tl); 
    1063  
    1064         ExpectErr(tl, ID); 
    1065         AddDef(tl, tl->t, R_ACL); 
    1066         Fh(tl, 0, "static struct vcl_acl acl_%T[];\n", tl->t); 
    1067         Fc(tl, 1, "static struct vcl_acl acl_%T[] = {\n", tl->t); 
    1068         NextToken(tl); 
    1069  
    1070         tl->indent += INDENT; 
    1071  
    1072         ExpectErr(tl, '{'); 
    1073         NextToken(tl); 
    1074  
    1075         while (tl->t->tok == CNUM) { 
    1076                 u = IpVal(tl); 
    1077                 if (tl->t->tok == '/') { 
    1078                         NextToken(tl); 
    1079                         ExpectErr(tl, CNUM); 
    1080                         m = UintVal(tl); 
    1081                 } else 
    1082                         m = 32; 
    1083                 ExpectErr(tl, ';'); 
    1084                 NextToken(tl); 
    1085                 Fc(tl, 1, "{ %11uU, %3uU }, /* %u.%u.%u.%u/%u */\n", 
    1086                     u, m, 
    1087                     (u >> 24) & 0xff, (u >> 16) & 0xff, 
    1088                     (u >> 8) & 0xff, (u) & 0xff, m); 
    1089         } 
    1090         ExpectErr(tl, '}'); 
    1091         Fc(tl, 1, "{ %11uU, %3uU }\n", 0, 0); 
    1092  
    1093         tl->indent -= INDENT; 
    1094  
    1095         Fc(tl, 1, "};\n\n"); 
    1096         NextToken(tl); 
    1097 } 
    1098  
    1099 /*--------------------------------------------------------------------*/ 
    1100  
    1101 static void 
    1102 Compound(struct tokenlist *tl) 
    1103 { 
    1104  
    1105         ExpectErr(tl, '{'); 
    1106         Fc(tl, 1, "{\n"); 
    1107         tl->indent += INDENT; 
    1108         C(tl, ";"); 
    1109         NextToken(tl); 
    1110         while (1) { 
    1111                 ERRCHK(tl); 
    1112                 switch (tl->t->tok) { 
    1113                 case '{': 
    1114                         Compound(tl); 
    1115                         break; 
    1116                 case T_IF: 
    1117                         IfStmt(tl); 
    1118                         break; 
    1119                 case '}': 
    1120                         NextToken(tl); 
    1121                         tl->indent -= INDENT; 
    1122                         Fc(tl, 1, "}\n"); 
    1123                         return; 
    1124                 case EOI: 
    1125                         sbuf_printf(tl->sb, 
    1126                             "End of input while in compound statement\n"); 
    1127                         tl->err = 1; 
    1128                         return; 
    1129                 default: 
    1130                         Action(tl); 
    1131                         ERRCHK(tl); 
    1132                         ExpectErr(tl, ';'); 
    1133                         NextToken(tl); 
    1134                         break; 
    1135                 } 
    1136         } 
    1137 } 
    1138  
    1139 /*--------------------------------------------------------------------*/ 
    1140  
    1141 static const char * 
    1142 CheckHostPort(const char *host, const char *port) 
    1143 { 
    1144         struct addrinfo *res, hint; 
    1145         int error; 
    1146  
    1147         memset(&hint, 0, sizeof hint); 
    1148         hint.ai_family = PF_UNSPEC; 
    1149         hint.ai_socktype = SOCK_STREAM; 
    1150         error = getaddrinfo(host, port, &hint, &res); 
    1151         if (error)  
    1152                 return (gai_strerror(error)); 
    1153         freeaddrinfo(res); 
    1154         return (NULL); 
    1155 } 
    1156  
    1157 static void 
    1158 Backend(struct tokenlist *tl) 
    1159 { 
    1160         struct var *vp; 
    1161         struct token *t_be = NULL; 
    1162         struct token *t_host = NULL; 
    1163         struct token *t_port = NULL; 
    1164         char *host = NULL; 
    1165         char *port = NULL; 
    1166         const char *ep; 
    1167  
    1168         NextToken(tl); 
    1169         ExpectErr(tl, ID); 
    1170         t_be = tl->t; 
    1171         AddDef(tl, tl->t, R_BACKEND); 
    1172         if (tl->nbackend == 0) 
    1173                 AddRef(tl, tl->t, R_BACKEND); 
    1174         Fh(tl, 1, "#define VGC_backend_%T (VCL_conf.backend[%d])\n", 
    1175             tl->t, tl->nbackend); 
    1176         Fc(tl, 0, "static void\n"); 
    1177         Fc(tl, 1, "VGC_init_backend_%T (void)\n", tl->t); 
    1178         Fc(tl, 1, "{\n"); 
    1179         Fc(tl, 1, "\tstruct backend *backend = VGC_backend_%T;\n", tl->t); 
    1180         Fc(tl, 1, "\tconst char *p;\n"); 
    1181         Fc(tl, 1, "\n"); 
    1182         Fc(tl, 1, "\tVRT_set_backend_name(backend, \"%T\");\n", tl->t); 
    1183         NextToken(tl); 
    1184         ExpectErr(tl, '{'); 
    1185         NextToken(tl); 
    1186         while (1) { 
    1187                 if (tl->t->tok == '}') 
    1188                         break; 
    1189                 ExpectErr(tl, T_SET); 
    1190                 NextToken(tl); 
    1191                 ExpectErr(tl, VAR); 
    1192                 vp = FindVar(tl, tl->t, be_vars); 
    1193                 ERRCHK(tl); 
    1194                 assert(vp != NULL); 
    1195                 NextToken(tl); 
    1196                 ExpectErr(tl, '='); 
    1197                 NextToken(tl); 
    1198                 switch (vp->fmt) { 
    1199                 case HOSTNAME: 
    1200                         ExpectErr(tl, CSTR); 
    1201                         t_host = tl->t; 
    1202                         Fc(tl, 1, "\tp = %T;\n", tl->t); 
    1203                         Fc(tl, 1, "\t"); 
    1204                         Fc(tl, 0, vp->lname, "p"); 
    1205                         Fc(tl, 0, ";\n"); 
    1206                         NextToken(tl); 
    1207                         break; 
    1208                 case PORTNAME: 
    1209                         ExpectErr(tl, CSTR); 
    1210                         t_port = tl->t; 
    1211                         Fc(tl, 1, "\tp = %T;\n", tl->t); 
    1212                         Fc(tl, 1, "\t"); 
    1213                         Fc(tl, 0, vp->lname, "p"); 
    1214                         Fc(tl, 0, ";\n"); 
    1215                         NextToken(tl); 
    1216                         break; 
    1217                 default: 
    1218                         sbuf_printf(tl->sb, 
    1219                             "Assignments not possible for '%s'\n", vp->name); 
    1220                         ErrWhere(tl, tl->t); 
    1221                         return; 
    1222                 } 
    1223                 ExpectErr(tl, ';'); 
    1224                 NextToken(tl); 
    1225         } 
    1226         ExpectErr(tl, '}'); 
    1227         if (t_host == NULL) { 
    1228                 sbuf_printf(tl->sb, "Backend '%T' has no hostname\n", t_be); 
    1229                 ErrWhere(tl, tl->t); 
    1230                 return; 
    1231         } 
    1232         host = EncString(t_host); 
    1233         ep = CheckHostPort(host, "80"); 
    1234         if (ep != NULL) { 
    1235                 sbuf_printf(tl->sb, "Backend '%T': %s\n", t_be, ep); 
    1236                 ErrWhere(tl, t_host); 
    1237                 return; 
    1238         } 
    1239         if (t_port != NULL) { 
    1240                 port = EncString(t_port); 
    1241                 ep = CheckHostPort(host, port); 
    1242                 if (ep != NULL) { 
    1243                         sbuf_printf(tl->sb, "Backend '%T': %s\n", t_be, ep); 
    1244                         ErrWhere(tl, t_port); 
    1245                         return; 
    1246                 } 
    1247         } 
    1248          
    1249         NextToken(tl); 
    1250         Fc(tl, 1, "}\n"); 
    1251         Fc(tl, 0, "\n"); 
    1252         tl->nbackend++; 
    1253 } 
    1254  
    1255 /*--------------------------------------------------------------------*/ 
    1256  
    1257 static void 
    1258 Function(struct tokenlist *tl) 
    1259 { 
    1260  
    1261         NextToken(tl); 
    1262         ExpectErr(tl, ID); 
    1263         tl->curproc = AddProc(tl, tl->t, 1); 
    1264         tl->curproc->exists++; 
    1265         AddDef(tl, tl->t, R_FUNC); 
    1266         Fh(tl, 0, "static int VGC_function_%T (struct sess *sp);\n", tl->t); 
    1267         Fc(tl, 1, "static int\n"); 
    1268         Fc(tl, 1, "VGC_function_%T (struct sess *sp)\n", tl->t); 
    1269         NextToken(tl); 
    1270         L(tl, Compound(tl)); 
    1271         Fc(tl, 0, "\n"); 
    1272 } 
    1273  
    1274 /*-------------------------------------------------------------------- 
    1275  * Top level of parser, recognize: 
    1276  *      Function definitions 
    1277  *      Backend definitions 
    1278  *      End of input 
    1279  */ 
    1280  
    1281 static void 
    1282 Parse(struct tokenlist *tl) 
    1283 { 
    1284  
    1285         while (tl->t->tok != EOI) { 
    1286                 ERRCHK(tl); 
    1287                 switch (tl->t->tok) { 
    1288                 case T_ACL: 
    1289                         Acl(tl); 
    1290                         break; 
    1291                 case T_SUB: 
    1292                         Function(tl); 
    1293                         break; 
    1294                 case T_BACKEND: 
    1295                         Backend(tl); 
    1296                         break; 
    1297                 case EOI: 
    1298                         break; 
    1299                 default: 
    1300                         sbuf_printf(tl->sb, 
    1301                             "Expected 'acl', 'sub' or 'backend', found "); 
    1302                         ErrToken(tl, tl->t); 
    1303                         sbuf_printf(tl->sb, " at\n"); 
    1304                         ErrWhere(tl, tl->t); 
    1305                         return; 
    1306                 } 
    1307         } 
    1308 } 
    1309  
    1310 /*-------------------------------------------------------------------- 
    1311  * Add a token to the token list. 
    1312  */ 
    1313  
    1314 static void 
    1315 AddToken(struct tokenlist *tl, unsigned tok, const char *b, const char *e) 
    1316 { 
    1317         struct token *t; 
    1318  
    1319         t = calloc(sizeof *t, 1); 
    1320         assert(t != NULL); 
    1321         t->tok = tok; 
    1322         t->b = b; 
    1323         t->e = e; 
    1324         TAILQ_INSERT_TAIL(&tl->tokens, t, list); 
    1325         tl->t = t; 
    1326         if (0) { 
    1327                 fprintf(stderr, "[%s %*.*s] ", 
    1328                     vcl_tnames[tok], 
    1329                     e - b, e - b, b); 
    1330                 if (tok == EOI) 
    1331                         fprintf(stderr, "\n"); 
    1332         } 
    1333 } 
    1334  
    1335 /*-------------------------------------------------------------------- 
    1336  * Lexical analysis and token generation 
    1337  */ 
    1338  
    1339 static void 
    1340 Lexer(struct tokenlist *tl, const char *b, const char *e) 
    1341 { 
    1342         const char *p, *q; 
    1343         unsigned u; 
    1344  
    1345         for (p = b; p < e; ) { 
    1346  
    1347                 /* Skip any whitespace */ 
    1348                 if (isspace(*p)) { 
    1349                         p++; 
    1350                         continue; 
    1351                 } 
    1352  
    1353                 /* Skip '#.*\n' comments */ 
    1354                 if (*p == '#') { 
    1355                         while (p < e && *p != '\n') 
    1356                                 p++; 
    1357                         continue; 
    1358                 } 
    1359  
    1360                 /* Skip C-style comments */ 
    1361                 if (*p == '/' && p[1] == '*') { 
    1362                         p += 2; 
    1363                         for (p += 2; p < e; p++) { 
    1364                                 if (*p == '*' && p[1] == '/') { 
    1365                                         p += 2; 
    1366                                         break; 
    1367                                 } 
    1368                         } 
    1369                         continue; 
    1370                 } 
    1371  
    1372                 /* Match for the fixed tokens (see token.tcl) */ 
    1373                 u = vcl_fixed_token(p, &q); 
    1374                 if (u != 0) { 
    1375                         AddToken(tl, u, p, q); 
    1376                         p = q; 
    1377                         continue; 
    1378                 } 
    1379  
    1380                 /* Match strings, with \\ and \" escapes */ 
    1381                 if (*p == '"') { 
    1382                         for (q = p + 1; q < e; q++) { 
    1383                                 if (*q == '\\' && q[1] == '\\') 
    1384                                         q++; 
    1385                                 else if (*q == '\\' && q[1] == '"') 
    1386                                         q++; 
    1387                                 else if (*q == '"') { 
    1388                                         q++; 
    1389                                         break; 
    1390                                 } 
    1391                         } 
    1392                         AddToken(tl, CSTR, p, q); 
    1393                         p = q; 
    1394                         continue; 
    1395                 } 
    1396  
    1397                 /* Match Identifiers */ 
    1398                 if (isident1(*p)) { 
    1399                         for (q = p; q < e; q++) 
    1400                                 if (!isident(*q)) 
    1401                                         break; 
    1402                         if (isvar(*q)) { 
    1403                                 for (; q < e; q++) 
    1404                                         if (!isvar(*q)) 
    1405                                                 break; 
    1406                                 AddToken(tl, VAR, p, q); 
    1407                         } else { 
    1408                                 AddToken(tl, ID, p, q); 
    1409                         } 
    1410                         p = q; 
    1411                         continue; 
    1412                 } 
    1413  
    1414                 /* Match numbers { [0-9]+ } */ 
    1415                 if (isdigit(*p)) { 
    1416                         for (q = p; q < e; q++) 
    1417                                 if (!isdigit(*q)) 
    1418                                         break; 
    1419                         AddToken(tl, CNUM, p, q); 
    1420                         p = q; 
    1421                         continue; 
    1422                 } 
    1423                 AddToken(tl, EOI, p, p + 1); 
    1424                 sbuf_printf(tl->sb, "Syntax error at\n"); 
    1425                 ErrWhere(tl, tl->t); 
    1426                 return; 
    1427         } 
    1428 } 
    1429  
    1430 /*-------------------------------------------------------------------- 
    1431  * Consistency check 
    1432  */ 
    1433  
    1434 static struct proc * 
    1435 AddProc(struct tokenlist *tl, struct token *t, int def) 
    1436 { 
    1437         struct proc *p; 
    1438  
    1439         TAILQ_FOREACH(p, &tl->procs, list) { 
    1440                 if (!Teq(p->name, t))  
    1441                         continue; 
    1442                 if (def) 
    1443                         p->name = t; 
    1444                 return (p); 
    1445         } 
    1446         p = calloc(sizeof *p, 1); 
    1447         assert(p != NULL); 
    1448         p->name = t; 
    1449         TAILQ_INIT(&p->calls); 
    1450         TAILQ_INSERT_TAIL(&tl->procs, p, list); 
    1451         return (p); 
    1452 } 
    1453  
    1454 static void 
    1455 AddCall(struct tokenlist *tl, struct token *t) 
    1456 { 
    1457         struct proccall *pc; 
    1458         struct proc *p; 
    1459  
    1460         p = AddProc(tl, t, 0); 
    1461         TAILQ_FOREACH(pc, &tl->curproc->calls, list) { 
    1462                 if (pc->p == p) 
    1463                         return; 
    1464         } 
    1465         pc = calloc(sizeof *pc, 1); 
    1466         assert(pc != NULL); 
    1467         pc->p = p; 
    1468         pc->t = t; 
    1469         TAILQ_INSERT_TAIL(&tl->curproc->calls, pc, list); 
    1470 } 
    1471  
    1472 static int 
    1473 Consist_Decend(struct tokenlist *tl, struct proc *p, unsigned returns) 
    1474 { 
    1475         unsigned u; 
    1476         struct proccall *pc; 
    1477  
    1478         if (!p->exists) { 
    1479                 sbuf_printf(tl->sb, "Function %T does not exist\n", p->name); 
    1480                 return (1); 
    1481         } 
    1482         if (p->active) { 
    1483                 sbuf_printf(tl->sb, "Function recurses on\n"); 
    1484                 ErrWhere(tl, p->name); 
    1485                 return (1); 
    1486         } 
    1487         u = p->returns & ~returns; 
    1488         if (u) { 
    1489 #define VCL_RET_MAC(a, b, c) \ 
    1490                 if (u & VCL_RET_##b) { \ 
    1491                         sbuf_printf(tl->sb, "Illegal return for method\n"); \ 
    1492                         ErrWhere(tl, p->returnt[c]); \ 
    1493                 }  
    1494 #include "vcl_returns.h" 
    1495 #undef VCL_RET_MAC 
    1496                 sbuf_printf(tl->sb, "In function\n"); 
    1497                 ErrWhere(tl, p->name); 
    1498                 return (1); 
    1499         } 
    1500         p->active = 1; 
    1501         TAILQ_FOREACH(pc, &p->calls, list) { 
    1502                 if (Consist_Decend(tl, pc->p, returns)) { 
    1503                         sbuf_printf(tl->sb, "\nCalled from\n"); 
    1504                         ErrWhere(tl, p->name); 
    1505                         sbuf_printf(tl->sb, "at\n"); 
    1506                         ErrWhere(tl, pc->t); 
    1507                         return (1); 
    1508                 } 
    1509         } 
    1510         p->active = 0; 
    1511         p->called++; 
    1512         return (0); 
    1513 } 
    1514  
    1515 static int 
    1516 Consistency(struct tokenlist *tl) 
    1517 { 
    1518         struct proc *p; 
    1519         struct method *m; 
    1520  
    1521         TAILQ_FOREACH(p, &tl->procs, list) { 
    1522                 for(m = method_tab; m->name != NULL; m++) { 
    1523                         if (IdIs(p->name, m->defname)) 
    1524                                 p->called = 1; 
    1525                         if (IdIs(p->name, m->name)) 
    1526                                 break; 
    1527                 } 
    1528                 if (m->name == NULL)  
    1529                         continue; 
    1530                 if (Consist_Decend(tl, p, m->returns)) { 
    1531                         sbuf_printf(tl->sb, 
    1532                             "\nwhich is a %s method\n", m->name); 
    1533                         return (1); 
    1534                 } 
    1535         } 
    1536         TAILQ_FOREACH(p, &tl->procs, list) { 
    1537                 if (p->called) 
    1538                         continue; 
    1539                 sbuf_printf(tl->sb, "Function unused\n"); 
    1540                 ErrWhere(tl, p->name); 
    1541                 return (1); 
    1542         } 
    1543         return (0); 
    1544 } 
    1545  
    1546 /*--------------------------------------------------------------------*/ 
    1547  
    1548 static int 
    1549 CheckRefs(struct tokenlist *tl) 
    1550 { 
    1551         struct ref *r; 
    1552         const char *type; 
    1553         int nerr = 0; 
    1554  
    1555         TAILQ_FOREACH(r, &tl->refs, list) { 
    1556                 if (r->defcnt != 0 && r->refcnt != 0) 
    1557                         continue; 
    1558                 nerr++; 
    1559  
    1560                 switch(r->type) { 
    1561                 case R_FUNC: 
    1562                         type = "function"; 
    1563                         break; 
    1564                 case R_ACL: 
    1565                         type = "acl"; 
    1566                         break; 
    1567                 case R_BACKEND: 
    1568                         type = "backend"; 
    1569                         break; 
    1570                 default: 
    1571                         ErrInternal(tl); 
    1572                         sbuf_printf(tl->sb, "Ref "); 
    1573                         ErrToken(tl, r->name); 
    1574                         sbuf_printf(tl->sb, " has unknown type %d\n", 
    1575                             r->type); 
    1576                         continue; 
    1577                 } 
    1578                 if (r->defcnt == 0 && r->name->tok == METHOD) { 
    1579                         sbuf_printf(tl->sb, 
    1580                             "No definition for method %T\n", r->name); 
    1581                         continue; 
    1582                 } 
    1583  
    1584                 if (r->defcnt == 0) { 
    1585                         sbuf_printf(tl->sb, 
    1586                             "Undefined %s %T, first reference:\n", 
    1587                             type, r->name); 
    1588                         ErrWhere(tl, r->name); 
    1589                         continue; 
    1590                 }  
    1591  
    1592                 sbuf_printf(tl->sb, "Unused %s %T, defined:\n", type, r->name); 
    1593                 ErrWhere(tl, r->name); 
    1594         } 
    1595         return (nerr); 
    1596 } 
    1597  
    1598 /*--------------------------------------------------------------------*/ 
    1599  
    1600 static void 
    1601 LocTable(struct tokenlist *tl) 
    1602 { 
    1603         struct token *t; 
    1604         unsigned lin, pos; 
    1605         const char *p; 
    1606          
    1607         Fh(tl, 0, "#define VGC_NREFS %u\n", tl->cnt + 1); 
    1608         Fh(tl, 0, "static struct vrt_ref VGC_ref[VGC_NREFS];\n"); 
    1609         Fc(tl, 0, "static struct vrt_ref VGC_ref[VGC_NREFS] = {\n"); 
    1610         lin = 1; 
    1611         pos = 0; 
    1612         p = tl->b; 
    1613         TAILQ_FOREACH(t, &tl->tokens, list) { 
    1614                 if (t->cnt == 0) 
    1615                         continue; 
    1616                 for (;p < t->b; p++) { 
    1617                         if (*p == '\n') { 
    1618                                 lin++; 
    1619                                 pos = 0; 
    1620                         } else if (*p == '\t') { 
    1621                                 pos &= ~7; 
    1622                                 pos += 8; 
    1623                         } else 
    1624                                 pos++; 
    1625                  
    1626                 } 
    1627                 Fc(tl, 0, "  [%3u] = { %4u, %3u, 0, \"%T\" },\n", 
    1628                     t->cnt, lin, pos + 1, t); 
    1629         } 
    1630         Fc(tl, 0, "};\n"); 
    1631 } 
    1632  
    1633  
    1634 /*--------------------------------------------------------------------*/ 
    1635  
    1636 static void 
    1637 EmitInitFunc(struct tokenlist *tl) 
    1638 { 
    1639         struct ref *r; 
    1640  
    1641         Fc(tl, 0, "\nstatic void\nVGC_Init(void)\n{\n\n"); 
    1642         Fc(tl, 0, "\tVRT_alloc_backends(&VCL_conf);\n"); 
    1643          
    1644         TAILQ_FOREACH(r, &tl->refs, list) { 
    1645                 switch(r->type) { 
    1646                 case R_FUNC: 
    1647                         break; 
    1648                 case R_ACL: 
    1649                         break; 
    1650                 case R_BACKEND: 
    1651                         Fc(tl, 0, "\tVGC_init_backend_%T();\n", r->name); 
    1652                         break; 
    1653                 } 
    1654         } 
    1655         Fc(tl, 0, "}\n"); 
    1656 } 
    1657  
    1658 /*--------------------------------------------------------------------*/ 
    1659  
    1660 static void 
    1661 EmitStruct(struct tokenlist *tl) 
    1662 { 
    1663  
    1664         Fc(tl, 0, "\nstruct VCL_conf VCL_conf = {\n"); 
    1665         Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n"); 
    1666         Fc(tl, 0, "\t.init_func = VGC_Init,\n"); 
    1667         Fc(tl, 0, "\t.nbackend = %d,\n", tl->nbackend); 
    1668         Fc(tl, 0, "\t.ref = VGC_ref,\n"); 
    1669         Fc(tl, 0, "\t.nref = VGC_NREFS,\n"); 
    1670 #define VCL_RET_MAC(l,u,b) 
    1671 #define VCL_MET_MAC(l,u,b) \ 
    1672         if (FindRefStr(tl, "vcl_" #l, R_FUNC)) { \ 
    1673                 Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); \ 
    1674                 AddRefStr(tl, "vcl_" #l, R_FUNC); \ 
    1675         } else { \ 
    1676                 Fc(tl, 0, "\t." #l "_func = VGC_function_default_vcl_" #l ",\n"); \ 
    1677         } \ 
    1678         AddRefStr(tl, "default_vcl_" #l, R_FUNC); 
    1679 #include "vcl_returns.h" 
    1680 #undef VCL_MET_MAC 
    1681 #undef VCL_RET_MAC 
    1682         Fc(tl, 0, "};\n"); 
    1683 } 
    1684  
    1685 /*--------------------------------------------------------------------*/ 
    1686  
    1687 char * 
    1688 VCC_Compile(struct sbuf *sb, const char *b, const char *e) 
    1689 { 
    1690         struct tokenlist tokens; 
    1691         struct ref *r; 
    1692         struct token *t; 
    1693         FILE *fo; 
    1694         char *of = NULL; 
    1695         char buf[BUFSIZ]; 
    1696  
    1697         memset(&tokens, 0, sizeof tokens); 
    1698         TAILQ_INIT(&tokens.tokens); 
    1699         TAILQ_INIT(&tokens.refs); 
    1700         TAILQ_INIT(&tokens.procs); 
    1701         tokens.sb = sb; 
    1702  
    1703         tokens.fc = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 
    1704         assert(tokens.fc != NULL); 
    1705  
    1706         tokens.fh = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 
    1707         assert(tokens.fh != NULL); 
    1708  
    1709         Fh(&tokens, 0, "extern struct VCL_conf VCL_conf;\n"); 
    1710  
    1711         tokens.b = b; 
    1712         if (e == NULL) 
    1713                 e = strchr(b, '\0'); 
    1714         assert(e != NULL); 
    1715         tokens.e = e; 
    1716         Lexer(&tokens, b, e); 
    1717         Lexer(&tokens, vcc_default_vcl_b, vcc_default_vcl_e); 
    1718         AddToken(&tokens, EOI, e, e); 
    1719         if (tokens.err) 
    1720                 goto done; 
    1721         tokens.t = TAILQ_FIRST(&tokens.tokens); 
    1722         Parse(&tokens); 
    1723         if (tokens.err) 
    1724                 goto done; 
    1725         Consistency(&tokens); 
    1726         if (tokens.err) 
    1727                 goto done; 
    1728         LocTable(&tokens); 
    1729  
    1730         EmitInitFunc(&tokens); 
    1731  
    1732         EmitStruct(&tokens); 
    1733  
    1734         if (CheckRefs(&tokens)) 
    1735                 goto done; 
    1736  
    1737         of = strdup("/tmp/vcl.XXXXXXXX"); 
    1738         assert(of != NULL); 
    1739         mktemp(of); 
    1740  
    1741         sprintf(buf,  
    1742             "tee /tmp/_.c |" 
    1743             "cc -fpic -shared -Wl,-x -o %s -x c - ", of); 
    1744  
    1745         fo = popen(buf, "w"); 
    1746         assert(fo != NULL); 
    1747  
    1748         vcl_output_lang_h(fo); 
    1749  
    1750         sbuf_finish(tokens.fh); 
    1751         fputs(sbuf_data(tokens.fh), fo); 
    1752         sbuf_delete(tokens.fh); 
    1753  
    1754         sbuf_finish(tokens.fc); 
    1755         fputs(sbuf_data(tokens.fc), fo); 
    1756         sbuf_delete(tokens.fc); 
    1757  
    1758         pclose(fo); 
    1759 done: 
    1760  
    1761         /* Free References */ 
    1762         while (!TAILQ_EMPTY(&tokens.refs)) { 
    1763                 r = TAILQ_FIRST(&tokens.refs); 
    1764                 TAILQ_REMOVE(&tokens.refs, r, list); 
    1765                 free(r); 
    1766         } 
    1767  
    1768         /* Free Tokens */ 
    1769         while (!TAILQ_EMPTY(&tokens.tokens)) { 
    1770                 t = TAILQ_FIRST(&tokens.tokens); 
    1771                 TAILQ_REMOVE(&tokens.tokens, t, list); 
    1772                 free(t); 
    1773         } 
    1774         return (of); 
    1775 } 
    1776  
    1777 /*--------------------------------------------------------------------*/ 
    1778  
    1779 char * 
    1780 VCC_CompileFile(struct sbuf *sb, const char *fn) 
    1781 { 
    1782         char *f, *r; 
    1783         int fd, i; 
    1784         struct stat st; 
    1785  
    1786         fd = open(fn, O_RDONLY); 
    1787         if (fd < 0) { 
    1788                 sbuf_printf(sb, "Cannot open file '%s': %s", 
    1789                     fn, strerror(errno)); 
    1790                 return (NULL); 
    1791         } 
    1792         assert(0 == fstat(fd, &st)); 
    1793         f = malloc(st.st_size + 1); 
    1794         assert(f != NULL); 
    1795         i = read(fd, f, st.st_size);  
    1796         assert(i == st.st_size); 
    1797         f[i] = '\0'; 
    1798         r = VCC_Compile(sb, f, NULL); 
    1799         free(f); 
    1800         return (r); 
    1801 } 
    1802  
    1803 /*--------------------------------------------------------------------*/ 
    1804  
    1805 static int 
    1806 VCC_T_render(FILE *f, const struct printf_info *info __unused, const void *const *args) 
    1807 { 
    1808         const struct token *t; 
    1809  
    1810         t = *((const struct token * const*) (args[0])); 
    1811         return (fprintf(f, "%*.*s", 
    1812             t->e - t->b, t->e - t->b, t->b)); 
    1813 } 
    1814       
    1815 static int 
    1816 VCC_T_arginfo(const struct printf_info *info __unused, size_t n, int *argtypes) 
    1817 { 
    1818  
    1819         if (n > 0) 
    1820                 argtypes[0] = PA_POINTER; 
    1821         return 1; 
    1822 } 
    1823       
    1824 /*--------------------------------------------------------------------*/ 
    1825  
    1826 void 
    1827 VCC_InitCompile(const char *default_vcl) 
    1828 { 
    1829         struct var *v; 
    1830  
    1831         vcc_default_vcl_b = default_vcl; 
    1832         vcc_default_vcl_e = strchr(default_vcl, '\0'); 
    1833         assert(vcc_default_vcl_e != NULL); 
    1834          
    1835         register_printf_function ('T', VCC_T_render, VCC_T_arginfo); 
    1836         vcl_init_tnames(); 
    1837         for (v = vars; v->name != NULL; v++) 
    1838                 v->len = strlen(v->name); 
    1839         for (v = be_vars; v->name != NULL; v++) 
    1840                 v->len = strlen(v->name); 
    1841 } 
    1842  
    1843 #endif 
     56const char *vrt_obj_h =  
     57        "/*\n" 
     58        " * $Id$\n" 
     59        " *\n" 
     60        " * NB:  This file is machine generated, DO NOT EDIT!\n" 
     61        " *\n" 
     62        " * Edit vcc_gen_obj.tcl instead\n" 
     63        " */\n" 
     64        "\n" 
     65        "char * VRT_r_backend_host(struct backend *);\n" 
     66        "void VRT_l_backend_host(struct backend *, char *);\n" 
     67        "char * VRT_r_backend_port(struct backend *);\n" 
     68        "void VRT_l_backend_port(struct backend *, char *);\n" 
     69        "char * VRT_r_req_request(struct sess *);\n" 
     70        "void VRT_l_req_request(struct sess *, char *);\n" 
     71        "char * VRT_r_req_url(struct sess *);\n" 
     72        "void VRT_l_req_url(struct sess *, char *);\n" 
     73        "double VRT_r_obj_valid(struct sess *);\n" 
     74        "void VRT_l_obj_valid(struct sess *, double);\n" 
     75        "double VRT_r_obj_cacheable(struct sess *);\n" 
     76        "void VRT_l_obj_cacheable(struct sess *, double);\n" 
     77        "struct backend * VRT_r_obj_backend(struct sess *);\n" 
     78        "void VRT_l_obj_backend(struct sess *, struct backend *);\n" 
     79        "double VRT_r_obj_ttl(struct sess *);\n" 
     80        "void VRT_l_obj_ttl(struct sess *, double);\n" 
     81        "char * VRT_r_req_http_(struct sess *);\n" 
     82        "void VRT_l_req_http_(struct sess *, char *);\n" 
     83; 
Note: See TracChangeset for help on using the changeset viewer.