Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
c4cd450f
Commit
c4cd450f
authored
Nov 26, 2015
by
Francis Dupont
Browse files
[4204fd] Applied my proposed changes
parent
83a7bf90
Changes
17
Hide whitespace changes
Inline
Side-by-side
doc/guide/classify.xml
View file @
c4cd450f
...
...
@@ -161,7 +161,7 @@
<row><entry>
Hex String
</entry><entry>
0XABCD
</entry><entry>
A hexadecimal string
</entry></row>
<row><entry>
Integer
</entry><entry>
123
</entry><entry>
An integer value
</entry></row>
<row><entry>
Option Text
</entry><entry>
option[code].text
</entry><entry>
The value of the option with code "code" from the packet as text
</entry></row>
<row><entry>
Option
Hex
</entry><entry>
option[code].
hex
</entry><entry>
The value of the option with code "code" from the packet as
hex
</entry></row>
<row><entry>
Option
Bin
</entry><entry>
option[code].
bin
</entry><entry>
The value of the option with code "code" from the packet as
binary
</entry></row>
</tbody>
</tgroup>
</table>
...
...
@@ -178,8 +178,8 @@
<para>
"option[code]" extracts the value of the option with the given code
from the incoming packet. If the packet doesn't contain the option, it
returns the empty string. The string can be presented as text or
hex
with the ".text" or ".
hex
" modifiers. In both cases only the payload
returns the empty string. The string can be presented as text or
binary
with the ".text" or ".
bin
" modifiers. In both cases only the payload
is presented; the type code and length fields are not included.
</para>
...
...
@@ -297,7 +297,7 @@
"client-classes": [
<userinput>
{
"name": "Client_enterprise",
"test": "substring(option[2].
hex
,0,6) == 0x0002AABBCCDD'",
"test": "substring(option[2].
bin
,0,6) == 0x0002AABBCCDD'",
"option-data": [
{
"name": "dns-servers",
...
...
@@ -370,7 +370,7 @@
"client-classes": [
{
"name": "Client_enterprise",
"test": "substring(option[2].
hex
,0,6) == 0x0002AABBCCDD'",
"test": "substring(option[2].
bin
,0,6) == 0x0002AABBCCDD'",
"option-data": [
{
"name": "dns-servers",
...
...
doc/guide/dhcp6-srv.xml
View file @
c4cd450f
...
...
@@ -1615,7 +1615,7 @@ should include options from the isc option space:
"client-classes": [
{
<userinput>
"name": "Client_enterprise",
"test": "substring(option[2].
hex
,0,6) == 0x0002AABBCCDD'",
"test": "substring(option[2].
bin
,0,6) == 0x0002AABBCCDD'",
"option-data": [
{
"name": "dns-servers",
...
...
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
View file @
c4cd450f
...
...
@@ -1766,6 +1766,101 @@ TEST_F(Dhcpv4SrvTest, matchClassification) {
EXPECT_FALSE
(
opt3
);
}
// Checks if client packets are classified properly using match expressions
// using option names
TEST_F
(
Dhcpv4SrvTest
,
matchClassificationOptionName
)
{
NakedDhcpv4Srv
srv
(
0
);
// The router class matches incoming packets with foo in a host-name
string
config
=
"{
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
] }, "
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
valid-lifetime
\"
: 4000, "
"
\"
subnet4
\"
: [ "
"{
\"
pools
\"
: [ {
\"
pool
\"
:
\"
192.0.2.1 - 192.0.2.100
\"
} ], "
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
} ], "
"
\"
client-classes
\"
: [ "
"{
\"
name
\"
:
\"
router
\"
, "
"
\"
test
\"
:
\"
option[host-name].text == 'foo'
\"
} ] }"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
ConstElementPtr
status
;
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
srv
,
json
));
ASSERT_TRUE
(
status
);
comment_
=
config
::
parseAnswer
(
rcode_
,
status
);
ASSERT_EQ
(
0
,
rcode_
);
CfgMgr
::
instance
().
commit
();
// Create a packet with enough to select the subnet
Pkt4Ptr
query
(
new
Pkt4
(
DHCPDISCOVER
,
1234
));
query
->
setRemoteAddr
(
IOAddress
(
"192.0.2.1"
));
// Create and add a host-name option to the query
OptionStringPtr
hostname
(
new
OptionString
(
Option
::
V4
,
12
,
"foo"
));
ASSERT_TRUE
(
hostname
);
query
->
addOption
(
hostname
);
// Classify packets
srv
.
classifyPacket
(
query
);
// The queey should be in the router class
EXPECT_TRUE
(
query
->
inClass
(
"router"
));
}
// Checks if client packets are classified properly using match expressions
// using option names and definitions
TEST_F
(
Dhcpv4SrvTest
,
matchClassificationOptionDef
)
{
NakedDhcpv4Srv
srv
(
0
);
// The router class matches incoming packets with foo in a defined
// option
string
config
=
"{
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
] }, "
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
valid-lifetime
\"
: 4000, "
"
\"
subnet4
\"
: [ "
"{
\"
pools
\"
: [ {
\"
pool
\"
:
\"
192.0.2.1 - 192.0.2.100
\"
} ], "
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
} ], "
"
\"
client-classes
\"
: [ "
"{
\"
name
\"
:
\"
router
\"
, "
"
\"
test
\"
:
\"
option[my-host-name].text == 'foo'
\"
} ], "
"
\"
option-def
\"
: [ {"
"
\"
name
\"
:
\"
my-host-name
\"
, "
"
\"
code
\"
: 250, "
"
\"
type
\"
:
\"
string
\"
} ] }"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
ConstElementPtr
status
;
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
srv
,
json
));
ASSERT_TRUE
(
status
);
comment_
=
config
::
parseAnswer
(
rcode_
,
status
);
ASSERT_EQ
(
0
,
rcode_
);
CfgMgr
::
instance
().
commit
();
// Create a packet with enough to select the subnet
Pkt4Ptr
query
(
new
Pkt4
(
DHCPDISCOVER
,
1234
));
query
->
setRemoteAddr
(
IOAddress
(
"192.0.2.1"
));
// Create and add a my-host-name option to the query
OptionStringPtr
hostname
(
new
OptionString
(
Option
::
V4
,
250
,
"foo"
));
ASSERT_TRUE
(
hostname
);
query
->
addOption
(
hostname
);
// Classify packets
srv
.
classifyPacket
(
query
);
// The queey should be in the router class
EXPECT_TRUE
(
query
->
inClass
(
"router"
));
}
// Checks subnet options have the priority over class options
TEST_F
(
Dhcpv4SrvTest
,
subnetClassPriority
)
{
IfaceMgrTestConfig
test_config
(
true
);
...
...
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
View file @
c4cd450f
...
...
@@ -1837,6 +1837,7 @@ TEST_F(Dhcpv6SrvTest, docsisClientClassification) {
}
// Checks if client packets are classified properly using match expressions.
// Note option names and definitions are used.
TEST_F
(
Dhcpv6SrvTest
,
matchClassification
)
{
IfaceMgrTestConfig
test_config
(
true
);
...
...
@@ -1866,7 +1867,7 @@ TEST_F(Dhcpv6SrvTest, matchClassification) {
"
\"
option-data
\"
: ["
" {
\"
name
\"
:
\"
ipv6-forwarding
\"
, "
"
\"
data
\"
:
\"
true
\"
} ], "
"
\"
test
\"
:
\"
option[
1234
].text == 'foo'
\"
} ] }"
;
"
\"
test
\"
:
\"
option[
host-name
].text == 'foo'
\"
} ] }"
;
ASSERT_NO_THROW
(
configure
(
config
));
// Create packets with enough to select the subnet
...
...
src/lib/dhcp/option.cc
View file @
c4cd450f
...
...
@@ -229,7 +229,7 @@ Option::toBinary(const bool include_header) {
pack
(
buf
);
}
catch
(
const
std
::
exception
&
ex
)
{
isc_throw
(
OutOfRange
,
"unable to obtain
hexadecimal
representation"
isc_throw
(
OutOfRange
,
"unable to obtain
binary
representation"
" of option "
<<
getType
()
<<
": "
<<
ex
.
what
());
}
const
uint8_t
*
option_data
=
static_cast
<
const
uint8_t
*>
(
buf
.
getData
());
...
...
src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc
View file @
c4cd450f
...
...
@@ -182,19 +182,19 @@ TEST_F(ExpressionParserTest, validExpressionWithOptionName4) {
"hundred4"
);
}
// Verifies that given a valid expression using .
hex
operator for option, the
// Verifies that given a valid expression using .
bin
operator for option, the
// ExpressionParser produces an Expression which can be evaluated against
// a v4 packet.
TEST_F
(
ExpressionParserTest
,
validExpressionWith
Hex
4
)
{
testValidExpression
<
Pkt4
>
(
Option
::
V4
,
"
\"
option[12].
hex
== 0x68756E6472656434
\"
"
,
TEST_F
(
ExpressionParserTest
,
validExpressionWith
Bin
4
)
{
testValidExpression
<
Pkt4
>
(
Option
::
V4
,
"
\"
option[12].
bin
== 0x68756E6472656434
\"
"
,
"hundred4"
);
}
// Verifies that the option name can be used together with .
hex
operator in
// Verifies that the option name can be used together with .
bin
operator in
// the evaluated expression.
TEST_F
(
ExpressionParserTest
,
validExpressionWithOptionNameAnd
Hex
4
)
{
TEST_F
(
ExpressionParserTest
,
validExpressionWithOptionNameAnd
Bin
4
)
{
testValidExpression
<
Pkt6
>
(
Option
::
V4
,
"
\"
option[host-name].
text
== 0x68756E6472656434
\"
"
,
"
\"
option[host-name].
bin
== 0x68756E6472656434
\"
"
,
"hundred4"
);
}
...
...
@@ -212,19 +212,19 @@ TEST_F(ExpressionParserTest, validExpressionWithOptionName6) {
"hundred6"
);
}
// Verifies that given a valid expression using .
hex
operator for option, the
// Verifies that given a valid expression using .
bin
operator for option, the
// ExpressionParser produces an Expression which can be evaluated against
// a v6 packet.
TEST_F
(
ExpressionParserTest
,
validExpressionWith
Hex
6
)
{
testValidExpression
<
Pkt6
>
(
Option
::
V6
,
"
\"
option[59].
hex
== 0x68756E6472656436
\"
"
,
TEST_F
(
ExpressionParserTest
,
validExpressionWith
Bin
6
)
{
testValidExpression
<
Pkt6
>
(
Option
::
V6
,
"
\"
option[59].
bin
== 0x68756E6472656436
\"
"
,
"hundred6"
);
}
// Verifies that the option name can be used together with .
hex
operator in
// Verifies that the option name can be used together with .
bin
operator in
// the evaluated expression.
TEST_F
(
ExpressionParserTest
,
validExpressionWithOptionNameAnd
Hex
6
)
{
TEST_F
(
ExpressionParserTest
,
validExpressionWithOptionNameAnd
Bin
6
)
{
testValidExpression
<
Pkt6
>
(
Option
::
V6
,
"
\"
option[bootfile-url].
text
== 0x68756E6472656436
\"
"
,
"
\"
option[bootfile-url].
bin
== 0x68756E6472656436
\"
"
,
"hundred6"
);
}
...
...
src/lib/eval/eval.dox
View file @
c4cd450f
...
...
@@ -85,9 +85,9 @@
19. TokenPtr opt(new TokenOption($3, TokenOption::TEXTUAL));
20. ctx.expression.push_back(opt);
21. }
22. | OPTION '[' INTEGER ']' DOT
HEX
22. | OPTION '[' INTEGER ']' DOT
BIN
23. {
24. TokenPtr opt(new TokenOption($3, TokenOption::
HEXADECIMAL
));
24. TokenPtr opt(new TokenOption($3, TokenOption::
BINARY
));
25. ctx.expression.push_back(opt);
26. }
27. ;
...
...
@@ -99,7 +99,7 @@ single token or an expression "token == token" (EQUAL has been defined as
"==" elsewhere). Token is further
defined in lines 7-22: it may either be a string (lines 7-11),
a hex string (lines 12-16), option in the textual format (lines 17-21)
or option in
a hexadecimal
format (lines 22-26).
or option in
the binary
format (lines 22-26).
When the actual case is determined, the respective C++ action
is executed. For example, if the token is a string, the TokenString class is
instantiated with the appropriate value and put onto the expression vector.
...
...
src/lib/eval/lexer.cc
View file @
c4cd450f
...
...
@@ -18,7 +18,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 3
5
#define YY_FLEX_SUBMINOR_VERSION 3
9
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
...
...
@@ -72,7 +72,6 @@ typedef int16_t flex_int16_t;
typedef
uint16_t
flex_uint16_t
;
typedef
int32_t
flex_int32_t
;
typedef
uint32_t
flex_uint32_t
;
typedef
uint64_t
flex_uint64_t
;
#else
typedef
signed
char
flex_int8_t
;
typedef
short
int
flex_int16_t
;
...
...
@@ -80,7 +79,6 @@ typedef int flex_int32_t;
typedef
unsigned
char
flex_uint8_t
;
typedef
unsigned
short
int
flex_uint16_t
;
typedef
unsigned
int
flex_uint32_t
;
#endif
/* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
...
...
@@ -111,6 +109,8 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
#endif
/* ! C99 */
#endif
/* ! FLEXINT_H */
/* %endif */
...
...
@@ -225,11 +225,18 @@ extern FILE *yyin, *yyout;
*/
#define YY_LESS_LINENO(n) \
do { \
yy_size_
t yyl;\
in
t yyl;\
for ( yyl = n; yyl < yyleng; ++yyl )\
if ( yytext[yyl] == '\n' )\
--yylineno;\
}while(0)
#define YY_LINENO_REWIND_TO(dst) \
do {\
const char *p;\
for ( p = yy_cp-1; p >= (dst); --p)\
if ( *p == '\n' )\
--yylineno;\
}while(0)
/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
...
...
@@ -420,7 +427,7 @@ void yyfree (void * );
/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
/* Begin user sect3 */
#define yywrap(
n
) 1
#define yywrap() 1
#define YY_SKIP_YYWRAP
#define FLEX_DEBUG
...
...
@@ -438,6 +445,8 @@ int yylineno = 1;
extern
char
*
yytext
;
#define yytext_ptr yytext
/* %% [1.5] DFA */
/* %if-c-only Standard (non-C++) definition */
static
yy_state_type
yy_get_previous_state
(
void
);
...
...
@@ -453,7 +462,7 @@ static void yy_fatal_error (yyconst char msg[] );
#define YY_DO_BEFORE_ACTION \
(yytext_ptr) = yy_bp; \
/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */
\
yyleng = (
yy_
size_t) (yy_cp - yy_bp); \
yyleng = (size_t) (yy_cp - yy_bp); \
(yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \
/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */
\
...
...
@@ -469,27 +478,27 @@ struct yy_trans_info
flex_int32_t
yy_verify
;
flex_int32_t
yy_nxt
;
};
static
yyconst
flex_int16_t
yy_acclist
[
84
]
=
static
yyconst
flex_int16_t
yy_acclist
[
90
]
=
{
0
,
21
,
19
,
20
,
1
,
19
,
20
,
2
,
20
,
19
,
20
,
1
3
,
19
,
20
,
1
4
,
19
,
20
,
1
7
,
19
,
20
,
19
,
20
,
1
2
,
19
,
20
,
5
,
19
,
20
,
5
,
19
,
20
,
19
,
20
,
19
,
20
,
15
,
19
,
2
0
,
16
,
19
,
20
,
19
,
20
,
19
,
20
,
19
,
2
0
,
19
,
20
,
19
,
20
,
1
,
2
,
3
,
5
,
6
,
16402
,
16402
,
16402
,
16402
,
16402
,
16402
,
4
,
8210
,
11
,
16402
,
9
,
16402
,
16402
,
16402
,
1640
2
,
16
402
,
16402
,
8
,
16
402
,
16402
,
16402
,
7
,
16402
,
16402
,
16402
,
16
402
,
10
,
16402
1
4
,
19
,
20
,
1
5
,
19
,
20
,
1
8
,
19
,
20
,
19
,
20
,
1
3
,
19
,
20
,
5
,
19
,
20
,
5
,
19
,
20
,
19
,
20
,
19
,
20
,
1639
0
,
16
,
19
,
20
,
17
,
19
,
20
,
19
,
20
,
1639
0
,
19
,
20
,
16390
,
19
,
20
,
16390
,
1
9
,
20
,
16390
,
19
,
20
,
16390
,
1
,
2
,
3
,
5
,
7
,
16390
,
8198
,
16390
,
16390
,
16390
,
16390
,
16390
,
4
,
1
2
,
16
390
,
10
,
16
390
,
16390
,
16390
,
16390
,
16390
,
16390
,
9
,
16390
,
16
390
,
16390
,
8
,
16390
,
16390
,
16390
,
16390
,
11
,
16390
}
;
static
yyconst
flex_int16_t
yy_accept
[
5
7
]
=
static
yyconst
flex_int16_t
yy_accept
[
5
8
]
=
{
0
,
1
,
1
,
1
,
2
,
4
,
7
,
9
,
11
,
14
,
17
,
20
,
22
,
25
,
28
,
31
,
33
,
3
5
,
3
8
,
4
1
,
4
3
,
4
5
,
47
,
4
9
,
5
1
,
5
2
,
5
3
,
5
3
,
54
,
55
,
55
,
5
6
,
57
,
58
,
59
,
6
0
,
6
1
,
6
2
,
6
3
,
6
3
,
6
4
,
66
,
68
,
69
,
7
0
,
7
1
,
7
2
,
7
3
,
7
5
,
76
,
77
,
79
,
8
0
,
8
1
,
8
2
,
8
4
,
84
20
,
22
,
25
,
28
,
31
,
33
,
3
6
,
3
9
,
4
2
,
4
5
,
4
8
,
51
,
5
4
,
5
7
,
5
8
,
5
9
,
5
9
,
60
,
61
,
61
,
6
2
,
62
,
62
,
63
,
6
4
,
6
5
,
6
6
,
6
7
,
6
8
,
6
9
,
70
,
72
,
74
,
7
5
,
7
6
,
7
7
,
7
8
,
7
9
,
81
,
82
,
83
,
8
5
,
8
6
,
8
7
,
8
8
,
90
,
90
}
;
static
yyconst
flex_int32_t
yy_ec
[
256
]
=
...
...
@@ -505,8 +514,8 @@ static yyconst flex_int32_t yy_ec[256] =
14
,
14
,
14
,
14
,
14
,
14
,
14
,
15
,
14
,
14
,
16
,
1
,
17
,
1
,
18
,
1
,
19
,
20
,
13
,
13
,
21
,
13
,
22
,
23
,
2
4
,
14
,
14
,
2
5
,
14
,
2
6
,
2
7
,
2
8
,
14
,
2
9
,
30
,
3
1
,
3
2
,
14
,
14
,
3
3
,
21
,
13
,
22
,
14
,
2
3
,
14
,
14
,
2
4
,
14
,
2
5
,
2
6
,
2
7
,
14
,
2
8
,
29
,
3
0
,
3
1
,
14
,
14
,
3
2
,
14
,
14
,
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
,
...
...
@@ -524,74 +533,72 @@ static yyconst flex_int32_t yy_ec[256] =
1
,
1
,
1
,
1
,
1
}
;
static
yyconst
flex_int32_t
yy_meta
[
3
4
]
=
static
yyconst
flex_int32_t
yy_meta
[
3
3
]
=
{
0
,
1
,
1
,
2
,
1
,
1
,
1
,
1
,
3
,
1
,
4
,
4
,
1
,
4
,
3
,
3
,
1
,
1
,
3
,
4
,
4
,
4
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
1
,
2
,
3
,
1
,
1
,
1
,
1
,
2
,
1
,
4
,
4
,
1
,
4
,
2
,
2
,
1
,
2
,
2
,
4
,
4
,
4
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
}
;
static
yyconst
flex_int16_t
yy_base
[
59
]
=
static
yyconst
flex_int16_t
yy_base
[
60
]
=
{
0
,
0
,
0
,
1
2
1
,
1
22
,
11
8
,
1
16
,
1
10
,
1
22
,
1
22
,
1
22
,
2
4
,
1
22
,
2
6
,
2
8
,
9
8
,
0
,
1
22
,
1
22
,
77
,
79
,
67
,
61
,
6
3
,
68
,
50
,
47
,
1
22
,
3
2
,
0
,
1
22
,
38
,
43
,
44
,
45
,
46
,
47
,
0
,
4
8
,
122
,
5
0
,
52
,
54
,
55
,
56
,
7
2
,
73
,
77
,
7
9
,
80
,
81
,
84
,
8
6
,
89
,
9
0
,
122
,
112
,
114
,
40
0
,
0
,
11
3
,
1
14
,
11
0
,
1
08
,
10
6
,
1
14
,
1
14
,
1
14
,
2
3
,
1
14
,
2
5
,
2
7
,
9
7
,
37
,
1
14
,
1
14
,
56
,
18
,
19
,
20
,
2
6
,
106
,
104
,
102
,
1
14
,
3
8
,
0
,
1
14
,
50
,
51
,
81
,
114
,
80
,
35
,
32
,
4
1
,
39
,
0
,
79
,
78
,
46
,
48
,
5
2
,
55
,
54
,
7
6
,
61
,
59
,
73
,
6
5
,
66
,
7
0
,
69
,
114
,
94
,
97
,
62
}
;
static
yyconst
flex_int16_t
yy_def
[
59
]
=
static
yyconst
flex_int16_t
yy_def
[
60
]
=
{
0
,
5
5
,
1
,
5
5
,
5
5
,
5
5
,
5
5
,
5
6
,
5
5
,
5
5
,
5
5
,
5
5
,
5
5
,
5
5
,
5
5
,
5
5
,
5
7
,
5
5
,
5
5
,
5
7
,
57
,
57
,
57
,
57
,
5
5
,
55
,
56
,
5
5
,
5
5
,
5
8
,
5
5
,
5
7
,
57
,
57
,
5
7
,
57
,
57
,
58
,
55
,
55
,
5
7
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
57
,
0
,
5
5
,
5
5
,
5
5
5
6
,
1
,
5
6
,
5
6
,
5
6
,
5
6
,
5
7
,
5
6
,
5
6
,
5
6
,
5
6
,
5
6
,
5
6
,
5
6
,
5
6
,
5
8
,
5
6
,
5
6
,
5
8
,
19
,
19
,
19
,
19
,
5
6
,
56
,
5
7
,
56
,
5
6
,
5
9
,
5
6
,
5
6
,
19
,
19
,
5
6
,
19
,
19
,
19
,
19
,
19
,
5
9
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
19
,
0
,
5
6
,
5
6
,
5
6
}
;
static
yyconst
flex_int16_t
yy_nxt
[
1
56
]
=
static
yyconst
flex_int16_t
yy_nxt
[
1
47
]
=
{
0
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
16
,
16
,
17
,
18
,
4
,
19
,
16
,
16
,
16
,
20
,
16
,
16
,
16
,
21
,
16
,
16
,
22
,
23
,
16
,
16
,
28
,
28
,
28
,
28
,
28
,
28
,
38
,
29
,
28
,
28
,
37
,
38
,
38
,
38
,
38
,
38
,
38
,
27
,
38
,
25
,
38
,
39
,
38
,
38
,
38
,
29
,
39
,
39
,
39
,
39
,
39
,
39
,
43
,
39
,
40
,
39
,
24
,
39
,
39
,
39
,
38
,
38
,
42
,
41
,
45
,
38
,
44
,
38
,
38
,
38
,
36
,
46
,
38
,
47
,
38
,
39
,
39
,
38
,
38
,
35
,
39
,
34
,
39
,
39
,
39
,
48
,
33
,
39
,
32
,
39
,
49
,
50
,
39
,
39
,
52
,
51
,
30
,
54
,
53
,
26
,
27
,
26
,
26
,
31
,
31
,
25
,
24
,
55
,
3
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
14
,
15
,
16
,
16
,
16
,
17
,
18
,
4
,
19
,
20
,
16
,
16
,
16
,
16
,
16
,
21
,
16
,
16
,
22
,
23
,
16
,
16
,
28
,
28
,
28
,
28
,
28
,
28
,
31
,
29
,
36
,
33
,
33
,
33
,
32
,
37
,
39
,
28
,
28
,
33
,
38
,
31
,
56
,
34
,
32
,
33
,
29
,
31
,
33
,
42
,
44
,
43
,
33
,
32
,
33
,
40
,
34
,
56
,
46
,
33
,
45
,
33
,
34
,
32
,
33
,
33
,
47
,
33
,
33
,
35
,
49
,
48
,
33
,
50
,
33
,
51
,
52
,
53
,
33
,
33
,
54
,
55
,
33
,
33
,
26
,
26
,
33
,
26
,
33
,
33
,
33
,
33
,
33
,
41
,
33
,
27
,
25
,
24
,
30
,
27
,
25
,
24
,
56
,
3
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
}
;
static
yyconst
flex_int16_t
yy_chk
[
1
56
]
=
static
yyconst
flex_int16_t
yy_chk
[
1
47
]
=
{
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
,
11
,
11
,
13
,
13
,
14
,
14
,
31
,
13
,
28
,
28
,
58
,
32
,
33
,
34
,
35
,
36
,
38
,
26
,
40
,
25
,
41
,
31
,
42
,
43
,
44
,
13
,
32
,
33
,
34
,
35
,
36
,
38
,
35
,
40
,
32
,
41
,
24
,
42
,
43
,
44
,
45
,
46
,
34
,
33
,
42
,
47
,
36
,
48
,
49
,
50
,
23
,
43
,
51
,
44
,
52
,
45
,
46
,
53
,
54
,
22
,
47
,
21
,
48
,
49
,
50
,
45
,
20
,
51
,
19
,
52
,
46
,
48
,
53
,
54
,
51
,
49
,
15
,
53
,
52
,
56
,
7
,
56
,
56
,
57
,
57
,
6
,
5
,
3
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
,
55
1
,
1
,
11
,
11
,
13
,
13
,
14
,
14
,
16
,
13
,
20
,
20
,
21
,
22
,
16
,
21
,
23
,
28
,
28
,
23
,
22
,
31
,
32
,
16
,
16
,
37
,
13
,
19
,
36
,
36
,
38
,
37
,
39
,
19
,
38
,
59
,
31
,
32
,
43
,
43
,
39
,
44
,
19
,
19
,
32
,
45
,
44
,
47
,
46
,
19
,
46
,
45
,
50
,
47
,
49
,
49
,
50
,
52
,
52
,
53
,
53
,
54
,
55
,
54
,
57
,
57
,
51
,
57
,
58
,
48
,
58
,
42
,
41
,
35
,
33
,
26
,
25
,
24
,
15
,
7
,
6
,
5
,
3
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
,
56
}
;
/* Table of booleans, true if rule could match eol. */
...
...
@@ -605,8 +612,8 @@ int yy_flex_debug = 1;
static
yyconst
flex_int16_t
yy_rule_linenum
[
20
]
=
{
0
,
83
,
87
,
93
,
103
,
109
,
123
,
1
24
,
1
25
,
12
6
,
1
27
,
1
28
,
1
29
,
13
0
,
13
1
,
13
2
,
13
3
,
1
3
4
,
1
36
,
143
83
,
87
,
93
,
103
,
109
,
123
,
1
30
,
1
31
,
1
3
2
,
1
33
,
1
34
,
1
35
,
13
6
,
13
7
,
13
8
,
13
9
,
14
0
,
1
41
,
143
}
;
static
yy_state_type
*
yy_state_buf
=
0
,
*
yy_state_ptr
=
0
;
...
...
@@ -688,7 +695,7 @@ static isc::eval::location loc;
// by moving it ahead by yyleng bytes. yyleng specifies the length of the
// currently matched token.
#define YY_USER_ACTION loc.columns(yyleng);
#line 69
2
"lexer.cc"
#line 69
9
"lexer.cc"
#define INITIAL 0
...
...
@@ -806,7 +813,7 @@ static int input (void );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
#define ECHO fwrite( yytext, yyleng, 1, yyout )
#define ECHO
do { if (
fwrite( yytext, yyleng, 1, yyout )
) {} } while (0)
/* %endif */
/* %if-c++-only C++ definition */
/* %endif */
...
...
@@ -821,7 +828,7 @@ static int input (void );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
yy_
size_t n; \
size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
...
...
@@ -927,17 +934,6 @@ YY_DECL
register
char
*
yy_cp
,
*
yy_bp
;
register
int
yy_act
;
/* %% [7.0] user's declarations go here */
#line 76 "lexer.ll"
// Code run each time yylex is called.
loc
.
step
();
#line 940 "lexer.cc"
if
(
!
(
yy_init
)
)
{
(
yy_init
)
=
1
;
...
...
@@ -978,6 +974,18 @@ YY_DECL
yy_load_buffer_state
(
);
}
{
/* %% [7.0] user's declarations go here */
#line 76 "lexer.ll"
// Code run each time yylex is called.
loc
.
step
();
#line 988 "lexer.cc"
while
(
1
)
/* loops until end-of-file is reached */
{
/* %% [8.0] yymore()-related code goes here */
...
...
@@ -1000,24 +1008,23 @@ YY_DECL