* Evaluate a parse tree
* @param r The current request
* @param expr The expression to be evaluated
- * @param err A more detailed error string
+ * @param err Where an error message should be stored
* @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
+ * @note err will be set to NULL on success, or to an error message on error
*/
AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *expr,
const char **err);
+/**
+ * Evaluate a parse tree, with regexp backreferences
+ * @param r The current request
+ * @param expr The expression to be evaluated
+ * @param nmatch size of the regex match vector pmatch
+ * @param pmatch information about regex matches
+ * @param source the string that pmatch applies to
+ * @param err Where an error message should be stored
+ * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
+ * @note err will be set to NULL on success, or to an error message on error
+ * @note nmatch/pmatch/source can be used both to make previous matches
+ * available to ap_expr_exec_re and to use ap_expr_exec_re's matches
+ * later on.
+ */
+AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *expr,
+ apr_size_t nmatch, ap_regmatch_t *pmatch,
+ const char **source, const char **err);
+
/** Context used during evaluation of a parse tree, created by ap_expr_exec */
typedef struct {
/** the current request */
const char **err;
/** ap_expr_info_t for the expression */
const ap_expr_info_t *info;
+ /** regex match information for back references */
+ ap_regmatch_t *re_pmatch;
+ /** size of the vector pointed to by re_pmatch */
+ apr_size_t re_nmatch;
+ /** the string corresponding to the re_pmatch*/
+ const char **re_source;
} ap_expr_eval_ctx;
const ap_expr_info_t *expr = parsed_require_line;
int rc = ap_expr_exec(r, expr, &err);
- if (err || !rc)
+ if (rc <= 0)
/* XXX: real error handling? */
return AUTHZ_DENIED;
else
if (entry_core->condition) {
/* XXX: error handling */
- if (!ap_expr_exec(r, entry_core->condition, &err)) {
+ if (ap_expr_exec(r, entry_core->condition, &err) <= 0) {
continue;
}
}
static const char *ap_expr_eval_string_func(ap_expr_eval_ctx *ctx, const ap_expr *info,
const ap_expr *args);
+static const char *ap_expr_eval_re_backref(ap_expr_eval_ctx *ctx, int n);
static const char *ap_expr_eval_var(ap_expr_eval_ctx *ctx,
const ap_expr_var_func_t *func,
const void *data);
/* define AP_EXPR_DEBUG to log the parse tree when parsing an expression */
-/*#define AP_EXPR_DEBUG */
#ifdef AP_EXPR_DEBUG
static void expr_dump_tree(const ap_expr *e, const server_rec *s, int loglevel, int indent);
#endif
case op_Var:
result = ap_expr_eval_var(ctx, node->node_arg1, node->node_arg2);
break;
+ case op_Concat: {
+ const char *s1 = ap_expr_eval_word(ctx, node->node_arg1);
+ const char *s2 = ap_expr_eval_word(ctx, node->node_arg2);
+ if (!*s1)
+ result = s2;
+ else if (!*s2)
+ result = s1;
+ else
+ result = apr_pstrcat(ctx->p, s1, s2, NULL);
+ break;
+ }
case op_StringFuncCall: {
const ap_expr *info = node->node_arg1;
const ap_expr *args = node->node_arg2;
result = ap_expr_eval_string_func(ctx, info, args);
break;
}
+ case op_RegexBackref: {
+ const int *np = node->node_arg1;
+ result = ap_expr_eval_re_backref(ctx, *np);
+ break;
+ }
default:
- *ctx->err = "Internal evaluation error: Unknown expression node";
+ *ctx->err = "Internal evaluation error: Unknown word expression node";
break;
}
if (!result)
return (*func)(ctx, data);
}
+static const char *ap_expr_eval_re_backref(ap_expr_eval_ctx *ctx, int n)
+{
+ int len;
+
+ if (!ctx->re_pmatch || !ctx->re_source || *ctx->re_source == '\0' ||
+ ctx->re_nmatch < n + 1)
+ return "";
+
+ len = ctx->re_pmatch[n].rm_eo - ctx->re_pmatch[n].rm_so;
+ if (len == 0)
+ return "";
+
+ return apr_pstrndup(ctx->p, *ctx->re_source + ctx->re_pmatch[n].rm_so, len);
+}
+
static const char *ap_expr_eval_string_func(ap_expr_eval_ctx *ctx, const ap_expr *info,
const ap_expr *arg)
{
}
return 0;
}
- case op_REG: {
- const ap_expr *e1;
- const ap_expr *e2;
- const char *word;
- const ap_regex_t *regex;
-
- e1 = node->node_arg1;
- e2 = node->node_arg2;
- word = ap_expr_eval_word(ctx, e1);
- regex = e2->node_arg1;
- return (ap_regexec(regex, word, 0, NULL, 0) == 0);
- }
+ case op_REG:
case op_NRE: {
const ap_expr *e1;
const ap_expr *e2;
const char *word;
const ap_regex_t *regex;
+ int result;
e1 = node->node_arg1;
e2 = node->node_arg2;
word = ap_expr_eval_word(ctx, e1);
regex = e2->node_arg1;
- return !(ap_regexec(regex, word, 0, NULL, 0) == 0);
+
+ /*
+ * $0 ... $9 may contain stuff the user wants to keep. Therefore
+ * we only set them if there are capturing parens in the regex.
+ */
+ if (regex->re_nsub > 0) {
+ result = (0 == ap_regexec(regex, word, ctx->re_nmatch,
+ ctx->re_pmatch, 0));
+ *ctx->re_source = result ? word : NULL;
+ }
+ else {
+ result = (0 == ap_regexec(regex, word, 0, NULL, 0));
+ }
+
+ if (node->node_op == op_REG)
+ return result;
+ else
+ return !result;
}
default: {
- *ctx->err = "Internal evaluation error: Unknown expression node";
+ *ctx->err = "Internal evaluation error: Unknown comp expression node";
return -1;
}
}
ap_log_error(MARK,"%*s%s: '%s' '%s'", indent, " ", op, (char *)s1, (char *)s2)
#define DUMP_P(op, p1) \
ap_log_error(MARK,"%*s%s: %pp", indent, " ", op, p1);
+#define DUMP_IP(op, p1) \
+ ap_log_error(MARK,"%*s%s: %d", indent, " ", op, *(int *)p1);
#define DUMP_S(op, s1) \
ap_log_error(MARK,"%*s%s: '%s'", indent, " ", op, (char *)s1)
case op_Regex:
DUMP_P("op_Regex", e->node_arg1);
break;
+ /* arg1: pointer to int */
+ case op_RegexBackref:
+ DUMP_IP("op_RegexBackref", e->node_arg1);
+ break;
default:
ap_log_error(MARK, "%*sERROR: INVALID OP %d", indent, " ", e->node_op);
break;
}
}
-
AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *info, const char **err)
+{
+ return ap_expr_exec_re(r, info, 0, NULL, NULL, err);
+}
+
+AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *info,
+ apr_size_t nmatch, ap_regmatch_t *pmatch,
+ const char **source, const char **err)
{
ap_expr_eval_ctx ctx;
int rc;
ctx.p = r->pool;
ctx.err = err;
ctx.info = info;
+ ctx.re_nmatch = nmatch;
+ ctx.re_pmatch = pmatch;
+ ctx.re_source = source;
+ ap_regmatch_t tmp_pmatch[10];
+ const char *tmp_source;
+
+ if (!pmatch) {
+ ctx.re_nmatch = 10;
+ ctx.re_pmatch = tmp_pmatch;
+ ctx.re_source = &tmp_source;
+ tmp_source = NULL;
+ }
+ else {
+ AP_DEBUG_ASSERT(source != NULL);
+ AP_DEBUG_ASSERT(nmatch > 0);
+ }
*err = NULL;
rc = ap_expr_eval(&ctx, info->root_node);
T_STRING = 263,
T_REGEX = 264,
T_REGEX_I = 265,
- T_OP_UNARY = 266,
- T_OP_BINARY = 267,
- T_STR_BEGIN = 268,
- T_STR_END = 269,
- T_VAR_BEGIN = 270,
- T_VAR_END = 271,
- T_OP_EQ = 272,
- T_OP_NE = 273,
- T_OP_LT = 274,
- T_OP_LE = 275,
- T_OP_GT = 276,
- T_OP_GE = 277,
- T_OP_REG = 278,
- T_OP_NRE = 279,
- T_OP_IN = 280,
- T_OP_STR_EQ = 281,
- T_OP_STR_NE = 282,
- T_OP_STR_LT = 283,
- T_OP_STR_LE = 284,
- T_OP_STR_GT = 285,
- T_OP_STR_GE = 286,
- T_OP_CONCAT = 287,
- T_OP_OR = 288,
- T_OP_AND = 289,
- T_OP_NOT = 290
+ T_REGEX_BACKREF = 266,
+ T_OP_UNARY = 267,
+ T_OP_BINARY = 268,
+ T_STR_BEGIN = 269,
+ T_STR_END = 270,
+ T_VAR_BEGIN = 271,
+ T_VAR_END = 272,
+ T_OP_EQ = 273,
+ T_OP_NE = 274,
+ T_OP_LT = 275,
+ T_OP_LE = 276,
+ T_OP_GT = 277,
+ T_OP_GE = 278,
+ T_OP_REG = 279,
+ T_OP_NRE = 280,
+ T_OP_IN = 281,
+ T_OP_STR_EQ = 282,
+ T_OP_STR_NE = 283,
+ T_OP_STR_LT = 284,
+ T_OP_STR_LE = 285,
+ T_OP_STR_GT = 286,
+ T_OP_STR_GE = 287,
+ T_OP_CONCAT = 288,
+ T_OP_OR = 289,
+ T_OP_AND = 290,
+ T_OP_NOT = 291
};
#endif
char *cpVal;
ap_expr *exVal;
+ int num;
/* Line 214 of yacc.c */
-#line 164 "util_expr_parse.c"
+#line 166 "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 264 of yacc.c */
-#line 96 "util_expr_parse.y"
+#line 99 "util_expr_parse.y"
#include "util_expr_private.h"
#define yyscanner ctx->scanner
/* Line 264 of yacc.c */
-#line 184 "util_expr_parse.c"
+#line 186 "util_expr_parse.c"
#ifdef short
# undef short
#endif
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 27
+#define YYFINAL 30
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 117
+#define YYLAST 122
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 42
+#define YYNTOKENS 43
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 13
+#define YYNNTS 14
/* YYNRULES -- Number of rules. */
-#define YYNRULES 47
+#define YYNRULES 50
/* YYNRULES -- Number of states. */
-#define YYNSTATES 88
+#define YYNSTATES 91
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 290
+#define YYMAXUTOK 291
#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,
- 36, 37, 2, 2, 40, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 41, 2,
+ 37, 38, 2, 2, 41, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 42, 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, 38, 2, 39, 2, 2, 2, 2,
+ 2, 2, 2, 39, 2, 40, 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
+ 35, 36
};
#if YYDEBUG
0, 0, 3, 5, 7, 9, 11, 14, 18, 22,
24, 27, 31, 35, 39, 43, 47, 51, 55, 59,
63, 67, 71, 75, 79, 83, 87, 91, 95, 97,
- 101, 103, 107, 110, 112, 114, 116, 120, 126, 128,
- 132, 134, 136, 140, 143, 145, 147, 152
+ 101, 103, 107, 110, 112, 114, 116, 118, 122, 128,
+ 130, 134, 136, 138, 140, 144, 147, 149, 151, 153,
+ 158
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 43, 0, -1, 44, -1, 5, -1, 3, -1, 4,
- -1, 35, 44, -1, 44, 33, 44, -1, 44, 34,
- 44, -1, 45, -1, 11, 51, -1, 36, 44, 37,
- -1, 51, 17, 51, -1, 51, 18, 51, -1, 51,
- 19, 51, -1, 51, 20, 51, -1, 51, 21, 51,
- -1, 51, 22, 51, -1, 51, 26, 51, -1, 51,
- 27, 51, -1, 51, 28, 51, -1, 51, 29, 51,
- -1, 51, 30, 51, -1, 51, 31, 51, -1, 51,
- 25, 46, -1, 51, 23, 52, -1, 51, 24, 52,
- -1, 51, 12, 51, -1, 53, -1, 38, 47, 39,
- -1, 51, -1, 47, 40, 51, -1, 48, 49, -1,
- 49, -1, 8, -1, 50, -1, 15, 7, 16, -1,
- 15, 7, 41, 48, 16, -1, 6, -1, 51, 32,
- 51, -1, 50, -1, 54, -1, 13, 48, 14, -1,
- 13, 14, -1, 9, -1, 10, -1, 7, 36, 51,
- 37, -1, 7, 36, 51, 37, -1
+ 44, 0, -1, 45, -1, 5, -1, 3, -1, 4,
+ -1, 36, 45, -1, 45, 34, 45, -1, 45, 35,
+ 45, -1, 46, -1, 12, 52, -1, 37, 45, 38,
+ -1, 52, 18, 52, -1, 52, 19, 52, -1, 52,
+ 20, 52, -1, 52, 21, 52, -1, 52, 22, 52,
+ -1, 52, 23, 52, -1, 52, 27, 52, -1, 52,
+ 28, 52, -1, 52, 29, 52, -1, 52, 30, 52,
+ -1, 52, 31, 52, -1, 52, 32, 52, -1, 52,
+ 26, 47, -1, 52, 24, 53, -1, 52, 25, 53,
+ -1, 52, 13, 52, -1, 55, -1, 39, 48, 40,
+ -1, 52, -1, 48, 41, 52, -1, 49, 50, -1,
+ 50, -1, 8, -1, 51, -1, 54, -1, 16, 7,
+ 17, -1, 16, 7, 42, 49, 17, -1, 6, -1,
+ 52, 33, 52, -1, 51, -1, 54, -1, 56, -1,
+ 14, 49, 15, -1, 14, 15, -1, 9, -1, 10,
+ -1, 11, -1, 7, 37, 52, 38, -1, 7, 37,
+ 52, 38, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 106, 106, 107, 110, 111, 112, 113, 114, 115,
- 116, 117, 120, 121, 122, 123, 124, 125, 126, 127,
- 128, 129, 130, 131, 132, 133, 134, 135, 138, 139,
- 142, 143, 146, 147, 151, 152, 155, 156, 159, 160,
- 161, 162, 163, 164, 167, 176, 187, 190
+ 0, 109, 109, 110, 113, 114, 115, 116, 117, 118,
+ 119, 120, 123, 124, 125, 126, 127, 128, 129, 130,
+ 131, 132, 133, 134, 135, 136, 137, 138, 141, 142,
+ 145, 146, 149, 150, 153, 154, 155, 158, 159, 162,
+ 163, 164, 165, 166, 167, 168, 171, 180, 191, 198,
+ 201
};
#endif
static const char *const yytname[] =
{
"$end", "error", "$undefined", "T_TRUE", "T_FALSE", "ERROR", "T_DIGIT",
- "T_ID", "T_STRING", "T_REGEX", "T_REGEX_I", "T_OP_UNARY", "T_OP_BINARY",
- "T_STR_BEGIN", "T_STR_END", "T_VAR_BEGIN", "T_VAR_END", "T_OP_EQ",
- "T_OP_NE", "T_OP_LT", "T_OP_LE", "T_OP_GT", "T_OP_GE", "T_OP_REG",
- "T_OP_NRE", "T_OP_IN", "T_OP_STR_EQ", "T_OP_STR_NE", "T_OP_STR_LT",
- "T_OP_STR_LE", "T_OP_STR_GT", "T_OP_STR_GE", "T_OP_CONCAT", "T_OP_OR",
- "T_OP_AND", "T_OP_NOT", "'('", "')'", "'{'", "'}'", "','", "':'",
- "$accept", "root", "expr", "comparison", "wordlist", "words", "string",
- "strpart", "var", "word", "regex", "lstfunccall", "strfunccall", 0
+ "T_ID", "T_STRING", "T_REGEX", "T_REGEX_I", "T_REGEX_BACKREF",
+ "T_OP_UNARY", "T_OP_BINARY", "T_STR_BEGIN", "T_STR_END", "T_VAR_BEGIN",
+ "T_VAR_END", "T_OP_EQ", "T_OP_NE", "T_OP_LT", "T_OP_LE", "T_OP_GT",
+ "T_OP_GE", "T_OP_REG", "T_OP_NRE", "T_OP_IN", "T_OP_STR_EQ",
+ "T_OP_STR_NE", "T_OP_STR_LT", "T_OP_STR_LE", "T_OP_STR_GT",
+ "T_OP_STR_GE", "T_OP_CONCAT", "T_OP_OR", "T_OP_AND", "T_OP_NOT", "'('",
+ "')'", "'{'", "'}'", "','", "':'", "$accept", "root", "expr",
+ "comparison", "wordlist", "words", "string", "strpart", "var", "word",
+ "regex", "backref", "lstfunccall", "strfunccall", 0
};
#endif
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 40, 41, 123, 125,
- 44, 58
+ 285, 286, 287, 288, 289, 290, 291, 40, 41, 123,
+ 125, 44, 58
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 42, 43, 43, 44, 44, 44, 44, 44, 44,
- 44, 44, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 46, 46,
- 47, 47, 48, 48, 49, 49, 50, 50, 51, 51,
- 51, 51, 51, 51, 52, 52, 53, 54
+ 0, 43, 44, 44, 45, 45, 45, 45, 45, 45,
+ 45, 45, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 47, 47,
+ 48, 48, 49, 49, 50, 50, 50, 51, 51, 52,
+ 52, 52, 52, 52, 52, 52, 53, 53, 54, 55,
+ 56
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
0, 2, 1, 1, 1, 1, 2, 3, 3, 1,
2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 1, 3,
- 1, 3, 2, 1, 1, 1, 3, 5, 1, 3,
- 1, 1, 3, 2, 1, 1, 4, 4
+ 1, 3, 2, 1, 1, 1, 1, 3, 5, 1,
+ 3, 1, 1, 1, 3, 2, 1, 1, 1, 4,
+ 4
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 4, 5, 3, 38, 0, 0, 0, 0, 0,
- 0, 0, 2, 9, 40, 0, 41, 0, 10, 34,
- 43, 0, 33, 35, 0, 6, 0, 1, 0, 0,
+ 0, 4, 5, 3, 39, 0, 48, 0, 0, 0,
+ 0, 0, 0, 2, 9, 41, 0, 42, 43, 0,
+ 10, 34, 45, 0, 33, 35, 36, 0, 6, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 42, 32,
- 36, 0, 11, 7, 8, 27, 12, 13, 14, 15,
- 16, 17, 44, 45, 25, 26, 0, 0, 24, 28,
- 18, 19, 20, 21, 22, 23, 39, 47, 0, 0,
- 0, 30, 37, 0, 29, 0, 46, 31
+ 0, 44, 32, 37, 0, 11, 7, 8, 27, 12,
+ 13, 14, 15, 16, 17, 46, 47, 25, 26, 0,
+ 0, 24, 28, 18, 19, 20, 21, 22, 23, 40,
+ 50, 0, 0, 0, 30, 38, 0, 29, 0, 49,
+ 31
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 11, 12, 13, 68, 80, 21, 22, 14, 15,
- 64, 69, 16
+ -1, 12, 13, 14, 71, 83, 23, 24, 15, 16,
+ 67, 17, 72, 18
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
#define YYPACT_NINF -29
static const yytype_int8 yypact[] =
{
- 49, -29, -29, -29, -29, 12, 1, 35, 25, 65,
- 65, 57, -15, -29, -29, 85, -29, 1, 31, -29,
- -29, 51, -29, -29, -10, -29, 53, -29, 65, 65,
- 1, 1, 1, 1, 1, 1, 1, 11, 11, -5,
- 1, 1, 1, 1, 1, 1, 1, -28, -29, -29,
- -29, 36, -29, 33, -29, 31, 31, 31, 31, 31,
- 31, 31, -29, -29, -29, -29, 34, 1, -29, -29,
- 31, 31, 31, 31, 31, 31, -29, -29, -3, 1,
- 6, 31, -29, -22, -29, 1, -29, 31
+ 50, -29, -29, -29, -29, -13, -29, 9, -6, 14,
+ 85, 85, 48, -28, -29, -29, 87, -29, -29, 9,
+ 25, -29, -29, 36, -29, -29, -29, -9, -29, 45,
+ -29, 85, 85, 9, 9, 9, 9, 9, 9, 9,
+ 60, 60, 4, 9, 9, 9, 9, 9, 9, 9,
+ -16, -29, -29, -29, 74, -29, 43, -29, 25, 25,
+ 25, 25, 25, 25, 25, -29, -29, -29, -29, 23,
+ 9, -29, -29, 25, 25, 25, 25, 25, 25, -29,
+ -29, 57, 9, 5, 25, -29, 34, -29, 9, -29,
+ 25
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -29, -29, 13, -29, -29, -29, 24, -20, -4, -6,
- 39, -29, -29
+ -29, -29, 3, -29, -29, -29, 17, -22, -5, -7,
+ 52, -4, -29, -29
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
- 18, 49, 66, 23, 46, 19, 50, 4, 5, 77,
- 46, 47, 8, 82, 7, 86, 8, 23, 28, 29,
- 62, 63, 25, 26, 55, 56, 57, 58, 59, 60,
- 61, 51, 24, 67, 70, 71, 72, 73, 74, 75,
- 76, 53, 54, 19, 19, 84, 85, 23, 17, 20,
- 8, 8, 1, 2, 3, 4, 5, 27, 49, 19,
- 6, 81, 7, 46, 8, 48, 8, 29, 1, 2,
- 79, 4, 5, 83, 23, 78, 6, 65, 7, 87,
- 8, 0, 0, 0, 9, 10, 28, 29, 0, 0,
- 52, 0, 0, 0, 0, 0, 0, 30, 0, 0,
- 9, 10, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42, 43, 44, 45, 46
+ 20, 52, 21, 25, 26, 6, 31, 32, 53, 22,
+ 9, 69, 50, 28, 29, 4, 5, 49, 25, 26,
+ 6, 27, 80, 8, 19, 9, 58, 59, 60, 61,
+ 62, 63, 64, 54, 56, 57, 73, 74, 75, 76,
+ 77, 78, 79, 70, 21, 87, 88, 6, 30, 25,
+ 26, 51, 9, 1, 2, 3, 4, 5, 49, 52,
+ 82, 6, 7, 84, 8, 21, 9, 49, 6, 65,
+ 66, 81, 89, 9, 85, 86, 25, 26, 32, 31,
+ 32, 90, 21, 55, 0, 6, 10, 11, 1, 2,
+ 9, 4, 5, 68, 0, 0, 6, 7, 0, 8,
+ 33, 9, 0, 0, 0, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 10, 11
};
static const yytype_int8 yycheck[] =
{
- 6, 21, 7, 7, 32, 8, 16, 6, 7, 37,
- 32, 17, 15, 16, 13, 37, 15, 21, 33, 34,
- 9, 10, 9, 10, 30, 31, 32, 33, 34, 35,
- 36, 41, 7, 38, 40, 41, 42, 43, 44, 45,
- 46, 28, 29, 8, 8, 39, 40, 51, 36, 14,
- 15, 15, 3, 4, 5, 6, 7, 0, 78, 8,
- 11, 67, 13, 32, 15, 14, 15, 34, 3, 4,
- 36, 6, 7, 79, 78, 51, 11, 38, 13, 85,
- 15, -1, -1, -1, 35, 36, 33, 34, -1, -1,
- 37, -1, -1, -1, -1, -1, -1, 12, -1, -1,
- 35, 36, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32
+ 7, 23, 8, 8, 8, 11, 34, 35, 17, 15,
+ 16, 7, 19, 10, 11, 6, 7, 33, 23, 23,
+ 11, 7, 38, 14, 37, 16, 33, 34, 35, 36,
+ 37, 38, 39, 42, 31, 32, 43, 44, 45, 46,
+ 47, 48, 49, 39, 8, 40, 41, 11, 0, 54,
+ 54, 15, 16, 3, 4, 5, 6, 7, 33, 81,
+ 37, 11, 12, 70, 14, 8, 16, 33, 11, 9,
+ 10, 54, 38, 16, 17, 82, 81, 81, 35, 34,
+ 35, 88, 8, 38, -1, 11, 36, 37, 3, 4,
+ 16, 6, 7, 41, -1, -1, 11, 12, -1, 14,
+ 13, 16, -1, -1, -1, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 36, 37
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 3, 4, 5, 6, 7, 11, 13, 15, 35,
- 36, 43, 44, 45, 50, 51, 54, 36, 51, 8,
- 14, 48, 49, 50, 7, 44, 44, 0, 33, 34,
- 12, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 51, 14, 49,
- 16, 41, 37, 44, 44, 51, 51, 51, 51, 51,
- 51, 51, 9, 10, 52, 52, 7, 38, 46, 53,
- 51, 51, 51, 51, 51, 51, 51, 37, 48, 36,
- 47, 51, 16, 51, 39, 40, 37, 51
+ 0, 3, 4, 5, 6, 7, 11, 12, 14, 16,
+ 36, 37, 44, 45, 46, 51, 52, 54, 56, 37,
+ 52, 8, 15, 49, 50, 51, 54, 7, 45, 45,
+ 0, 34, 35, 13, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 52, 15, 50, 17, 42, 38, 45, 45, 52, 52,
+ 52, 52, 52, 52, 52, 9, 10, 53, 53, 7,
+ 39, 47, 55, 52, 52, 52, 52, 52, 52, 52,
+ 38, 49, 37, 48, 52, 17, 52, 40, 41, 38,
+ 52
};
#define yyerrok (yyerrstatus = 0)
case 2:
/* Line 1455 of yacc.c */
-#line 106 "util_expr_parse.y"
+#line 109 "util_expr_parse.y"
{ ctx->expr = (yyvsp[(1) - (1)].exVal); ;}
break;
case 3:
/* Line 1455 of yacc.c */
-#line 107 "util_expr_parse.y"
+#line 110 "util_expr_parse.y"
{ YYABORT; ;}
break;
case 4:
/* Line 1455 of yacc.c */
-#line 110 "util_expr_parse.y"
+#line 113 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_True, NULL, NULL, ctx); ;}
break;
case 5:
/* Line 1455 of yacc.c */
-#line 111 "util_expr_parse.y"
+#line 114 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_False, NULL, NULL, ctx); ;}
break;
case 6:
/* Line 1455 of yacc.c */
-#line 112 "util_expr_parse.y"
+#line 115 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_Not, (yyvsp[(2) - (2)].exVal), NULL, ctx); ;}
break;
case 7:
/* Line 1455 of yacc.c */
-#line 113 "util_expr_parse.y"
+#line 116 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_Or, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 8:
/* Line 1455 of yacc.c */
-#line 114 "util_expr_parse.y"
+#line 117 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_And, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 9:
/* Line 1455 of yacc.c */
-#line 115 "util_expr_parse.y"
+#line 118 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_Comp, (yyvsp[(1) - (1)].exVal), NULL, ctx); ;}
break;
case 10:
/* Line 1455 of yacc.c */
-#line 116 "util_expr_parse.y"
+#line 119 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_unary_op_make( (yyvsp[(1) - (2)].cpVal), (yyvsp[(2) - (2)].exVal), ctx); ;}
break;
case 11:
/* Line 1455 of yacc.c */
-#line 117 "util_expr_parse.y"
+#line 120 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;}
break;
case 12:
/* Line 1455 of yacc.c */
-#line 120 "util_expr_parse.y"
+#line 123 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_EQ, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 13:
/* Line 1455 of yacc.c */
-#line 121 "util_expr_parse.y"
+#line 124 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_NE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 14:
/* Line 1455 of yacc.c */
-#line 122 "util_expr_parse.y"
+#line 125 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_LT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 15:
/* Line 1455 of yacc.c */
-#line 123 "util_expr_parse.y"
+#line 126 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_LE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 16:
/* Line 1455 of yacc.c */
-#line 124 "util_expr_parse.y"
+#line 127 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_GT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 17:
/* Line 1455 of yacc.c */
-#line 125 "util_expr_parse.y"
+#line 128 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_GE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 18:
/* Line 1455 of yacc.c */
-#line 126 "util_expr_parse.y"
+#line 129 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_EQ, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 19:
/* Line 1455 of yacc.c */
-#line 127 "util_expr_parse.y"
+#line 130 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_NE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 20:
/* Line 1455 of yacc.c */
-#line 128 "util_expr_parse.y"
+#line 131 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_LT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 21:
/* Line 1455 of yacc.c */
-#line 129 "util_expr_parse.y"
+#line 132 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_LE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 22:
/* Line 1455 of yacc.c */
-#line 130 "util_expr_parse.y"
+#line 133 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_GT, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 23:
/* Line 1455 of yacc.c */
-#line 131 "util_expr_parse.y"
+#line 134 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_STR_GE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 24:
/* Line 1455 of yacc.c */
-#line 132 "util_expr_parse.y"
+#line 135 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_IN, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 25:
/* Line 1455 of yacc.c */
-#line 133 "util_expr_parse.y"
+#line 136 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_REG, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 26:
/* Line 1455 of yacc.c */
-#line 134 "util_expr_parse.y"
+#line 137 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_NRE, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 27:
/* Line 1455 of yacc.c */
-#line 135 "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 28:
/* Line 1455 of yacc.c */
-#line 138 "util_expr_parse.y"
+#line 141 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
break;
case 29:
/* Line 1455 of yacc.c */
-#line 139 "util_expr_parse.y"
+#line 142 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;}
break;
case 30:
/* Line 1455 of yacc.c */
-#line 142 "util_expr_parse.y"
+#line 145 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(1) - (1)].exVal), NULL, ctx); ;}
break;
case 31:
/* Line 1455 of yacc.c */
-#line 143 "util_expr_parse.y"
+#line 146 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_ListElement, (yyvsp[(3) - (3)].exVal), (yyvsp[(1) - (3)].exVal), ctx); ;}
break;
case 32:
/* Line 1455 of yacc.c */
-#line 146 "util_expr_parse.y"
+#line 149 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (2)].exVal), (yyvsp[(2) - (2)].exVal), ctx); ;}
break;
case 33:
/* Line 1455 of yacc.c */
-#line 147 "util_expr_parse.y"
+#line 150 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
break;
case 34:
/* Line 1455 of yacc.c */
-#line 151 "util_expr_parse.y"
+#line 153 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_make(op_String, (yyvsp[(1) - (1)].cpVal), NULL, ctx); ;}
break;
case 35:
/* Line 1455 of yacc.c */
-#line 152 "util_expr_parse.y"
+#line 154 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
break;
/* Line 1455 of yacc.c */
#line 155 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); ;}
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
break;
case 37:
/* Line 1455 of yacc.c */
-#line 156 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(2) - (5)].cpVal), (yyvsp[(4) - (5)].exVal), ctx); ;}
+#line 158 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_var_make((yyvsp[(2) - (3)].cpVal), ctx); ;}
break;
case 38:
/* Line 1455 of yacc.c */
#line 159 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_Digit, (yyvsp[(1) - (1)].cpVal), NULL, ctx); ;}
+ { (yyval.exVal) = ap_expr_str_func_make((yyvsp[(2) - (5)].cpVal), (yyvsp[(4) - (5)].exVal), ctx); ;}
break;
case 39:
/* Line 1455 of yacc.c */
-#line 160 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
+#line 162 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_Digit, (yyvsp[(1) - (1)].cpVal), NULL, ctx); ;}
break;
case 40:
/* Line 1455 of yacc.c */
-#line 161 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
+#line 163 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_Concat, (yyvsp[(1) - (3)].exVal), (yyvsp[(3) - (3)].exVal), ctx); ;}
break;
case 41:
/* Line 1455 of yacc.c */
-#line 162 "util_expr_parse.y"
+#line 164 "util_expr_parse.y"
{ (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
break;
case 42:
/* Line 1455 of yacc.c */
-#line 163 "util_expr_parse.y"
- { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;}
+#line 165 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
break;
case 43:
/* Line 1455 of yacc.c */
-#line 164 "util_expr_parse.y"
- { (yyval.exVal) = ap_expr_make(op_String, "", NULL, ctx); ;}
+#line 166 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(1) - (1)].exVal); ;}
break;
case 44:
/* Line 1455 of yacc.c */
#line 167 "util_expr_parse.y"
+ { (yyval.exVal) = (yyvsp[(2) - (3)].exVal); ;}
+ break;
+
+ case 45:
+
+/* Line 1455 of yacc.c */
+#line 168 "util_expr_parse.y"
+ { (yyval.exVal) = ap_expr_make(op_String, "", NULL, ctx); ;}
+ break;
+
+ case 46:
+
+/* Line 1455 of yacc.c */
+#line 171 "util_expr_parse.y"
{
ap_regex_t *regex;
if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
;}
break;
- case 45:
+ case 47:
/* Line 1455 of yacc.c */
-#line 176 "util_expr_parse.y"
+#line 180 "util_expr_parse.y"
{
ap_regex_t *regex;
if ((regex = ap_pregcomp(ctx->pool, (yyvsp[(1) - (1)].cpVal),
;}
break;
- case 46:
+ case 48:
/* Line 1455 of yacc.c */
-#line 187 "util_expr_parse.y"
+#line 191 "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);
+ ;}
+ break;
+
+ case 49:
+
+/* Line 1455 of yacc.c */
+#line 198 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_list_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); ;}
break;
- case 47:
+ case 50:
/* Line 1455 of yacc.c */
-#line 190 "util_expr_parse.y"
+#line 201 "util_expr_parse.y"
{ (yyval.exVal) = ap_expr_str_func_make((yyvsp[(1) - (4)].cpVal), (yyvsp[(3) - (4)].exVal), ctx); ;}
break;
/* Line 1455 of yacc.c */
-#line 1798 "util_expr_parse.c"
+#line 1836 "util_expr_parse.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
/* Line 1675 of yacc.c */
-#line 193 "util_expr_parse.y"
+#line 204 "util_expr_parse.y"
void yyerror(ap_expr_parse_ctx *ctx, char *s)
T_STRING = 263,
T_REGEX = 264,
T_REGEX_I = 265,
- T_OP_UNARY = 266,
- T_OP_BINARY = 267,
- T_STR_BEGIN = 268,
- T_STR_END = 269,
- T_VAR_BEGIN = 270,
- T_VAR_END = 271,
- T_OP_EQ = 272,
- T_OP_NE = 273,
- T_OP_LT = 274,
- T_OP_LE = 275,
- T_OP_GT = 276,
- T_OP_GE = 277,
- T_OP_REG = 278,
- T_OP_NRE = 279,
- T_OP_IN = 280,
- T_OP_STR_EQ = 281,
- T_OP_STR_NE = 282,
- T_OP_STR_LT = 283,
- T_OP_STR_LE = 284,
- T_OP_STR_GT = 285,
- T_OP_STR_GE = 286,
- T_OP_CONCAT = 287,
- T_OP_OR = 288,
- T_OP_AND = 289,
- T_OP_NOT = 290
+ T_REGEX_BACKREF = 266,
+ T_OP_UNARY = 267,
+ T_OP_BINARY = 268,
+ T_STR_BEGIN = 269,
+ T_STR_END = 270,
+ T_VAR_BEGIN = 271,
+ T_VAR_END = 272,
+ T_OP_EQ = 273,
+ T_OP_NE = 274,
+ T_OP_LT = 275,
+ T_OP_LE = 276,
+ T_OP_GT = 277,
+ T_OP_GE = 278,
+ T_OP_REG = 279,
+ T_OP_NRE = 280,
+ T_OP_IN = 281,
+ T_OP_STR_EQ = 282,
+ T_OP_STR_NE = 283,
+ T_OP_STR_LT = 284,
+ T_OP_STR_LE = 285,
+ T_OP_STR_GT = 286,
+ T_OP_STR_GE = 287,
+ T_OP_CONCAT = 288,
+ T_OP_OR = 289,
+ T_OP_AND = 290,
+ T_OP_NOT = 291
};
#endif
char *cpVal;
ap_expr *exVal;
+ int num;
/* Line 1676 of yacc.c */
-#line 94 "util_expr_parse.h"
+#line 96 "util_expr_parse.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
%union {
char *cpVal;
ap_expr *exVal;
+ int num;
}
%token T_TRUE
%token <cpVal> T_STRING
%token <cpVal> T_REGEX
%token <cpVal> T_REGEX_I
+%token <num> T_REGEX_BACKREF
%token <cpVal> T_OP_UNARY
%token <cpVal> T_OP_BINARY
%type <exVal> string
%type <exVal> strpart
%type <exVal> var
+%type <exVal> backref
%{
#include "util_expr_private.h"
| strpart { $$ = $1; }
;
-
strpart : T_STRING { $$ = ap_expr_make(op_String, $1, NULL, ctx); }
| var { $$ = $1; }
+ | backref { $$ = $1; }
;
var : T_VAR_BEGIN T_ID T_VAR_END { $$ = ap_expr_var_make($2, ctx); }
word : T_DIGIT { $$ = ap_expr_make(op_Digit, $1, NULL, ctx); }
| word T_OP_CONCAT word { $$ = ap_expr_make(op_Concat, $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); }
}
;
+backref : T_REGEX_BACKREF {
+ int *n = apr_palloc(ctx->pool, sizeof(int));
+ *n = $1;
+ $$ = ap_expr_make(op_RegexBackref, n, NULL, ctx);
+ }
+ ;
+
lstfunccall : T_ID '(' word ')' { $$ = ap_expr_list_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_Digit, op_String, op_Regex, op_RegexBackref,
op_Var,
op_ListElement,
/*
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 65
-#define YY_END_OF_BUFFER 66
+#define YY_NUM_RULES 67
+#define YY_END_OF_BUFFER 68
/* 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[119] =
+static yyconst flex_int16_t yy_accept[124] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 66, 64, 1, 41, 2, 64, 64, 63,
- 64, 42, 24, 61, 30, 28, 32, 62, 62, 62,
- 62, 62, 62, 62, 62, 62, 62, 62, 64, 13,
- 4, 3, 16, 65, 16, 21, 4, 20, 18, 19,
- 65, 15, 22, 25, 27, 26, 1, 29, 35, 17,
- 37, 61, 57, 57, 57, 57, 57, 57, 31, 28,
- 34, 33, 62, 62, 55, 62, 53, 52, 56, 51,
- 50, 23, 23, 54, 62, 38, 62, 39, 13, 14,
- 12, 5, 6, 10, 11, 7, 8, 9, 18, 58,
-
- 44, 46, 48, 43, 47, 49, 45, 36, 62, 40,
- 62, 5, 6, 62, 59, 5, 60, 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
} ;
static yyconst flex_int32_t yy_ec[256] =
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, 6, 7, 8, 5, 9,
- 9, 1, 1, 10, 11, 12, 13, 14, 14, 14,
- 14, 14, 14, 14, 14, 15, 15, 16, 6, 17,
- 18, 19, 6, 1, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 1, 21, 1, 6, 22, 1, 23, 24, 20, 25,
-
- 26, 27, 28, 20, 29, 20, 20, 30, 31, 32,
- 33, 20, 34, 35, 36, 37, 38, 20, 20, 20,
- 20, 20, 39, 40, 41, 42, 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,
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[43] =
+static yyconst flex_int32_t yy_meta[44] =
{ 0,
- 1, 1, 2, 1, 2, 1, 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, 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
} ;
-static yyconst flex_int16_t yy_base[128] =
+static yyconst flex_int16_t yy_base[133] =
{ 0,
- 0, 0, 40, 41, 82, 0, 122, 123, 0, 0,
- 138, 133, 161, 260, 47, 33, 260, 121, 151, 260,
- 151, 260, 260, 38, 140, 36, 139, 0, 124, 121,
- 131, 29, 121, 30, 180, 31, 117, 116, 110, 0,
- 260, 260, 110, 207, 260, 260, 260, 260, 0, 260,
- 260, 260, 260, 260, 260, 260, 56, 260, 260, 260,
- 260, 54, 0, 114, 34, 115, 37, 120, 260, 260,
- 260, 260, 0, 120, 0, 112, 0, 0, 0, 0,
- 0, 260, 0, 0, 104, 0, 102, 260, 0, 260,
- 260, 58, 62, 260, 260, 260, 260, 260, 0, 260,
-
- 260, 260, 260, 260, 260, 260, 260, 0, 103, 0,
- 112, 65, 117, 111, 0, 119, 0, 260, 244, 247,
- 250, 133, 132, 253, 256, 67, 62
+ 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, 275, 275, 275, 275, 275, 275,
+ 275, 275, 0, 99, 0, 61, 133, 135, 57, 0,
+ 138, 0, 275, 259, 262, 265, 79, 67, 268, 271,
+ 65, 42
} ;
-static yyconst flex_int16_t yy_def[128] =
+static yyconst flex_int16_t yy_def[133] =
{ 0,
- 118, 1, 119, 119, 118, 5, 119, 119, 120, 120,
- 121, 121, 118, 118, 118, 118, 118, 118, 118, 118,
- 122, 118, 118, 118, 118, 118, 118, 123, 123, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 118, 124,
- 118, 118, 118, 125, 118, 118, 118, 118, 126, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 127, 127, 127, 127, 127, 127, 118, 118,
- 118, 118, 123, 123, 123, 123, 123, 123, 123, 123,
- 123, 118, 123, 123, 123, 123, 123, 118, 124, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 126, 118,
-
- 118, 118, 118, 118, 118, 118, 118, 123, 123, 123,
- 123, 118, 118, 123, 123, 118, 123, 0, 118, 118,
- 118, 118, 118, 118, 118, 118, 118
+ 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, 123, 123, 123, 123, 123, 123,
+ 123, 123, 128, 128, 128, 128, 123, 123, 128, 128,
+ 123, 128, 0, 123, 123, 123, 123, 123, 123, 123,
+ 123, 123
} ;
-static yyconst flex_int16_t yy_nxt[303] =
+static yyconst flex_int16_t yy_nxt[319] =
{ 0,
- 14, 15, 15, 16, 17, 14, 18, 19, 20, 20,
- 21, 22, 23, 24, 24, 20, 25, 26, 27, 28,
- 14, 14, 29, 28, 28, 30, 31, 32, 33, 34,
- 35, 36, 37, 28, 28, 28, 38, 28, 20, 39,
- 20, 14, 41, 41, 42, 42, 43, 43, 57, 57,
- 58, 62, 62, 70, 77, 80, 84, 57, 57, 102,
- 44, 44, 105, 85, 100, 78, 81, 62, 62, 99,
- 103, 112, 113, 106, 59, 113, 113, 71, 116, 113,
- 45, 45, 46, 46, 47, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 48, 46, 46,
-
- 46, 49, 46, 46, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 46, 46, 50, 46, 41, 41, 51, 51, 52, 52,
- 113, 113, 113, 113, 73, 63, 117, 115, 114, 111,
- 110, 109, 44, 44, 108, 107, 104, 101, 90, 88,
- 87, 86, 79, 76, 75, 74, 72, 69, 61, 60,
- 118, 56, 53, 53, 62, 62, 56, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 64, 118, 65, 66,
- 67, 118, 68, 82, 82, 82, 82, 118, 118, 82,
- 82, 82, 82, 118, 118, 82, 118, 118, 118, 118,
-
- 118, 83, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 82,
- 92, 93, 118, 118, 118, 118, 118, 118, 118, 118,
- 94, 118, 118, 95, 118, 118, 118, 118, 96, 118,
- 118, 97, 118, 98, 40, 40, 40, 54, 54, 54,
- 55, 55, 55, 89, 118, 89, 91, 91, 91, 13,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-
- 118, 118
+ 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
} ;
-static yyconst flex_int16_t yy_chk[303] =
+static yyconst flex_int16_t yy_chk[319] =
{ 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, 3, 4, 3, 4, 3, 4, 15, 15,
- 16, 24, 24, 26, 32, 34, 36, 57, 57, 65,
- 3, 4, 67, 36, 127, 32, 34, 62, 62, 126,
- 65, 92, 92, 67, 16, 93, 93, 26, 112, 112,
- 3, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 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,
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, 8, 7, 8, 7, 8,
- 113, 113, 116, 116, 123, 122, 114, 111, 109, 87,
- 85, 76, 7, 8, 74, 68, 66, 64, 43, 39,
- 38, 37, 33, 31, 30, 29, 27, 25, 19, 18,
- 13, 12, 7, 8, 21, 21, 11, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 21, 0, 21, 21,
- 21, 0, 21, 35, 35, 35, 35, 0, 0, 35,
- 35, 35, 35, 0, 0, 35, 0, 0, 0, 0,
-
- 0, 35, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 35,
- 44, 44, 0, 0, 0, 0, 0, 0, 0, 0,
- 44, 0, 0, 44, 0, 0, 0, 0, 44, 0,
- 0, 44, 0, 44, 119, 119, 119, 120, 120, 120,
- 121, 121, 121, 124, 0, 124, 125, 125, 125, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
-
- 118, 118
+ 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,
+ 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
} ;
/* The intent behind this definition is that it'll catch
#define str_buf (yyextra->scan_buf)
#define str_del (yyextra->scan_del)
-#line 604 "util_expr_scan.c"
+#line 609 "util_expr_scan.c"
#define INITIAL 0
#define str 1
/*
* Whitespaces
*/
-#line 859 "util_expr_scan.c"
+#line 864 "util_expr_scan.c"
yylval = yylval_param;
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 >= 119 )
+ if ( yy_current_state >= 124 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_current_state != 118 );
+ while ( yy_current_state != 123 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
*str_ptr++ = yytext[1];
}
YY_BREAK
+/* regexp backref inside string/arg */
case 13:
YY_RULE_SETUP
-#line 145 "util_expr_scan.l"
+#line 146 "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;
+ }
+}
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 161 "util_expr_scan.l"
{
char *cp = yytext;
while (*cp != '\0')
*str_ptr++ = *cp++;
}
YY_BREAK
-/* variable inside string */
-case 14:
+/* variable inside string/arg */
+case 15:
YY_RULE_SETUP
-#line 152 "util_expr_scan.l"
+#line 168 "util_expr_scan.l"
{
if (str_ptr != str_buf) {
/* return what we have so far and scan '%{' again */
}
}
YY_BREAK
-case 15:
+case 16:
YY_RULE_SETUP
-#line 167 "util_expr_scan.l"
+#line 183 "util_expr_scan.l"
{
*str_ptr++ = yytext[0];
}
YY_BREAK
-case 16:
+case 17:
YY_RULE_SETUP
-#line 171 "util_expr_scan.l"
+#line 187 "util_expr_scan.l"
{
*str_ptr++ = yytext[0];
}
YY_BREAK
-case 17:
+case 18:
YY_RULE_SETUP
-#line 175 "util_expr_scan.l"
+#line 191 "util_expr_scan.l"
{
yy_push_state(var, yyscanner);
return T_VAR_BEGIN;
}
YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 196 "util_expr_scan.l"
+{
+ yylval->num = yytext[1] - '0';
+ return T_REGEX_BACKREF;
+}
+ YY_BREAK
/*
* fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
*/
-case 18:
+case 20:
YY_RULE_SETUP
-#line 183 "util_expr_scan.l"
+#line 204 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_ID;
}
YY_BREAK
-case 19:
+case 21:
YY_RULE_SETUP
-#line 188 "util_expr_scan.l"
+#line 209 "util_expr_scan.l"
{
yy_pop_state(yyscanner);
return T_VAR_END;
}
YY_BREAK
-case 20:
+case 22:
YY_RULE_SETUP
-#line 193 "util_expr_scan.l"
+#line 214 "util_expr_scan.l"
{
BEGIN(vararg);
return yytext[0];
}
YY_BREAK
-case 21:
-/* rule 21 can match eol */
+case 23:
+/* rule 23 can match eol */
YY_RULE_SETUP
-#line 198 "util_expr_scan.l"
+#line 219 "util_expr_scan.l"
{
char *msg = apr_psprintf(yyextra->pool,
"Invalid character in variable name '%c'", yytext[0]);
PERROR(msg);
}
YY_BREAK
-case 22:
+case 24:
YY_RULE_SETUP
-#line 204 "util_expr_scan.l"
+#line 225 "util_expr_scan.l"
{
if (str_ptr != str_buf) {
/* return what we have so far and scan '}' again */
/*
* Regular Expression
*/
-case 23:
+case 25:
YY_RULE_SETUP
-#line 222 "util_expr_scan.l"
+#line 243 "util_expr_scan.l"
{
regex_del = yytext[1];
regex_ptr = regex_buf;
BEGIN(regex);
}
YY_BREAK
-case 24:
+case 26:
YY_RULE_SETUP
-#line 227 "util_expr_scan.l"
+#line 248 "util_expr_scan.l"
{
regex_del = yytext[0];
regex_ptr = regex_buf;
BEGIN(regex);
}
YY_BREAK
-case 25:
-/* rule 25 can match eol */
+case 27:
+/* rule 27 can match eol */
YY_RULE_SETUP
-#line 232 "util_expr_scan.l"
+#line 253 "util_expr_scan.l"
{
if (yytext[0] == regex_del) {
*regex_ptr = '\0';
}
}
YY_BREAK
-case 26:
+case 28:
YY_RULE_SETUP
-#line 241 "util_expr_scan.l"
+#line 262 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
BEGIN(INITIAL);
return T_REGEX_I;
}
YY_BREAK
-case 27:
-/* rule 27 can match eol */
+case 29:
+/* rule 29 can match eol */
YY_RULE_SETUP
-#line 246 "util_expr_scan.l"
+#line 267 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
yyless(0);
}
YY_BREAK
case YY_STATE_EOF(regex_flags):
-#line 252 "util_expr_scan.l"
+#line 273 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, regex_buf);
BEGIN(INITIAL);
/*
* Operators
*/
-case 28:
+case 30:
YY_RULE_SETUP
-#line 261 "util_expr_scan.l"
+#line 282 "util_expr_scan.l"
{ return T_OP_STR_EQ; }
YY_BREAK
-case 29:
+case 31:
YY_RULE_SETUP
-#line 262 "util_expr_scan.l"
+#line 283 "util_expr_scan.l"
{ return T_OP_STR_NE; }
YY_BREAK
-case 30:
+case 32:
YY_RULE_SETUP
-#line 263 "util_expr_scan.l"
+#line 284 "util_expr_scan.l"
{ return T_OP_STR_LT; }
YY_BREAK
-case 31:
+case 33:
YY_RULE_SETUP
-#line 264 "util_expr_scan.l"
+#line 285 "util_expr_scan.l"
{ return T_OP_STR_LE; }
YY_BREAK
-case 32:
+case 34:
YY_RULE_SETUP
-#line 265 "util_expr_scan.l"
+#line 286 "util_expr_scan.l"
{ return T_OP_STR_GT; }
YY_BREAK
-case 33:
+case 35:
YY_RULE_SETUP
-#line 266 "util_expr_scan.l"
+#line 287 "util_expr_scan.l"
{ return T_OP_STR_GE; }
YY_BREAK
-case 34:
+case 36:
YY_RULE_SETUP
-#line 267 "util_expr_scan.l"
+#line 288 "util_expr_scan.l"
{ return T_OP_REG; }
YY_BREAK
-case 35:
+case 37:
YY_RULE_SETUP
-#line 268 "util_expr_scan.l"
+#line 289 "util_expr_scan.l"
{ return T_OP_NRE; }
YY_BREAK
-case 36:
+case 38:
YY_RULE_SETUP
-#line 269 "util_expr_scan.l"
+#line 290 "util_expr_scan.l"
{ return T_OP_AND; }
YY_BREAK
-case 37:
+case 39:
YY_RULE_SETUP
-#line 270 "util_expr_scan.l"
+#line 291 "util_expr_scan.l"
{ return T_OP_AND; }
YY_BREAK
-case 38:
+case 40:
YY_RULE_SETUP
-#line 271 "util_expr_scan.l"
+#line 292 "util_expr_scan.l"
{ return T_OP_OR; }
YY_BREAK
-case 39:
+case 41:
YY_RULE_SETUP
-#line 272 "util_expr_scan.l"
+#line 293 "util_expr_scan.l"
{ return T_OP_OR; }
YY_BREAK
-case 40:
+case 42:
YY_RULE_SETUP
-#line 273 "util_expr_scan.l"
+#line 294 "util_expr_scan.l"
{ return T_OP_NOT; }
YY_BREAK
-case 41:
+case 43:
YY_RULE_SETUP
-#line 274 "util_expr_scan.l"
+#line 295 "util_expr_scan.l"
{ return T_OP_NOT; }
YY_BREAK
-case 42:
+case 44:
YY_RULE_SETUP
-#line 275 "util_expr_scan.l"
+#line 296 "util_expr_scan.l"
{ return T_OP_CONCAT; }
YY_BREAK
-case 43:
+case 45:
YY_RULE_SETUP
-#line 276 "util_expr_scan.l"
+#line 297 "util_expr_scan.l"
{ return T_OP_IN; }
YY_BREAK
-case 44:
+case 46:
YY_RULE_SETUP
-#line 277 "util_expr_scan.l"
+#line 298 "util_expr_scan.l"
{ return T_OP_EQ; }
YY_BREAK
-case 45:
+case 47:
YY_RULE_SETUP
-#line 278 "util_expr_scan.l"
+#line 299 "util_expr_scan.l"
{ return T_OP_NE; }
YY_BREAK
-case 46:
+case 48:
YY_RULE_SETUP
-#line 279 "util_expr_scan.l"
+#line 300 "util_expr_scan.l"
{ return T_OP_GE; }
YY_BREAK
-case 47:
+case 49:
YY_RULE_SETUP
-#line 280 "util_expr_scan.l"
+#line 301 "util_expr_scan.l"
{ return T_OP_LE; }
YY_BREAK
-case 48:
+case 50:
YY_RULE_SETUP
-#line 281 "util_expr_scan.l"
+#line 302 "util_expr_scan.l"
{ return T_OP_GT; }
YY_BREAK
-case 49:
+case 51:
YY_RULE_SETUP
-#line 282 "util_expr_scan.l"
+#line 303 "util_expr_scan.l"
{ return T_OP_LT; }
YY_BREAK
/* for compatibility with ssl_expr */
-case 50:
+case 52:
YY_RULE_SETUP
-#line 285 "util_expr_scan.l"
+#line 306 "util_expr_scan.l"
{ return T_OP_LT; }
YY_BREAK
-case 51:
+case 53:
YY_RULE_SETUP
-#line 286 "util_expr_scan.l"
+#line 307 "util_expr_scan.l"
{ return T_OP_LE; }
YY_BREAK
-case 52:
+case 54:
YY_RULE_SETUP
-#line 287 "util_expr_scan.l"
+#line 308 "util_expr_scan.l"
{ return T_OP_GT; }
YY_BREAK
-case 53:
+case 55:
YY_RULE_SETUP
-#line 288 "util_expr_scan.l"
+#line 309 "util_expr_scan.l"
{ return T_OP_GE; }
YY_BREAK
-case 54:
+case 56:
YY_RULE_SETUP
-#line 289 "util_expr_scan.l"
+#line 310 "util_expr_scan.l"
{ return T_OP_NE; }
YY_BREAK
-case 55:
+case 57:
YY_RULE_SETUP
-#line 290 "util_expr_scan.l"
+#line 311 "util_expr_scan.l"
{ return T_OP_EQ; }
YY_BREAK
-case 56:
+case 58:
YY_RULE_SETUP
-#line 291 "util_expr_scan.l"
+#line 312 "util_expr_scan.l"
{ return T_OP_IN; }
YY_BREAK
-case 57:
+case 59:
YY_RULE_SETUP
-#line 293 "util_expr_scan.l"
+#line 314 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
return T_OP_UNARY;
}
YY_BREAK
-case 58:
+case 60:
YY_RULE_SETUP
-#line 298 "util_expr_scan.l"
+#line 319 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext + 1);
return T_OP_BINARY;
/*
* Specials
*/
-case 59:
+case 61:
YY_RULE_SETUP
-#line 306 "util_expr_scan.l"
+#line 327 "util_expr_scan.l"
{ return T_TRUE; }
YY_BREAK
-case 60:
+case 62:
YY_RULE_SETUP
-#line 307 "util_expr_scan.l"
+#line 328 "util_expr_scan.l"
{ return T_FALSE; }
YY_BREAK
/*
* Digits
*/
-case 61:
+case 63:
YY_RULE_SETUP
-#line 312 "util_expr_scan.l"
+#line 333 "util_expr_scan.l"
{
yylval->cpVal = apr_pstrdup(yyextra->pool, yytext);
return T_DIGIT;
/*
* Identifiers
*/
-case 62:
+case 64:
YY_RULE_SETUP
-#line 320 "util_expr_scan.l"
+#line 341 "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 63:
+case 65:
YY_RULE_SETUP
-#line 328 "util_expr_scan.l"
+#line 349 "util_expr_scan.l"
{
return yytext[0];
}
/*
* Anything else is an error
*/
-case 64:
-/* rule 64 can match eol */
+case 66:
+/* rule 66 can match eol */
YY_RULE_SETUP
-#line 335 "util_expr_scan.l"
+#line 356 "util_expr_scan.l"
{
char *msg = apr_psprintf(yyextra->pool, "Parse error near '%c'", yytext[0]);
PERROR(msg);
}
YY_BREAK
-case 65:
+case 67:
YY_RULE_SETUP
-#line 340 "util_expr_scan.l"
+#line 361 "util_expr_scan.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1453 "util_expr_scan.c"
+#line 1485 "util_expr_scan.c"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(regex):
yyterminate();
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 >= 119 )
+ if ( yy_current_state >= 124 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
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 >= 119 )
+ if ( yy_current_state >= 124 )
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 == 118);
+ yy_is_jam = (yy_current_state == 123);
return yy_is_jam ? 0 : yy_current_state;
}
#define YYTABLES_NAME "yytables"
-#line 340 "util_expr_scan.l"
+#line 361 "util_expr_scan.l"
*str_ptr++ = yytext[1];
}
-<str,vararg>[^\\\n"'%}]+ {
+ /* 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);
+ return T_STRING;
+ }
+ else {
+ yylval->num = yytext[1] - '0';
+ return T_REGEX_BACKREF;
+ }
+}
+
+<str,vararg>[^\\\n"'%}$]+ {
char *cp = yytext;
while (*cp != '\0')
*str_ptr++ = *cp++;
}
- /* variable inside string */
-<str>%\{ {
+ /* variable inside string/arg */
+<str,vararg>%\{ {
if (str_ptr != str_buf) {
/* return what we have so far and scan '%{' again */
*str_ptr = '\0';
}
}
-<vararg>% {
+<vararg>[%$] {
*str_ptr++ = yytext[0];
}
-<str>[%}] {
+<str>[%}$] {
*str_ptr++ = yytext[0];
}
return T_VAR_BEGIN;
}
+[$][0-9] {
+ yylval->num = yytext[1] - '0';
+ return T_REGEX_BACKREF;
+}
+
/*
* fixed name variable expansion %{XXX} and function call in %{func:arg} syntax
*/