#define AP_REG_MULTI 0x10 /**< perl's /g (needs fixing) */
#define AP_REG_NOMEM 0x20 /**< nomem in our code */
#define AP_REG_DOTALL 0x40 /**< perl's /s flag */
+
+#define AP_REG_NOTEMPTY 0x080 /**< Empty match not valid */
+#define AP_REG_ANCHORED 0x100 /**< Match at the first position */
#define AP_REG_MATCH "MATCH_" /**< suggested prefix for ap_regname */
#include "util_varbuf.h"
#include "util_expr_private.h"
#include "util_md5.h"
+#include "util_varbuf.h"
#include "apr_lib.h"
#include "apr_fnmatch.h"
#define LOG_MARK(info) __FILE__, __LINE__, (info)->module_index
+static int ap_expr_eval_cond(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node);
+
static const char *ap_expr_eval_string_func(ap_expr_eval_ctx_t *ctx,
const ap_expr_t *info,
const ap_expr_t *args);
ap_expr_var_func_t *func,
const void *data);
+typedef struct {
+ int type, flags;
+ const ap_expr_t *subst;
+} ap_expr_regctx_t;
+
+static const char *ap_expr_regexec(const char *subject,
+ const ap_expr_t *reg,
+ apr_array_header_t *list,
+ ap_expr_eval_ctx_t *ctx);
+
+static apr_array_header_t *ap_expr_list_make(ap_expr_eval_ctx_t *ctx,
+ const ap_expr_t *node);
+
/* define AP_EXPR_DEBUG to log the parse tree when parsing an expression */
#ifdef AP_EXPR_DEBUG
static void expr_dump_tree(const ap_expr_t *e, const server_rec *s,
/*
* To reduce counting overhead, we only count calls to
- * ap_expr_eval_word() and ap_expr_eval(). The max number of
+ * ap_expr_eval_word() and ap_expr_eval_cond(). The max number of
* stack frames is larger by some factor.
*/
#define AP_EXPR_MAX_RECURSION 20
return 1;
}
+static const char *ap_expr_list_pstrcat(apr_pool_t *p,
+ const apr_array_header_t *list,
+ const char *sep)
+{
+ if (list->nelts <= 0) {
+ return NULL;
+ }
+ else if (list->nelts == 1) {
+ return APR_ARRAY_IDX(list, 0, const char*);
+ }
+ else {
+ struct ap_varbuf vb;
+ int n = list->nelts - 1, i;
+ apr_size_t slen = strlen(sep), vlen;
+ const char *val;
+
+ ap_varbuf_init(p, &vb, 0);
+ for (i = 0; i < n; ++i) {
+ val = APR_ARRAY_IDX(list, i, const char*);
+ vlen = strlen(val);
+ ap_varbuf_grow(&vb, vlen + slen + 1);
+ ap_varbuf_strmemcat(&vb, val, vlen);
+ ap_varbuf_strmemcat(&vb, sep, slen);
+ }
+ val = APR_ARRAY_IDX(list, n, const char*);
+ ap_varbuf_strmemcat(&vb, val, strlen(val));
+
+ return vb.buf;
+ }
+}
+
static const char *ap_expr_eval_word(ap_expr_eval_ctx_t *ctx,
const ap_expr_t *node)
{
case op_String:
result = node->node_arg1;
break;
+ case op_Word:
+ result = ap_expr_eval_word(ctx, node->node_arg1);
+ break;
+ case op_Bool:
+ result = ap_expr_eval_cond(ctx, node->node_arg1) ? "true" : "false";
+ break;
case op_Var:
result = ap_expr_eval_var(ctx, (ap_expr_var_func_t *)node->node_arg1,
node->node_arg2);
result = ap_expr_eval_string_func(ctx, info, args);
break;
}
- case op_RegexBackref: {
+ case op_Join: {
+ const char *sep;
+ apr_array_header_t *list = ap_expr_list_make(ctx, node->node_arg1);
+ sep = node->node_arg2 ? ap_expr_eval_word(ctx, node->node_arg2) : "";
+ result = ap_expr_list_pstrcat(ctx->p, list, sep);
+ break;
+ }
+ case op_Regsub: {
+ const ap_expr_t *reg = node->node_arg2;
+ const char *subject = ap_expr_eval_word(ctx, node->node_arg1);
+ result = ap_expr_regexec(subject, reg, NULL, ctx);
+ break;
+ }
+ case op_Regref: {
const unsigned int *np = node->node_arg1;
result = ap_expr_eval_re_backref(ctx, *np);
break;
if (arg->node_op == op_ListElement) {
/* Evaluate the list elements and store them in apr_array_header. */
ap_expr_string_list_func_t *func = (ap_expr_string_list_func_t *)info->node_arg1;
- apr_array_header_t *args = apr_array_make(ctx->p, 2, sizeof(char *));
- do {
- const ap_expr_t *val = arg->node_arg1;
- const char **new = apr_array_push(args);
- *new = ap_expr_eval_word(ctx, val);
-
- arg = arg->node_arg2;
- } while (arg != NULL);
-
+ apr_array_header_t *args = ap_expr_list_make(ctx, arg->node_arg1);
return (*func)(ctx, data, args);
}
else {
return 1;
}
+static const char *ap_expr_regexec(const char *subject,
+ const ap_expr_t *reg,
+ apr_array_header_t *list,
+ ap_expr_eval_ctx_t *ctx)
+{
+ struct ap_varbuf vb;
+ const char *val = subject;
+ const ap_regex_t *regex = reg->node_arg1;
+ const ap_expr_regctx_t *regctx = reg->node_arg2;
+ ap_regmatch_t *pmatch = NULL, match0;
+ apr_size_t nmatch = 0;
+ const char *str = "";
+ apr_size_t len = 0;
+ int empty = 0, rv;
+
+ ap_varbuf_init(ctx->p, &vb, 0);
+ if (ctx->re_nmatch > 0) {
+ nmatch = ctx->re_nmatch;
+ pmatch = ctx->re_pmatch;
+ }
+ else if (regctx->type != 'm') {
+ nmatch = 1;
+ pmatch = &match0;
+ }
+ do {
+ /* If previous match was empty, we can't issue the exact same one or
+ * we'd loop indefinitively. So let's instead ask for an anchored and
+ * non-empty match (i.e. something not empty at the start of the value)
+ * and if nothing is found advance by one character below.
+ */
+ rv = ap_regexec(regex, val, nmatch, pmatch,
+ empty ? AP_REG_ANCHORED | AP_REG_NOTEMPTY : 0);
+ if (regctx->type == 'm') {
+ /* Simple match "m//", just return whether it matched (subject)
+ * or not (NULL)
+ */
+ return (rv == 0) ? subject : NULL;
+ }
+ if (rv == 0) {
+ /* Substitution "s//" or split "S//" matched.
+ * s// => replace $0 with evaluated regctx->subst
+ * S// => split at $0 (keeping evaluated regctx->subst if any)
+ */
+ int pos = pmatch[0].rm_so,
+ end = pmatch[0].rm_eo;
+ AP_DEBUG_ASSERT(pos >= 0 && pos <= end);
+
+ if (regctx->subst) {
+ *ctx->re_source = val;
+ str = ap_expr_eval_word(ctx, regctx->subst);
+ len = strlen(str);
+ }
+ /* Splitting makes sense into a given list only, if NULL we fall
+ * back into returning a s// string...
+ */
+ if (list) {
+ char *tmp = apr_palloc(ctx->p, pos + len + 1);
+ memcpy(tmp, val, pos);
+ memcpy(tmp + pos, str, len);
+ tmp[pos + len] = '\0';
+ APR_ARRAY_PUSH(list, const char*) = tmp;
+ }
+ else { /* regctx->type == 's' */
+ ap_varbuf_grow(&vb, pos + len + 1);
+ ap_varbuf_strmemcat(&vb, val, pos);
+ ap_varbuf_strmemcat(&vb, str, len);
+ if (!(regctx->flags & AP_REG_MULTI)) {
+ /* Single substitution, preserve remaining data */
+ ap_varbuf_strmemcat(&vb, val + end, strlen(val) - end);
+ break;
+ }
+ }
+ /* Note an empty match */
+ empty = (end == 0);
+ val += end;
+ }
+ else if (empty) {
+ /* Skip this non-matching character (or CRLF) and restart
+ * another "normal" match (possibly empty) from there.
+ */
+ if (val[0] == APR_ASCII_CR && val[1] == APR_ASCII_LF) {
+ val += 2;
+ }
+ else {
+ val++;
+ }
+ empty = 0;
+ }
+ else {
+ if (list) {
+ APR_ARRAY_PUSH(list, const char*) = val;
+ }
+ else if (vb.avail) {
+ ap_varbuf_strmemcat(&vb, val, strlen(val));
+ }
+ else {
+ return val;
+ }
+ break;
+ }
+ } while (*val);
+
+ return vb.buf;
+}
+
+static apr_array_header_t *ap_expr_list_make(ap_expr_eval_ctx_t *ctx,
+ const ap_expr_t *node)
+{
+ apr_array_header_t *list = NULL;
+
+ if (node->node_op == op_ListRegex) {
+ const ap_expr_t *arg = node->node_arg1;
+ const ap_expr_t *reg = node->node_arg2;
+ const ap_expr_regctx_t *regctx = reg->node_arg2;
+ const apr_array_header_t *source = ap_expr_list_make(ctx, arg);
+ int i;
+
+ list = apr_array_make(ctx->p, source->nelts, sizeof(const char*));
+ for (i = 0; i < source->nelts; ++i) {
+ const char *val = APR_ARRAY_IDX(source, i, const char*);
+ if (regctx->type == 'S') {
+ (void)ap_expr_regexec(val, reg, list, ctx);
+ }
+ else {
+ val = ap_expr_regexec(val, reg, NULL, ctx);
+ if (val) {
+ APR_ARRAY_PUSH(list, const char*) = val;
+ }
+ }
+ }
+ }
+ else if (node->node_op == op_ListElement) {
+ int n = 0;
+ const ap_expr_t *elem;
+ for (elem = node; elem; elem = elem->node_arg2) {
+ AP_DEBUG_ASSERT(elem->node_op == op_ListElement);
+ n++;
+ }
+
+ list = apr_array_make(ctx->p, n, sizeof(const char*));
+ for (elem = node; elem; elem = elem->node_arg2) {
+ APR_ARRAY_PUSH(list, const char*) =
+ ap_expr_eval_word(ctx, elem->node_arg1);
+ }
+ }
+ else if (node->node_op == op_ListFuncCall) {
+ const ap_expr_t *info = node->node_arg1;
+ ap_expr_list_func_t *func = info->node_arg1;
+
+ AP_DEBUG_ASSERT(func != NULL);
+ AP_DEBUG_ASSERT(info->node_op == op_ListFuncInfo);
+ list = (*func)(ctx, info->node_arg2,
+ ap_expr_eval_word(ctx, node->node_arg2));
+ }
+ else {
+ const char *subject = ap_expr_eval_word(ctx, node);
+
+ list = apr_array_make(ctx->p, 8, sizeof(const char*));
+ (void)ap_expr_regexec(subject, node->node_arg2, list, ctx);
+ }
+
+ return list;
+}
+
static int ap_expr_eval_comp(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node)
{
const ap_expr_t *e1 = node->node_arg1;
case op_STR_GE:
return (strcmp(ap_expr_eval_word(ctx, e1), ap_expr_eval_word(ctx, e2)) >= 0);
case op_IN: {
- const char *needle = ap_expr_eval_word(ctx, e1);
- if (e2->node_op == op_ListElement) {
- do {
- const ap_expr_t *val = e2->node_arg1;
- AP_DEBUG_ASSERT(e2->node_op == op_ListElement);
- if (strcmp(needle, ap_expr_eval_word(ctx, val)) == 0)
+ int n;
+ const char *needle, *subject;
+ apr_array_header_t *haystack;
+ haystack = ap_expr_list_make(ctx, e2);
+ if (haystack) {
+ needle = ap_expr_eval_word(ctx, e1);
+ for (n = 0; n < haystack->nelts; ++n) {
+ subject = APR_ARRAY_IDX(haystack, n, const char*);
+ if (strcmp(needle, subject) == 0) {
return 1;
- e2 = e2->node_arg2;
- } while (e2 != NULL);
- }
- else if (e2->node_op == op_ListFuncCall) {
- const ap_expr_t *info = e2->node_arg1;
- const ap_expr_t *arg = e2->node_arg2;
- ap_expr_list_func_t *func = (ap_expr_list_func_t *)info->node_arg1;
- apr_array_header_t *haystack;
-
- AP_DEBUG_ASSERT(func != NULL);
- AP_DEBUG_ASSERT(info->node_op == op_ListFuncInfo);
- haystack = (*func)(ctx, info->node_arg2, ap_expr_eval_word(ctx, arg));
- if (haystack == NULL) {
- return 0;
- }
- if (ap_array_str_contains(haystack, needle)) {
- return 1;
+ }
}
}
return 0;
result = (0 == ap_regexec(regex, word, 0, NULL, 0));
}
- if (node->node_op == op_REG)
- return result;
- else
- return !result;
+ return result ^ (node->node_op == op_NRE);
}
default:
*ctx->err = "Internal evaluation error: Unknown comp expression node";
ap_expr_parse_ctx_t ctx;
int rc;
+ memset(&ctx, 0, sizeof ctx);
ctx.pool = pool;
ctx.ptemp = ptemp;
ctx.inputbuf = expr;
ctx.inputlen = strlen(expr);
ctx.inputptr = ctx.inputbuf;
- ctx.expr = NULL;
- ctx.error = NULL; /* generic bison error message (XXX: usually not very useful, should be axed) */
- ctx.error2 = NULL; /* additional error message */
ctx.flags = info->flags;
- ctx.scan_del = '\0';
- ctx.scan_buf[0] = '\0';
- ctx.scan_ptr = ctx.scan_buf;
ctx.lookup_fn = lookup_fn ? lookup_fn : ap_expr_lookup_default;
ctx.at_start = 1;
ap_expr_yyset_extra(&ctx, ctx.scanner);
rc = ap_expr_yyparse(&ctx);
ap_expr_yylex_destroy(ctx.scanner);
+
+ /* ctx.error: the generic bison error message
+ * (XXX: usually not very useful, should be axed)
+ * ctx.error2: an additional error message
+ */
if (ctx.error) {
if (ctx.error2)
return apr_psprintf(pool, "%s: %s", ctx.error, ctx.error2);
}
ap_expr_t *ap_expr_make(ap_expr_node_op_e op, const void *a1, const void *a2,
- ap_expr_parse_ctx_t *ctx)
+ ap_expr_parse_ctx_t *ctx)
{
ap_expr_t *node = apr_palloc(ctx->pool, sizeof(ap_expr_t));
node->node_op = op;
return node;
}
+ap_expr_t *ap_expr_concat_make(const void *a1, const void *a2,
+ ap_expr_parse_ctx_t *ctx)
+{
+ const ap_expr_t *node;
+
+ /* Optimize out empty string(s) concatenation */
+ if ((node = a1)
+ && node->node_op == op_String
+ && !*(const char *)node->node_arg1) {
+ return (ap_expr_t *)a2;
+ }
+ if ((node = a2)
+ && node->node_op == op_String
+ && !*(const char *)node->node_arg1) {
+ return (ap_expr_t *)a1;
+ }
+
+ return ap_expr_make(op_Concat, a1, a2, ctx);
+}
+
+ap_expr_t *ap_expr_str_word_make(const ap_expr_t *arg,
+ ap_expr_parse_ctx_t *ctx)
+{
+ ap_expr_t *node = apr_palloc(ctx->pool, sizeof(ap_expr_t));
+ node->node_op = op_Word;
+ node->node_arg1 = arg;
+ node->node_arg2 = NULL;
+ return node;
+}
+
+ap_expr_t *ap_expr_str_bool_make(const ap_expr_t *arg,
+ ap_expr_parse_ctx_t *ctx)
+{
+ ap_expr_t *node = apr_palloc(ctx->pool, sizeof(ap_expr_t));
+ node->node_op = op_Bool;
+ node->node_arg1 = arg;
+ node->node_arg2 = NULL;
+ return node;
+}
+
+ap_expr_t *ap_expr_regex_make(const char *pattern, const char *flags,
+ const ap_expr_t *subst, int split,
+ ap_expr_parse_ctx_t *ctx)
+{
+ ap_expr_t *node = NULL;
+ ap_expr_regctx_t *regctx;
+ ap_regex_t *regex;
+
+ regctx = apr_palloc(ctx->pool, sizeof *regctx);
+ regctx->subst = subst;
+ regctx->flags = 0;
+ if (flags) {
+ for (; *flags; ++flags) {
+ switch (*flags) {
+ case 'i':
+ regctx->flags |= AP_REG_ICASE;
+ break;
+ case 'm':
+ regctx->flags |= AP_REG_NEWLINE;
+ break;
+ case 's':
+ regctx->flags |= AP_REG_DOTALL;
+ break;
+ case 'g':
+ regctx->flags |= AP_REG_MULTI;
+ break;
+ }
+ }
+ }
+ if (subst) {
+ if (split) {
+ regctx->type = 'S';
+ regctx->flags |= AP_REG_MULTI;
+ }
+ else {
+ regctx->type = 's';
+ }
+ }
+ else {
+ regctx->type = 'm';
+ }
+
+ regex = ap_pregcomp(ctx->pool, pattern, regctx->flags);
+ if (!regex) {
+ return NULL;
+ }
+
+ node = apr_palloc(ctx->pool, sizeof(ap_expr_t));
+ node->node_op = op_Regex;
+ node->node_arg1 = regex;
+ node->node_arg2 = regctx;
+ return node;
+}
+
static ap_expr_t *ap_expr_info_make(int type, const char *name,
ap_expr_parse_ctx_t *ctx,
const ap_expr_t *arg)
return ap_expr_make(op_ListFuncCall, info, arg, ctx);
}
+ap_expr_t *ap_expr_list_regex_make(const ap_expr_t *arg, const ap_expr_t *reg,
+ ap_expr_parse_ctx_t *ctx)
+{
+ ap_expr_t *node = apr_palloc(ctx->pool, sizeof(ap_expr_t));
+ node->node_op = op_ListRegex;
+ node->node_arg1 = arg;
+ node->node_arg2 = reg;
+ return node;
+}
+
ap_expr_t *ap_expr_unary_op_make(const char *name, const ap_expr_t *arg,
ap_expr_parse_ctx_t *ctx)
{
case op_IN:
case op_REG:
case op_NRE:
+ case op_Word:
+ case op_Bool:
+ case op_Join:
+ case op_Regsub:
case op_Concat:
case op_StringFuncCall:
case op_ListFuncCall:
case op_ListElement:
+ case op_ListRegex:
{
char *name;
switch (e->node_op) {
CASE_OP(op_IN);
CASE_OP(op_REG);
CASE_OP(op_NRE);
+ CASE_OP(op_Word);
+ CASE_OP(op_Bool);
+ CASE_OP(op_Join);
+ CASE_OP(op_Regsub);
CASE_OP(op_Concat);
CASE_OP(op_StringFuncCall);
CASE_OP(op_ListFuncCall);
CASE_OP(op_ListElement);
+ CASE_OP(op_ListRegex);
default:
ap_assert(0);
}
DUMP_P("op_Regex", e->node_arg1);
break;
/* arg1: pointer to int */
- case op_RegexBackref:
- DUMP_IP("op_RegexBackref", e->node_arg1);
+ case op_Regref:
+ DUMP_IP("op_Regref", e->node_arg1);
break;
default:
ap_log_error(MARK, "%*sERROR: INVALID OP %d", indent, " ", e->node_op);
}
-static int ap_expr_eval(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node)
+static int ap_expr_eval_cond(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node)
{
const ap_expr_t *e1 = node->node_arg1;
const ap_expr_t *e2 = node->node_arg2;
case op_Or:
do {
if (e1->node_op == op_Not) {
- if (!ap_expr_eval(ctx, e1->node_arg1)) {
+ if (!ap_expr_eval_cond(ctx, e1->node_arg1)) {
result ^= TRUE;
goto out;
}
}
else {
- if (ap_expr_eval(ctx, e1)) {
+ if (ap_expr_eval_cond(ctx, e1)) {
result ^= TRUE;
goto out;
}
case op_And:
do {
if (e1->node_op == op_Not) {
- if (ap_expr_eval(ctx, e1->node_arg1)) {
+ if (ap_expr_eval_cond(ctx, e1->node_arg1)) {
result ^= FALSE;
goto out;
}
}
else {
- if (!ap_expr_eval(ctx, e1)) {
+ if (!ap_expr_eval_cond(ctx, e1)) {
result ^= FALSE;
goto out;
}
}
}
else {
- rc = ap_expr_eval(ctx, ctx->info->root_node);
+ rc = ap_expr_eval_cond(ctx, ctx->info->root_node);
if (*ctx->err != NULL) {
ap_log_rerror(LOG_MARK(ctx->info), APLOG_ERR, 0, ctx->r,
APLOGNO(03299)
-/* A Bison parser, made by GNU Bison 2.7.12-4996. */
+/* A Bison parser, made by GNU Bison 2.7.1. */
/* Bison implementation for Yacc-like parsers in C
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.7.12-4996"
+#define YYBISON_VERSION "2.7.1"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
T_ID = 264,
T_STRING = 265,
T_REGEX = 266,
- T_REGEX_I = 267,
- T_REGEX_BACKREF = 268,
- T_OP_UNARY = 269,
- T_OP_BINARY = 270,
- T_STR_BEGIN = 271,
- T_STR_END = 272,
- T_VAR_BEGIN = 273,
- T_VAR_END = 274,
- T_OP_EQ = 275,
- T_OP_NE = 276,
- T_OP_LT = 277,
- T_OP_LE = 278,
- T_OP_GT = 279,
- T_OP_GE = 280,
- T_OP_REG = 281,
- T_OP_NRE = 282,
- T_OP_IN = 283,
- T_OP_STR_EQ = 284,
- T_OP_STR_NE = 285,
- T_OP_STR_LT = 286,
- T_OP_STR_LE = 287,
- T_OP_STR_GT = 288,
- T_OP_STR_GE = 289,
- T_OP_CONCAT = 290,
- T_OP_OR = 291,
- T_OP_AND = 292,
- T_OP_NOT = 293
+ T_REGSUB = 267,
+ T_REG_MATCH = 268,
+ T_REG_SUBST = 269,
+ T_REG_FLAGS = 270,
+ T_REG_REF = 271,
+ T_OP_UNARY = 272,
+ T_OP_BINARY = 273,
+ T_STR_BEGIN = 274,
+ T_STR_END = 275,
+ T_VAR_BEGIN = 276,
+ T_VAR_END = 277,
+ T_VAREXP_BEGIN = 278,
+ T_VAREXP_END = 279,
+ T_OP_EQ = 280,
+ T_OP_NE = 281,
+ T_OP_LT = 282,
+ T_OP_LE = 283,
+ T_OP_GT = 284,
+ T_OP_GE = 285,
+ T_OP_REG = 286,
+ T_OP_NRE = 287,
+ T_OP_IN = 288,
+ T_OP_STR_EQ = 289,
+ T_OP_STR_NE = 290,
+ T_OP_STR_LT = 291,
+ T_OP_STR_LE = 292,
+ T_OP_STR_GT = 293,
+ T_OP_STR_GE = 294,
+ T_OP_CONCAT = 295,
+ T_OP_SPLIT = 296,
+ T_OP_JOIN = 297,
+ T_OP_OR = 298,
+ T_OP_AND = 299,
+ T_OP_NOT = 300
};
#endif
/* Line 387 of yacc.c */
-#line 167 "util_expr_parse.c"
+#line 174 "util_expr_parse.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
/* Copy the second part of user declarations. */
/* Line 390 of yacc.c */
-#line 102 "util_expr_parse.y"
+#line 116 "util_expr_parse.y"
#include "util_expr_private.h"
#define yyscanner ctx->scanner
int ap_expr_yylex(YYSTYPE *lvalp, void *scanner);
/* Line 390 of yacc.c */
-#line 201 "util_expr_parse.c"
+#line 208 "util_expr_parse.c"
#ifdef short
# undef short
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 28
+#define YYFINAL 30
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 134
+#define YYLAST 300
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 50
+#define YYNTOKENS 66
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 14
+#define YYNNTS 17
/* YYNRULES -- Number of rules. */
-#define YYNRULES 54
+#define YYNRULES 68
/* YYNRULES -- Number of states. */
-#define YYNSTATES 98
+#define YYNSTATES 139
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 298
+#define YYMAXUTOK 314
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 44, 45, 2, 2, 48, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 49, 2,
+ 60, 61, 2, 2, 64, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 65, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 46, 2, 47, 2, 2, 2, 2,
+ 2, 2, 2, 62, 2, 63, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
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
+ 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
};
#if YYDEBUG
0, 0, 3, 6, 9, 11, 13, 15, 18, 22,
26, 28, 31, 35, 39, 41, 45, 49, 53, 57,
61, 65, 69, 73, 77, 81, 85, 89, 93, 97,
- 101, 103, 107, 109, 113, 116, 118, 120, 122, 124,
- 126, 130, 136, 138, 142, 144, 146, 148, 152, 155,
- 157, 159, 161, 166, 171
+ 101, 103, 107, 111, 115, 119, 121, 125, 127, 130,
+ 132, 134, 136, 138, 142, 148, 152, 156, 158, 161,
+ 165, 169, 173, 175, 177, 179, 182, 187, 194, 198,
+ 202, 207, 212, 214, 216, 218, 220, 225, 230
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 51, 0, -1, 5, 52, -1, 6, 56, -1, 7,
- -1, 3, -1, 4, -1, 38, 52, -1, 52, 36,
- 52, -1, 52, 37, 52, -1, 53, -1, 14, 59,
- -1, 59, 15, 59, -1, 44, 52, 45, -1, 7,
- -1, 59, 20, 59, -1, 59, 21, 59, -1, 59,
- 22, 59, -1, 59, 23, 59, -1, 59, 24, 59,
- -1, 59, 25, 59, -1, 59, 29, 59, -1, 59,
- 30, 59, -1, 59, 31, 59, -1, 59, 32, 59,
- -1, 59, 33, 59, -1, 59, 34, 59, -1, 59,
- 28, 54, -1, 59, 26, 60, -1, 59, 27, 60,
- -1, 62, -1, 46, 55, 47, -1, 59, -1, 55,
- 48, 59, -1, 56, 57, -1, 57, -1, 7, -1,
- 10, -1, 58, -1, 61, -1, 18, 9, 19, -1,
- 18, 9, 49, 56, 19, -1, 8, -1, 59, 35,
- 59, -1, 58, -1, 61, -1, 63, -1, 16, 56,
- 17, -1, 16, 17, -1, 11, -1, 12, -1, 13,
- -1, 9, 44, 59, 45, -1, 9, 44, 59, 45,
- -1, 9, 44, 55, 45, -1
+ 67, 0, -1, 5, 68, -1, 6, 72, -1, 7,
+ -1, 3, -1, 4, -1, 45, 68, -1, 68, 43,
+ 68, -1, 68, 44, 68, -1, 69, -1, 17, 75,
+ -1, 75, 18, 75, -1, 60, 68, 61, -1, 7,
+ -1, 75, 25, 75, -1, 75, 26, 75, -1, 75,
+ 27, 75, -1, 75, 28, 75, -1, 75, 29, 75,
+ -1, 75, 30, 75, -1, 75, 34, 75, -1, 75,
+ 35, 75, -1, 75, 36, 75, -1, 75, 37, 75,
+ -1, 75, 38, 75, -1, 75, 39, 75, -1, 75,
+ 33, 70, -1, 75, 31, 76, -1, 75, 32, 76,
+ -1, 81, -1, 75, 31, 78, -1, 70, 31, 79,
+ -1, 62, 71, 63, -1, 60, 70, 61, -1, 75,
+ -1, 75, 64, 71, -1, 73, -1, 72, 73, -1,
+ 7, -1, 10, -1, 74, -1, 80, -1, 21, 9,
+ 22, -1, 21, 9, 65, 72, 22, -1, 23, 75,
+ 24, -1, 23, 68, 24, -1, 8, -1, 19, 20,
+ -1, 19, 72, 20, -1, 75, 40, 75, -1, 75,
+ 31, 77, -1, 74, -1, 80, -1, 82, -1, 42,
+ 70, -1, 42, 70, 64, 75, -1, 42, 60, 70,
+ 64, 75, 61, -1, 60, 75, 61, -1, 11, 13,
+ 15, -1, 12, 13, 72, 15, -1, 41, 13, 72,
+ 15, -1, 76, -1, 77, -1, 78, -1, 16, -1,
+ 9, 60, 75, 61, -1, 9, 60, 75, 61, -1,
+ 9, 60, 71, 61, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] =
+static const yytype_uint16 yyrline[] =
{
- 0, 112, 112, 113, 114, 117, 118, 119, 120, 121,
- 122, 123, 124, 125, 126, 129, 130, 131, 132, 133,
- 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
- 146, 147, 150, 151, 154, 155, 156, 159, 160, 161,
- 164, 165, 168, 169, 170, 171, 172, 173, 174, 177,
- 186, 197, 204, 207, 208
+ 0, 126, 126, 127, 128, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 143, 144, 145, 146, 147,
+ 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
+ 160, 161, 162, 163, 164, 167, 168, 171, 172, 173,
+ 176, 177, 178, 181, 182, 183, 184, 187, 188, 189,
+ 190, 191, 192, 193, 194, 195, 198, 201, 204, 207,
+ 216, 225, 242, 243, 244, 247, 254, 258, 259
};
#endif
{
"$end", "error", "$undefined", "\"true\"", "\"false\"",
"\"boolean expression\"", "\"string expression\"", "\"error token\"",
- "\"number\"", "\"identifier\"", "\"cstring\"", "\"regex\"",
- "\"case-indendent regex\"", "\"regex back reference\"",
- "\"unary operator\"", "\"binary operator\"", "\"start of string\"",
- "\"end of string\"", "\"start of variable name\"",
- "\"end of variable name\"", "\"integer equal\"", "\"integer not equal\"",
- "\"integer less than\"", "\"integer less or equal\"",
- "\"integer greater than\"", "\"integer greater or equal\"",
- "\"regex match\"", "\"regex non-match\"", "\"contained in\"",
- "\"string equal\"", "\"string not equal\"", "\"string less than\"",
- "\"string less or equal\"", "\"string greater than\"",
- "\"string greater or equal\"", "\"string concatenation\"",
- "\"logical or\"", "\"logical and\"", "\"logical not\"", "\"function\"",
- "\"listfunction\"", "\"stringpart\"", "\"variable\"", "\"rebackref\"",
- "'('", "')'", "'{'", "'}'", "','", "':'", "$accept", "root", "expr",
- "comparison", "wordlist", "words", "string", "strpart", "var", "word",
- "regex", "backref", "lstfunccall", "strfunccall", YY_NULL
+ "\"number\"", "\"identifier\"", "\"string\"", "\"match regex\"",
+ "\"substitution regex\"", "\"match pattern of the regex\"",
+ "\"substitution pattern of the regex\"", "\"flags of the regex\"",
+ "\"regex back reference\"", "\"unary operator\"", "\"binary operator\"",
+ "\"start of string\"", "\"end of string\"", "\"start of variable name\"",
+ "\"end of variable name\"", "\"start of variable expression\"",
+ "\"end of variable expression\"", "\"integer equal\"",
+ "\"integer not equal\"", "\"integer less than\"",
+ "\"integer less or equal\"", "\"integer greater than\"",
+ "\"integer greater or equal\"", "\"regex match\"", "\"regex non-match\"",
+ "\"contained in\"", "\"string equal\"", "\"string not equal\"",
+ "\"string less than\"", "\"string less or equal\"",
+ "\"string greater than\"", "\"string greater or equal\"",
+ "\"string concatenation\"", "\"split operator\"", "\"join operator\"",
+ "\"logical or\"", "\"logical and\"", "\"logical not\"", "\"condition\"",
+ "\"comparison\"", "\"string function\"", "\"list function\"",
+ "\"list of words\"", "\"tuple of words\"", "\"word expression\"",
+ "\"any string expression\"", "\"variable expression\"",
+ "\"regular expression match\"", "\"regular expression substitution\"",
+ "\"regular expression split\"", "\"any regular expression\"",
+ "\"regular expression back reference\"", "'('", "')'", "'{'", "'}'",
+ "','", "':'", "$accept", "root", "cond", "comp", "wordlist", "words",
+ "string", "strany", "var", "word", "regex", "regsub", "regsplit",
+ "regany", "regref", "lstfunc", "strfunc", YY_NULL
};
#endif
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, 40, 41, 123, 125, 44, 58
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 40, 41, 123, 125, 44, 58
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 50, 51, 51, 51, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 54, 54, 55, 55, 56, 56, 56, 57, 57, 57,
- 58, 58, 59, 59, 59, 59, 59, 59, 59, 60,
- 60, 61, 62, 63, 63
+ 0, 66, 67, 67, 67, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+ 70, 70, 70, 70, 70, 71, 71, 72, 72, 72,
+ 73, 73, 73, 74, 74, 74, 74, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 76,
+ 77, 78, 79, 79, 79, 80, 81, 82, 82
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
0, 2, 2, 2, 1, 1, 1, 2, 3, 3,
1, 2, 3, 3, 1, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 1, 3, 1, 3, 2, 1, 1, 1, 1, 1,
- 3, 5, 1, 3, 1, 1, 1, 3, 2, 1,
- 1, 1, 4, 4, 4
+ 1, 3, 3, 3, 3, 1, 3, 1, 2, 1,
+ 1, 1, 1, 3, 5, 3, 3, 1, 2, 3,
+ 3, 3, 1, 1, 1, 2, 4, 6, 3, 3,
+ 4, 4, 1, 1, 1, 1, 4, 4, 4
};
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 0, 0, 4, 0, 5, 6, 14, 42, 0,
- 51, 0, 0, 0, 0, 0, 2, 10, 44, 0,
- 45, 46, 36, 37, 3, 35, 38, 39, 1, 0,
- 11, 48, 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 5, 6, 14, 47, 0,
+ 65, 0, 0, 0, 0, 0, 0, 0, 2, 10,
+ 52, 0, 53, 54, 39, 40, 3, 37, 41, 42,
+ 1, 0, 0, 11, 48, 0, 0, 0, 0, 0,
+ 0, 0, 55, 0, 30, 7, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 34, 0, 32, 47, 40,
- 0, 13, 8, 9, 12, 15, 16, 17, 18, 19,
- 20, 49, 50, 28, 29, 0, 0, 27, 30, 21,
- 22, 23, 24, 25, 26, 43, 54, 0, 53, 0,
- 0, 0, 32, 33, 41, 0, 31, 52
+ 0, 0, 0, 0, 0, 0, 0, 38, 0, 0,
+ 0, 0, 49, 43, 0, 46, 45, 0, 0, 0,
+ 0, 0, 35, 0, 0, 0, 13, 58, 8, 9,
+ 12, 15, 16, 17, 18, 19, 20, 0, 0, 28,
+ 51, 29, 27, 21, 22, 23, 24, 25, 26, 50,
+ 68, 67, 0, 0, 0, 0, 34, 0, 33, 0,
+ 62, 63, 64, 32, 56, 31, 0, 0, 36, 44,
+ 66, 0, 0, 59, 0, 57, 0, 60, 61
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 4, 16, 17, 77, 56, 24, 25, 18, 19,
- 73, 20, 78, 21
+ -1, 4, 18, 19, 42, 68, 26, 27, 20, 21,
+ 99, 100, 122, 123, 22, 44, 23
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -41
-static const yytype_int8 yypact[] =
+#define YYPACT_NINF -46
+static const yytype_int16 yypact[] =
{
- 22, 48, 60, -41, 16, -41, -41, -41, -41, -24,
- -41, 102, 8, 32, 48, 48, -23, -41, -41, 74,
- -41, -41, -41, -41, 50, -41, -41, -41, -41, 102,
- -3, -41, 116, 23, -41, 87, 48, 48, 102, 102,
- 102, 102, 102, 102, 102, 68, 68, -6, 102, 102,
- 102, 102, 102, 102, 102, -41, -40, -28, -41, -41,
- 60, -41, -23, 28, -3, -3, -3, -3, -3, -3,
- -3, -41, -41, -41, -41, 30, 102, -41, -41, -3,
- -3, -3, -3, -3, -3, -3, -41, 102, -41, 103,
- 102, 36, -3, -3, -41, -26, -41, -41
+ 257, 136, 277, -46, 29, -46, -46, -46, -46, -29,
+ -46, 164, 216, 39, 136, 7, 136, 136, 27, -46,
+ -46, 243, -46, -46, -46, -46, 276, -46, -46, -46,
+ -46, 164, 164, -22, -46, 100, -18, 75, 220, 8,
+ 142, 164, -9, 19, -46, -46, 0, 182, 136, 136,
+ 164, 164, 164, 164, 164, 164, 164, 83, 47, 142,
+ 164, 164, 164, 164, 164, 164, 164, -46, 21, 107,
+ 1, 48, -46, -46, 277, -46, -46, 164, 142, 32,
+ 66, 37, -19, 42, 164, -6, -46, -46, 27, 57,
+ -22, -22, -22, -22, -22, -22, -22, 91, 92, -46,
+ -46, -46, 77, -22, -22, -22, -22, -22, -22, -22,
+ -46, -46, 164, 154, 129, -24, -46, 164, -46, 101,
+ -46, -46, -46, -46, -22, -46, 109, 277, -46, -46,
+ -46, 67, 277, -46, 176, -46, 219, -46, -46
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -41, -41, 39, -41, -41, 1, -10, -20, -2, -5,
- 35, -1, -41, -41
+ -46, -46, 3, -46, -32, -38, -10, -21, -2, 25,
+ -45, 46, 51, -46, -1, -46, -46
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
- 26, 27, 32, 75, 55, 86, 30, 54, 87, 54,
- 26, 27, 55, 36, 37, 22, 28, 88, 23, 97,
- 29, 10, 26, 27, 57, 31, 13, 1, 2, 3,
- 26, 27, 54, 64, 65, 66, 67, 68, 69, 70,
- 76, 33, 59, 79, 80, 81, 82, 83, 84, 85,
- 89, 5, 6, 34, 35, 7, 8, 9, 26, 27,
- 23, 10, 11, 10, 12, 37, 13, 22, 13, 55,
- 23, 92, 60, 10, 90, 62, 63, 91, 13, 71,
- 72, 74, 93, 96, 87, 95, 14, 26, 27, 38,
- 0, 0, 15, 0, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 8, 9, 0, 23, 0, 10, 10, 0, 12, 0,
- 13, 13, 94, 36, 37, 0, 23, 0, 0, 10,
- 0, 0, 61, 58, 13
+ 28, 29, 35, 81, 73, 67, 98, 83, 79, 71,
+ 28, 29, 71, 101, 67, 8, 39, 37, 66, 45,
+ 46, 66, 83, 10, 28, 29, 12, 102, 13, 30,
+ 14, 31, 71, 28, 29, 119, 33, 116, 120, 38,
+ 43, 66, 47, 48, 49, 112, 115, 74, 36, 15,
+ 85, 88, 89, 97, 98, 84, 69, 70, 97, 66,
+ 98, 86, 87, 83, 113, 80, 82, 40, 77, 41,
+ 48, 49, 28, 29, 128, 90, 91, 92, 93, 94,
+ 95, 96, 110, 119, 43, 103, 104, 105, 106, 107,
+ 108, 109, 67, 116, 97, 98, 117, 85, 71, 75,
+ 118, 49, 114, 80, 126, 127, 66, 66, 83, 124,
+ 25, 28, 29, 67, 132, 67, 10, 134, 48, 49,
+ 72, 13, 136, 14, 133, 28, 29, 87, 135, 121,
+ 28, 29, 28, 29, 28, 29, 125, 82, 71, 5,
+ 6, 0, 131, 7, 8, 9, 0, 66, 0, 0,
+ 8, 39, 10, 11, 0, 12, 0, 13, 10, 14,
+ 71, 12, 0, 13, 25, 14, 0, 0, 111, 66,
+ 10, 112, 8, 9, 0, 13, 129, 14, 15, 0,
+ 10, 16, 0, 12, 15, 13, 25, 14, 0, 0,
+ 130, 137, 10, 112, 0, 0, 17, 13, 0, 14,
+ 50, 0, 78, 0, 41, 0, 15, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 24, 32, 0, 25, 0, 0, 25,
+ 0, 0, 10, 0, 138, 10, 34, 13, 50, 14,
+ 13, 0, 14, 87, 76, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 50, 1, 2, 3, 0, 0, 0, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 24, 0, 25, 25, 0, 0,
+ 0, 0, 10, 10, 0, 0, 0, 13, 13, 14,
+ 14
};
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-41)))
+ (!!((Yystate) == (-46)))
#define yytable_value_is_error(Yytable_value) \
YYID (0)
-static const yytype_int8 yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 2, 2, 12, 9, 24, 45, 11, 35, 48, 35,
- 12, 12, 32, 36, 37, 7, 0, 45, 10, 45,
- 44, 13, 24, 24, 29, 17, 18, 5, 6, 7,
- 32, 32, 35, 38, 39, 40, 41, 42, 43, 44,
- 46, 9, 19, 48, 49, 50, 51, 52, 53, 54,
- 60, 3, 4, 14, 15, 7, 8, 9, 60, 60,
- 10, 13, 14, 13, 16, 37, 18, 7, 18, 89,
- 10, 76, 49, 13, 44, 36, 37, 76, 18, 11,
- 12, 46, 87, 47, 48, 90, 38, 89, 89, 15,
- -1, -1, 44, -1, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 8, 9, -1, 10, -1, 13, 13, -1, 16, -1,
- 18, 18, 19, 36, 37, -1, 10, -1, -1, 13,
- -1, -1, 45, 17, 18
+ 2, 2, 12, 41, 22, 26, 12, 31, 40, 31,
+ 12, 12, 31, 58, 35, 8, 9, 14, 40, 16,
+ 17, 40, 31, 16, 26, 26, 19, 59, 21, 0,
+ 23, 60, 31, 35, 35, 41, 11, 61, 83, 14,
+ 15, 40, 17, 43, 44, 64, 78, 65, 9, 42,
+ 31, 48, 49, 11, 12, 64, 31, 32, 11, 40,
+ 12, 61, 61, 31, 74, 40, 41, 60, 60, 62,
+ 43, 44, 74, 74, 112, 50, 51, 52, 53, 54,
+ 55, 56, 61, 41, 59, 60, 61, 62, 63, 64,
+ 65, 66, 113, 61, 11, 12, 64, 31, 31, 24,
+ 63, 44, 77, 78, 13, 13, 40, 40, 31, 84,
+ 10, 113, 113, 134, 13, 136, 16, 127, 43, 44,
+ 20, 21, 132, 23, 15, 127, 127, 61, 61, 83,
+ 132, 132, 134, 134, 136, 136, 85, 112, 31, 3,
+ 4, -1, 117, 7, 8, 9, -1, 40, -1, -1,
+ 8, 9, 16, 17, -1, 19, -1, 21, 16, 23,
+ 31, 19, -1, 21, 10, 23, -1, -1, 61, 40,
+ 16, 64, 8, 9, -1, 21, 22, 23, 42, -1,
+ 16, 45, -1, 19, 42, 21, 10, 23, -1, -1,
+ 61, 15, 16, 64, -1, -1, 60, 21, -1, 23,
+ 18, -1, 60, -1, 62, -1, 42, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 7, 60, -1, 10, -1, -1, 10,
+ -1, -1, 16, -1, 15, 16, 20, 21, 18, 23,
+ 21, -1, 23, 61, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 18, 5, 6, 7, -1, -1, -1, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 7, -1, 10, 10, -1, -1,
+ -1, -1, 16, 16, -1, -1, -1, 21, 21, 23,
+ 23
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 5, 6, 7, 51, 3, 4, 7, 8, 9,
- 13, 14, 16, 18, 38, 44, 52, 53, 58, 59,
- 61, 63, 7, 10, 56, 57, 58, 61, 0, 44,
- 59, 17, 56, 9, 52, 52, 36, 37, 15, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 57, 55, 59, 17, 19,
- 49, 45, 52, 52, 59, 59, 59, 59, 59, 59,
- 59, 11, 12, 60, 60, 9, 46, 54, 62, 59,
- 59, 59, 59, 59, 59, 59, 45, 48, 45, 56,
- 44, 55, 59, 59, 19, 59, 47, 45
+ 0, 5, 6, 7, 67, 3, 4, 7, 8, 9,
+ 16, 17, 19, 21, 23, 42, 45, 60, 68, 69,
+ 74, 75, 80, 82, 7, 10, 72, 73, 74, 80,
+ 0, 60, 60, 75, 20, 72, 9, 68, 75, 9,
+ 60, 62, 70, 75, 81, 68, 68, 75, 43, 44,
+ 18, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 73, 71, 75,
+ 75, 31, 20, 22, 65, 24, 24, 60, 60, 70,
+ 75, 71, 75, 31, 64, 31, 61, 61, 68, 68,
+ 75, 75, 75, 75, 75, 75, 75, 11, 12, 76,
+ 77, 76, 70, 75, 75, 75, 75, 75, 75, 75,
+ 61, 61, 64, 72, 75, 70, 61, 64, 63, 41,
+ 76, 77, 78, 79, 75, 78, 13, 13, 71, 22,
+ 61, 75, 13, 15, 72, 61, 72, 15, 15
};
#define yyerrok (yyerrstatus = 0)
{
case 2:
/* Line 1787 of yacc.c */
-#line 112 "util_expr_parse.y"
+#line 126 "util_expr_parse.y"
{ ctx->expr = (yyvsp[(2) - (2)].exVal); }
break;
case 3:
/* Line 1787 of yacc.c */
-#line 113 "util_expr_parse.y"
+#line 127 "util_expr_parse.y"
{ ctx->expr = (yyvsp[(2) - (2)].exVal); }
break;
case 4:
/* Line 1787 of yacc.c */
-#line 114 "util_expr_parse.y"
+#line 128 "util_expr_parse.y"
{ YYABORT; }
break;
case 5:
/* Line 1787 of yacc.c */
-#line 117 "util_expr_parse.y"
+#line 131 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_True, NULL, NULL, ctx); }
break;
case 6:
/* Line 1787 of yacc.c */
-#line 118 "util_expr_parse.y"
+#line 132 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_False, NULL, NULL, ctx); }
break;
case 7:
/* Line 1787 of yacc.c */
-#line 119 "util_expr_parse.y"
+#line 133 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_Not, (yyvsp[(2) - (2)].exVal), NULL, ctx); }
break;
case 8:
/* Line 1787 of yacc.c */
-#line 120 "util_expr_parse.y"
+#line 134 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_Or, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 9:
/* Line 1787 of yacc.c */
-#line 121 "util_expr_parse.y"
+#line 135 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_And, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 10:
/* Line 1787 of yacc.c */
-#line 122 "util_expr_parse.y"
+#line 136 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_Comp, (yyvsp[(1) - (1)].exVal), NULL, ctx); }
break;
case 11:
/* Line 1787 of yacc.c */
-#line 123 "util_expr_parse.y"
+#line 137 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_unary_op_make( (yyvsp[(1) - (2)].cpVal), (yyvsp[(2) - (2)].exVal), ctx); }
break;
case 12:
/* Line 1787 of yacc.c */
-#line 124 "util_expr_parse.y"
+#line 138 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_binary_op_make((yyvsp[(2) - (3)].cpVal), (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 13:
/* Line 1787 of yacc.c */
-#line 125 "util_expr_parse.y"
+#line 139 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
break;
case 14:
/* Line 1787 of yacc.c */
-#line 126 "util_expr_parse.y"
+#line 140 "util_expr_parse.y"
{ YYABORT; }
break;
case 15:
/* Line 1787 of yacc.c */
-#line 129 "util_expr_parse.y"
+#line 143 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_EQ, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 16:
/* Line 1787 of yacc.c */
-#line 130 "util_expr_parse.y"
+#line 144 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_NE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 17:
/* Line 1787 of yacc.c */
-#line 131 "util_expr_parse.y"
+#line 145 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_LT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 18:
/* Line 1787 of yacc.c */
-#line 132 "util_expr_parse.y"
+#line 146 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_LE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 19:
/* Line 1787 of yacc.c */
-#line 133 "util_expr_parse.y"
+#line 147 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_GT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 20:
/* Line 1787 of yacc.c */
-#line 134 "util_expr_parse.y"
+#line 148 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_GE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 21:
/* Line 1787 of yacc.c */
-#line 135 "util_expr_parse.y"
+#line 149 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_EQ, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 22:
/* Line 1787 of yacc.c */
-#line 136 "util_expr_parse.y"
+#line 150 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_NE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 23:
/* Line 1787 of yacc.c */
-#line 137 "util_expr_parse.y"
+#line 151 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_LT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 24:
/* Line 1787 of yacc.c */
-#line 138 "util_expr_parse.y"
+#line 152 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_LE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 25:
/* Line 1787 of yacc.c */
-#line 139 "util_expr_parse.y"
+#line 153 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_GT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 26:
/* Line 1787 of yacc.c */
-#line 140 "util_expr_parse.y"
+#line 154 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_GE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 27:
/* Line 1787 of yacc.c */
-#line 141 "util_expr_parse.y"
+#line 155 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_IN, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 28:
/* Line 1787 of yacc.c */
-#line 142 "util_expr_parse.y"
+#line 156 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_REG, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 29:
/* Line 1787 of yacc.c */
-#line 143 "util_expr_parse.y"
+#line 157 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_NRE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 30:
/* Line 1787 of yacc.c */
-#line 146 "util_expr_parse.y"
+#line 160 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
break;
case 31:
/* Line 1787 of yacc.c */
-#line 147 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
+#line 161 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_list_regex_make((yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 32:
/* Line 1787 of yacc.c */
-#line 150 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(1) - (1)].exVal), NULL, ctx); }
+#line 162 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_list_regex_make((yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 33:
/* Line 1787 of yacc.c */
-#line 151 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(3) - (3)].exVal), (yyvsp[(1) - (3)].exVal), ctx); }
+#line 163 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
break;
case 34:
/* Line 1787 of yacc.c */
-#line 154 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (2)].exVal), (yyvsp[(2) - (2)].exVal), ctx); }
+#line 164 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
break;
case 35:
/* Line 1787 of yacc.c */
-#line 155 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+#line 167 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(1) - (1)].exVal), NULL, ctx); }
break;
case 36:
/* Line 1787 of yacc.c */
-#line 156 "util_expr_parse.y"
- { YYABORT; }
+#line 168 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
break;
case 37:
/* Line 1787 of yacc.c */
-#line 159 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_String, (yyvsp[(1) - (1)].cpVal), NULL, ctx); }
+#line 171 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
break;
case 38:
/* Line 1787 of yacc.c */
-#line 160 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+#line 172 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_concat_make((yyvsp[(1) - (2)].exVal), (yyvsp[(2) - (2)].exVal), ctx); }
break;
case 39:
/* Line 1787 of yacc.c */
-#line 161 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+#line 173 "util_expr_parse.y"
+ { YYABORT; }
break;
case 40:
/* Line 1787 of yacc.c */
-#line 164 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); }
+#line 176 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_String, (yyvsp[(1) - (1)].cpVal), NULL, ctx); }
break;
case 41:
/* Line 1787 of yacc.c */
-#line 165 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(2) - (5)].cpVal), (yyvsp[(4) - (5)].exVal), ctx); }
+#line 177 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
break;
case 42:
/* Line 1787 of yacc.c */
-#line 168 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_Digit, (yyvsp[(1) - (1)].cpVal), NULL, ctx); }
+#line 178 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
break;
case 43:
/* Line 1787 of yacc.c */
-#line 169 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
+#line 181 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); }
break;
case 44:
/* Line 1787 of yacc.c */
-#line 170 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+#line 182 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(2) - (5)].cpVal), (yyvsp[(4) - (5)].exVal), ctx); }
break;
case 45:
/* Line 1787 of yacc.c */
-#line 171 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+#line 183 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_str_word_make((yyvsp[(2) - (3)].exVal), ctx); }
break;
case 46:
/* Line 1787 of yacc.c */
-#line 172 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+#line 184 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_str_bool_make((yyvsp[(2) - (3)].exVal), ctx); }
break;
case 47:
/* Line 1787 of yacc.c */
-#line 173 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
+#line 187 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_Digit, (yyvsp[(1) - (1)].cpVal), NULL, ctx); }
break;
case 48:
/* Line 1787 of yacc.c */
-#line 174 "util_expr_parse.y"
+#line 188 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_String, "", NULL, ctx); }
break;
case 49:
/* Line 1787 of yacc.c */
-#line 177 "util_expr_parse.y"
+#line 189 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
+ break;
+
+ case 50:
+/* Line 1787 of yacc.c */
+#line 190 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
+ break;
+
+ case 51:
+/* Line 1787 of yacc.c */
+#line 191 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_Regsub, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); }
+ break;
+
+ case 52:
+/* Line 1787 of yacc.c */
+#line 192 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+ break;
+
+ case 53:
+/* Line 1787 of yacc.c */
+#line 193 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+ break;
+
+ case 54:
+/* Line 1787 of yacc.c */
+#line 194 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+ break;
+
+ case 55:
+/* Line 1787 of yacc.c */
+#line 195 "util_expr_parse.y"
+ {
+ (yyval.exVal) = ap_expr_make(op_Join, (yyvsp[(2) - (2)].exVal), NULL, ctx);
+ }
+ break;
+
+ case 56:
+/* Line 1787 of yacc.c */
+#line 198 "util_expr_parse.y"
{
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
- AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
+ (yyval.exVal) = ap_expr_make(op_Join, (yyvsp[(2) - (4)].exVal), (yyvsp[(4) - (4)].exVal), ctx);
+ }
+ break;
+
+ case 57:
+/* Line 1787 of yacc.c */
+#line 201 "util_expr_parse.y"
+ {
+ (yyval.exVal) = ap_expr_make(op_Join, (yyvsp[(3) - (6)].exVal), (yyvsp[(5) - (6)].exVal), ctx);
+ }
+ break;
+
+ case 58:
+/* Line 1787 of yacc.c */
+#line 204 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); }
+ break;
+
+ case 59:
+/* Line 1787 of yacc.c */
+#line 207 "util_expr_parse.y"
+ {
+ ap_expr_t *e = ap_expr_regex_make((yyvsp[(2) - (3)].cpVal), (yyvsp[(3) - (3)].cpVal), NULL, 0, ctx);
+ if (!e) {
ctx->error = "Failed to compile regular expression";
YYERROR;
}
- (yyval.exVal) = ap_expr_make(op_Regex, regex, NULL, ctx);
+ (yyval.exVal) = e;
}
break;
- case 50:
+ case 60:
/* Line 1787 of yacc.c */
-#line 186 "util_expr_parse.y"
+#line 216 "util_expr_parse.y"
{
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
- AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
+ ap_expr_t *e = ap_expr_regex_make((yyvsp[(2) - (4)].cpVal), (yyvsp[(4) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), 0, ctx);
+ if (!e) {
ctx->error = "Failed to compile regular expression";
YYERROR;
}
- (yyval.exVal) = ap_expr_make(op_Regex, regex, NULL, ctx);
+ (yyval.exVal) = e;
}
break;
- case 51:
+ case 61:
/* Line 1787 of yacc.c */
-#line 197 "util_expr_parse.y"
+#line 225 "util_expr_parse.y"
+ {
+ /* Returns a list:
+ * <word> ~= split/://
+ * => split around ':', replace it with empty
+ * <word> ~= split/:/\n/
+ * => split around ':', replace it with '\n'
+ * <list> ~= split/.*?Ip Address:([^,]+)/$1/
+ * => split around the whole match, replace it with $1
+ */
+ ap_expr_t *e = ap_expr_regex_make((yyvsp[(2) - (4)].cpVal), (yyvsp[(4) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), 1, ctx);
+ if (!e) {
+ ctx->error = "Failed to compile regular expression";
+ YYERROR;
+ }
+ (yyval.exVal) = e;
+ }
+ break;
+
+ case 62:
+/* Line 1787 of yacc.c */
+#line 242 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+ break;
+
+ case 63:
+/* Line 1787 of yacc.c */
+#line 243 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+ break;
+
+ case 64:
+/* Line 1787 of yacc.c */
+#line 244 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); }
+ break;
+
+ case 65:
+/* Line 1787 of yacc.c */
+#line 247 "util_expr_parse.y"
{
int *n = apr_palloc(ctx->pool, sizeof(int));
*n = (yyvsp[(1) - (1)].num);
- (yyval.exVal) = ap_expr_make(op_RegexBackref, n, NULL, ctx);
+ (yyval.exVal) = ap_expr_make(op_Regref, n, NULL, ctx);
}
break;
- case 52:
+ case 66:
/* Line 1787 of yacc.c */
-#line 204 "util_expr_parse.y"
+#line 254 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_list_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); }
break;
- case 53:
+ case 67:
/* Line 1787 of yacc.c */
-#line 207 "util_expr_parse.y"
+#line 258 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_str_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); }
break;
- case 54:
+ case 68:
/* Line 1787 of yacc.c */
-#line 208 "util_expr_parse.y"
+#line 259 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_str_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); }
break;
/* Line 1787 of yacc.c */
-#line 1849 "util_expr_parse.c"
+#line 2027 "util_expr_parse.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
/* Line 2050 of yacc.c */
-#line 211 "util_expr_parse.y"
+#line 262 "util_expr_parse.y"
void yyerror(ap_expr_parse_ctx_t *ctx, const char *s)
-/* A Bison parser, made by GNU Bison 2.7.12-4996. */
+/* A Bison parser, made by GNU Bison 2.7.1. */
/* Bison interface for Yacc-like parsers in C
T_ID = 264,
T_STRING = 265,
T_REGEX = 266,
- T_REGEX_I = 267,
- T_REGEX_BACKREF = 268,
- T_OP_UNARY = 269,
- T_OP_BINARY = 270,
- T_STR_BEGIN = 271,
- T_STR_END = 272,
- T_VAR_BEGIN = 273,
- T_VAR_END = 274,
- T_OP_EQ = 275,
- T_OP_NE = 276,
- T_OP_LT = 277,
- T_OP_LE = 278,
- T_OP_GT = 279,
- T_OP_GE = 280,
- T_OP_REG = 281,
- T_OP_NRE = 282,
- T_OP_IN = 283,
- T_OP_STR_EQ = 284,
- T_OP_STR_NE = 285,
- T_OP_STR_LT = 286,
- T_OP_STR_LE = 287,
- T_OP_STR_GT = 288,
- T_OP_STR_GE = 289,
- T_OP_CONCAT = 290,
- T_OP_OR = 291,
- T_OP_AND = 292,
- T_OP_NOT = 293
+ T_REGSUB = 267,
+ T_REG_MATCH = 268,
+ T_REG_SUBST = 269,
+ T_REG_FLAGS = 270,
+ T_REG_REF = 271,
+ T_OP_UNARY = 272,
+ T_OP_BINARY = 273,
+ T_STR_BEGIN = 274,
+ T_STR_END = 275,
+ T_VAR_BEGIN = 276,
+ T_VAR_END = 277,
+ T_VAREXP_BEGIN = 278,
+ T_VAREXP_END = 279,
+ T_OP_EQ = 280,
+ T_OP_NE = 281,
+ T_OP_LT = 282,
+ T_OP_LE = 283,
+ T_OP_GT = 284,
+ T_OP_GE = 285,
+ T_OP_REG = 286,
+ T_OP_NRE = 287,
+ T_OP_IN = 288,
+ T_OP_STR_EQ = 289,
+ T_OP_STR_NE = 290,
+ T_OP_STR_LT = 291,
+ T_OP_STR_LE = 292,
+ T_OP_STR_GT = 293,
+ T_OP_STR_GE = 294,
+ T_OP_CONCAT = 295,
+ T_OP_SPLIT = 296,
+ T_OP_JOIN = 297,
+ T_OP_OR = 298,
+ T_OP_AND = 299,
+ T_OP_NOT = 300
};
#endif
/* Line 2053 of yacc.c */
-#line 102 "util_expr_parse.h"
+#line 109 "util_expr_parse.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
%token <cpVal> T_DIGIT "number"
%token <cpVal> T_ID "identifier"
-%token <cpVal> T_STRING "cstring"
-%token <cpVal> T_REGEX "regex"
-%token <cpVal> T_REGEX_I "case-indendent regex"
-%token <num> T_REGEX_BACKREF "regex back reference"
+%token <cpVal> T_STRING "string"
+
+%token T_REGEX "match regex"
+%token T_REGSUB "substitution regex"
+%token <cpVal> T_REG_MATCH "match pattern of the regex"
+%token <cpVal> T_REG_SUBST "substitution pattern of the regex"
+%token <cpVal> T_REG_FLAGS "flags of the regex"
+%token <num> T_REG_REF "regex back reference"
+
%token <cpVal> T_OP_UNARY "unary operator"
%token <cpVal> T_OP_BINARY "binary operator"
%token T_STR_END "end of string"
%token T_VAR_BEGIN "start of variable name"
%token T_VAR_END "end of variable name"
+%token T_VAREXP_BEGIN "start of variable expression"
+%token T_VAREXP_END "end of variable expression"
%token T_OP_EQ "integer equal"
%token T_OP_NE "integer not equal"
%token T_OP_STR_LE "string less or equal"
%token T_OP_STR_GT "string greater than"
%token T_OP_STR_GE "string greater or equal"
+
%token T_OP_CONCAT "string concatenation"
+%token T_OP_SPLIT "split operator"
+%token T_OP_JOIN "join operator"
+
%token T_OP_OR "logical or"
%token T_OP_AND "logical and"
%token T_OP_NOT "logical not"
%right T_OP_NOT
%right T_OP_CONCAT
-%type <exVal> expr
-%type <exVal> comparison
-%type <exVal> strfunccall "function"
-%type <exVal> lstfunccall "listfunction"
-%type <exVal> regex
-%type <exVal> words
-%type <exVal> wordlist
-%type <exVal> word
-%type <exVal> string
-%type <exVal> strpart "stringpart"
-%type <exVal> var "variable"
-%type <exVal> backref "rebackref"
+%type <exVal> cond "condition"
+%type <exVal> comp "comparison"
+%type <exVal> strfunc "string function"
+%type <exVal> lstfunc "list function"
+%type <exVal> wordlist "list of words"
+%type <exVal> words "tuple of words"
+%type <exVal> word "word expression"
+%type <exVal> string "string expression"
+%type <exVal> strany "any string expression"
+%type <exVal> var "variable expression"
+%type <exVal> regex "regular expression match"
+%type <exVal> regsub "regular expression substitution"
+%type <exVal> regsplit "regular expression split"
+%type <exVal> regany "any regular expression"
+%type <exVal> regref "regular expression back reference"
%{
#include "util_expr_private.h"
%%
-root : T_EXPR_BOOL expr { ctx->expr = $2; }
+root : T_EXPR_BOOL cond { ctx->expr = $2; }
| T_EXPR_STRING string { ctx->expr = $2; }
| T_ERROR { YYABORT; }
;
-expr : T_TRUE { $$ = ap_expr_make(op_True, NULL, NULL, ctx); }
+cond : T_TRUE { $$ = ap_expr_make(op_True, NULL, NULL, ctx); }
| T_FALSE { $$ = ap_expr_make(op_False, NULL, NULL, ctx); }
- | T_OP_NOT expr { $$ = ap_expr_make(op_Not, $2, NULL, ctx); }
- | expr T_OP_OR expr { $$ = ap_expr_make(op_Or, $1, $3, ctx); }
- | expr T_OP_AND expr { $$ = ap_expr_make(op_And, $1, $3, ctx); }
- | comparison { $$ = ap_expr_make(op_Comp, $1, NULL, ctx); }
+ | T_OP_NOT cond { $$ = ap_expr_make(op_Not, $2, NULL, ctx); }
+ | cond T_OP_OR cond { $$ = ap_expr_make(op_Or, $1, $3, ctx); }
+ | cond T_OP_AND cond { $$ = ap_expr_make(op_And, $1, $3, ctx); }
+ | comp { $$ = ap_expr_make(op_Comp, $1, NULL, ctx); }
| T_OP_UNARY word { $$ = ap_expr_unary_op_make( $1, $2, ctx); }
| word T_OP_BINARY word { $$ = ap_expr_binary_op_make($2, $1, $3, ctx); }
- | '(' expr ')' { $$ = $2; }
+ | '(' cond ')' { $$ = $2; }
| T_ERROR { YYABORT; }
;
-comparison: word T_OP_EQ word { $$ = ap_expr_make(op_EQ, $1, $3, ctx); }
+comp : word T_OP_EQ word { $$ = ap_expr_make(op_EQ, $1, $3, ctx); }
| word T_OP_NE word { $$ = ap_expr_make(op_NE, $1, $3, ctx); }
| word T_OP_LT word { $$ = ap_expr_make(op_LT, $1, $3, ctx); }
| word T_OP_LE word { $$ = ap_expr_make(op_LE, $1, $3, ctx); }
| word T_OP_NRE regex { $$ = ap_expr_make(op_NRE, $1, $3, ctx); }
;
-wordlist : lstfunccall { $$ = $1; }
+wordlist : lstfunc { $$ = $1; }
+ | word T_OP_REG regsplit { $$ = ap_expr_list_regex_make($1, $3, ctx); }
+ | wordlist T_OP_REG regany { $$ = ap_expr_list_regex_make($1, $3, ctx); }
| '{' words '}' { $$ = $2; }
+ | '(' wordlist ')' { $$ = $2; }
;
words : word { $$ = ap_expr_make(op_ListElement, $1, NULL, ctx); }
- | words ',' word { $$ = ap_expr_make(op_ListElement, $3, $1, ctx); }
+ | word ',' words { $$ = ap_expr_make(op_ListElement, $1, $3, ctx); }
;
-string : string strpart { $$ = ap_expr_make(op_Concat, $1, $2, ctx); }
- | strpart { $$ = $1; }
+string : strany { $$ = $1; }
+ | string strany { $$ = ap_expr_concat_make($1, $2, ctx); }
| T_ERROR { YYABORT; }
;
-strpart : T_STRING { $$ = ap_expr_make(op_String, $1, NULL, ctx); }
+strany : T_STRING { $$ = ap_expr_make(op_String, $1, NULL, ctx); }
| var { $$ = $1; }
- | backref { $$ = $1; }
+ | regref { $$ = $1; }
;
var : T_VAR_BEGIN T_ID T_VAR_END { $$ = ap_expr_var_make($2, ctx); }
| T_VAR_BEGIN T_ID ':' string T_VAR_END { $$ = ap_expr_str_func_make($2, $4, ctx); }
+ | T_VAREXP_BEGIN word T_VAREXP_END { $$ = ap_expr_str_word_make($2, ctx); }
+ | T_VAREXP_BEGIN cond T_VAREXP_END { $$ = ap_expr_str_bool_make($2, ctx); }
;
word : T_DIGIT { $$ = ap_expr_make(op_Digit, $1, NULL, ctx); }
+ | T_STR_BEGIN T_STR_END { $$ = ap_expr_make(op_String, "", NULL, ctx); }
+ | T_STR_BEGIN string T_STR_END { $$ = $2; }
| word T_OP_CONCAT word { $$ = ap_expr_make(op_Concat, $1, $3, ctx); }
+ | word T_OP_REG regsub { $$ = ap_expr_make(op_Regsub, $1, $3, ctx); }
| var { $$ = $1; }
- | backref { $$ = $1; }
- | strfunccall { $$ = $1; }
- | T_STR_BEGIN string T_STR_END { $$ = $2; }
- | T_STR_BEGIN T_STR_END { $$ = ap_expr_make(op_String, "", NULL, ctx); }
+ | regref { $$ = $1; }
+ | strfunc { $$ = $1; }
+ | T_OP_JOIN wordlist {
+ $$ = ap_expr_make(op_Join, $2, NULL, ctx);
+ }
+ | T_OP_JOIN wordlist ',' word {
+ $$ = ap_expr_make(op_Join, $2, $4, ctx);
+ }
+ | T_OP_JOIN '(' wordlist ',' word ')' {
+ $$ = ap_expr_make(op_Join, $3, $5, ctx);
+ }
+ | '(' word ')' { $$ = $2; }
;
-regex : T_REGEX {
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ctx->pool, $1,
- AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
+regex : T_REGEX T_REG_MATCH T_REG_FLAGS {
+ ap_expr_t *e = ap_expr_regex_make($2, $3, NULL, 0, ctx);
+ if (!e) {
ctx->error = "Failed to compile regular expression";
YYERROR;
}
- $$ = ap_expr_make(op_Regex, regex, NULL, ctx);
+ $$ = e;
}
- | T_REGEX_I {
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ctx->pool, $1,
- AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
+ ;
+regsub : T_REGSUB T_REG_MATCH string T_REG_FLAGS {
+ ap_expr_t *e = ap_expr_regex_make($2, $4, $3, 0, ctx);
+ if (!e) {
+ ctx->error = "Failed to compile regular expression";
+ YYERROR;
+ }
+ $$ = e;
+ }
+ ;
+regsplit : T_OP_SPLIT T_REG_MATCH string T_REG_FLAGS {
+ /* Returns a list:
+ * <word> ~= split/://
+ * => split around ':', replace it with empty
+ * <word> ~= split/:/\n/
+ * => split around ':', replace it with '\n'
+ * <list> ~= split/.*?Ip Address:([^,]+)/$1/
+ * => split around the whole match, replace it with $1
+ */
+ ap_expr_t *e = ap_expr_regex_make($2, $4, $3, 1, ctx);
+ if (!e) {
ctx->error = "Failed to compile regular expression";
YYERROR;
}
- $$ = ap_expr_make(op_Regex, regex, NULL, ctx);
+ $$ = e;
}
;
+regany : regex { $$ = $1; }
+ | regsub { $$ = $1; }
+ | regsplit { $$ = $1; }
+ ;
-backref : T_REGEX_BACKREF {
+regref : T_REG_REF {
int *n = apr_palloc(ctx->pool, sizeof(int));
*n = $1;
- $$ = ap_expr_make(op_RegexBackref, n, NULL, ctx);
+ $$ = ap_expr_make(op_Regref, n, NULL, ctx);
}
- ;
+ ;
-lstfunccall : T_ID '(' word ')' { $$ = ap_expr_list_func_make($1, $3, ctx); }
- ;
+lstfunc : T_ID '(' word ')' { $$ = ap_expr_list_func_make($1, $3, ctx); }
+ /* | T_ID '(' words ')' { $$ = ap_expr_list_func_make($1, $3, ctx); } */
+ ;
-strfunccall : T_ID '(' word ')' { $$ = ap_expr_str_func_make($1, $3, ctx); }
- | T_ID '(' words ')' { $$ = ap_expr_str_func_make($1, $3, ctx); }
- ;
+strfunc : T_ID '(' word ')' { $$ = ap_expr_str_func_make($1, $3, ctx); }
+ | T_ID '(' words ')' { $$ = ap_expr_str_func_make($1, $3, ctx); }
+ ;
%%
op_REG, op_NRE,
op_STR_EQ, op_STR_NE, op_STR_LT, op_STR_LE, op_STR_GT, op_STR_GE,
op_Concat,
- op_Digit, op_String, op_Regex, op_RegexBackref,
- op_Var,
- op_ListElement,
+ op_Digit, op_String,
+ op_Var, op_Word, op_Bool, op_Join,
+ op_Regex, op_Regsub, op_Regref,
+ op_ListElement, op_ListRegex,
/*
* call external functions/operators.
* The info node contains the function pointer and some function specific
const void *node_arg2;
};
+/** The stack used by scanner and parser */
+typedef struct ap_expr_parser_stack {
+ char *scan_ptr;
+ char scan_buf[MAX_STRING_LEN];
+ int scan_stop;
+ int scan_flag;
+ struct ap_expr_parser_stack *next;
+} ap_expr_parser_stack_t;
+
/** The context used by scanner and parser */
typedef struct {
/* internal state of the scanner */
int inputlen;
const char *inputptr;
void *scanner;
- char *scan_ptr;
- char scan_buf[MAX_STRING_LEN];
- char scan_del;
+ ap_expr_parser_stack_t *current,
+ *spares;
int at_start;
/* pools for result and temporary usage */
/* create a parse tree node */
ap_expr_t *ap_expr_make(ap_expr_node_op_e op, const void *arg1,
const void *arg2, ap_expr_parse_ctx_t *ctx);
+ap_expr_t *ap_expr_concat_make(const void *a1, const void *a2,
+ ap_expr_parse_ctx_t *ctx);
+ap_expr_t *ap_expr_str_word_make(const ap_expr_t *arg,
+ ap_expr_parse_ctx_t *ctx);
+ap_expr_t *ap_expr_str_bool_make(const ap_expr_t *arg,
+ ap_expr_parse_ctx_t *ctx);
+ap_expr_t *ap_expr_regex_make(const char *pattern, const char *flags,
+ const ap_expr_t *subst, int split,
+ ap_expr_parse_ctx_t *ctx);
/* create parse tree node for the string-returning function 'name' */
ap_expr_t *ap_expr_str_func_make(const char *name, const ap_expr_t *arg,
ap_expr_parse_ctx_t *ctx);
/* create parse tree node for the list-returning function 'name' */
ap_expr_t *ap_expr_list_func_make(const char *name, const ap_expr_t *arg,
ap_expr_parse_ctx_t *ctx);
+ap_expr_t *ap_expr_list_regex_make(const ap_expr_t *lst, const ap_expr_t *re,
+ ap_expr_parse_ctx_t *ctx);
/* create parse tree node for the variable 'name' */
ap_expr_t *ap_expr_var_make(const char *name, ap_expr_parse_ctx_t *ctx);
/* create parse tree node for the unary operator 'name' */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 1
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
#endif /* ! FLEXINT_H */
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* Returned upon end-of-file. */
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
#define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
/* Begin user sect3 */
-#define ap_expr_yywrap(n) 1
+#define ap_expr_yywrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 67
-#define YY_END_OF_BUFFER 68
+#define YY_NUM_RULES 74
+#define YY_END_OF_BUFFER 75
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[124] =
+static yyconst flex_int16_t yy_accept[157] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 68, 66, 1, 43, 2, 66, 66, 66,
- 65, 66, 44, 26, 63, 32, 30, 34, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 66,
- 14, 4, 3, 17, 17, 67, 17, 23, 4, 22,
- 20, 21, 67, 16, 16, 24, 27, 29, 28, 1,
- 31, 37, 19, 18, 39, 63, 59, 59, 59, 59,
- 59, 59, 33, 30, 36, 35, 64, 64, 57, 64,
- 55, 54, 58, 53, 52, 25, 25, 56, 64, 40,
- 64, 41, 14, 13, 15, 12, 5, 6, 10, 11,
-
- 7, 8, 9, 20, 60, 46, 48, 50, 45, 49,
- 51, 47, 38, 64, 42, 64, 5, 6, 64, 61,
- 5, 62, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 75, 73,
+ 15, 14, 1, 15, 15, 15, 16, 46, 17, 73,
+ 73, 73, 72, 73, 47, 27, 70, 73, 35, 33,
+ 37, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 73, 26, 22, 21, 25, 24,
+ 14, 24, 24, 24, 23, 66, 65, 29, 30, 14,
+ 30, 30, 30, 31, 2, 3, 13, 6, 6, 5,
+ 11, 12, 8, 9, 10, 13, 16, 34, 40, 32,
+ 20, 42, 70, 63, 63, 63, 63, 63, 63, 19,
+
+ 36, 33, 39, 38, 71, 71, 60, 71, 58, 57,
+ 61, 71, 56, 55, 28, 28, 59, 71, 43, 71,
+ 71, 44, 21, 4, 6, 6, 0, 5, 7, 18,
+ 62, 49, 51, 53, 48, 52, 54, 50, 41, 71,
+ 71, 45, 71, 71, 6, 5, 5, 5, 7, 71,
+ 67, 71, 68, 69, 64, 0
} ;
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 4, 5, 6, 7, 8, 9, 5, 10,
10, 1, 1, 11, 12, 13, 14, 15, 15, 15,
- 15, 15, 15, 15, 15, 16, 16, 17, 6, 18,
- 19, 20, 6, 1, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 1, 22, 1, 6, 23, 1, 24, 25, 21, 26,
-
- 27, 28, 29, 21, 30, 21, 21, 31, 32, 33,
- 34, 21, 35, 36, 37, 38, 39, 21, 21, 21,
- 21, 21, 40, 41, 42, 43, 1, 1, 1, 1,
+ 15, 16, 16, 16, 16, 17, 17, 18, 6, 19,
+ 20, 21, 6, 1, 22, 22, 22, 22, 22, 22,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 1, 24, 1, 6, 25, 1, 26, 27, 22, 28,
+
+ 29, 30, 31, 23, 32, 33, 23, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 23, 23, 44,
+ 23, 23, 45, 46, 47, 48, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[44] =
+static yyconst YY_CHAR yy_meta[49] =
{ 0,
- 1, 1, 2, 1, 2, 1, 2, 2, 1, 1,
- 1, 1, 1, 1, 3, 3, 1, 1, 1, 1,
- 3, 2, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 1,
- 1, 2, 1
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 3, 3, 1, 1, 1,
+ 1, 3, 4, 1, 4, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 1, 1, 1, 1
} ;
-static yyconst flex_int16_t yy_base[133] =
+static yyconst flex_uint16_t yy_base[171] =
{ 0,
- 0, 0, 41, 47, 89, 0, 130, 136, 0, 0,
- 147, 146, 175, 275, 54, 28, 275, 43, 134, 164,
- 275, 164, 275, 275, 45, 152, 32, 151, 0, 136,
- 133, 143, 26, 133, 35, 194, 38, 129, 128, 122,
- 0, 275, 275, 51, 122, 221, 275, 275, 275, 275,
- 0, 275, 275, 61, 121, 275, 275, 275, 275, 76,
- 275, 275, 275, 275, 275, 65, 0, 125, 47, 126,
- 107, 130, 275, 275, 275, 275, 0, 130, 0, 124,
- 0, 0, 0, 0, 0, 275, 0, 0, 104, 0,
- 101, 275, 0, 275, 275, 275, 71, 131, 275, 275,
-
- 275, 275, 275, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 99, 0, 61, 133, 135, 57, 0,
- 138, 0, 275, 259, 262, 265, 79, 67, 268, 271,
- 65, 42
+ 0, 0, 0, 6, 30, 0, 78, 0, 124, 126,
+ 170, 213, 0, 0, 132, 134, 0, 0, 244, 455,
+ 455, 455, 455, 0, 198, 245, 16, 116, 455, 5,
+ 197, 232, 455, 275, 455, 455, 10, 193, 219, 118,
+ 217, 0, 200, 196, 208, 101, 197, 195, 115, 308,
+ 116, 190, 191, 188, 177, 455, 455, 0, 455, 455,
+ 455, 144, 177, 340, 455, 455, 455, 455, 455, 455,
+ 152, 170, 370, 455, 455, 196, 455, 13, 170, 174,
+ 455, 455, 455, 455, 455, 0, 144, 455, 455, 455,
+ 195, 455, 177, 0, 173, 120, 175, 123, 181, 455,
+
+ 455, 455, 455, 455, 0, 181, 0, 174, 0, 0,
+ 0, 175, 0, 0, 455, 0, 0, 164, 0, 171,
+ 137, 455, 0, 455, 139, 181, 184, 187, 0, 455,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 138,
+ 136, 0, 138, 134, 455, 455, 455, 455, 455, 122,
+ 0, 86, 0, 0, 0, 455, 414, 418, 422, 426,
+ 430, 434, 438, 442, 444, 446, 448, 3, 450, 1
} ;
-static yyconst flex_int16_t yy_def[133] =
+static yyconst flex_int16_t yy_def[171] =
{ 0,
- 123, 1, 124, 124, 123, 5, 124, 124, 125, 125,
- 126, 126, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 127, 123, 123, 123, 123, 123, 123, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128, 128, 123,
- 129, 123, 123, 123, 123, 130, 123, 123, 123, 123,
- 131, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 132, 132, 132, 132,
- 132, 132, 123, 123, 123, 123, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 123, 128, 128, 128, 128,
- 128, 123, 129, 123, 123, 123, 123, 123, 123, 123,
-
- 123, 123, 123, 131, 132, 132, 132, 132, 132, 132,
- 132, 132, 128, 128, 128, 128, 123, 123, 128, 128,
- 123, 128, 0, 123, 123, 123, 123, 123, 123, 123,
- 123, 123
+ 157, 157, 158, 158, 156, 5, 156, 7, 159, 159,
+ 160, 160, 161, 161, 162, 162, 163, 163, 156, 156,
+ 156, 156, 156, 156, 156, 164, 156, 156, 156, 156,
+ 156, 156, 156, 165, 156, 156, 156, 156, 156, 156,
+ 156, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+ 166, 166, 50, 166, 156, 156, 156, 167, 156, 156,
+ 156, 156, 156, 164, 156, 156, 156, 156, 156, 156,
+ 156, 156, 164, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 168, 156, 156, 156, 156,
+ 156, 156, 156, 169, 169, 169, 169, 169, 169, 156,
+
+ 156, 156, 156, 156, 166, 166, 166, 166, 166, 166,
+ 166, 166, 166, 166, 156, 166, 166, 166, 166, 166,
+ 166, 156, 167, 156, 156, 156, 156, 156, 170, 156,
+ 169, 169, 169, 169, 169, 169, 169, 169, 166, 166,
+ 166, 166, 166, 166, 156, 156, 156, 156, 156, 166,
+ 166, 166, 166, 166, 166, 0, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156
} ;
-static yyconst flex_int16_t yy_nxt[319] =
+static yyconst flex_uint16_t yy_nxt[504] =
{ 0,
- 14, 15, 15, 16, 17, 14, 18, 19, 20, 21,
- 21, 22, 23, 24, 25, 25, 21, 26, 27, 28,
- 29, 14, 14, 30, 29, 29, 31, 32, 33, 34,
- 35, 36, 37, 38, 29, 29, 29, 39, 29, 21,
- 40, 21, 14, 42, 105, 43, 61, 44, 45, 42,
- 74, 43, 81, 44, 45, 60, 60, 63, 63, 66,
- 66, 84, 46, 82, 88, 94, 94, 104, 46, 77,
- 62, 89, 85, 107, 75, 94, 94, 60, 60, 66,
- 66, 67, 47, 122, 108, 117, 118, 120, 47, 48,
- 48, 49, 48, 48, 48, 48, 48, 48, 48, 48,
-
- 48, 48, 48, 48, 48, 50, 48, 48, 48, 51,
- 48, 48, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 48, 48,
- 52, 48, 42, 110, 53, 119, 54, 55, 42, 116,
- 53, 115, 54, 55, 111, 118, 118, 121, 118, 118,
- 118, 46, 118, 118, 114, 113, 112, 46, 109, 106,
- 95, 95, 92, 91, 90, 83, 80, 79, 78, 76,
- 73, 56, 65, 64, 123, 59, 59, 56, 66, 66,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 68, 123, 69, 70, 71, 123, 72, 86, 86, 86,
-
- 86, 86, 123, 123, 86, 86, 86, 86, 123, 123,
- 86, 123, 123, 123, 123, 123, 87, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 86, 97, 98, 123, 123, 123,
- 123, 123, 123, 123, 123, 99, 123, 123, 100, 123,
- 123, 123, 123, 101, 123, 123, 102, 123, 103, 41,
- 41, 41, 57, 57, 57, 58, 58, 58, 93, 123,
- 93, 96, 96, 96, 13, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
-
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123
+ 156, 156, 22, 149, 23, 129, 24, 25, 22, 156,
+ 23, 156, 24, 25, 75, 75, 75, 87, 87, 90,
+ 90, 90, 156, 26, 93, 93, 93, 125, 125, 26,
+ 20, 27, 27, 28, 29, 20, 30, 31, 32, 33,
+ 33, 34, 35, 36, 37, 37, 37, 38, 39, 40,
+ 41, 42, 42, 20, 20, 43, 42, 42, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 42, 42, 42,
+ 53, 54, 42, 42, 33, 55, 33, 20, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 57, 56, 56, 56, 58,
+
+ 58, 56, 56, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 58, 56, 56, 59, 56, 61, 155, 61, 109,
+ 62, 63, 62, 63, 70, 88, 70, 102, 71, 72,
+ 71, 72, 110, 113, 117, 87, 87, 64, 133, 64,
+ 154, 136, 118, 145, 145, 73, 114, 73, 75, 75,
+ 75, 134, 153, 89, 137, 103, 75, 75, 75, 152,
+ 65, 151, 65, 67, 67, 67, 67, 67, 150, 144,
+ 67, 67, 67, 67, 126, 126, 127, 67, 128, 128,
+ 128, 93, 93, 93, 67, 146, 146, 147, 147, 147,
+
+ 147, 148, 148, 148, 143, 142, 141, 140, 139, 138,
+ 135, 132, 130, 124, 76, 67, 67, 67, 67, 67,
+ 67, 76, 122, 67, 67, 67, 67, 121, 120, 119,
+ 67, 112, 111, 108, 107, 106, 104, 67, 101, 100,
+ 92, 91, 76, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 67, 78,
+ 79, 80, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 81, 156, 156, 82, 156, 156, 156, 156, 156,
+ 83, 156, 156, 156, 84, 156, 85, 156, 86, 93,
+ 93, 93, 156, 156, 156, 156, 156, 156, 156, 156,
+
+ 156, 156, 156, 95, 156, 96, 97, 156, 98, 156,
+ 99, 115, 115, 115, 115, 115, 156, 156, 115, 115,
+ 115, 115, 156, 156, 156, 115, 156, 156, 156, 156,
+ 156, 156, 116, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 115, 78, 79, 80, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 81, 156, 156, 82,
+ 156, 156, 156, 156, 156, 83, 156, 156, 156, 84,
+ 156, 85, 156, 86, 78, 79, 80, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 81, 156, 156, 82,
+
+ 156, 156, 156, 156, 156, 83, 156, 156, 156, 84,
+ 156, 85, 156, 86, 20, 20, 20, 20, 21, 21,
+ 21, 21, 60, 60, 60, 60, 66, 66, 66, 66,
+ 68, 68, 68, 68, 69, 69, 69, 69, 74, 74,
+ 74, 74, 77, 156, 77, 77, 94, 94, 105, 105,
+ 123, 123, 131, 131, 19, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+
+ 156, 156, 156
} ;
-static yyconst flex_int16_t yy_chk[319] =
+static yyconst flex_int16_t yy_chk[504] =
{ 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 3, 132, 3, 16, 3, 3, 4,
- 27, 4, 33, 4, 4, 15, 15, 18, 18, 25,
- 25, 35, 3, 33, 37, 44, 44, 131, 4, 128,
- 16, 37, 35, 69, 27, 54, 54, 60, 60, 66,
- 66, 127, 3, 119, 69, 97, 97, 116, 4, 5,
+ 0, 0, 3, 170, 3, 168, 3, 3, 4, 0,
+ 4, 0, 4, 4, 24, 24, 24, 27, 27, 30,
+ 30, 30, 0, 3, 37, 37, 37, 78, 78, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 7, 71, 7, 114, 7, 7, 8, 91,
- 8, 89, 8, 8, 71, 98, 98, 117, 117, 118,
- 118, 7, 121, 121, 80, 78, 72, 8, 70, 68,
- 55, 45, 40, 39, 38, 34, 32, 31, 30, 28,
- 26, 7, 20, 19, 13, 12, 11, 8, 22, 22,
+ 5, 5, 5, 5, 5, 5, 5, 5, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 9, 152, 10, 46,
+ 9, 9, 10, 10, 15, 28, 16, 40, 15, 15,
+ 16, 16, 46, 49, 51, 87, 87, 9, 96, 10,
+ 150, 98, 51, 125, 125, 15, 49, 16, 62, 62,
+ 62, 96, 144, 28, 98, 40, 71, 71, 71, 143,
+ 9, 141, 10, 11, 11, 11, 11, 11, 140, 121,
+ 11, 11, 11, 11, 79, 79, 79, 11, 80, 80,
+ 80, 93, 93, 93, 11, 126, 126, 126, 127, 127,
+
+ 127, 128, 128, 128, 120, 118, 112, 108, 106, 99,
+ 97, 95, 91, 76, 72, 11, 12, 12, 12, 12,
+ 12, 63, 55, 12, 12, 12, 12, 54, 53, 52,
+ 12, 48, 47, 45, 44, 43, 41, 12, 39, 38,
+ 32, 31, 25, 19, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 26,
+ 26, 26, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 26, 0, 0, 26, 0, 0, 0, 0, 0,
+ 26, 0, 0, 0, 26, 0, 26, 0, 26, 34,
+ 34, 34, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 34, 0, 34, 34, 0, 34, 0,
+ 34, 50, 50, 50, 50, 50, 0, 0, 50, 50,
+ 50, 50, 0, 0, 0, 50, 0, 0, 0, 0,
+ 0, 0, 50, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 22, 0, 22, 22, 22, 0, 22, 36, 36, 36,
-
- 36, 36, 0, 0, 36, 36, 36, 36, 0, 0,
- 36, 0, 0, 0, 0, 0, 36, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 36, 46, 46, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 0, 0, 46, 0,
- 0, 0, 0, 46, 0, 0, 46, 0, 46, 124,
- 124, 124, 125, 125, 125, 126, 126, 126, 129, 0,
- 129, 130, 130, 130, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
-
- 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123
+ 0, 0, 0, 50, 64, 64, 64, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 64, 0, 0, 64,
+ 0, 0, 0, 0, 0, 64, 0, 0, 0, 64,
+ 0, 64, 0, 64, 73, 73, 73, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 73, 0, 0, 73,
+
+ 0, 0, 0, 0, 0, 73, 0, 0, 0, 73,
+ 0, 73, 0, 73, 157, 157, 157, 157, 158, 158,
+ 158, 158, 159, 159, 159, 159, 160, 160, 160, 160,
+ 161, 161, 161, 161, 162, 162, 162, 162, 163, 163,
+ 163, 163, 164, 0, 164, 164, 165, 165, 166, 166,
+ 167, 167, 169, 169, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+
+ 156, 156, 156
} ;
/* The intent behind this definition is that it'll catch
-
#line 43 "util_expr_scan.l"
#include "util_expr_private.h"
#include "util_expr_parse.h"
#include "http_main.h"
#include "http_log.h"
+#include "apr_lib.h"
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
* XXX: longjmp. It is not clear if the scanner is in any state
* XXX: to be cleaned up, though.
*/
+static int unreachable = 0;
#define YY_FATAL_ERROR(msg) \
do { \
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, \
APLOGNO(03296) \
"expr parser fatal error (BUG?): " \
"%s, exiting", msg); \
- abort(); \
+ if (unreachable) { \
+ /* Not reached, silence [-Wunused-function] */ \
+ yy_fatal_error(msg, yyscanner); \
+ } \
+ else { \
+ abort(); \
+ } \
} while (0)
#define YY_EXTRA_TYPE ap_expr_parse_ctx_t*
-#define PERROR(msg) do { yyextra->error2 = msg ; return T_ERROR; } while (0)
+#define PERROR(msg) do { \
+ yyextra->error2 = msg; \
+ return T_ERROR; \
+} while (0)
+
+#define PERROR_CHAR(prefix, chr) do { \
+ char *msg; \
+ if (apr_isprint((chr))) { \
+ msg = apr_psprintf(yyextra->pool, prefix "'%c'", (char)(chr)); \
+ } \
+ else { \
+ msg = apr_psprintf(yyextra->pool, prefix "'\\x%.2X'", (int)(chr)); \
+ } \
+ PERROR(msg); \
+} while (0)
+
+#define STACK_PUSH() do { \
+ ap_expr_parser_stack_t *sk; \
+ if (yyextra->spares) { \
+ sk = yyextra->spares; \
+ yyextra->spares = sk->next; \
+ } \
+ else { \
+ sk = apr_palloc(yyextra->ptemp, sizeof(*sk)); \
+ } \
+ sk->scan_ptr = sk->scan_buf; \
+ sk->scan_stop = sk->scan_buf[0] = '\0'; \
+ sk->scan_flag = 0; \
+ sk->next = yyextra->current; \
+ yyextra->current = sk; \
+} while (0)
+
+#define STACK_POP() do { \
+ ap_expr_parser_stack_t *sk; \
+ sk = yyextra->current; \
+ yyextra->current = sk->next; \
+ sk->next = yyextra->spares; \
+ yyextra->spares = sk; \
+} while (0)
+
+#define STATE_PUSH(st, sk) do { \
+ yy_push_state((st), yyscanner); \
+ if ((sk)) { \
+ STACK_PUSH(); \
+ } \
+} while (0)
+
+#define STATE_POP(sk) do { \
+ if ((sk)) { \
+ STACK_POP(); \
+ } \
+ yy_pop_state(yyscanner); \
+} while (0)
+
+#define str_ptr (yyextra->current->scan_ptr)
+#define str_buf (yyextra->current->scan_buf)
+#define str_stop (yyextra->current->scan_stop)
+#define str_flag (yyextra->current->scan_flag)
+
+#define STR_APPEND_CHECK(chr, chk) do { \
+ if ((chk) && apr_iscntrl((chr))) { \
+ PERROR_CHAR("Invalid string character ", (chr)); \
+ } \
+ if (str_ptr >= str_buf + sizeof(str_buf) - 1) { \
+ PERROR("String too long"); \
+ } \
+ *str_ptr++ = (char)(chr); \
+} while (0)
-#define str_ptr (yyextra->scan_ptr)
-#define str_buf (yyextra->scan_buf)
-#define str_del (yyextra->scan_del)
+#define STR_APPEND_NOCHECK(chr) \
+ STR_APPEND_CHECK((chr), 0)
-#define STR_APPEND(c) do { \
- *str_ptr++ = (c); \
- if (str_ptr >= str_buf + sizeof(str_buf)) \
- PERROR("String too long"); \
- } while (0)
+#define STR_EMPTY() \
+ (str_ptr == str_buf)
-#line 630 "util_expr_scan.c"
+#define STR_RETURN() \
+ (apr_pstrdup(yyextra->pool, (*str_ptr = '\0', str_ptr = str_buf)))
+
+#line 744 "util_expr_scan.c"
#define INITIAL 0
#define str 1
-#define var 2
-#define vararg 3
-#define regex 4
-#define regex_flags 5
+#define expr 2
+#define var 3
+#define vararg 4
+#define split 5
+#define regex 6
+#define regsub 7
+#define regflags 8
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
FILE *ap_expr_yyget_in (yyscan_t yyscanner );
-void ap_expr_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+void ap_expr_yyset_in (FILE * _in_str ,yyscan_t yyscanner );
FILE *ap_expr_yyget_out (yyscan_t yyscanner );
-void ap_expr_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+void ap_expr_yyset_out (FILE * _out_str ,yyscan_t yyscanner );
-int ap_expr_yyget_leng (yyscan_t yyscanner );
+ int ap_expr_yyget_leng (yyscan_t yyscanner );
char *ap_expr_yyget_text (yyscan_t yyscanner );
int ap_expr_yyget_lineno (yyscan_t yyscanner );
-void ap_expr_yyset_lineno (int line_number ,yyscan_t yyscanner );
+void ap_expr_yyset_lineno (int _line_number ,yyscan_t yyscanner );
+
+int ap_expr_yyget_column (yyscan_t yyscanner );
+
+void ap_expr_yyset_column (int _column_no ,yyscan_t yyscanner );
YYSTYPE * ap_expr_yyget_lval (yyscan_t yyscanner );
#endif
#endif
+#ifndef YY_NO_UNPUT
+
+#endif
+
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
#endif
#endif
- static void yy_push_state (int new_state ,yyscan_t yyscanner);
+ static void yy_push_state (int _new_state ,yyscan_t yyscanner);
static void yy_pop_state (yyscan_t yyscanner );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
else \
{ \
errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
-#define YY_BREAK break;
+#define YY_BREAK /*LINTED*/break;
#endif
#define YY_RULE_SETUP \
*/
YY_DECL
{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-#line 93 "util_expr_scan.l"
-
-
- char regex_buf[MAX_STRING_LEN];
- char *regex_ptr = NULL;
- char regex_del = '\0';
-
-
- /*
- * Set initial state for string expressions
- */
- if (yyextra->at_start) {
- yyextra->at_start = 0;
- if (yyextra->flags & AP_EXPR_FLAG_STRING_RESULT) {
- BEGIN(str);
- return T_EXPR_STRING;
- }
- else {
- return T_EXPR_BOOL;
- }
- }
-
-
- /*
- * Whitespaces
- */
-#line 901 "util_expr_scan.c"
-
yylval = yylval_param;
if ( !yyg->yy_init )
ap_expr_yy_load_buffer_state(yyscanner );
}
- while ( 1 ) /* loops until end-of-file is reached */
+ {
+#line 179 "util_expr_scan.l"
+
+
+
+ /*
+ * Set initial state for string expressions
+ */
+ if (yyextra->at_start) {
+ yyextra->at_start = 0;
+ if (yyextra->flags & AP_EXPR_FLAG_STRING_RESULT) {
+ STATE_PUSH(str, 1);
+ return T_EXPR_STRING;
+ }
+ else {
+ STATE_PUSH(expr, 1);
+ return T_EXPR_BOOL;
+ }
+ }
+
+
+ /*
+ * Back off INITIAL pushes
+ */
+#line 1052 "util_expr_scan.c"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
yy_cp = yyg->yy_c_buf_p;
yy_match:
do
{
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 124 )
+ if ( yy_current_state >= 157 )
yy_c = yy_meta[(unsigned int) yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
++yy_cp;
}
- while ( yy_current_state != 123 );
+ while ( yy_current_state != 156 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
yy_current_state = yyg->yy_last_accepting_state;
goto yy_find_action;
-case 1:
-/* rule 1 can match eol */
-YY_RULE_SETUP
-#line 118 "util_expr_scan.l"
-{
- /* NOP */
+case YY_STATE_EOF(str):
+#line 201 "util_expr_scan.l"
+{
+ STATE_POP(0); /* <str> */
+ if (YY_START != INITIAL) {
+ PERROR("Unterminated string");
+ }
+ yylval->cpVal = STR_RETURN();
+ STACK_POP(); /* ^ after this */
+ return T_STRING;
}
YY_BREAK
-/*
- * strings ("..." and '...')
- */
-case 2:
-YY_RULE_SETUP
-#line 125 "util_expr_scan.l"
+case YY_STATE_EOF(expr):
+#line 210 "util_expr_scan.l"
{
- str_ptr = str_buf;
- str_del = yytext[0];
- BEGIN(str);
- return T_STR_BEGIN;
+ STATE_POP(1); /* <expr> */
+ if (YY_START != INITIAL) {
+ PERROR("Unterminated expression");
+ }
}
YY_BREAK
-case 3:
+case 1:
YY_RULE_SETUP
-#line 131 "util_expr_scan.l"
+#line 217 "util_expr_scan.l"
{
- if (yytext[0] == str_del) {
- if (YY_START == var) {
- PERROR("Unterminated variable in string");
- }
- else if (str_ptr == str_buf) {
- BEGIN(INITIAL);
- return T_STR_END;
- }
- else {
- /* return what we have so far and scan delimiter again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- yyless(0);
- str_ptr = str_buf;
+ if (yytext[0] == str_stop) {
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
return T_STRING;
}
+ STATE_POP(1); /* <str> */
+ return T_STR_END;
}
- else {
- STR_APPEND(yytext[0]);
- }
+ STR_APPEND_NOCHECK(yytext[0]);
}
YY_BREAK
-case 4:
-/* rule 4 can match eol */
+/* regexp backref inside string/arg */
+case 2:
YY_RULE_SETUP
-#line 153 "util_expr_scan.l"
+#line 231 "util_expr_scan.l"
{
- PERROR("Unterminated string or variable");
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
+ return T_STRING;
+ }
+ yylval->num = yytext[1] - '0';
+ return T_REG_REF;
}
YY_BREAK
-case YY_STATE_EOF(var):
-case YY_STATE_EOF(vararg):
-#line 156 "util_expr_scan.l"
+/* variable inside string/arg */
+case 3:
+YY_RULE_SETUP
+#line 242 "util_expr_scan.l"
{
- PERROR("Unterminated string or variable");
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
+ return T_STRING;
+ }
+ STATE_PUSH(var, 1);
+ return T_VAR_BEGIN;
}
YY_BREAK
-case YY_STATE_EOF(str):
-#line 159 "util_expr_scan.l"
+case 4:
+YY_RULE_SETUP
+#line 252 "util_expr_scan.l"
{
- if (!(yyextra->flags & AP_EXPR_FLAG_STRING_RESULT)) {
- PERROR("Unterminated string or variable");
- }
- else {
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- str_ptr = str_buf;
- BEGIN(INITIAL);
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
return T_STRING;
}
+ STATE_PUSH(expr, 1);
+ return T_VAREXP_BEGIN;
}
YY_BREAK
+/* Any non-octal or octal higher than 377 (decimal 255) is invalid */
case 5:
YY_RULE_SETUP
-#line 172 "util_expr_scan.l"
+#line 263 "util_expr_scan.l"
{
- int result;
-
- (void)sscanf(yytext+1, "%o", &result);
- if (result > 0xff) {
- PERROR("Escape sequence out of bound");
- }
- else {
- STR_APPEND(result);
- }
+ PERROR("Bad character escape sequence");
}
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 183 "util_expr_scan.l"
+#line 266 "util_expr_scan.l"
{
- PERROR("Bad escape sequence");
+ int result;
+ (void)sscanf(yytext+1, "%o", &result);
+ STR_APPEND_NOCHECK(result);
}
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 186 "util_expr_scan.l"
-{ STR_APPEND('\n'); }
+#line 271 "util_expr_scan.l"
+{
+ int result;
+ (void)sscanf(yytext+1, "%x", &result);
+ STR_APPEND_NOCHECK(result);
+}
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 187 "util_expr_scan.l"
-{ STR_APPEND('\r'); }
+#line 276 "util_expr_scan.l"
+{ STR_APPEND_NOCHECK('\n'); }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 188 "util_expr_scan.l"
-{ STR_APPEND('\t'); }
+#line 277 "util_expr_scan.l"
+{ STR_APPEND_NOCHECK('\r'); }
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 189 "util_expr_scan.l"
-{ STR_APPEND('\b'); }
+#line 278 "util_expr_scan.l"
+{ STR_APPEND_NOCHECK('\t'); }
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 190 "util_expr_scan.l"
-{ STR_APPEND('\f'); }
+#line 279 "util_expr_scan.l"
+{ STR_APPEND_NOCHECK('\b'); }
YY_BREAK
case 12:
-/* rule 12 can match eol */
YY_RULE_SETUP
-#line 191 "util_expr_scan.l"
-{ STR_APPEND(yytext[1]); }
+#line 280 "util_expr_scan.l"
+{ STR_APPEND_NOCHECK('\f'); }
YY_BREAK
-/* regexp backref inside string/arg */
case 13:
YY_RULE_SETUP
-#line 194 "util_expr_scan.l"
-{
- if (str_ptr != str_buf) {
- /* return what we have so far and scan '$x' again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- str_ptr = str_buf;
- yyless(0);
- return T_STRING;
- }
- else {
- yylval->num = yytext[1] - '0';
- return T_REGEX_BACKREF;
- }
-}
+#line 281 "util_expr_scan.l"
+{ STR_APPEND_CHECK(yytext[1], 1); }
YY_BREAK
case 14:
+/* rule 14 can match eol */
YY_RULE_SETUP
-#line 209 "util_expr_scan.l"
+#line 283 "util_expr_scan.l"
{
- char *cp = yytext;
- while (*cp != '\0') {
- STR_APPEND(*cp);
- cp++;
- }
+ PERROR("Unterminated string or variable");
}
YY_BREAK
-/* variable inside string/arg */
case 15:
+/* rule 15 can match eol */
YY_RULE_SETUP
-#line 218 "util_expr_scan.l"
+#line 287 "util_expr_scan.l"
{
- if (str_ptr != str_buf) {
- /* return what we have so far and scan '%{' again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- yyless(0);
- str_ptr = str_buf;
- return T_STRING;
- }
- else {
- yy_push_state(var, yyscanner);
- return T_VAR_BEGIN;
- }
+ STR_APPEND_CHECK(yytext[0], 1);
}
YY_BREAK
case 16:
+/* rule 16 can match eol */
YY_RULE_SETUP
-#line 233 "util_expr_scan.l"
-{
- STR_APPEND(yytext[0]);
+#line 291 "util_expr_scan.l"
+{
+ /* NOP */
}
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 237 "util_expr_scan.l"
+#line 295 "util_expr_scan.l"
{
- STR_APPEND(yytext[0]);
+ STATE_PUSH(str, 1);
+ str_stop = yytext[0];
+ return T_STR_BEGIN;
}
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 241 "util_expr_scan.l"
+#line 301 "util_expr_scan.l"
{
- yy_push_state(var, yyscanner);
- return T_VAR_BEGIN;
+ STATE_PUSH(expr, 1);
+ return T_VAREXP_BEGIN;
}
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 246 "util_expr_scan.l"
+#line 305 "util_expr_scan.l"
{
- yylval->num = yytext[1] - '0';
- return T_REGEX_BACKREF;
+ STATE_POP(1); /* <expr> */
+ return T_VAREXP_END;
}
YY_BREAK
-/*
- * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
- */
case 20:
YY_RULE_SETUP
-#line 254 "util_expr_scan.l"
+#line 311 "util_expr_scan.l"
{
- yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
- return T_ID;
+ STATE_PUSH(var, 1);
+ return T_VAR_BEGIN;
}
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 259 "util_expr_scan.l"
+#line 315 "util_expr_scan.l"
{
- yy_pop_state(yyscanner);
- return T_VAR_END;
+ yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
+ return T_ID;
}
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 264 "util_expr_scan.l"
+#line 319 "util_expr_scan.l"
{
- BEGIN(vararg);
+ STATE_PUSH(vararg, 0);
return yytext[0];
}
YY_BREAK
case 23:
-/* rule 23 can match eol */
YY_RULE_SETUP
-#line 269 "util_expr_scan.l"
+#line 323 "util_expr_scan.l"
{
- char *msg = apr_psprintf(yyextra->pool,
- "Invalid character in variable name '%c'", yytext[0]);
- PERROR(msg);
+ yyless(0); /* let <var> handle */
+ yylval->cpVal = STR_RETURN();
+ STATE_POP(0); /* <vararg> */
+ return T_STRING;
}
YY_BREAK
case 24:
+/* rule 24 can match eol */
YY_RULE_SETUP
-#line 275 "util_expr_scan.l"
+#line 329 "util_expr_scan.l"
{
- if (str_ptr != str_buf) {
- /* return what we have so far and scan '}' again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- str_ptr = str_buf;
- yyless(0);
- return T_STRING;
- }
- else {
- yy_pop_state(yyscanner);
- return T_VAR_END;
- }
+ STR_APPEND_CHECK(yytext[0], 1);
}
YY_BREAK
-/*
- * Regular Expression
- */
case 25:
YY_RULE_SETUP
-#line 293 "util_expr_scan.l"
+#line 332 "util_expr_scan.l"
{
- regex_del = yytext[1];
- regex_ptr = regex_buf;
- BEGIN(regex);
+ STATE_POP(1); /* <var> */
+ return T_VAR_END;
}
YY_BREAK
case 26:
+/* rule 26 can match eol */
YY_RULE_SETUP
-#line 298 "util_expr_scan.l"
+#line 336 "util_expr_scan.l"
{
- regex_del = yytext[0];
- regex_ptr = regex_buf;
- BEGIN(regex);
+ PERROR_CHAR("Unexpected variable character ", yytext[0]);
}
YY_BREAK
+case YY_STATE_EOF(var):
+case YY_STATE_EOF(vararg):
+#line 339 "util_expr_scan.l"
+{
+ PERROR("Unterminated variable");
+}
+ YY_BREAK
+/*
+ * Regular Expression
+ */
case 27:
-/* rule 27 can match eol */
YY_RULE_SETUP
-#line 303 "util_expr_scan.l"
+#line 347 "util_expr_scan.l"
{
- if (yytext[0] == regex_del) {
- *regex_ptr = '\0';
- BEGIN(regex_flags);
- }
- else {
- *regex_ptr++ = yytext[0];
- if (regex_ptr >= regex_buf + sizeof(regex_buf))
- PERROR("Regexp too long");
- }
+ STATE_PUSH(regex, 1);
+ str_stop = yytext[0];
+ str_flag = 'm';
+ return T_REGEX;
}
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 314 "util_expr_scan.l"
+#line 353 "util_expr_scan.l"
{
- yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
- BEGIN(INITIAL);
- return T_REGEX_I;
+ STATE_PUSH(regex, 1);
+ str_stop = yytext[1];
+ str_flag = yytext[0];
+ return (str_flag == 'm') ? T_REGEX : T_REGSUB;
}
YY_BREAK
case 29:
/* rule 29 can match eol */
YY_RULE_SETUP
-#line 319 "util_expr_scan.l"
+#line 359 "util_expr_scan.l"
{
- yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
- yyless(0);
- BEGIN(INITIAL);
- return T_REGEX;
+ if (yytext[0] == str_stop) {
+ STATE_POP(0); /* <regex> */
+ if (str_flag == 'm') {
+ STATE_PUSH(regflags, 0);
+ }
+ else {
+ STATE_PUSH(regsub, 0);
+ }
+ yylval->cpVal = STR_RETURN();
+ return T_REG_MATCH;
+ }
+ STR_APPEND_CHECK(yytext[0], 1);
}
YY_BREAK
-case YY_STATE_EOF(regex_flags):
-#line 325 "util_expr_scan.l"
+case 30:
+/* rule 30 can match eol */
+YY_RULE_SETUP
+#line 373 "util_expr_scan.l"
{
- yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
- BEGIN(INITIAL);
- return T_REGEX;
+ if (yytext[0] == str_stop) {
+ STATE_POP(0); /* <regsub> */
+ STATE_PUSH(regflags, 0);
+ }
+ else {
+ STR_APPEND_CHECK(yytext[0], 1);
+ }
+}
+ YY_BREAK
+case 31:
+/* rule 31 can match eol */
+YY_RULE_SETUP
+#line 382 "util_expr_scan.l"
+{
+ if (ap_strchr_c("ismg", yytext[0])) {
+ STR_APPEND_NOCHECK(yytext[0]);
+ }
+ else if (apr_isalnum(yytext[0])) {
+ PERROR("Invalid regexp flag(s)");
+ }
+ else {
+ yyless(0); /* not a flags, rewind */
+ yylval->cpVal = STR_RETURN();
+ STATE_POP(1); /* <regflags> */
+ return T_REG_FLAGS;
+ }
+}
+ YY_BREAK
+case YY_STATE_EOF(regflags):
+#line 396 "util_expr_scan.l"
+{
+ yylval->cpVal = STR_RETURN();
+ STATE_POP(1); /* <regflags> */
+ return T_REG_FLAGS;
+}
+ YY_BREAK
+case YY_STATE_EOF(regex):
+case YY_STATE_EOF(regsub):
+#line 401 "util_expr_scan.l"
+{
+ PERROR("Unterminated regexp");
+}
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 405 "util_expr_scan.l"
+{
+ yylval->num = yytext[1] - '0';
+ return T_REG_REF;
}
YY_BREAK
/*
* Operators
*/
-case 30:
+case 33:
YY_RULE_SETUP
-#line 334 "util_expr_scan.l"
+#line 413 "util_expr_scan.l"
{ return T_OP_STR_EQ; }
YY_BREAK
-case 31:
+case 34:
YY_RULE_SETUP
-#line 335 "util_expr_scan.l"
+#line 414 "util_expr_scan.l"
{ return T_OP_STR_NE; }
YY_BREAK
-case 32:
+case 35:
YY_RULE_SETUP
-#line 336 "util_expr_scan.l"
+#line 415 "util_expr_scan.l"
{ return T_OP_STR_LT; }
YY_BREAK
-case 33:
+case 36:
YY_RULE_SETUP
-#line 337 "util_expr_scan.l"
+#line 416 "util_expr_scan.l"
{ return T_OP_STR_LE; }
YY_BREAK
-case 34:
+case 37:
YY_RULE_SETUP
-#line 338 "util_expr_scan.l"
+#line 417 "util_expr_scan.l"
{ return T_OP_STR_GT; }
YY_BREAK
-case 35:
+case 38:
YY_RULE_SETUP
-#line 339 "util_expr_scan.l"
+#line 418 "util_expr_scan.l"
{ return T_OP_STR_GE; }
YY_BREAK
-case 36:
+case 39:
YY_RULE_SETUP
-#line 340 "util_expr_scan.l"
+#line 419 "util_expr_scan.l"
{ return T_OP_REG; }
YY_BREAK
-case 37:
+case 40:
YY_RULE_SETUP
-#line 341 "util_expr_scan.l"
+#line 420 "util_expr_scan.l"
{ return T_OP_NRE; }
YY_BREAK
-case 38:
+case 41:
YY_RULE_SETUP
-#line 342 "util_expr_scan.l"
+#line 421 "util_expr_scan.l"
{ return T_OP_AND; }
YY_BREAK
-case 39:
+case 42:
YY_RULE_SETUP
-#line 343 "util_expr_scan.l"
+#line 422 "util_expr_scan.l"
{ return T_OP_AND; }
YY_BREAK
-case 40:
+case 43:
YY_RULE_SETUP
-#line 344 "util_expr_scan.l"
+#line 423 "util_expr_scan.l"
{ return T_OP_OR; }
YY_BREAK
-case 41:
+case 44:
YY_RULE_SETUP
-#line 345 "util_expr_scan.l"
+#line 424 "util_expr_scan.l"
{ return T_OP_OR; }
YY_BREAK
-case 42:
+case 45:
YY_RULE_SETUP
-#line 346 "util_expr_scan.l"
+#line 425 "util_expr_scan.l"
{ return T_OP_NOT; }
YY_BREAK
-case 43:
+case 46:
YY_RULE_SETUP
-#line 347 "util_expr_scan.l"
+#line 426 "util_expr_scan.l"
{ return T_OP_NOT; }
YY_BREAK
-case 44:
+case 47:
YY_RULE_SETUP
-#line 348 "util_expr_scan.l"
+#line 427 "util_expr_scan.l"
{ return T_OP_CONCAT; }
YY_BREAK
-case 45:
+case 48:
YY_RULE_SETUP
-#line 349 "util_expr_scan.l"
+#line 428 "util_expr_scan.l"
{ return T_OP_IN; }
YY_BREAK
-case 46:
+case 49:
YY_RULE_SETUP
-#line 350 "util_expr_scan.l"
+#line 429 "util_expr_scan.l"
{ return T_OP_EQ; }
YY_BREAK
-case 47:
+case 50:
YY_RULE_SETUP
-#line 351 "util_expr_scan.l"
+#line 430 "util_expr_scan.l"
{ return T_OP_NE; }
YY_BREAK
-case 48:
+case 51:
YY_RULE_SETUP
-#line 352 "util_expr_scan.l"
+#line 431 "util_expr_scan.l"
{ return T_OP_GE; }
YY_BREAK
-case 49:
+case 52:
YY_RULE_SETUP
-#line 353 "util_expr_scan.l"
+#line 432 "util_expr_scan.l"
{ return T_OP_LE; }
YY_BREAK
-case 50:
+case 53:
YY_RULE_SETUP
-#line 354 "util_expr_scan.l"
+#line 433 "util_expr_scan.l"
{ return T_OP_GT; }
YY_BREAK
-case 51:
+case 54:
YY_RULE_SETUP
-#line 355 "util_expr_scan.l"
+#line 434 "util_expr_scan.l"
{ return T_OP_LT; }
YY_BREAK
/* for compatibility with ssl_expr */
-case 52:
+case 55:
YY_RULE_SETUP
-#line 358 "util_expr_scan.l"
+#line 437 "util_expr_scan.l"
{ return T_OP_LT; }
YY_BREAK
-case 53:
+case 56:
YY_RULE_SETUP
-#line 359 "util_expr_scan.l"
+#line 438 "util_expr_scan.l"
{ return T_OP_LE; }
YY_BREAK
-case 54:
+case 57:
YY_RULE_SETUP
-#line 360 "util_expr_scan.l"
+#line 439 "util_expr_scan.l"
{ return T_OP_GT; }
YY_BREAK
-case 55:
+case 58:
YY_RULE_SETUP
-#line 361 "util_expr_scan.l"
+#line 440 "util_expr_scan.l"
{ return T_OP_GE; }
YY_BREAK
-case 56:
+case 59:
YY_RULE_SETUP
-#line 362 "util_expr_scan.l"
+#line 441 "util_expr_scan.l"
{ return T_OP_NE; }
YY_BREAK
-case 57:
+case 60:
YY_RULE_SETUP
-#line 363 "util_expr_scan.l"
+#line 442 "util_expr_scan.l"
{ return T_OP_EQ; }
YY_BREAK
-case 58:
+case 61:
YY_RULE_SETUP
-#line 364 "util_expr_scan.l"
+#line 443 "util_expr_scan.l"
{ return T_OP_IN; }
YY_BREAK
-case 59:
+case 62:
YY_RULE_SETUP
-#line 366 "util_expr_scan.l"
+#line 445 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
- return T_OP_UNARY;
+ return T_OP_BINARY;
}
YY_BREAK
-case 60:
+case 63:
YY_RULE_SETUP
-#line 371 "util_expr_scan.l"
+#line 450 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
- return T_OP_BINARY;
+ return T_OP_UNARY;
+}
+ YY_BREAK
+/* Split a string (or list) into a(nother) list */
+case 64:
+YY_RULE_SETUP
+#line 456 "util_expr_scan.l"
+{
+ STATE_PUSH(split, 0);
+ return T_OP_SPLIT;
+}
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 460 "util_expr_scan.l"
+{
+ STATE_POP(0); /* <split> */
+ STATE_PUSH(regex, 1);
+ str_stop = yytext[0];
+ str_flag = 'S';
+}
+ YY_BREAK
+case 66:
+/* rule 66 can match eol */
+YY_RULE_SETUP
+#line 466 "util_expr_scan.l"
+{
+ PERROR("Expecting split regular expression");
+}
+ YY_BREAK
+case YY_STATE_EOF(split):
+#line 469 "util_expr_scan.l"
+{
+ PERROR("Unterminated split");
+}
+ YY_BREAK
+/* Join a list into a string */
+case 67:
+YY_RULE_SETUP
+#line 474 "util_expr_scan.l"
+{
+ return T_OP_JOIN;
}
YY_BREAK
/*
* Specials
*/
-case 61:
+case 68:
YY_RULE_SETUP
-#line 379 "util_expr_scan.l"
+#line 481 "util_expr_scan.l"
{ return T_TRUE; }
YY_BREAK
-case 62:
+case 69:
YY_RULE_SETUP
-#line 380 "util_expr_scan.l"
+#line 482 "util_expr_scan.l"
{ return T_FALSE; }
YY_BREAK
/*
* Digits
*/
-case 63:
+case 70:
YY_RULE_SETUP
-#line 385 "util_expr_scan.l"
+#line 487 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_DIGIT;
/*
* Identifiers
*/
-case 64:
+case 71:
YY_RULE_SETUP
-#line 393 "util_expr_scan.l"
+#line 495 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_ID;
/*
* These are parts of the grammar and are returned as is
*/
-case 65:
+case 72:
YY_RULE_SETUP
-#line 401 "util_expr_scan.l"
+#line 503 "util_expr_scan.l"
{
return yytext[0];
}
/*
* Anything else is an error
*/
-case 66:
-/* rule 66 can match eol */
+case 73:
+/* rule 73 can match eol */
YY_RULE_SETUP
-#line 408 "util_expr_scan.l"
+#line 510 "util_expr_scan.l"
{
- char *msg = apr_psprintf(yyextra->pool, "Parse error near '%c'", yytext[0]);
- PERROR(msg);
+ PERROR_CHAR("Parse error near character ", yytext[0]);
}
YY_BREAK
-case 67:
+case 74:
YY_RULE_SETUP
-#line 413 "util_expr_scan.l"
+#line 514 "util_expr_scan.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1538 "util_expr_scan.c"
+#line 1718 "util_expr_scan.c"
case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(regex):
yyterminate();
case YY_END_OF_BUFFER:
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
+ } /* end of user's declarations */
} /* end of ap_expr_yylex */
/* yy_get_next_buffer - try to read in a new buffer
static int yy_get_next_buffer (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = yyg->yytext_ptr;
- register int number_to_move, i;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
{ /* Not enough room in the buffer - grow it. */
/* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
int yy_c_buf_p_offset =
(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
+ b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- yyg->yy_n_chars, (size_t) num_to_read );
+ yyg->yy_n_chars, num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
}
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ap_expr_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
{
- register yy_state_type yy_current_state;
- register char *yy_cp;
+ yy_state_type yy_current_state;
+ char *yy_cp;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_current_state = yyg->yy_start;
for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
{
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 124 )
+ if ( yy_current_state >= 157 )
yy_c = yy_meta[(unsigned int) yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
}
return yy_current_state;
*/
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
{
- register int yy_is_jam;
+ int yy_is_jam;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- register char *yy_cp = yyg->yy_c_buf_p;
+ char *yy_cp = yyg->yy_c_buf_p;
- register YY_CHAR yy_c = 1;
+ YY_CHAR yy_c = 1;
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 124 )
+ if ( yy_current_state >= 157 )
yy_c = yy_meta[(unsigned int) yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 123);
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ yy_is_jam = (yy_current_state == 156);
+ (void)yyg;
return yy_is_jam ? 0 : yy_current_state;
}
+#ifndef YY_NO_UNPUT
+
+#endif
+
#ifndef YY_NO_INPUT
#ifdef __cplusplus
static int yyinput (yyscan_t yyscanner)
case EOB_ACT_END_OF_FILE:
{
if ( ap_expr_yywrap(yyscanner ) )
- return EOF;
+ return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_create_buffer()" );
- b->yy_buf_size = size;
+ b->yy_buf_size = (yy_size_t)size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1;
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
yyg->yy_buffer_stack = (struct yy_buffer_state**)ap_expr_yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yyensure_buffer_stack()" );
-
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
/* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
yyg->yy_buffer_stack = (struct yy_buffer_state**)ap_expr_yyrealloc
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE ap_expr_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
- return 0;
+ return NULL;
b = (YY_BUFFER_STATE) ap_expr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
if ( ! b )
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
+ b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
YY_BUFFER_STATE ap_expr_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
{
- return ap_expr_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return ap_expr_yy_scan_bytes(yystr,(int) strlen(yystr) ,yyscanner);
}
/** Setup the input buffer state to scan the given bytes. The next call to ap_expr_yylex() will
int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
+ n = (yy_size_t) (_yybytes_len + 2);
buf = (char *) ap_expr_yyalloc(n ,yyscanner );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in ap_expr_yy_scan_bytes()" );
return b;
}
- static void yy_push_state (int new_state , yyscan_t yyscanner)
+ static void yy_push_state (int _new_state , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth )
yy_size_t new_size;
yyg->yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yyg->yy_start_stack_depth * sizeof( int );
+ new_size = (yy_size_t) yyg->yy_start_stack_depth * sizeof( int );
if ( ! yyg->yy_start_stack )
yyg->yy_start_stack = (int *) ap_expr_yyalloc(new_size ,yyscanner );
yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START;
- BEGIN(new_state);
+ BEGIN(_new_state);
}
static void yy_pop_state (yyscan_t yyscanner)
#define YY_EXIT_FAILURE 2
#endif
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
{
- (void) fprintf( stderr, "%s\n", msg );
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ (void) fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
int ap_expr_yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
}
/** Set the current line number.
- * @param line_number
+ * @param _line_number line number
* @param yyscanner The scanner object.
*/
-void ap_expr_yyset_lineno (int line_number , yyscan_t yyscanner)
+void ap_expr_yyset_lineno (int _line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "ap_expr_yyset_lineno called with no buffer" , yyscanner);
+ YY_FATAL_ERROR( "ap_expr_yyset_lineno called with no buffer" );
- yylineno = line_number;
+ yylineno = _line_number;
}
/** Set the current column.
- * @param line_number
+ * @param _column_no column number
* @param yyscanner The scanner object.
*/
/** Set the input stream. This does not discard the current
* input buffer.
- * @param in_str A readable stream.
+ * @param _in_str A readable stream.
* @param yyscanner The scanner object.
* @see ap_expr_yy_switch_to_buffer
*/
-void ap_expr_yyset_in (FILE * in_str , yyscan_t yyscanner)
+void ap_expr_yyset_in (FILE * _in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
+ yyin = _in_str ;
}
-void ap_expr_yyset_out (FILE * out_str , yyscan_t yyscanner)
+void ap_expr_yyset_out (FILE * _out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
+ yyout = _out_str ;
}
int ap_expr_yyget_debug (yyscan_t yyscanner)
return yy_flex_debug;
}
-void ap_expr_yyset_debug (int bdebug , yyscan_t yyscanner)
+void ap_expr_yyset_debug (int _bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
+ yy_flex_debug = _bdebug ;
}
/* Accessor methods for yylval and yylloc */
errno = EINVAL;
return 1;
}
-
+
*ptr_yy_globals = (yyscan_t) ap_expr_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+
ap_expr_yyset_extra (yy_user_defined, *ptr_yy_globals);
-
+
return yy_init_globals ( *ptr_yy_globals );
}
* This function is called from ap_expr_yylex_destroy(), so don't allocate here.
*/
- yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack = NULL;
yyg->yy_buffer_stack_top = 0;
yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_c_buf_p = NULL;
yyg->yy_init = 0;
yyg->yy_start = 0;
yyin = stdin;
yyout = stdout;
#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
+ yyin = NULL;
+ yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
#ifndef yytext_ptr
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
{
- register int i;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
+ int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
}
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
{
- register int n;
+ int n;
for ( n = 0; s[n]; ++n )
;
void *ap_expr_yyalloc (yy_size_t size , yyscan_t yyscanner)
{
- return (void *) malloc( size );
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ return malloc(size);
}
void *ap_expr_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
- return (void *) realloc( (char *) ptr, size );
+ return realloc(ptr, size);
}
void ap_expr_yyfree (void * ptr , yyscan_t yyscanner)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
free( (char *) ptr ); /* see ap_expr_yyrealloc() for (char *) cast */
}
#define YYTABLES_NAME "yytables"
-#line 413 "util_expr_scan.l"
+#line 514 "util_expr_scan.l"
%option warn
%option noinput nounput noyy_top_state
%option stack
-%x str
-%x var
-%x vararg
-%x regex regex_flags
+
+%x str expr
+%x var vararg
+%x split regex regsub regflags
%{
#include "util_expr_private.h"
#include "util_expr_parse.h"
#include "http_main.h"
#include "http_log.h"
+#include "apr_lib.h"
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
* XXX: longjmp. It is not clear if the scanner is in any state
* XXX: to be cleaned up, though.
*/
+static int unreachable = 0;
#define YY_FATAL_ERROR(msg) \
do { \
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, \
APLOGNO(03296) \
"expr parser fatal error (BUG?): " \
"%s, exiting", msg); \
- abort(); \
+ if (unreachable) { \
+ /* Not reached, silence [-Wunused-function] */ \
+ yy_fatal_error(msg, yyscanner); \
+ } \
+ else { \
+ abort(); \
+ } \
} while (0)
#define YY_EXTRA_TYPE ap_expr_parse_ctx_t*
-#define PERROR(msg) do { yyextra->error2 = msg ; return T_ERROR; } while (0)
+#define PERROR(msg) do { \
+ yyextra->error2 = msg; \
+ return T_ERROR; \
+} while (0)
+
+#define PERROR_CHAR(prefix, chr) do { \
+ char *msg; \
+ if (apr_isprint((chr))) { \
+ msg = apr_psprintf(yyextra->pool, prefix "'%c'", (char)(chr)); \
+ } \
+ else { \
+ msg = apr_psprintf(yyextra->pool, prefix "'\\x%.2X'", (int)(chr)); \
+ } \
+ PERROR(msg); \
+} while (0)
+
+#define STACK_PUSH() do { \
+ ap_expr_parser_stack_t *sk; \
+ if (yyextra->spares) { \
+ sk = yyextra->spares; \
+ yyextra->spares = sk->next; \
+ } \
+ else { \
+ sk = apr_palloc(yyextra->ptemp, sizeof(*sk)); \
+ } \
+ sk->scan_ptr = sk->scan_buf; \
+ sk->scan_stop = sk->scan_buf[0] = '\0'; \
+ sk->scan_flag = 0; \
+ sk->next = yyextra->current; \
+ yyextra->current = sk; \
+} while (0)
+
+#define STACK_POP() do { \
+ ap_expr_parser_stack_t *sk; \
+ sk = yyextra->current; \
+ yyextra->current = sk->next; \
+ sk->next = yyextra->spares; \
+ yyextra->spares = sk; \
+} while (0)
+
+#define STATE_PUSH(st, sk) do { \
+ yy_push_state((st), yyscanner); \
+ if ((sk)) { \
+ STACK_PUSH(); \
+ } \
+} while (0)
+
+#define STATE_POP(sk) do { \
+ if ((sk)) { \
+ STACK_POP(); \
+ } \
+ yy_pop_state(yyscanner); \
+} while (0)
+
+#define str_ptr (yyextra->current->scan_ptr)
+#define str_buf (yyextra->current->scan_buf)
+#define str_stop (yyextra->current->scan_stop)
+#define str_flag (yyextra->current->scan_flag)
+
+#define STR_APPEND_CHECK(chr, chk) do { \
+ if ((chk) && apr_iscntrl((chr))) { \
+ PERROR_CHAR("Invalid string character ", (chr)); \
+ } \
+ if (str_ptr >= str_buf + sizeof(str_buf) - 1) { \
+ PERROR("String too long"); \
+ } \
+ *str_ptr++ = (char)(chr); \
+} while (0)
-#define str_ptr (yyextra->scan_ptr)
-#define str_buf (yyextra->scan_buf)
-#define str_del (yyextra->scan_del)
+#define STR_APPEND_NOCHECK(chr) \
+ STR_APPEND_CHECK((chr), 0)
-#define STR_APPEND(c) do { \
- *str_ptr++ = (c); \
- if (str_ptr >= str_buf + sizeof(str_buf)) \
- PERROR("String too long"); \
- } while (0)
+#define STR_EMPTY() \
+ (str_ptr == str_buf)
+
+#define STR_RETURN() \
+ (apr_pstrdup(yyextra->pool, (*str_ptr = '\0', str_ptr = str_buf)))
%}
+ANY (.|\n)
+SPACE [ \t\n]
+QUOTE ["']
+TOKEN ([a-zA-Z][a-zA-Z0-9_]*)
+VAR_BEGIN (\%\{)
+VAR_ARG (\:)
+VAR_END (\})
+VAREXP_BEGIN (\%\{\:)
+VAREXP_END (\:\})
+REG_SEP [/#$%^|?!'",;:._-]
+REG_REF (\$[0-9])
%%
- char regex_buf[MAX_STRING_LEN];
- char *regex_ptr = NULL;
- char regex_del = '\0';
-
%{
/*
* Set initial state for string expressions
if (yyextra->at_start) {
yyextra->at_start = 0;
if (yyextra->flags & AP_EXPR_FLAG_STRING_RESULT) {
- BEGIN(str);
+ STATE_PUSH(str, 1);
return T_EXPR_STRING;
}
else {
+ STATE_PUSH(expr, 1);
return T_EXPR_BOOL;
}
}
%}
/*
- * Whitespaces
+ * Back off INITIAL pushes
*/
-[ \t\n]+ {
- /* NOP */
+<str><<EOF>> {
+ STATE_POP(0); /* <str> */
+ if (YY_START != INITIAL) {
+ PERROR("Unterminated string");
+ }
+ yylval->cpVal = STR_RETURN();
+ STACK_POP(); /* ^ after this */
+ return T_STRING;
+}
+<expr><<EOF>> {
+ STATE_POP(1); /* <expr> */
+ if (YY_START != INITIAL) {
+ PERROR("Unterminated expression");
+ }
}
- /*
- * strings ("..." and '...')
- */
-["'] {
- str_ptr = str_buf;
- str_del = yytext[0];
- BEGIN(str);
- return T_STR_BEGIN;
-}
-<str>["'] {
- if (yytext[0] == str_del) {
- if (YY_START == var) {
- PERROR("Unterminated variable in string");
- }
- else if (str_ptr == str_buf) {
- BEGIN(INITIAL);
- return T_STR_END;
- }
- else {
- /* return what we have so far and scan delimiter again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- yyless(0);
- str_ptr = str_buf;
+<str>{QUOTE} {
+ if (yytext[0] == str_stop) {
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
return T_STRING;
}
+ STATE_POP(1); /* <str> */
+ return T_STR_END;
}
- else {
- STR_APPEND(yytext[0]);
- }
-}
-<str,var,vararg>\n {
- PERROR("Unterminated string or variable");
+ STR_APPEND_NOCHECK(yytext[0]);
}
-<var,vararg><<EOF>> {
- PERROR("Unterminated string or variable");
-}
-<str><<EOF>> {
- if (!(yyextra->flags & AP_EXPR_FLAG_STRING_RESULT)) {
- PERROR("Unterminated string or variable");
- }
- else {
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- str_ptr = str_buf;
- BEGIN(INITIAL);
+
+ /* regexp backref inside string/arg */
+<str,vararg,regsub>{REG_REF} {
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
return T_STRING;
}
+ yylval->num = yytext[1] - '0';
+ return T_REG_REF;
}
-<str,vararg>\\[0-7]{1,3} {
- int result;
-
- (void)sscanf(yytext+1, "%o", &result);
- if (result > 0xff) {
- PERROR("Escape sequence out of bound");
- }
- else {
- STR_APPEND(result);
+ /* variable inside string/arg */
+<str,vararg,regsub>{VAR_BEGIN} {
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
+ return T_STRING;
}
+ STATE_PUSH(var, 1);
+ return T_VAR_BEGIN;
}
-<str,vararg>\\[0-9]+ {
- PERROR("Bad escape sequence");
-}
-<str,vararg>\\n { STR_APPEND('\n'); }
-<str,vararg>\\r { STR_APPEND('\r'); }
-<str,vararg>\\t { STR_APPEND('\t'); }
-<str,vararg>\\b { STR_APPEND('\b'); }
-<str,vararg>\\f { STR_APPEND('\f'); }
-<str,vararg>\\(.|\n) { STR_APPEND(yytext[1]); }
- /* regexp backref inside string/arg */
-<str,vararg>[$][0-9] {
- if (str_ptr != str_buf) {
- /* return what we have so far and scan '$x' again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- str_ptr = str_buf;
- yyless(0);
+<str,vararg,regsub>{VAREXP_BEGIN} {
+ if (!STR_EMPTY()) {
+ yyless(0); /* come back below */
+ yylval->cpVal = STR_RETURN();
return T_STRING;
}
- else {
- yylval->num = yytext[1] - '0';
- return T_REGEX_BACKREF;
- }
+ STATE_PUSH(expr, 1);
+ return T_VAREXP_BEGIN;
}
-<str,vararg>[^\\\n"'%}$]+ {
- char *cp = yytext;
- while (*cp != '\0') {
- STR_APPEND(*cp);
- cp++;
- }
+ /* Any non-octal or octal higher than 377 (decimal 255) is invalid */
+<str,vararg,regsub>\\([4-9][0-9]{2}|[8-9][0-9]{0,2}) {
+ PERROR("Bad character escape sequence");
}
+<str,vararg,regsub>\\[0-7]{1,3} {
+ int result;
+ (void)sscanf(yytext+1, "%o", &result);
+ STR_APPEND_NOCHECK(result);
+}
+<str,vararg,regsub>\\x[0-9A-Fa-f]{1,2} {
+ int result;
+ (void)sscanf(yytext+1, "%x", &result);
+ STR_APPEND_NOCHECK(result);
+}
+<str,vararg,regsub>\\n { STR_APPEND_NOCHECK('\n'); }
+<str,vararg,regsub>\\r { STR_APPEND_NOCHECK('\r'); }
+<str,vararg,regsub>\\t { STR_APPEND_NOCHECK('\t'); }
+<str,vararg,regsub>\\b { STR_APPEND_NOCHECK('\b'); }
+<str,vararg,regsub>\\f { STR_APPEND_NOCHECK('\f'); }
+<str,vararg,regsub>\\. { STR_APPEND_CHECK(yytext[1], 1); }
- /* variable inside string/arg */
-<str,vararg>%\{ {
- if (str_ptr != str_buf) {
- /* return what we have so far and scan '%{' again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- yyless(0);
- str_ptr = str_buf;
- return T_STRING;
- }
- else {
- yy_push_state(var, yyscanner);
- return T_VAR_BEGIN;
- }
+<str,vararg,regsub>\n {
+ PERROR("Unterminated string or variable");
}
-<vararg>[%$] {
- STR_APPEND(yytext[0]);
+<str>{ANY} {
+ STR_APPEND_CHECK(yytext[0], 1);
}
-<str>[%}$] {
- STR_APPEND(yytext[0]);
+<expr>{SPACE}+ {
+ /* NOP */
}
-%\{ {
- yy_push_state(var, yyscanner);
- return T_VAR_BEGIN;
+<expr>{QUOTE} {
+ STATE_PUSH(str, 1);
+ str_stop = yytext[0];
+ return T_STR_BEGIN;
}
-[$][0-9] {
- yylval->num = yytext[1] - '0';
- return T_REGEX_BACKREF;
+<expr>{VAREXP_BEGIN} {
+ STATE_PUSH(expr, 1);
+ return T_VAREXP_BEGIN;
+}
+<expr>{VAREXP_END} {
+ STATE_POP(1); /* <expr> */
+ return T_VAREXP_END;
}
- /*
- * fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
- */
-<var>[a-ij-rs-zA-IJ-RS-Z][a-ij-rs-zA-IJ-RS-Z0-9_]* {
+
+<expr>{VAR_BEGIN} {
+ STATE_PUSH(var, 1);
+ return T_VAR_BEGIN;
+}
+<var>{TOKEN} {
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_ID;
}
-
-<var>\} {
- yy_pop_state(yyscanner);
+<var>{VAR_ARG} {
+ STATE_PUSH(vararg, 0);
+ return yytext[0];
+}
+<vararg>{VAR_END} {
+ yyless(0); /* let <var> handle */
+ yylval->cpVal = STR_RETURN();
+ STATE_POP(0); /* <vararg> */
+ return T_STRING;
+}
+<vararg>{ANY} {
+ STR_APPEND_CHECK(yytext[0], 1);
+}
+<var>{VAR_END} {
+ STATE_POP(1); /* <var> */
return T_VAR_END;
}
-
-<var>: {
- BEGIN(vararg);
- return yytext[0];
+<var>{ANY} {
+ PERROR_CHAR("Unexpected variable character ", yytext[0]);
}
-
-<var>.|\n {
- char *msg = apr_psprintf(yyextra->pool,
- "Invalid character in variable name '%c'", yytext[0]);
- PERROR(msg);
+<var,vararg><<EOF>> {
+ PERROR("Unterminated variable");
}
-<vararg>\} {
- if (str_ptr != str_buf) {
- /* return what we have so far and scan '}' again */
- *str_ptr = '\0';
- yylval->cpVal = apr_pstrdup(yyextra->pool, str_buf);
- str_ptr = str_buf;
- yyless(0);
- return T_STRING;
- }
- else {
- yy_pop_state(yyscanner);
- return T_VAR_END;
- }
-}
/*
* Regular Expression
*/
-"m"[/#$%^,;:_\?\|\^\-\!\.\'\"] {
- regex_del = yytext[1];
- regex_ptr = regex_buf;
- BEGIN(regex);
-}
-"/" {
- regex_del = yytext[0];
- regex_ptr = regex_buf;
- BEGIN(regex);
-}
-<regex>.|\n {
- if (yytext[0] == regex_del) {
- *regex_ptr = '\0';
- BEGIN(regex_flags);
+<expr>\/ {
+ STATE_PUSH(regex, 1);
+ str_stop = yytext[0];
+ str_flag = 'm';
+ return T_REGEX;
+}
+<expr>[ms]{REG_SEP} {
+ STATE_PUSH(regex, 1);
+ str_stop = yytext[1];
+ str_flag = yytext[0];
+ return (str_flag == 'm') ? T_REGEX : T_REGSUB;
+}
+<regex>{ANY} {
+ if (yytext[0] == str_stop) {
+ STATE_POP(0); /* <regex> */
+ if (str_flag == 'm') {
+ STATE_PUSH(regflags, 0);
+ }
+ else {
+ STATE_PUSH(regsub, 0);
+ }
+ yylval->cpVal = STR_RETURN();
+ return T_REG_MATCH;
+ }
+ STR_APPEND_CHECK(yytext[0], 1);
+}
+<regsub>{ANY} {
+ if (yytext[0] == str_stop) {
+ STATE_POP(0); /* <regsub> */
+ STATE_PUSH(regflags, 0);
}
else {
- *regex_ptr++ = yytext[0];
- if (regex_ptr >= regex_buf + sizeof(regex_buf))
- PERROR("Regexp too long");
+ STR_APPEND_CHECK(yytext[0], 1);
}
}
-<regex_flags>i {
- yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
- BEGIN(INITIAL);
- return T_REGEX_I;
+<regflags>{ANY} {
+ if (ap_strchr_c("ismg", yytext[0])) {
+ STR_APPEND_NOCHECK(yytext[0]);
+ }
+ else if (apr_isalnum(yytext[0])) {
+ PERROR("Invalid regexp flag(s)");
+ }
+ else {
+ yyless(0); /* not a flags, rewind */
+ yylval->cpVal = STR_RETURN();
+ STATE_POP(1); /* <regflags> */
+ return T_REG_FLAGS;
+ }
}
-<regex_flags>.|\n {
- yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
- yyless(0);
- BEGIN(INITIAL);
- return T_REGEX;
+<regflags><<EOF>> {
+ yylval->cpVal = STR_RETURN();
+ STATE_POP(1); /* <regflags> */
+ return T_REG_FLAGS;
}
-<regex_flags><<EOF>> {
- yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
- BEGIN(INITIAL);
- return T_REGEX;
+<regex,regsub><<EOF>> {
+ PERROR("Unterminated regexp");
+}
+
+<expr>{REG_REF} {
+ yylval->num = yytext[1] - '0';
+ return T_REG_REF;
}
/*
* Operators
*/
-==? { return T_OP_STR_EQ; }
-"!=" { return T_OP_STR_NE; }
-"<" { return T_OP_STR_LT; }
-"<=" { return T_OP_STR_LE; }
-">" { return T_OP_STR_GT; }
-">=" { return T_OP_STR_GE; }
-"=~" { return T_OP_REG; }
-"!~" { return T_OP_NRE; }
-"and" { return T_OP_AND; }
-"&&" { return T_OP_AND; }
-"or" { return T_OP_OR; }
-"||" { return T_OP_OR; }
-"not" { return T_OP_NOT; }
-"!" { return T_OP_NOT; }
-"." { return T_OP_CONCAT; }
-"-in" { return T_OP_IN; }
-"-eq" { return T_OP_EQ; }
-"-ne" { return T_OP_NE; }
-"-ge" { return T_OP_GE; }
-"-le" { return T_OP_LE; }
-"-gt" { return T_OP_GT; }
-"-lt" { return T_OP_LT; }
+<expr>==? { return T_OP_STR_EQ; }
+<expr>"!=" { return T_OP_STR_NE; }
+<expr>"<" { return T_OP_STR_LT; }
+<expr>"<=" { return T_OP_STR_LE; }
+<expr>">" { return T_OP_STR_GT; }
+<expr>">=" { return T_OP_STR_GE; }
+<expr>"=~" { return T_OP_REG; }
+<expr>"!~" { return T_OP_NRE; }
+<expr>"and" { return T_OP_AND; }
+<expr>"&&" { return T_OP_AND; }
+<expr>"or" { return T_OP_OR; }
+<expr>"||" { return T_OP_OR; }
+<expr>"not" { return T_OP_NOT; }
+<expr>"!" { return T_OP_NOT; }
+<expr>"." { return T_OP_CONCAT; }
+<expr>"-in" { return T_OP_IN; }
+<expr>"-eq" { return T_OP_EQ; }
+<expr>"-ne" { return T_OP_NE; }
+<expr>"-ge" { return T_OP_GE; }
+<expr>"-le" { return T_OP_LE; }
+<expr>"-gt" { return T_OP_GT; }
+<expr>"-lt" { return T_OP_LT; }
/* for compatibility with ssl_expr */
-"lt" { return T_OP_LT; }
-"le" { return T_OP_LE; }
-"gt" { return T_OP_GT; }
-"ge" { return T_OP_GE; }
-"ne" { return T_OP_NE; }
-"eq" { return T_OP_EQ; }
-"in" { return T_OP_IN; }
-
-"-"[a-ij-rs-zA-IJ-RS-Z_] {
+<expr>"lt" { return T_OP_LT; }
+<expr>"le" { return T_OP_LE; }
+<expr>"gt" { return T_OP_GT; }
+<expr>"ge" { return T_OP_GE; }
+<expr>"ne" { return T_OP_NE; }
+<expr>"eq" { return T_OP_EQ; }
+<expr>"in" { return T_OP_IN; }
+
+<expr>"-"[a-zA-Z_][a-zA-Z_0-9]+ {
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
- return T_OP_UNARY;
+ return T_OP_BINARY;
}
-"-"[a-ij-rs-zA-IJ-RS-Z_][a-ij-rs-zA-IJ-RS-Z_0-9]+ {
+<expr>"-"[a-zA-Z_] {
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
- return T_OP_BINARY;
+ return T_OP_UNARY;
+}
+
+ /* Split a string (or list) into a(nother) list */
+<expr>"split" {
+ STATE_PUSH(split, 0);
+ return T_OP_SPLIT;
+}
+<split>{REG_SEP} {
+ STATE_POP(0); /* <split> */
+ STATE_PUSH(regex, 1);
+ str_stop = yytext[0];
+ str_flag = 'S';
+}
+<split>{ANY} {
+ PERROR("Expecting split regular expression");
+}
+<split><<EOF>> {
+ PERROR("Unterminated split");
+}
+
+ /* Join a list into a string */
+<expr>"join" {
+ return T_OP_JOIN;
}
/*
* Specials
*/
-"true" { return T_TRUE; }
-"false" { return T_FALSE; }
+<expr>"true" { return T_TRUE; }
+<expr>"false" { return T_FALSE; }
/*
* Digits
*/
--?[0-9]+ {
+<expr>\-?[0-9]+ {
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_DIGIT;
}
/*
* Identifiers
*/
-[a-ij-rs-zA-IJ-RS-Z][a-ij-rs-zA-IJ-RS-Z0-9_]* {
+<expr>{TOKEN} {
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_ID;
}
/*
* These are parts of the grammar and are returned as is
*/
-[(){},:] {
+<expr>[(){},] {
return yytext[0];
}
/*
* Anything else is an error
*/
-.|\n {
- char *msg = apr_psprintf(yyextra->pool, "Parse error near '%c'", yytext[0]);
- PERROR(msg);
+<INITIAL,expr>{ANY} {
+ PERROR_CHAR("Parse error near character ", yytext[0]);
}
%%
options |= PCREn(NOTBOL);
if ((eflags & AP_REG_NOTEOL) != 0)
options |= PCREn(NOTEOL);
+ if ((eflags & AP_REG_NOTEMPTY) != 0)
+ options |= PCREn(NOTEMPTY);
+ if ((eflags & AP_REG_ANCHORED) != 0)
+ options |= PCREn(ANCHORED);
#ifdef HAVE_PCRE2
/* TODO: create a generic TLS matchdata buffer of some nmatch limit,