mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[#2272] Added split function to expression syntax
doc/sphinx/arm/classify.rst Documented new split() function src/lib/eval/eval_messages.cc b/src/lib/eval/eval_messages.* New debug log messges src/lib/eval/lexer.ll src/lib/eval/parser.yy added split parsing src/lib/eval/tests/token_unittest.cc Added tests for split() src/lib/eval/token.* Added TokenSplit class
This commit is contained in:
committed by
Razvan Becheriu
parent
2404bd82a2
commit
29988a24e2
@@ -474,6 +474,10 @@ Notes:
|
|||||||
| | | a hexadecimal string, |
|
| | | a hexadecimal string, |
|
||||||
| | | e.g. 0a:1b:2c:3e |
|
| | | e.g. 0a:1b:2c:3e |
|
||||||
+-----------------------+-------------------------+-----------------------+
|
+-----------------------+-------------------------+-----------------------+
|
||||||
|
| Split | split('foo.bar','.',2) | Return the second |
|
||||||
|
| | | field, splitting on |
|
||||||
|
| | | dots. |
|
||||||
|
+-----------------------+-------------------------+-----------------------+
|
||||||
|
|
||||||
.. table:: List of conversion-to-text expressions
|
.. table:: List of conversion-to-text expressions
|
||||||
|
|
||||||
@@ -586,6 +590,25 @@ or:
|
|||||||
|
|
||||||
'abcdefghijkl...'
|
'abcdefghijkl...'
|
||||||
|
|
||||||
|
Split
|
||||||
|
---------
|
||||||
|
|
||||||
|
The Split operator ``Split(value, delimiters, field-number)`` accepts a list
|
||||||
|
of characters to use as delimiters and a positive field number of the
|
||||||
|
desired field when the value is split into fields separated by the delimiters.
|
||||||
|
Adjacent delimit are not compressed out, rather they result in
|
||||||
|
an empty string for that field number. If value is an empty string, the result
|
||||||
|
will an empty string. If the delimiters list is empty, the result will be the
|
||||||
|
original value. If the is less than one or larger than the number of fields,
|
||||||
|
the result will be an empty string. Some examples follow:
|
||||||
|
|
||||||
|
::
|
||||||
|
split ('one.two..four', '.', 1) == 'one'
|
||||||
|
split ('one.two..four', '.', 2) == 'two'
|
||||||
|
split ('one.two..four', '.', 3) == ''
|
||||||
|
split ('one.two..four', '.', 4) == 'four'
|
||||||
|
split ('one.two..four', '.', 5) == ''
|
||||||
|
|
||||||
Ifelse
|
Ifelse
|
||||||
------
|
------
|
||||||
|
|
||||||
|
@@ -27,6 +27,10 @@ extern const isc::log::MessageID EVAL_DEBUG_PKT4 = "EVAL_DEBUG_PKT4";
|
|||||||
extern const isc::log::MessageID EVAL_DEBUG_PKT6 = "EVAL_DEBUG_PKT6";
|
extern const isc::log::MessageID EVAL_DEBUG_PKT6 = "EVAL_DEBUG_PKT6";
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_RELAY6 = "EVAL_DEBUG_RELAY6";
|
extern const isc::log::MessageID EVAL_DEBUG_RELAY6 = "EVAL_DEBUG_RELAY6";
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_RELAY6_RANGE = "EVAL_DEBUG_RELAY6_RANGE";
|
extern const isc::log::MessageID EVAL_DEBUG_RELAY6_RANGE = "EVAL_DEBUG_RELAY6_RANGE";
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT = "EVAL_DEBUG_SPLIT";
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT_DELIM_EMPTY = "EVAL_DEBUG_SPLIT_DELIM_EMPTY";
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT_EMPTY = "EVAL_DEBUG_SPLIT_EMPTY";
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE = "EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE";
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_STRING = "EVAL_DEBUG_STRING";
|
extern const isc::log::MessageID EVAL_DEBUG_STRING = "EVAL_DEBUG_STRING";
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING = "EVAL_DEBUG_SUBSTRING";
|
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING = "EVAL_DEBUG_SUBSTRING";
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_EMPTY = "EVAL_DEBUG_SUBSTRING_EMPTY";
|
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_EMPTY = "EVAL_DEBUG_SUBSTRING_EMPTY";
|
||||||
@@ -75,6 +79,10 @@ const char* values[] = {
|
|||||||
"EVAL_DEBUG_PKT6", "Pushing PKT6 field %1 with value %2",
|
"EVAL_DEBUG_PKT6", "Pushing PKT6 field %1 with value %2",
|
||||||
"EVAL_DEBUG_RELAY6", "Pushing PKT6 relay field %1 nest %2 with value %3",
|
"EVAL_DEBUG_RELAY6", "Pushing PKT6 relay field %1 nest %2 with value %3",
|
||||||
"EVAL_DEBUG_RELAY6_RANGE", "Pushing PKT6 relay field %1 nest %2 with value %3",
|
"EVAL_DEBUG_RELAY6_RANGE", "Pushing PKT6 relay field %1 nest %2 with value %3",
|
||||||
|
"EVAL_DEBUG_SPLIT", "Popping field %1, delimiters %2, string %3, pushing result %4",
|
||||||
|
"EVAL_DEBUG_SPLIT_DELIM_EMPTY", "Popping field %1, delimiters %2, string %3, pushing result %4",
|
||||||
|
"EVAL_DEBUG_SPLIT_EMPTY", "Popping field %1, delimiters %2, string %3, pushing result %4",
|
||||||
|
"EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE", "Popping field %1, delimiters %2, string %3, pushing result %4",
|
||||||
"EVAL_DEBUG_STRING", "Pushing text string %1",
|
"EVAL_DEBUG_STRING", "Pushing text string %1",
|
||||||
"EVAL_DEBUG_SUBSTRING", "Popping length %1, start %2, string %3 pushing result %4",
|
"EVAL_DEBUG_SUBSTRING", "Popping length %1, start %2, string %3 pushing result %4",
|
||||||
"EVAL_DEBUG_SUBSTRING_EMPTY", "Popping length %1, start %2, string %3 pushing result %4",
|
"EVAL_DEBUG_SUBSTRING_EMPTY", "Popping length %1, start %2, string %3 pushing result %4",
|
||||||
|
@@ -28,6 +28,10 @@ extern const isc::log::MessageID EVAL_DEBUG_PKT4;
|
|||||||
extern const isc::log::MessageID EVAL_DEBUG_PKT6;
|
extern const isc::log::MessageID EVAL_DEBUG_PKT6;
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_RELAY6;
|
extern const isc::log::MessageID EVAL_DEBUG_RELAY6;
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_RELAY6_RANGE;
|
extern const isc::log::MessageID EVAL_DEBUG_RELAY6_RANGE;
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT;
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT_DELIM_EMPTY;
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT_EMPTY;
|
||||||
|
extern const isc::log::MessageID EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE;
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_STRING;
|
extern const isc::log::MessageID EVAL_DEBUG_STRING;
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING;
|
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING;
|
||||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_EMPTY;
|
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_EMPTY;
|
||||||
|
@@ -261,3 +261,26 @@ and vendor option was not found.
|
|||||||
This debug message indicates that the expression has been evaluated
|
This debug message indicates that the expression has been evaluated
|
||||||
to said value. This message is mostly useful during debugging of the
|
to said value. This message is mostly useful during debugging of the
|
||||||
client classification expressions.
|
client classification expressions.
|
||||||
|
|
||||||
|
% EVAL_DEBUG_SPLIT_EMPTY Popping field %1, delimiters %2, string %3, pushing result %4
|
||||||
|
This debug message indicates that the string popped from the stack was empty
|
||||||
|
and so the result will also be empty. The field, deli meter string, and string are
|
||||||
|
still popped from the stack and the result is still pushed.
|
||||||
|
|
||||||
|
% EVAL_DEBUG_SPLIT_DELIM_EMPTY Popping field %1, delimiters %2, string %3, pushing result %4
|
||||||
|
This debug message indicates that the deli meter string popped from the stack was empty
|
||||||
|
and so the result will also be empty. The field, deli meter string, and string are
|
||||||
|
still popped from the stack and the result is still pushed.
|
||||||
|
|
||||||
|
% EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE Popping field %1, delimiters %2, string %3, pushing result %4
|
||||||
|
This debug message indicates that the field is either less than one or larger
|
||||||
|
than the number of fields in the string popped from the stack. the result will
|
||||||
|
be empty. The field, deli meter string, and string are still popped from the
|
||||||
|
stack and the result is still pushed.
|
||||||
|
|
||||||
|
% EVAL_DEBUG_SPLIT Popping field %1, delimiters %2, string %3, pushing result %4
|
||||||
|
This debug message indicates that three values are being popped from
|
||||||
|
the value stack and a result is being pushed onto the value stack. The
|
||||||
|
values being popped are the field, delimiter_string and string and the
|
||||||
|
result is the extracted field. The resulting string is pushed onto
|
||||||
|
the stack. The strings are displayed in hex.
|
||||||
|
@@ -710,8 +710,8 @@ static void yynoreturn yy_fatal_error ( const char* msg );
|
|||||||
/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
|
/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
|
||||||
(yy_c_buf_p) = yy_cp;
|
(yy_c_buf_p) = yy_cp;
|
||||||
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
|
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
|
||||||
#define YY_NUM_RULES 62
|
#define YY_NUM_RULES 63
|
||||||
#define YY_END_OF_BUFFER 63
|
#define YY_END_OF_BUFFER 64
|
||||||
/* This struct is not used in this scanner,
|
/* This struct is not used in this scanner,
|
||||||
but its presence is necessary. */
|
but its presence is necessary. */
|
||||||
struct yy_trans_info
|
struct yy_trans_info
|
||||||
@@ -719,38 +719,38 @@ struct yy_trans_info
|
|||||||
flex_int32_t yy_verify;
|
flex_int32_t yy_verify;
|
||||||
flex_int32_t yy_nxt;
|
flex_int32_t yy_nxt;
|
||||||
};
|
};
|
||||||
static const flex_int16_t yy_accept[275] =
|
static const flex_int16_t yy_accept[279] =
|
||||||
{ 0,
|
{ 0,
|
||||||
0, 0, 63, 61, 1, 2, 61, 54, 55, 59,
|
0, 0, 64, 62, 1, 2, 62, 55, 56, 60,
|
||||||
60, 58, 61, 53, 5, 5, 61, 61, 61, 61,
|
61, 59, 62, 54, 5, 5, 62, 62, 62, 62,
|
||||||
56, 57, 61, 61, 61, 61, 61, 61, 61, 61,
|
57, 58, 62, 62, 62, 62, 62, 62, 62, 62,
|
||||||
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
|
62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
|
||||||
1, 2, 0, 3, 5, 0, 5, 0, 0, 0,
|
1, 2, 0, 3, 5, 0, 5, 0, 0, 0,
|
||||||
0, 7, 8, 0, 0, 0, 0, 6, 0, 0,
|
0, 7, 8, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 4, 7, 0, 38, 50, 0, 0,
|
0, 0, 0, 0, 4, 7, 0, 39, 51, 0,
|
||||||
|
|
||||||
0, 20, 0, 0, 0, 15, 0, 0, 0, 0,
|
0, 0, 20, 0, 0, 0, 15, 0, 0, 0,
|
||||||
0, 21, 0, 23, 0, 0, 49, 0, 0, 17,
|
0, 0, 21, 0, 23, 0, 0, 50, 0, 0,
|
||||||
0, 0, 19, 0, 0, 0, 0, 0, 0, 0,
|
17, 0, 0, 0, 19, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 35, 0, 0, 0, 0, 24, 0,
|
0, 0, 0, 0, 0, 35, 0, 0, 0, 0,
|
||||||
|
24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 22, 30, 0, 0, 0, 0, 14, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
22, 30, 0, 0, 0, 14, 0, 0, 0, 0,
|
0, 25, 18, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 25, 18,
|
0, 0, 0, 0, 38, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 26, 40, 0, 16, 27, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
26, 39, 0, 16, 27, 0, 40, 0, 0, 0,
|
|
||||||
|
|
||||||
0, 52, 0, 9, 0, 10, 11, 29, 0, 0,
|
41, 0, 0, 0, 0, 53, 0, 9, 0, 10,
|
||||||
0, 0, 0, 33, 28, 7, 0, 0, 0, 0,
|
11, 29, 0, 0, 0, 0, 0, 33, 28, 7,
|
||||||
0, 0, 0, 31, 0, 0, 32, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 31, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 13, 12, 0,
|
32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 41, 0, 0, 0,
|
0, 13, 12, 0, 0, 0, 0, 0, 0, 0,
|
||||||
37, 0, 0, 0, 0, 42, 36, 0, 0, 43,
|
42, 0, 0, 0, 37, 0, 0, 0, 0, 43,
|
||||||
0, 0, 0, 0, 44, 45, 0, 0, 46, 0,
|
36, 0, 0, 44, 0, 0, 0, 0, 45, 46,
|
||||||
47, 48, 34, 0
|
0, 0, 47, 0, 48, 49, 34, 0
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
static const YY_CHAR yy_ec[256] =
|
static const YY_CHAR yy_ec[256] =
|
||||||
@@ -794,128 +794,129 @@ static const YY_CHAR yy_meta[50] =
|
|||||||
1, 1, 1, 1, 1, 1, 1, 1, 1
|
1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
static const flex_int16_t yy_base[284] =
|
static const flex_int16_t yy_base[288] =
|
||||||
{ 0,
|
{ 0,
|
||||||
0, 0, 379, 380, 376, 374, 372, 380, 380, 380,
|
0, 0, 383, 384, 380, 378, 376, 384, 384, 384,
|
||||||
380, 380, 0, 380, 39, 36, 355, 353, 86, 124,
|
384, 384, 0, 384, 39, 36, 359, 357, 86, 124,
|
||||||
380, 380, 35, 38, 34, 37, 337, 48, 43, 58,
|
384, 384, 35, 38, 34, 37, 341, 48, 43, 58,
|
||||||
63, 331, 22, 60, 339, 115, 116, 334, 337, 332,
|
63, 335, 22, 60, 343, 122, 116, 338, 341, 336,
|
||||||
365, 363, 361, 380, 0, 0, 121, 344, 343, 0,
|
369, 367, 365, 384, 0, 0, 121, 348, 347, 0,
|
||||||
342, 0, 380, 147, 160, 0, 0, 380, 330, 322,
|
346, 0, 384, 147, 158, 0, 0, 384, 334, 326,
|
||||||
328, 330, 317, 311, 310, 309, 317, 324, 303, 318,
|
332, 334, 321, 315, 314, 313, 321, 328, 307, 322,
|
||||||
300, 132, 303, 307, 306, 315, 305, 309, 297, 296,
|
304, 119, 307, 311, 310, 319, 309, 313, 301, 300,
|
||||||
0, 308, 294, 300, 309, 306, 306, 286, 305, 292,
|
0, 312, 298, 304, 313, 302, 309, 309, 289, 308,
|
||||||
291, 302, 318, 0, 0, 285, 0, 0, 296, 296,
|
295, 294, 305, 321, 0, 0, 288, 0, 0, 299,
|
||||||
|
|
||||||
297, 0, 292, 279, 291, 277, 280, 277, 288, 279,
|
299, 300, 0, 295, 282, 294, 280, 283, 280, 291,
|
||||||
152, 0, 279, 0, 286, 269, 0, 277, 269, 150,
|
282, 157, 0, 282, 0, 289, 272, 0, 280, 272,
|
||||||
283, 279, 0, 265, 263, 267, 261, 274, 273, 0,
|
159, 286, 282, 276, 0, 267, 265, 269, 263, 276,
|
||||||
258, 271, 273, 0, 257, 254, 267, 252, 0, 264,
|
275, 0, 260, 273, 275, 0, 259, 256, 269, 254,
|
||||||
263, 250, 275, 278, 246, 262, 257, 239, 246, 258,
|
0, 266, 265, 252, 277, 280, 248, 264, 259, 241,
|
||||||
0, 0, 236, 253, 238, 0, 238, 157, 240, 249,
|
248, 260, 0, 0, 238, 255, 240, 239, 0, 239,
|
||||||
268, 237, 234, 231, 233, 230, 230, 229, 0, 0,
|
166, 241, 250, 269, 238, 235, 232, 234, 231, 231,
|
||||||
239, 225, 224, 227, 236, 223, 223, 224, 232, 159,
|
230, 0, 0, 240, 226, 225, 228, 237, 224, 224,
|
||||||
219, 218, 224, 241, 244, 212, 213, 212, 0, 209,
|
225, 233, 162, 220, 0, 219, 225, 242, 245, 213,
|
||||||
0, 0, 210, 0, 0, 216, 0, 210, 209, 204,
|
214, 213, 0, 210, 0, 0, 211, 0, 0, 217,
|
||||||
|
|
||||||
217, 0, 215, 0, 215, 0, 0, 0, 209, 213,
|
0, 211, 210, 205, 218, 0, 216, 0, 216, 0,
|
||||||
198, 197, 200, 230, 0, 0, 207, 202, 197, 191,
|
0, 0, 210, 214, 199, 198, 201, 231, 0, 0,
|
||||||
190, 202, 190, 0, 189, 191, 0, 189, 188, 183,
|
208, 203, 198, 192, 191, 203, 191, 0, 190, 192,
|
||||||
176, 179, 182, 186, 176, 173, 156, 0, 0, 169,
|
0, 190, 189, 184, 160, 180, 183, 192, 193, 192,
|
||||||
156, 155, 167, 160, 152, 164, 0, 147, 146, 148,
|
175, 0, 0, 188, 176, 175, 187, 180, 172, 184,
|
||||||
0, 160, 159, 142, 161, 0, 0, 143, 142, 0,
|
0, 167, 166, 168, 0, 180, 179, 162, 176, 0,
|
||||||
137, 136, 138, 138, 0, 0, 136, 135, 0, 130,
|
0, 147, 144, 0, 140, 139, 138, 138, 0, 0,
|
||||||
0, 0, 0, 380, 206, 143, 209, 107, 212, 215,
|
129, 126, 0, 123, 0, 0, 0, 384, 190, 162,
|
||||||
219, 78, 77
|
193, 107, 196, 199, 203, 78, 77
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
static const flex_int16_t yy_def[284] =
|
static const flex_int16_t yy_def[288] =
|
||||||
{ 0,
|
{ 0,
|
||||||
274, 1, 274, 274, 274, 274, 275, 274, 274, 274,
|
278, 1, 278, 278, 278, 278, 279, 278, 278, 278,
|
||||||
274, 274, 276, 274, 274, 15, 277, 274, 274, 19,
|
278, 278, 280, 278, 278, 15, 281, 278, 278, 19,
|
||||||
274, 274, 19, 19, 19, 19, 20, 20, 20, 20,
|
278, 278, 19, 19, 19, 19, 20, 20, 20, 20,
|
||||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||||
274, 274, 275, 274, 276, 278, 15, 277, 279, 280,
|
278, 278, 279, 278, 280, 282, 15, 281, 283, 284,
|
||||||
277, 281, 274, 274, 20, 19, 20, 274, 19, 20,
|
281, 285, 278, 278, 20, 19, 20, 278, 19, 20,
|
||||||
20, 20, 20, 19, 20, 20, 20, 20, 20, 20,
|
20, 20, 20, 19, 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,
|
||||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||||
20, 20, 278, 280, 281, 19, 20, 20, 20, 20,
|
20, 20, 20, 282, 284, 285, 19, 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, 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, 282,
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||||
|
20, 286, 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, 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, 286, 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,
|
||||||
282, 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, 20, 283, 20,
|
|
||||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||||
|
20, 20, 287, 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, 20,
|
||||||
20, 20, 20, 20, 20, 283, 20, 20, 20, 20,
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 287,
|
||||||
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, 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, 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, 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, 0, 274, 274, 274, 274, 274, 274,
|
20, 20, 20, 20, 20, 20, 20, 0, 278, 278,
|
||||||
274, 274, 274
|
278, 278, 278, 278, 278, 278, 278
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
static const flex_int16_t yy_nxt[430] =
|
static const flex_int16_t yy_nxt[434] =
|
||||||
{ 0,
|
{ 0,
|
||||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||||
14, 15, 16, 16, 16, 16, 16, 16, 16, 17,
|
14, 15, 16, 16, 16, 16, 16, 16, 16, 17,
|
||||||
18, 19, 20, 20, 21, 22, 4, 23, 19, 24,
|
18, 19, 20, 20, 21, 22, 4, 23, 19, 24,
|
||||||
25, 26, 19, 27, 28, 29, 20, 30, 31, 32,
|
25, 26, 19, 27, 28, 29, 20, 30, 31, 32,
|
||||||
33, 34, 35, 36, 37, 38, 39, 20, 40, 46,
|
33, 34, 35, 36, 37, 38, 39, 20, 40, 46,
|
||||||
47, 47, 47, 47, 47, 47, 47, 47, 48, 274,
|
47, 47, 47, 47, 47, 47, 47, 47, 48, 278,
|
||||||
49, 64, 50, 80, 81, 59, 49, 49, 49, 49,
|
49, 64, 50, 80, 81, 59, 49, 49, 49, 49,
|
||||||
49, 49, 60, 62, 61, 72, 66, 65, 63, 69,
|
49, 49, 60, 62, 61, 72, 66, 65, 63, 69,
|
||||||
216, 161, 73, 274, 67, 70, 50, 54, 54, 74,
|
220, 164, 73, 278, 67, 70, 50, 54, 54, 74,
|
||||||
76, 82, 71, 75, 77, 55, 83, 56, 56, 56,
|
76, 82, 71, 75, 77, 55, 83, 56, 56, 56,
|
||||||
|
|
||||||
56, 56, 56, 56, 56, 48, 78, 56, 57, 57,
|
56, 56, 56, 56, 56, 48, 78, 56, 57, 57,
|
||||||
93, 58, 55, 56, 56, 56, 56, 56, 56, 57,
|
94, 58, 55, 56, 56, 56, 56, 56, 56, 57,
|
||||||
57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
|
57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
|
||||||
57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
|
57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
|
||||||
57, 57, 57, 274, 274, 57, 45, 88, 54, 54,
|
57, 57, 57, 278, 278, 57, 110, 89, 54, 54,
|
||||||
85, 57, 57, 57, 57, 57, 57, 86, 89, 109,
|
111, 57, 57, 57, 57, 57, 57, 85, 90, 278,
|
||||||
87, 274, 274, 110, 143, 151, 144, 152, 274, 184,
|
278, 278, 278, 86, 87, 45, 277, 88, 278, 145,
|
||||||
145, 185, 58, 273, 206, 186, 207, 274, 274, 272,
|
276, 146, 58, 275, 153, 147, 154, 210, 188, 211,
|
||||||
271, 270, 269, 268, 267, 274, 266, 265, 264, 263,
|
189, 274, 273, 278, 190, 278, 272, 271, 270, 248,
|
||||||
262, 261, 260, 259, 258, 257, 256, 255, 254, 253,
|
43, 269, 43, 43, 43, 43, 51, 51, 51, 49,
|
||||||
|
|
||||||
252, 274, 251, 250, 249, 244, 43, 248, 43, 43,
|
49, 49, 95, 268, 95, 96, 96, 96, 96, 267,
|
||||||
43, 43, 51, 51, 51, 49, 49, 49, 94, 247,
|
266, 265, 264, 263, 262, 261, 260, 259, 258, 257,
|
||||||
94, 95, 95, 95, 95, 246, 245, 243, 242, 241,
|
256, 255, 254, 253, 252, 251, 250, 249, 247, 246,
|
||||||
240, 239, 238, 237, 236, 235, 234, 233, 232, 231,
|
245, 244, 243, 242, 241, 240, 239, 238, 237, 236,
|
||||||
230, 229, 228, 227, 226, 225, 224, 223, 222, 221,
|
235, 234, 233, 232, 231, 230, 229, 228, 227, 226,
|
||||||
220, 219, 218, 217, 215, 214, 213, 212, 211, 210,
|
225, 224, 223, 222, 221, 219, 218, 217, 216, 215,
|
||||||
209, 208, 205, 204, 203, 202, 201, 200, 199, 198,
|
214, 213, 212, 209, 208, 207, 206, 205, 204, 203,
|
||||||
197, 196, 195, 194, 193, 192, 191, 190, 189, 188,
|
202, 201, 200, 199, 198, 197, 196, 195, 194, 193,
|
||||||
187, 183, 182, 181, 180, 179, 178, 177, 176, 175,
|
192, 191, 187, 186, 185, 184, 183, 182, 181, 180,
|
||||||
174, 173, 172, 171, 170, 169, 168, 167, 166, 165,
|
179, 178, 177, 176, 175, 174, 173, 172, 171, 170,
|
||||||
|
|
||||||
164, 163, 162, 160, 159, 158, 157, 156, 155, 154,
|
169, 168, 167, 166, 165, 163, 162, 161, 160, 159,
|
||||||
153, 150, 149, 148, 147, 146, 142, 141, 140, 139,
|
158, 157, 156, 155, 152, 151, 150, 149, 148, 144,
|
||||||
138, 137, 136, 135, 134, 133, 132, 131, 130, 129,
|
143, 142, 141, 140, 139, 138, 137, 136, 135, 134,
|
||||||
128, 127, 126, 125, 124, 123, 122, 121, 120, 119,
|
133, 132, 131, 130, 129, 128, 127, 126, 125, 124,
|
||||||
118, 117, 116, 115, 114, 113, 112, 111, 108, 107,
|
123, 122, 121, 120, 119, 118, 117, 116, 115, 114,
|
||||||
106, 105, 104, 103, 102, 101, 100, 99, 98, 97,
|
113, 112, 109, 108, 107, 106, 105, 104, 103, 102,
|
||||||
96, 52, 48, 52, 44, 42, 41, 92, 91, 90,
|
101, 100, 99, 98, 97, 52, 48, 52, 44, 42,
|
||||||
84, 79, 68, 53, 52, 44, 42, 41, 274, 3,
|
41, 93, 92, 91, 84, 79, 68, 53, 52, 44,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
42, 41, 278, 3, 278, 278, 278, 278, 278, 278,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
|
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
|
278, 278, 278
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
static const flex_int16_t yy_chk[430] =
|
static const flex_int16_t yy_chk[434] =
|
||||||
{ 0,
|
{ 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,
|
||||||
@@ -925,54 +926,55 @@ static const flex_int16_t yy_chk[430] =
|
|||||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 16,
|
15, 15, 15, 15, 15, 15, 15, 15, 15, 16,
|
||||||
15, 25, 15, 33, 33, 23, 15, 15, 15, 15,
|
15, 25, 15, 33, 33, 23, 15, 15, 15, 15,
|
||||||
15, 15, 23, 24, 23, 29, 26, 25, 24, 28,
|
15, 15, 23, 24, 23, 29, 26, 25, 24, 28,
|
||||||
283, 282, 29, 16, 26, 28, 15, 19, 19, 30,
|
287, 286, 29, 16, 26, 28, 15, 19, 19, 30,
|
||||||
31, 34, 28, 30, 31, 19, 34, 19, 19, 19,
|
31, 34, 28, 30, 31, 19, 34, 19, 19, 19,
|
||||||
|
|
||||||
19, 19, 19, 19, 19, 19, 31, 19, 19, 19,
|
19, 19, 19, 19, 19, 19, 31, 19, 19, 19,
|
||||||
278, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
282, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||||
19, 19, 19, 19, 19, 20, 20, 20, 20, 20,
|
19, 19, 19, 19, 19, 20, 20, 20, 20, 20,
|
||||||
20, 20, 20, 20, 47, 20, 276, 37, 54, 54,
|
20, 20, 20, 20, 47, 20, 72, 37, 54, 54,
|
||||||
36, 20, 20, 20, 20, 20, 20, 36, 37, 72,
|
72, 20, 20, 20, 20, 20, 20, 36, 37, 55,
|
||||||
36, 55, 55, 72, 111, 120, 111, 120, 47, 158,
|
55, 235, 235, 36, 36, 280, 274, 36, 47, 112,
|
||||||
111, 158, 54, 270, 180, 158, 180, 231, 231, 268,
|
272, 112, 54, 271, 121, 112, 121, 183, 161, 183,
|
||||||
267, 264, 263, 262, 261, 55, 259, 258, 255, 254,
|
161, 268, 267, 55, 161, 235, 266, 265, 263, 235,
|
||||||
253, 252, 250, 249, 248, 246, 245, 244, 243, 242,
|
279, 262, 279, 279, 279, 279, 281, 281, 281, 283,
|
||||||
|
|
||||||
241, 231, 240, 237, 236, 231, 275, 235, 275, 275,
|
283, 283, 284, 259, 284, 285, 285, 285, 285, 258,
|
||||||
275, 275, 277, 277, 277, 279, 279, 279, 280, 234,
|
257, 256, 254, 253, 252, 250, 249, 248, 247, 246,
|
||||||
280, 281, 281, 281, 281, 233, 232, 230, 229, 228,
|
245, 244, 241, 240, 239, 238, 237, 236, 234, 233,
|
||||||
226, 225, 223, 222, 221, 220, 219, 218, 217, 214,
|
232, 230, 229, 227, 226, 225, 224, 223, 222, 221,
|
||||||
213, 212, 211, 210, 209, 205, 203, 201, 200, 199,
|
218, 217, 216, 215, 214, 213, 209, 207, 205, 204,
|
||||||
198, 196, 193, 190, 188, 187, 186, 185, 184, 183,
|
203, 202, 200, 197, 194, 192, 191, 190, 189, 188,
|
||||||
182, 181, 179, 178, 177, 176, 175, 174, 173, 172,
|
187, 186, 184, 182, 181, 180, 179, 178, 177, 176,
|
||||||
171, 168, 167, 166, 165, 164, 163, 162, 161, 160,
|
175, 174, 171, 170, 169, 168, 167, 166, 165, 164,
|
||||||
159, 157, 155, 154, 153, 150, 149, 148, 147, 146,
|
163, 162, 160, 158, 157, 156, 155, 152, 151, 150,
|
||||||
145, 144, 143, 142, 141, 140, 138, 137, 136, 135,
|
149, 148, 147, 146, 145, 144, 143, 142, 140, 139,
|
||||||
|
|
||||||
133, 132, 131, 129, 128, 127, 126, 125, 124, 122,
|
138, 137, 135, 134, 133, 131, 130, 129, 128, 127,
|
||||||
121, 119, 118, 116, 115, 113, 110, 109, 108, 107,
|
126, 124, 123, 122, 120, 119, 117, 116, 114, 111,
|
||||||
106, 105, 104, 103, 101, 100, 99, 96, 93, 92,
|
110, 109, 108, 107, 106, 105, 104, 102, 101, 100,
|
||||||
91, 90, 89, 88, 87, 86, 85, 84, 83, 82,
|
97, 94, 93, 92, 91, 90, 89, 88, 87, 86,
|
||||||
80, 79, 78, 77, 76, 75, 74, 73, 71, 70,
|
85, 84, 83, 82, 80, 79, 78, 77, 76, 75,
|
||||||
69, 68, 67, 66, 65, 64, 63, 62, 61, 60,
|
74, 73, 71, 70, 69, 68, 67, 66, 65, 64,
|
||||||
59, 51, 49, 48, 43, 42, 41, 40, 39, 38,
|
63, 62, 61, 60, 59, 51, 49, 48, 43, 42,
|
||||||
35, 32, 27, 18, 17, 7, 6, 5, 3, 274,
|
41, 40, 39, 38, 35, 32, 27, 18, 17, 7,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
6, 5, 3, 278, 278, 278, 278, 278, 278, 278,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
|
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
274, 274, 274, 274, 274, 274, 274, 274, 274
|
278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||||
|
278, 278, 278
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/* Table of booleans, true if rule could match eol. */
|
/* Table of booleans, true if rule could match eol. */
|
||||||
static const flex_int32_t yy_rule_can_match_eol[63] =
|
static const flex_int32_t yy_rule_can_match_eol[64] =
|
||||||
{ 0,
|
{ 0,
|
||||||
0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 1, 0, 0, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, };
|
0, 0, 0, 0, };
|
||||||
|
|
||||||
static yy_state_type yy_last_accepting_state;
|
static yy_state_type yy_last_accepting_state;
|
||||||
static char *yy_last_accepting_cpos;
|
static char *yy_last_accepting_cpos;
|
||||||
@@ -980,7 +982,7 @@ static char *yy_last_accepting_cpos;
|
|||||||
extern int yy_flex_debug;
|
extern int yy_flex_debug;
|
||||||
int yy_flex_debug = 1;
|
int yy_flex_debug = 1;
|
||||||
|
|
||||||
static const flex_int16_t yy_rule_linenum[62] =
|
static const flex_int16_t yy_rule_linenum[63] =
|
||||||
{ 0,
|
{ 0,
|
||||||
106, 111, 117, 127, 133, 151, 175, 189, 190, 191,
|
106, 111, 117, 127, 133, 151, 175, 189, 190, 191,
|
||||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
|
192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
|
||||||
@@ -988,7 +990,7 @@ static const flex_int16_t yy_rule_linenum[62] =
|
|||||||
212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
|
212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
|
||||||
222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
|
222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
|
||||||
232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
|
232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
|
||||||
242
|
242, 243
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/* The intent behind this definition is that it'll catch
|
/* The intent behind this definition is that it'll catch
|
||||||
@@ -1000,7 +1002,7 @@ static const flex_int16_t yy_rule_linenum[62] =
|
|||||||
#define YY_RESTORE_YY_MORE_OFFSET
|
#define YY_RESTORE_YY_MORE_OFFSET
|
||||||
char *yytext;
|
char *yytext;
|
||||||
#line 1 "lexer.ll"
|
#line 1 "lexer.ll"
|
||||||
/* Copyright (C) 2015-2021 Internet Systems Consortium, Inc. ("ISC")
|
/* Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
|
||||||
This Source Code Form is subject to the terms of the Mozilla Public
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -1039,7 +1041,7 @@ namespace {
|
|||||||
|
|
||||||
/* To avoid the call to exit... oops! */
|
/* To avoid the call to exit... oops! */
|
||||||
#define YY_FATAL_ERROR(msg) isc::eval::EvalContext::fatal(msg)
|
#define YY_FATAL_ERROR(msg) isc::eval::EvalContext::fatal(msg)
|
||||||
#line 1042 "lexer.cc"
|
#line 1044 "lexer.cc"
|
||||||
/* noyywrap disables automatic rewinding for the next file to parse. Since we
|
/* noyywrap disables automatic rewinding for the next file to parse. Since we
|
||||||
always parse only a single string, there's no need to do any wraps. And
|
always parse only a single string, there's no need to do any wraps. And
|
||||||
using yywrap requires linking with -lfl, which provides the default yywrap
|
using yywrap requires linking with -lfl, which provides the default yywrap
|
||||||
@@ -1064,8 +1066,8 @@ namespace {
|
|||||||
by moving it ahead by yyleng bytes. yyleng specifies the length of the
|
by moving it ahead by yyleng bytes. yyleng specifies the length of the
|
||||||
currently matched token. */
|
currently matched token. */
|
||||||
#define YY_USER_ACTION loc.columns(evalleng);
|
#define YY_USER_ACTION loc.columns(evalleng);
|
||||||
#line 1067 "lexer.cc"
|
#line 1069 "lexer.cc"
|
||||||
#line 1068 "lexer.cc"
|
#line 1070 "lexer.cc"
|
||||||
|
|
||||||
#define INITIAL 0
|
#define INITIAL 0
|
||||||
|
|
||||||
@@ -1364,7 +1366,7 @@ YY_DECL
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#line 1367 "lexer.cc"
|
#line 1369 "lexer.cc"
|
||||||
|
|
||||||
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
|
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
|
||||||
{
|
{
|
||||||
@@ -1393,13 +1395,13 @@ yy_match:
|
|||||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != 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];
|
yy_current_state = (int) yy_def[yy_current_state];
|
||||||
if ( yy_current_state >= 275 )
|
if ( yy_current_state >= 279 )
|
||||||
yy_c = yy_meta[yy_c];
|
yy_c = yy_meta[yy_c];
|
||||||
}
|
}
|
||||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
||||||
++yy_cp;
|
++yy_cp;
|
||||||
}
|
}
|
||||||
while ( yy_current_state != 274 );
|
while ( yy_current_state != 278 );
|
||||||
yy_cp = (yy_last_accepting_cpos);
|
yy_cp = (yy_last_accepting_cpos);
|
||||||
yy_current_state = (yy_last_accepting_state);
|
yy_current_state = (yy_last_accepting_state);
|
||||||
|
|
||||||
@@ -1428,13 +1430,13 @@ do_action: /* This label is used only to access EOF actions. */
|
|||||||
{
|
{
|
||||||
if ( yy_act == 0 )
|
if ( yy_act == 0 )
|
||||||
fprintf( stderr, "--scanner backing up\n" );
|
fprintf( stderr, "--scanner backing up\n" );
|
||||||
else if ( yy_act < 62 )
|
else if ( yy_act < 63 )
|
||||||
fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
|
fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
|
||||||
(long)yy_rule_linenum[yy_act], yytext );
|
(long)yy_rule_linenum[yy_act], yytext );
|
||||||
else if ( yy_act == 62 )
|
else if ( yy_act == 63 )
|
||||||
fprintf( stderr, "--accepting default rule (\"%s\")\n",
|
fprintf( stderr, "--accepting default rule (\"%s\")\n",
|
||||||
yytext );
|
yytext );
|
||||||
else if ( yy_act == 63 )
|
else if ( yy_act == 64 )
|
||||||
fprintf( stderr, "--(end of buffer or a NUL)\n" );
|
fprintf( stderr, "--(end of buffer or a NUL)\n" );
|
||||||
else
|
else
|
||||||
fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
|
fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
|
||||||
@@ -1713,133 +1715,138 @@ return isc::eval::EvalParser::make_SUBSTRING(loc);
|
|||||||
case 38:
|
case 38:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 219 "lexer.ll"
|
#line 219 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_ALL(loc);
|
return isc::eval::EvalParser::make_SPLIT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 39:
|
case 39:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 220 "lexer.ll"
|
#line 220 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_CONCAT(loc);
|
return isc::eval::EvalParser::make_ALL(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 40:
|
case 40:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 221 "lexer.ll"
|
#line 221 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_IFELSE(loc);
|
return isc::eval::EvalParser::make_CONCAT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 41:
|
case 41:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 222 "lexer.ll"
|
#line 222 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_TOHEXSTRING(loc);
|
return isc::eval::EvalParser::make_IFELSE(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 42:
|
case 42:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 223 "lexer.ll"
|
#line 223 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_ADDRTOTEXT(loc);
|
return isc::eval::EvalParser::make_TOHEXSTRING(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 43:
|
case 43:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 224 "lexer.ll"
|
#line 224 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_INT8TOTEXT(loc);
|
return isc::eval::EvalParser::make_ADDRTOTEXT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 44:
|
case 44:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 225 "lexer.ll"
|
#line 225 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_INT16TOTEXT(loc);
|
return isc::eval::EvalParser::make_INT8TOTEXT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 45:
|
case 45:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 226 "lexer.ll"
|
#line 226 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_INT32TOTEXT(loc);
|
return isc::eval::EvalParser::make_INT16TOTEXT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 46:
|
case 46:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 227 "lexer.ll"
|
#line 227 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_UINT8TOTEXT(loc);
|
return isc::eval::EvalParser::make_INT32TOTEXT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 47:
|
case 47:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 228 "lexer.ll"
|
#line 228 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_UINT16TOTEXT(loc);
|
return isc::eval::EvalParser::make_UINT8TOTEXT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 48:
|
case 48:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 229 "lexer.ll"
|
#line 229 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_UINT32TOTEXT(loc);
|
return isc::eval::EvalParser::make_UINT16TOTEXT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 49:
|
case 49:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 230 "lexer.ll"
|
#line 230 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_NOT(loc);
|
return isc::eval::EvalParser::make_UINT32TOTEXT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 50:
|
case 50:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 231 "lexer.ll"
|
#line 231 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_AND(loc);
|
return isc::eval::EvalParser::make_NOT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 51:
|
case 51:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 232 "lexer.ll"
|
#line 232 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_OR(loc);
|
return isc::eval::EvalParser::make_AND(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 52:
|
case 52:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 233 "lexer.ll"
|
#line 233 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_MEMBER(loc);
|
return isc::eval::EvalParser::make_OR(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 53:
|
case 53:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 234 "lexer.ll"
|
#line 234 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_DOT(loc);
|
return isc::eval::EvalParser::make_MEMBER(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 54:
|
case 54:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 235 "lexer.ll"
|
#line 235 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_LPAREN(loc);
|
return isc::eval::EvalParser::make_DOT(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 55:
|
case 55:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 236 "lexer.ll"
|
#line 236 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_RPAREN(loc);
|
return isc::eval::EvalParser::make_LPAREN(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 56:
|
case 56:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 237 "lexer.ll"
|
#line 237 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_LBRACKET(loc);
|
return isc::eval::EvalParser::make_RPAREN(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 57:
|
case 57:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 238 "lexer.ll"
|
#line 238 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_RBRACKET(loc);
|
return isc::eval::EvalParser::make_LBRACKET(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 58:
|
case 58:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 239 "lexer.ll"
|
#line 239 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_COMA(loc);
|
return isc::eval::EvalParser::make_RBRACKET(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 59:
|
case 59:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 240 "lexer.ll"
|
#line 240 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_ANY(loc);
|
return isc::eval::EvalParser::make_COMA(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 60:
|
case 60:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 241 "lexer.ll"
|
#line 241 "lexer.ll"
|
||||||
return isc::eval::EvalParser::make_PLUS(loc);
|
return isc::eval::EvalParser::make_ANY(loc);
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 61:
|
case 61:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 242 "lexer.ll"
|
#line 242 "lexer.ll"
|
||||||
driver.error (loc, "Invalid character: " + std::string(evaltext));
|
return isc::eval::EvalParser::make_PLUS(loc);
|
||||||
YY_BREAK
|
|
||||||
case YY_STATE_EOF(INITIAL):
|
|
||||||
#line 243 "lexer.ll"
|
|
||||||
return isc::eval::EvalParser::make_END(loc);
|
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 62:
|
case 62:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
|
#line 243 "lexer.ll"
|
||||||
|
driver.error (loc, "Invalid character: " + std::string(evaltext));
|
||||||
|
YY_BREAK
|
||||||
|
case YY_STATE_EOF(INITIAL):
|
||||||
#line 244 "lexer.ll"
|
#line 244 "lexer.ll"
|
||||||
|
return isc::eval::EvalParser::make_END(loc);
|
||||||
|
YY_BREAK
|
||||||
|
case 63:
|
||||||
|
YY_RULE_SETUP
|
||||||
|
#line 245 "lexer.ll"
|
||||||
ECHO;
|
ECHO;
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
#line 1842 "lexer.cc"
|
#line 1849 "lexer.cc"
|
||||||
|
|
||||||
case YY_END_OF_BUFFER:
|
case YY_END_OF_BUFFER:
|
||||||
{
|
{
|
||||||
@@ -2158,7 +2165,7 @@ static int yy_get_next_buffer (void)
|
|||||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != 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];
|
yy_current_state = (int) yy_def[yy_current_state];
|
||||||
if ( yy_current_state >= 275 )
|
if ( yy_current_state >= 279 )
|
||||||
yy_c = yy_meta[yy_c];
|
yy_c = yy_meta[yy_c];
|
||||||
}
|
}
|
||||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
||||||
@@ -2191,11 +2198,11 @@ static int yy_get_next_buffer (void)
|
|||||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != 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];
|
yy_current_state = (int) yy_def[yy_current_state];
|
||||||
if ( yy_current_state >= 275 )
|
if ( yy_current_state >= 279 )
|
||||||
yy_c = yy_meta[yy_c];
|
yy_c = yy_meta[yy_c];
|
||||||
}
|
}
|
||||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
||||||
yy_is_jam = (yy_current_state == 274);
|
yy_is_jam = (yy_current_state == 278);
|
||||||
|
|
||||||
return yy_is_jam ? 0 : yy_current_state;
|
return yy_is_jam ? 0 : yy_current_state;
|
||||||
}
|
}
|
||||||
@@ -2951,7 +2958,7 @@ void yyfree (void * ptr )
|
|||||||
|
|
||||||
/* %ok-for-header */
|
/* %ok-for-header */
|
||||||
|
|
||||||
#line 244 "lexer.ll"
|
#line 245 "lexer.ll"
|
||||||
|
|
||||||
|
|
||||||
using namespace isc::eval;
|
using namespace isc::eval;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2015-2021 Internet Systems Consortium, Inc. ("ISC")
|
/* Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
|
||||||
This Source Code Form is subject to the terms of the Mozilla Public
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -215,6 +215,7 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]*
|
|||||||
"data" return isc::eval::EvalParser::make_DATA(loc);
|
"data" return isc::eval::EvalParser::make_DATA(loc);
|
||||||
"enterprise" return isc::eval::EvalParser::make_ENTERPRISE(loc);
|
"enterprise" return isc::eval::EvalParser::make_ENTERPRISE(loc);
|
||||||
"substring" return isc::eval::EvalParser::make_SUBSTRING(loc);
|
"substring" return isc::eval::EvalParser::make_SUBSTRING(loc);
|
||||||
|
"split" return isc::eval::EvalParser::make_SPLIT(loc);
|
||||||
"all" return isc::eval::EvalParser::make_ALL(loc);
|
"all" return isc::eval::EvalParser::make_ALL(loc);
|
||||||
"concat" return isc::eval::EvalParser::make_CONCAT(loc);
|
"concat" return isc::eval::EvalParser::make_CONCAT(loc);
|
||||||
"ifelse" return isc::eval::EvalParser::make_IFELSE(loc);
|
"ifelse" return isc::eval::EvalParser::make_IFELSE(loc);
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
// A Bison parser, made by GNU Bison 3.8.2.
|
// A Bison parser, made by GNU Bison 3.3.1.
|
||||||
|
|
||||||
// Locations for Bison parsers in C++
|
// Locations for Bison parsers in C++
|
||||||
|
|
||||||
// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
|
// Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// As a special exception, you may create a larger work that contains
|
// As a special exception, you may create a larger work that contains
|
||||||
// part or all of the Bison parser skeleton and distribute that work
|
// part or all of the Bison parser skeleton and distribute that work
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
#ifndef YY_EVAL_LOCATION_HH_INCLUDED
|
#ifndef YY_EVAL_LOCATION_HH_INCLUDED
|
||||||
# define YY_EVAL_LOCATION_HH_INCLUDED
|
# define YY_EVAL_LOCATION_HH_INCLUDED
|
||||||
|
|
||||||
|
# include <algorithm> // std::max
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
@@ -53,23 +54,17 @@
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#line 14 "parser.yy"
|
#line 14 "parser.yy" // location.cc:339
|
||||||
namespace isc { namespace eval {
|
namespace isc { namespace eval {
|
||||||
#line 59 "location.hh"
|
#line 60 "location.hh" // location.cc:339
|
||||||
|
|
||||||
/// A point in a source file.
|
/// A point in a source file.
|
||||||
class position
|
class position
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Type for file name.
|
|
||||||
typedef const std::string filename_type;
|
|
||||||
/// Type for line and column numbers.
|
|
||||||
typedef int counter_type;
|
|
||||||
|
|
||||||
/// Construct a position.
|
/// Construct a position.
|
||||||
explicit position (filename_type* f = YY_NULLPTR,
|
explicit position (std::string* f = YY_NULLPTR,
|
||||||
counter_type l = 1,
|
unsigned l = 1u,
|
||||||
counter_type c = 1)
|
unsigned c = 1u)
|
||||||
: filename (f)
|
: filename (f)
|
||||||
, line (l)
|
, line (l)
|
||||||
, column (c)
|
, column (c)
|
||||||
@@ -77,9 +72,9 @@ namespace isc { namespace eval {
|
|||||||
|
|
||||||
|
|
||||||
/// Initialization.
|
/// Initialization.
|
||||||
void initialize (filename_type* fn = YY_NULLPTR,
|
void initialize (std::string* fn = YY_NULLPTR,
|
||||||
counter_type l = 1,
|
unsigned l = 1u,
|
||||||
counter_type c = 1)
|
unsigned c = 1u)
|
||||||
{
|
{
|
||||||
filename = fn;
|
filename = fn;
|
||||||
line = l;
|
line = l;
|
||||||
@@ -89,40 +84,41 @@ namespace isc { namespace eval {
|
|||||||
/** \name Line and Column related manipulators
|
/** \name Line and Column related manipulators
|
||||||
** \{ */
|
** \{ */
|
||||||
/// (line related) Advance to the COUNT next lines.
|
/// (line related) Advance to the COUNT next lines.
|
||||||
void lines (counter_type count = 1)
|
void lines (int count = 1)
|
||||||
{
|
{
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
column = 1;
|
column = 1u;
|
||||||
line = add_ (line, count, 1);
|
line = add_ (line, count, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// (column related) Advance to the COUNT next columns.
|
/// (column related) Advance to the COUNT next columns.
|
||||||
void columns (counter_type count = 1)
|
void columns (int count = 1)
|
||||||
{
|
{
|
||||||
column = add_ (column, count, 1);
|
column = add_ (column, count, 1);
|
||||||
}
|
}
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/// File name to which this position refers.
|
/// File name to which this position refers.
|
||||||
filename_type* filename;
|
std::string* filename;
|
||||||
/// Current line number.
|
/// Current line number.
|
||||||
counter_type line;
|
unsigned line;
|
||||||
/// Current column number.
|
/// Current column number.
|
||||||
counter_type column;
|
unsigned column;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Compute max (min, lhs+rhs).
|
/// Compute max (min, lhs+rhs).
|
||||||
static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
|
static unsigned add_ (unsigned lhs, int rhs, int min)
|
||||||
{
|
{
|
||||||
return lhs + rhs < min ? min : lhs + rhs;
|
return static_cast<unsigned> (std::max (min,
|
||||||
|
static_cast<int> (lhs) + rhs));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Add \a width columns, in place.
|
/// Add \a width columns, in place.
|
||||||
inline position&
|
inline position&
|
||||||
operator+= (position& res, position::counter_type width)
|
operator+= (position& res, int width)
|
||||||
{
|
{
|
||||||
res.columns (width);
|
res.columns (width);
|
||||||
return res;
|
return res;
|
||||||
@@ -130,25 +126,43 @@ namespace isc { namespace eval {
|
|||||||
|
|
||||||
/// Add \a width columns.
|
/// Add \a width columns.
|
||||||
inline position
|
inline position
|
||||||
operator+ (position res, position::counter_type width)
|
operator+ (position res, int width)
|
||||||
{
|
{
|
||||||
return res += width;
|
return res += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns, in place.
|
/// Subtract \a width columns, in place.
|
||||||
inline position&
|
inline position&
|
||||||
operator-= (position& res, position::counter_type width)
|
operator-= (position& res, int width)
|
||||||
{
|
{
|
||||||
return res += -width;
|
return res += -width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns.
|
/// Subtract \a width columns.
|
||||||
inline position
|
inline position
|
||||||
operator- (position res, position::counter_type width)
|
operator- (position res, int width)
|
||||||
{
|
{
|
||||||
return res -= width;
|
return res -= width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compare two position objects.
|
||||||
|
inline bool
|
||||||
|
operator== (const position& pos1, const position& pos2)
|
||||||
|
{
|
||||||
|
return (pos1.line == pos2.line
|
||||||
|
&& pos1.column == pos2.column
|
||||||
|
&& (pos1.filename == pos2.filename
|
||||||
|
|| (pos1.filename && pos2.filename
|
||||||
|
&& *pos1.filename == *pos2.filename)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two position objects.
|
||||||
|
inline bool
|
||||||
|
operator!= (const position& pos1, const position& pos2)
|
||||||
|
{
|
||||||
|
return !(pos1 == pos2);
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
/** \brief Intercept output stream redirection.
|
||||||
** \param ostr the destination output stream
|
** \param ostr the destination output stream
|
||||||
** \param pos a reference to the position to redirect
|
** \param pos a reference to the position to redirect
|
||||||
@@ -166,10 +180,6 @@ namespace isc { namespace eval {
|
|||||||
class location
|
class location
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Type for file name.
|
|
||||||
typedef position::filename_type filename_type;
|
|
||||||
/// Type for line and column numbers.
|
|
||||||
typedef position::counter_type counter_type;
|
|
||||||
|
|
||||||
/// Construct a location from \a b to \a e.
|
/// Construct a location from \a b to \a e.
|
||||||
location (const position& b, const position& e)
|
location (const position& b, const position& e)
|
||||||
@@ -184,18 +194,18 @@ namespace isc { namespace eval {
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||||
explicit location (filename_type* f,
|
explicit location (std::string* f,
|
||||||
counter_type l = 1,
|
unsigned l = 1u,
|
||||||
counter_type c = 1)
|
unsigned c = 1u)
|
||||||
: begin (f, l, c)
|
: begin (f, l, c)
|
||||||
, end (f, l, c)
|
, end (f, l, c)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
/// Initialization.
|
/// Initialization.
|
||||||
void initialize (filename_type* f = YY_NULLPTR,
|
void initialize (std::string* f = YY_NULLPTR,
|
||||||
counter_type l = 1,
|
unsigned l = 1u,
|
||||||
counter_type c = 1)
|
unsigned c = 1u)
|
||||||
{
|
{
|
||||||
begin.initialize (f, l, c);
|
begin.initialize (f, l, c);
|
||||||
end = begin;
|
end = begin;
|
||||||
@@ -211,13 +221,13 @@ namespace isc { namespace eval {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next columns.
|
/// Extend the current location to the COUNT next columns.
|
||||||
void columns (counter_type count = 1)
|
void columns (int count = 1)
|
||||||
{
|
{
|
||||||
end += count;
|
end += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next lines.
|
/// Extend the current location to the COUNT next lines.
|
||||||
void lines (counter_type count = 1)
|
void lines (int count = 1)
|
||||||
{
|
{
|
||||||
end.lines (count);
|
end.lines (count);
|
||||||
}
|
}
|
||||||
@@ -232,49 +242,57 @@ namespace isc { namespace eval {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Join two locations, in place.
|
/// Join two locations, in place.
|
||||||
inline location&
|
inline location& operator+= (location& res, const location& end)
|
||||||
operator+= (location& res, const location& end)
|
|
||||||
{
|
{
|
||||||
res.end = end.end;
|
res.end = end.end;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join two locations.
|
/// Join two locations.
|
||||||
inline location
|
inline location operator+ (location res, const location& end)
|
||||||
operator+ (location res, const location& end)
|
|
||||||
{
|
{
|
||||||
return res += end;
|
return res += end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns to the end position, in place.
|
/// Add \a width columns to the end position, in place.
|
||||||
inline location&
|
inline location& operator+= (location& res, int width)
|
||||||
operator+= (location& res, location::counter_type width)
|
|
||||||
{
|
{
|
||||||
res.columns (width);
|
res.columns (width);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns to the end position.
|
/// Add \a width columns to the end position.
|
||||||
inline location
|
inline location operator+ (location res, int width)
|
||||||
operator+ (location res, location::counter_type width)
|
|
||||||
{
|
{
|
||||||
return res += width;
|
return res += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position, in place.
|
/// Subtract \a width columns to the end position, in place.
|
||||||
inline location&
|
inline location& operator-= (location& res, int width)
|
||||||
operator-= (location& res, location::counter_type width)
|
|
||||||
{
|
{
|
||||||
return res += -width;
|
return res += -width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position.
|
/// Subtract \a width columns to the end position.
|
||||||
inline location
|
inline location operator- (location res, int width)
|
||||||
operator- (location res, location::counter_type width)
|
|
||||||
{
|
{
|
||||||
return res -= width;
|
return res -= width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compare two location objects.
|
||||||
|
inline bool
|
||||||
|
operator== (const location& loc1, const location& loc2)
|
||||||
|
{
|
||||||
|
return loc1.begin == loc2.begin && loc1.end == loc2.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two location objects.
|
||||||
|
inline bool
|
||||||
|
operator!= (const location& loc1, const location& loc2)
|
||||||
|
{
|
||||||
|
return !(loc1 == loc2);
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
/** \brief Intercept output stream redirection.
|
||||||
** \param ostr the destination output stream
|
** \param ostr the destination output stream
|
||||||
** \param loc a reference to the location to redirect
|
** \param loc a reference to the location to redirect
|
||||||
@@ -285,8 +303,7 @@ namespace isc { namespace eval {
|
|||||||
std::basic_ostream<YYChar>&
|
std::basic_ostream<YYChar>&
|
||||||
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
|
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
|
||||||
{
|
{
|
||||||
location::counter_type end_col
|
unsigned end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||||
= 0 < loc.end.column ? loc.end.column - 1 : 0;
|
|
||||||
ostr << loc.begin;
|
ostr << loc.begin;
|
||||||
if (loc.end.filename
|
if (loc.end.filename
|
||||||
&& (!loc.begin.filename
|
&& (!loc.begin.filename
|
||||||
@@ -299,8 +316,7 @@ namespace isc { namespace eval {
|
|||||||
return ostr;
|
return ostr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 14 "parser.yy"
|
#line 14 "parser.yy" // location.cc:339
|
||||||
} } // isc::eval
|
} } // isc::eval
|
||||||
#line 305 "location.hh"
|
#line 322 "location.hh" // location.cc:339
|
||||||
|
|
||||||
#endif // !YY_EVAL_LOCATION_HH_INCLUDED
|
#endif // !YY_EVAL_LOCATION_HH_INCLUDED
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2015-2021 Internet Systems Consortium, Inc. ("ISC")
|
/* Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
|
||||||
This Source Code Form is subject to the terms of the Mozilla Public
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -70,6 +70,7 @@ using namespace isc::eval;
|
|||||||
YIADDR "yiaddr"
|
YIADDR "yiaddr"
|
||||||
SIADDR "siaddr"
|
SIADDR "siaddr"
|
||||||
SUBSTRING "substring"
|
SUBSTRING "substring"
|
||||||
|
SPLIT "split"
|
||||||
ALL "all"
|
ALL "all"
|
||||||
COMA ","
|
COMA ","
|
||||||
CONCAT "concat"
|
CONCAT "concat"
|
||||||
@@ -360,6 +361,11 @@ string_expr : STRING
|
|||||||
TokenPtr sub(new TokenSubstring());
|
TokenPtr sub(new TokenSubstring());
|
||||||
ctx.expression.push_back(sub);
|
ctx.expression.push_back(sub);
|
||||||
}
|
}
|
||||||
|
| SPLIT "(" string_expr "," string_expr "," int_expr ")"
|
||||||
|
{
|
||||||
|
TokenPtr split(new TokenSplit());
|
||||||
|
ctx.expression.push_back(split);
|
||||||
|
}
|
||||||
| CONCAT "(" string_expr "," string_expr ")"
|
| CONCAT "(" string_expr "," string_expr ")"
|
||||||
{
|
{
|
||||||
TokenPtr conc(new TokenConcat());
|
TokenPtr conc(new TokenConcat());
|
||||||
@@ -622,6 +628,12 @@ length_expr : INTEGER
|
|||||||
ctx.expression.push_back(str);
|
ctx.expression.push_back(str);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
int_expr : INTEGER
|
||||||
|
{
|
||||||
|
TokenPtr str(new TokenString($1));
|
||||||
|
ctx.expression.push_back(str);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
void
|
void
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2015-2019,2021 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -20,6 +20,9 @@
|
|||||||
#include <log/logger_support.h>
|
#include <log/logger_support.h>
|
||||||
#include <testutils/log_utils.h>
|
#include <testutils/log_utils.h>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
|
#include <boost/algorithm/string/constants.hpp>
|
||||||
|
#include <boost/algorithm/string/split.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
@@ -255,6 +258,45 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Verify that the split eval works properly
|
||||||
|
///
|
||||||
|
/// This function takes the parameters and sets up the value
|
||||||
|
/// stack then executes the eval and checks the results.
|
||||||
|
///
|
||||||
|
/// @param test_string The string to operate on
|
||||||
|
/// @param test_delimiters The string of delimiter characters to split upon
|
||||||
|
/// @param test_field The field number of the desired field
|
||||||
|
/// @param result_string The expected result of the eval
|
||||||
|
/// @param should_throw The eval will throw
|
||||||
|
void verifySplitEval(const std::string& test_string,
|
||||||
|
const std::string& test_delimeters,
|
||||||
|
const std::string& test_field,
|
||||||
|
const std::string& result_string,
|
||||||
|
bool should_throw = false) {
|
||||||
|
// create the token
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenSplit()));
|
||||||
|
|
||||||
|
// push values on stack
|
||||||
|
values_.push(test_string);
|
||||||
|
values_.push(test_delimeters);
|
||||||
|
values_.push(test_field);
|
||||||
|
|
||||||
|
// evaluate the token
|
||||||
|
if (should_throw) {
|
||||||
|
EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
|
||||||
|
ASSERT_EQ(0, values_.size());
|
||||||
|
} else {
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
|
||||||
|
// verify results
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
EXPECT_EQ(result_string, values_.top());
|
||||||
|
|
||||||
|
// remove result
|
||||||
|
values_.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Creates vendor-option with specified value and adds it to packet
|
/// @brief Creates vendor-option with specified value and adds it to packet
|
||||||
///
|
///
|
||||||
/// This method creates specified vendor option, removes any existing
|
/// This method creates specified vendor option, removes any existing
|
||||||
@@ -3324,4 +3366,114 @@ TEST_F(TokenTest, integer) {
|
|||||||
testInteger(encode(4294967295), 4294967295);
|
testInteger(encode(4294967295), 4294967295);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify TokenSplit::eval, single delimeter.
|
||||||
|
TEST_F(TokenTest, split) {
|
||||||
|
// Get the whole string
|
||||||
|
std::string input(".two.three..five.");
|
||||||
|
std::string delims(".");
|
||||||
|
|
||||||
|
// Empty input string should yield empty result.
|
||||||
|
verifySplitEval("", delims, "1", "");
|
||||||
|
|
||||||
|
// Empty delimiters string should original string result.
|
||||||
|
verifySplitEval(input, "", "1", input);
|
||||||
|
|
||||||
|
// Field number less than one yield empty result.
|
||||||
|
verifySplitEval(input, delims, "0", "");
|
||||||
|
|
||||||
|
// Now get each field in succession.
|
||||||
|
verifySplitEval(input, delims, "1", "");
|
||||||
|
verifySplitEval(input, delims, "2", "two");
|
||||||
|
verifySplitEval(input, delims, "3", "three");
|
||||||
|
verifySplitEval(input, delims, "4", "");
|
||||||
|
verifySplitEval(input, delims, "5", "five");
|
||||||
|
verifySplitEval(input, delims, "6", "");
|
||||||
|
|
||||||
|
// Too large of a field should yield empty result.
|
||||||
|
verifySplitEval(input, delims, "7", "");
|
||||||
|
|
||||||
|
// A string without delimiters returns as field 1.
|
||||||
|
verifySplitEval("just_one", delims, "1", "just_one");
|
||||||
|
|
||||||
|
// Check that the debug output was correct. Add the strings
|
||||||
|
// to the test vector in the class and then call checkFile
|
||||||
|
// for comparison
|
||||||
|
addString("EVAL_DEBUG_SPLIT_EMPTY Popping field 1, delimiters .,"
|
||||||
|
" string , pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT_DELIM_EMPTY Popping field 1, delimiters ,"
|
||||||
|
" string .two.three..five., pushing result 0x2E74776F2E74687265652E2E666976652E");
|
||||||
|
addString("EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE Popping field 0, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 1, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 2, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x74776F");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 3, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x7468726565");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 4, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 5, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x66697665");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 6, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE Popping field 7, delimiters .,"
|
||||||
|
" string .two.three..five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 1, delimiters .,"
|
||||||
|
" string just_one, pushing result 0x6A7573745F6F6E65");
|
||||||
|
EXPECT_TRUE(checkFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify TokenSplit::eval with more than one delimeter.
|
||||||
|
TEST_F(TokenTest, splitMultipleDelims) {
|
||||||
|
// Get the whole string
|
||||||
|
std::string input(".two:three.:five.");
|
||||||
|
std::string delims(".:");
|
||||||
|
|
||||||
|
// Empty input string should yield empty result.
|
||||||
|
verifySplitEval("", delims, "1", "");
|
||||||
|
|
||||||
|
// Too small of a field should yield empty result.
|
||||||
|
verifySplitEval(input, delims, "0", "");
|
||||||
|
|
||||||
|
// Now get each field in succession.
|
||||||
|
verifySplitEval(input, delims, "1", "");
|
||||||
|
verifySplitEval(input, delims, "2", "two");
|
||||||
|
verifySplitEval(input, delims, "3", "three");
|
||||||
|
verifySplitEval(input, delims, "4", "");
|
||||||
|
verifySplitEval(input, delims, "5", "five");
|
||||||
|
verifySplitEval(input, delims, "6", "");
|
||||||
|
|
||||||
|
// Too large of a field should yield empty result.
|
||||||
|
verifySplitEval(input, delims, "7", "");
|
||||||
|
|
||||||
|
// A string without delimiters returns as field 1.
|
||||||
|
verifySplitEval("just_one", delims, "1", "just_one");
|
||||||
|
|
||||||
|
// Check that the debug output was correct. Add the strings
|
||||||
|
// to the test vector in the class and then call checkFile
|
||||||
|
// for comparison
|
||||||
|
|
||||||
|
addString("EVAL_DEBUG_SPLIT_EMPTY Popping field 1, delimiters .:,"
|
||||||
|
" string , pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE Popping field 0, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 1, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 2, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x74776F");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 3, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x7468726565");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 4, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 5, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x66697665");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 6, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE Popping field 7, delimiters .:,"
|
||||||
|
" string .two:three.:five., pushing result 0x");
|
||||||
|
addString("EVAL_DEBUG_SPLIT Popping field 1, delimiters .:,"
|
||||||
|
" string just_one, pushing result 0x6A7573745F6F6E65");
|
||||||
|
EXPECT_TRUE(checkFile());
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2015-2021 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
#include <dhcp/dhcp6.h>
|
#include <dhcp/dhcp6.h>
|
||||||
#include <dhcp/option_vendor.h>
|
#include <dhcp/option_vendor.h>
|
||||||
#include <dhcp/option_vendor_class.h>
|
#include <dhcp/option_vendor_class.h>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
|
#include <boost/algorithm/string/split.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@@ -775,6 +779,90 @@ TokenSubstring::evaluate(Pkt& /*pkt*/, ValueStack& values) {
|
|||||||
.arg(toHex(values.top()));
|
.arg(toHex(values.top()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TokenSplit::evaluate(Pkt& /*pkt*/, ValueStack& values) {
|
||||||
|
if (values.size() < 3) {
|
||||||
|
isc_throw(EvalBadStack, "Incorrect stack order. Expected at least "
|
||||||
|
"3 values for split operator, got " << values.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop the parameters.
|
||||||
|
string field_str = values.top();
|
||||||
|
values.pop();
|
||||||
|
string delim_str = values.top();
|
||||||
|
values.pop();
|
||||||
|
string string_str = values.top();
|
||||||
|
values.pop();
|
||||||
|
|
||||||
|
// If we have no string to start with we push an empty string and leave
|
||||||
|
if (string_str.empty()) {
|
||||||
|
values.push("");
|
||||||
|
|
||||||
|
// Log what we popped and pushed
|
||||||
|
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SPLIT_EMPTY)
|
||||||
|
.arg(field_str)
|
||||||
|
.arg(delim_str)
|
||||||
|
.arg(string_str)
|
||||||
|
.arg("0x");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the starting position and length from strings to numbers
|
||||||
|
// the length may also be "all" in which case simply make it the
|
||||||
|
// length of the string.
|
||||||
|
// If we have a problem push an empty string and leave
|
||||||
|
int field;
|
||||||
|
try {
|
||||||
|
field = boost::lexical_cast<int>(field_str);
|
||||||
|
} catch (const boost::bad_lexical_cast&) {
|
||||||
|
isc_throw(EvalTypeError, "the parameter '" << field_str
|
||||||
|
<< "' for the field field for split "
|
||||||
|
<< "couldn't be converted to an integer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have no string to start with we push an empty string and leave
|
||||||
|
if (delim_str.empty()) {
|
||||||
|
values.push(string_str);
|
||||||
|
|
||||||
|
// Log what we popped and pushed
|
||||||
|
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SPLIT_DELIM_EMPTY)
|
||||||
|
.arg(field_str)
|
||||||
|
.arg(delim_str)
|
||||||
|
.arg(string_str)
|
||||||
|
.arg(toHex(values.top()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the string into fields.
|
||||||
|
std::vector<std::string> fields;
|
||||||
|
boost::split(fields, string_str, boost::is_any_of(delim_str),
|
||||||
|
boost::algorithm::token_compress_off);
|
||||||
|
|
||||||
|
// Range check the field.
|
||||||
|
if (field < 1 || field > fields.size()) {
|
||||||
|
// Push an empty string if field is out of range.
|
||||||
|
values.push("");
|
||||||
|
|
||||||
|
// Log what we popped and pushed
|
||||||
|
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SPLIT_FIELD_OUT_OF_RANGE)
|
||||||
|
.arg(field_str)
|
||||||
|
.arg(delim_str)
|
||||||
|
.arg(string_str)
|
||||||
|
.arg("0x");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push the desired field.
|
||||||
|
values.push(fields[field - 1]);
|
||||||
|
|
||||||
|
// Log what we popped and pushed
|
||||||
|
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SPLIT)
|
||||||
|
.arg(field_str)
|
||||||
|
.arg(delim_str)
|
||||||
|
.arg(string_str)
|
||||||
|
.arg(toHex(values.top()));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TokenConcat::evaluate(Pkt& /*pkt*/, ValueStack& values) {
|
TokenConcat::evaluate(Pkt& /*pkt*/, ValueStack& values) {
|
||||||
if (values.size() < 2) {
|
if (values.size() < 2) {
|
||||||
|
@@ -453,7 +453,7 @@ protected:
|
|||||||
/// encapsulation
|
/// encapsulation
|
||||||
///
|
///
|
||||||
/// This represents a reference to a given option similar to TokenOption
|
/// This represents a reference to a given option similar to TokenOption
|
||||||
/// but from within the information from a relay. In the expresssion
|
/// but from within the information from a relay. In the expression
|
||||||
/// relay6[nest-level].option[option-code], nest-level indicates which
|
/// relay6[nest-level].option[option-code], nest-level indicates which
|
||||||
/// of the relays to examine and option-code which option to extract.
|
/// of the relays to examine and option-code which option to extract.
|
||||||
///
|
///
|
||||||
@@ -795,6 +795,50 @@ public:
|
|||||||
void evaluate(Pkt& pkt, ValueStack& values);
|
void evaluate(Pkt& pkt, ValueStack& values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TokenSplit : public Token {
|
||||||
|
public:
|
||||||
|
/// @brief Constructor (does nothing)
|
||||||
|
TokenSplit() {}
|
||||||
|
|
||||||
|
/// @brief Extract a field from a delimited string
|
||||||
|
///
|
||||||
|
/// Evaluation does not use packet information. It requires at least
|
||||||
|
/// three values to be present on the stack. It will consume the top
|
||||||
|
/// three values on the stack as parameters and push the resulting substring
|
||||||
|
/// onto the stack. From the top it expects the values on the stack as:
|
||||||
|
/// - field
|
||||||
|
/// - delims
|
||||||
|
/// - str
|
||||||
|
///
|
||||||
|
/// str is the string to split. If it is empty, an empty
|
||||||
|
/// string is pushed onto the value stack.
|
||||||
|
/// delims is string of character delimiters by which to split str. If it is
|
||||||
|
/// empty the entire value of str will be pushed on onto the value stack.
|
||||||
|
/// field is the field number (starting at 1) of the desired field. If it is
|
||||||
|
/// out of range an empty string is pushed on the the value stack.
|
||||||
|
///
|
||||||
|
/// The following examples all use the base string "one.two..four" and shows
|
||||||
|
/// the value returned for a given field:
|
||||||
|
/// ```
|
||||||
|
/// field => value
|
||||||
|
/// --------------
|
||||||
|
/// - 0 => ""
|
||||||
|
/// - 1 => "one"
|
||||||
|
/// - 2 => "two"
|
||||||
|
/// - 3 => ""
|
||||||
|
/// - 4 => "four"
|
||||||
|
/// - 5 => ""
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// @throw EvalBadStack if there are less than 3 values on stack
|
||||||
|
/// @throw EvalTypeError if field is not a number
|
||||||
|
///
|
||||||
|
/// @param pkt (unused)
|
||||||
|
/// @param values - stack of values (3 arguments will be popped, 1 result
|
||||||
|
/// will be pushed)
|
||||||
|
void evaluate(Pkt& pkt, ValueStack& values);
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Token that represents concat operator (concatenates two other tokens)
|
/// @brief Token that represents concat operator (concatenates two other tokens)
|
||||||
///
|
///
|
||||||
/// For example in the sub-expression "concat('foo','bar')" the result
|
/// For example in the sub-expression "concat('foo','bar')" the result
|
||||||
|
Reference in New Issue
Block a user