Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Adam Osuchowski
Kea
Commits
734c918d
Commit
734c918d
authored
Feb 03, 2014
by
Mukund Sivaraman
Browse files
[2430] Support $GENERATE format modifiers
Supports everything except nibble mode. Nibble mode will come soon.
parent
981f0d20
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/lib/dns/master_loader.cc
View file @
734c918d
...
...
@@ -452,7 +452,7 @@ MasterLoader::MasterLoaderImpl::generateForIter(const std::string& str,
for
(
std
::
string
::
const_iterator
it
=
str
.
begin
();
it
!=
str
.
end
();)
{
switch
(
*
it
)
{
case
'$'
:
case
'$'
:
{
++
it
;
if
((
it
!=
str
.
end
())
&&
(
*
it
==
'$'
))
{
rstr
.
push_back
(
'$'
);
...
...
@@ -460,9 +460,56 @@ MasterLoader::MasterLoaderImpl::generateForIter(const std::string& str,
continue
;
}
// TODO: This doesn't handle format specifiers in {} yet.
rstr
+=
boost
::
str
(
boost
::
format
(
"%d"
)
%
i
);
bool
nibble_mode
=
false
;
bool
nibble_uppercase
=
false
;
std
::
string
fmt
(
"%d"
);
int
delta
=
0
;
if
(
*
it
==
'{'
)
{
const
char
*
scan_str
=
str
.
c_str
()
+
std
::
distance
(
str
.
begin
(),
it
);
unsigned
int
width
;
char
mode
[
2
]
=
{
'd'
,
0
};
// char plus null byte
const
int
n
=
sscanf
(
scan_str
,
"{%d,%u,%1[doxXnN]}"
,
&
delta
,
&
width
,
mode
);
switch
(
n
)
{
case
1
:
break
;
case
2
:
fmt
=
boost
::
str
(
boost
::
format
(
"%%0%ud"
)
%
width
);
break
;
case
3
:
if
((
mode
[
0
]
==
'n'
)
||
(
mode
[
0
]
==
'N'
))
{
nibble_mode
=
true
;
nibble_uppercase
=
(
mode
[
0
]
==
'N'
);
}
fmt
=
boost
::
str
(
boost
::
format
(
"%%0%u%c"
)
%
width
%
mode
[
0
]);
break
;
default:
reportError
(
lexer_
.
getSourceName
(),
lexer_
.
getSourceLine
(),
"Invalid $GENERATE format modifiers"
);
return
(
""
);
}
/* Skip past closing brace. */
while
((
it
!=
str
.
end
())
&&
(
*
it
!=
'}'
))
{
++
it
;
}
if
(
it
!=
str
.
end
())
{
++
it
;
}
}
// TODO: Handle nibble mode
assert
(
!
nibble_mode
);
nibble_uppercase
=
nibble_uppercase
;
rstr
+=
boost
::
str
(
boost
::
format
(
fmt
)
%
(
i
+
delta
));
break
;
}
case
'\\'
:
rstr
.
push_back
(
*
it
);
...
...
@@ -539,6 +586,14 @@ MasterLoader::MasterLoaderImpl::doGenerate() {
for
(
int
i
=
start
;
i
<=
stop
;
i
+=
step
)
{
const
std
::
string
generated_name
=
generateForIter
(
lhs
,
i
);
const
std
::
string
generated_rdata
=
generateForIter
(
rhs
,
i
);
if
(
generated_name
.
empty
()
||
generated_rdata
.
empty
())
{
// The error should have been sent to the callbacks already
// by generateForIter().
reportError
(
lexer_
.
getSourceName
(),
lexer_
.
getSourceLine
(),
"$GENERATE error"
);
return
;
}
const
size_t
name_length
=
generated_name
.
size
();
last_name_
.
reset
(
new
Name
(
generated_name
.
c_str
(),
name_length
,
&
active_origin_
));
...
...
src/lib/dns/tests/master_loader_unittest.cc
View file @
734c918d
...
...
@@ -502,6 +502,93 @@ TEST_F(MasterLoaderTest, generateWithStep) {
checkRR
(
"host31.example.org"
,
RRType
::
A
(),
"192.0.2.31"
);
}
TEST_F
(
MasterLoaderTest
,
generateWithModifiers
)
{
const
string
input
=
"$ORIGIN example.org.
\n
"
"$TTL 3600
\n
"
"$GENERATE 2-9/2 host${1} A 192.0.2.${-1}
\n
"
"$GENERATE 10-12 host${0,4} A 192.0.2.$
\n
"
"$GENERATE 14-15 host${0,4,d} A 192.0.2.$
\n
"
"$GENERATE 30-31 host${0,4,x} A 192.0.2.$
\n
"
// Names are case-insensitive, so we use TXT's RDATA to check
// case.
"$GENERATE 42-43 host$ TXT
\"
Value ${0,4,X}
\"\n
"
"$GENERATE 45-46 host${0,4,o} A 192.0.2.$
\n
"
// Junk type will not parse and 'd' is assumed.
"$GENERATE 100-101 host${0,4,j} A 192.0.2.$
\n
"
;
stringstream
ss
(
input
);
setLoader
(
ss
,
Name
(
"example.org."
),
RRClass
::
IN
(),
MasterLoader
::
MANY_ERRORS
);
loader_
->
load
();
EXPECT_TRUE
(
loader_
->
loadedSucessfully
());
EXPECT_TRUE
(
errors_
.
empty
());
checkRR
(
"host3.example.org"
,
RRType
::
A
(),
"192.0.2.1"
);
checkRR
(
"host5.example.org"
,
RRType
::
A
(),
"192.0.2.3"
);
checkRR
(
"host7.example.org"
,
RRType
::
A
(),
"192.0.2.5"
);
checkRR
(
"host9.example.org"
,
RRType
::
A
(),
"192.0.2.7"
);
checkRR
(
"host0010.example.org"
,
RRType
::
A
(),
"192.0.2.10"
);
checkRR
(
"host0011.example.org"
,
RRType
::
A
(),
"192.0.2.11"
);
checkRR
(
"host0012.example.org"
,
RRType
::
A
(),
"192.0.2.12"
);
checkRR
(
"host0014.example.org"
,
RRType
::
A
(),
"192.0.2.14"
);
checkRR
(
"host0015.example.org"
,
RRType
::
A
(),
"192.0.2.15"
);
checkRR
(
"host001e.example.org"
,
RRType
::
A
(),
"192.0.2.30"
);
checkRR
(
"host001f.example.org"
,
RRType
::
A
(),
"192.0.2.31"
);
checkRR
(
"host42.example.org"
,
RRType
::
TXT
(),
"Value 002A"
);
checkRR
(
"host43.example.org"
,
RRType
::
TXT
(),
"Value 002B"
);
checkRR
(
"host0055.example.org"
,
RRType
::
A
(),
"192.0.2.45"
);
checkRR
(
"host0056.example.org"
,
RRType
::
A
(),
"192.0.2.46"
);
checkRR
(
"host0100.example.org"
,
RRType
::
A
(),
"192.0.2.100"
);
checkRR
(
"host0101.example.org"
,
RRType
::
A
(),
"192.0.2.101"
);
}
TEST_F
(
MasterLoaderTest
,
generateWithNoModifiers
)
{
const
string
input
=
"$ORIGIN example.org.
\n
"
"$TTL 3600
\n
"
"$GENERATE 10-12 host${} A 192.0.2.$
\n
"
;
stringstream
ss
(
input
);
setLoader
(
ss
,
Name
(
"example.org."
),
RRClass
::
IN
(),
MasterLoader
::
MANY_ERRORS
);
loader_
->
load
();
EXPECT_FALSE
(
loader_
->
loadedSucessfully
());
ASSERT_EQ
(
2
,
errors_
.
size
());
// For the broken GENERATE
EXPECT_TRUE
(
warnings_
.
empty
());
checkCallbackMessage
(
errors_
.
at
(
0
),
"Invalid $GENERATE format modifiers"
,
3
);
checkCallbackMessage
(
errors_
.
at
(
1
),
"$GENERATE error"
,
3
);
}
TEST_F
(
MasterLoaderTest
,
generateWithBadModifiers
)
{
const
string
input
=
"$ORIGIN example.org.
\n
"
"$TTL 3600
\n
"
"$GENERATE 10-12 host${GARBAGE} A 192.0.2.$
\n
"
;
stringstream
ss
(
input
);
setLoader
(
ss
,
Name
(
"example.org."
),
RRClass
::
IN
(),
MasterLoader
::
MANY_ERRORS
);
loader_
->
load
();
EXPECT_FALSE
(
loader_
->
loadedSucessfully
());
ASSERT_EQ
(
2
,
errors_
.
size
());
// For the broken GENERATE
EXPECT_TRUE
(
warnings_
.
empty
());
checkCallbackMessage
(
errors_
.
at
(
0
),
"Invalid $GENERATE format modifiers"
,
3
);
checkCallbackMessage
(
errors_
.
at
(
1
),
"$GENERATE error"
,
3
);
}
TEST_F
(
MasterLoaderTest
,
generateMissingRange
)
{
const
string
input
=
"$ORIGIN example.org.
\n
"
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment