Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 17f2e93821
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 357 lines (294 sloc) 9.857 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
/*-
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006-2010 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/

#include <sys/types.h>

#include <errno.h>
#include <stdio.h>
#include <stdint.h>

#include "miniobj.h"
#include "vas.h"
#include "vcl.h"
#include "vdef.h"
#include "vqueue.h"
#include "vsb.h"


#include "vcc_token_defs.h"

#ifndef NULL
#define NULL ((void*)0)
#endif

struct vsb;

#define isident1(c) (isalpha(c))
#define isident(c) (isalpha(c) || isdigit(c) || (c) == '_' || (c) == '-')
#define isvar(c) (isident(c) || (c) == '.')
unsigned vcl_fixed_token(const char *p, const char **q);
extern const char * const vcl_tnames[256];
void vcl_output_lang_h(struct vsb *sb);

#define PF(t) (int)((t)->e - (t)->b), (t)->b

#define INDENT 2

struct acl_e;
struct proc;
struct expr;
struct vcc;
struct symbol;

enum var_type {
#define VCC_TYPE(foo) foo,
#include "tbl/vcc_types.h"
#undef VCC_TYPE
};

struct membit {
VTAILQ_ENTRY(membit) list;
void *ptr;
};

struct source {
VTAILQ_ENTRY(source) list;
char *name;
const char *b;
const char *e;
unsigned idx;
char *freeit;
};

struct token {
unsigned tok;
const char *b;
const char *e;
struct source *src;
VTAILQ_ENTRY(token) list;
unsigned cnt;
char *dec;
};

enum symkind {
#define VCC_SYMB(uu, ll) SYM_##uu,
#include "tbl/symbol_kind.h"
#undef VCC_SYMB
};

typedef void sym_expr_t(struct vcc *tl, struct expr **,
    const struct symbol *sym);
typedef struct symbol *sym_wildcard_t(struct vcc *tl, const struct token *t,
    const struct symbol *sym);

struct symbol {
unsigned magic;
#define SYMBOL_MAGIC 0x3368c9fb
VTAILQ_ENTRY(symbol) list;

char *name;
unsigned nlen;
sym_wildcard_t *wildcard;
enum symkind kind;

const struct token *def_b, *def_e;

enum var_type fmt;

sym_expr_t *eval;
void *eval_priv;

/* xref.c */
struct proc *proc;
unsigned nref, ndef;

/* SYM_PROC, SYM_FUNC */
const char *cfunc;
const char *extra;
const char *args;

/* SYM_VAR */
const struct var *var;
unsigned r_methods;
};

VTAILQ_HEAD(tokenhead, token);

struct vcc {
unsigned magic;
#define VCC_MAGIC 0x24ad719d

/* Parameter/Template section */
char *default_vcl;
char *vcl_dir;
char *vmod_dir;

const struct var *vars;
VTAILQ_HEAD(, symbol) symbols;

/* Instance section */
struct tokenhead tokens;
VTAILQ_HEAD(, source) sources;
VTAILQ_HEAD(, membit) membits;
VTAILQ_HEAD(, host) hosts;
unsigned nsources;
struct source *src;
struct token *t;
int indent;
int hindent;
int iindent;
int findent;
unsigned cnt;

struct vsb *fc; /* C-code */
struct vsb *fh; /* H-code (before C-code) */
struct vsb *fi; /* Init func code */
struct vsb *ff; /* Finish func code */
struct vsb *fb; /* Body of current sub
* NULL otherwise
*/
struct vsb *fm[VCL_MET_MAX]; /* Method bodies */
struct vsb *sb;
int err;
int ndirector;
struct proc *curproc;
struct proc *mprocs[VCL_MET_MAX];

VTAILQ_HEAD(, acl_e) acl;

int nprobe;

int defaultdir;
struct token *t_defaultdir;
struct token *t_dir;
struct token *t_policy;

unsigned unique;
unsigned nvmodpriv;

unsigned err_unref;
unsigned allow_inline_c;
unsigned unsafe_path;
};

struct var {
const char *name;
enum var_type fmt;
unsigned len;
const char *rname;
unsigned r_methods;
const char *lname;
unsigned w_methods;
};

struct method {
const char *name;
unsigned ret_bitmap;
unsigned bitval;
};

/*--------------------------------------------------------------------*/

/* vcc_acl.c */

void vcc_Acl(struct vcc *tl);
void vcc_Acl_Hack(struct vcc *tl, char *b);

/* vcc_action.c */
int vcc_ParseAction(struct vcc *tl);

/* vcc_backend.c */
struct fld_spec;
typedef void parsedirector_f(struct vcc *tl);

void vcc_ParseProbe(struct vcc *tl);
void vcc_ParseDirector(struct vcc *tl);
void vcc_ParseBackendHost(struct vcc *tl, int serial, char **nm);
struct fld_spec * vcc_FldSpec(struct vcc *tl, const char *first, ...);
void vcc_ResetFldSpec(struct fld_spec *f);
void vcc_IsField(struct vcc *tl, struct token **t, struct fld_spec *fs);
void vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs);

void Emit_Sockaddr(struct vcc *tl, const struct token *t_host,
    const char *port);

/* vcc_compile.c */
extern struct method method_tab[];
/*
* H -> Header, before the C code
* C -> C-code
* B -> Body of function, ends up in C once function is completed
* I -> Initializer function
* F -> Finish function
*/
void Fh(const struct vcc *tl, int indent, const char *fmt, ...)
    __printflike(3, 4);
void Fc(const struct vcc *tl, int indent, const char *fmt, ...)
    __printflike(3, 4);
void Fb(const struct vcc *tl, int indent, const char *fmt, ...)
    __printflike(3, 4);
void Fi(const struct vcc *tl, int indent, const char *fmt, ...)
    __printflike(3, 4);
void Ff(const struct vcc *tl, int indent, const char *fmt, ...)
    __printflike(3, 4);
void EncToken(struct vsb *sb, const struct token *t);
int IsMethod(const struct token *t);
void *TlAlloc(struct vcc *tl, unsigned len);
char *TlDup(struct vcc *tl, const char *s);
char *TlDupTok(struct vcc *tl, const struct token *tok);

void EncString(struct vsb *sb, const char *b, const char *e, int mode);

/* vcc_dir_random.c */
parsedirector_f vcc_ParseRandomDirector;

/* vcc_expr.c */
void vcc_Duration(struct vcc *tl, double *);
unsigned vcc_UintVal(struct vcc *tl);
void vcc_Expr(struct vcc *tl, enum var_type typ);
void vcc_Expr_Call(struct vcc *tl, const struct symbol *sym);
void vcc_Expr_Init(struct vcc *tl);
sym_expr_t vcc_Eval_Var;
sym_expr_t vcc_Eval_SymFunc;
void vcc_Eval_Func(struct vcc *tl, const char *cfunc, const char *extra,
    const char *name, const char *args);
sym_expr_t vcc_Eval_Backend;

/* vcc_dir_dns.c */
parsedirector_f vcc_ParseDnsDirector;

/* vcc_obj.c */
extern const struct var vcc_vars[];

/* vcc_parse.c */
void vcc_Parse(struct vcc *tl);

/* vcc_storage.c */
sym_wildcard_t vcc_Stv_Wildcard;

/* vcc_string.c */
char *vcc_regexp(struct vcc *tl);

/* vcc_symb.c */
struct symbol *VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind);
struct symbol *VCC_AddSymbolTok(struct vcc *tl, const struct token *t,
    enum symkind kind);
struct symbol *VCC_GetSymbolTok(struct vcc *tl, const struct token *tok,
    enum symkind);
struct symbol *VCC_FindSymbol(struct vcc *tl,
    const struct token *t, enum symkind kind);
const char * VCC_SymKind(struct vcc *tl, const struct symbol *s);
typedef void symwalk_f(struct vcc *tl, const struct symbol *s);
void VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind);

/* vcc_token.c */
void vcc_Coord(const struct vcc *tl, struct vsb *vsb,
    const struct token *t);
void vcc_ErrToken(const struct vcc *tl, const struct token *t);
void vcc_ErrWhere(struct vcc *, const struct token *);
void vcc_ErrWhere2(struct vcc *, const struct token *, const struct token *);

void vcc__Expect(struct vcc *tl, unsigned tok, unsigned line);
int vcc_Teq(const struct token *t1, const struct token *t2);
int vcc_IdIs(const struct token *t, const char *p);
void vcc_ExpectCid(struct vcc *tl);
void vcc_Lexer(struct vcc *tl, struct source *sp);
void vcc_NextToken(struct vcc *tl);
void vcc__ErrInternal(struct vcc *tl, const char *func,
    unsigned line);
void vcc_AddToken(struct vcc *tl, unsigned tok, const char *b,
    const char *e);

/* vcc_var.c */
sym_wildcard_t vcc_Var_Wildcard;
const struct var *vcc_FindVar(struct vcc *tl, const struct token *t,
    int wr_access, const char *use);

/* vcc_vmod.c */
void vcc_ParseImport(struct vcc *tl);

/* vcc_xref.c */
int vcc_AddDef(struct vcc *tl, const struct token *t, enum symkind type);
void vcc_AddRef(struct vcc *tl, const struct token *t, enum symkind type);
int vcc_CheckReferences(struct vcc *tl);

void vcc_AddCall(struct vcc *tl, struct token *t);
struct proc *vcc_AddProc(struct vcc *tl, struct token *t);
void vcc_ProcAction(struct proc *p, unsigned action, struct token *t);
int vcc_CheckAction(struct vcc *tl);
void vcc_AddUses(struct vcc *tl, const struct token *t, unsigned mask,
    const char *use);
int vcc_CheckUses(struct vcc *tl);

#define ERRCHK(tl) do { if ((tl)->err) return; } while (0)
#define ErrInternal(tl) vcc__ErrInternal(tl, __func__, __LINE__)
#define Expect(a, b) vcc__Expect(a, b, __LINE__)
#define ExpectErr(a, b) \
do { vcc__Expect(a, b, __LINE__); ERRCHK(a);} while (0)
#define SkipToken(a, b) \
do { vcc__Expect(a, b, __LINE__); ERRCHK(a); vcc_NextToken(a); } while (0)
Something went wrong with that request. Please try again.