Skip to content

Commit 1ccdf60

Browse files
committed
[#3285] Removed GENERATE code and tests
1 parent d5d2856 commit 1ccdf60

File tree

2 files changed

+0
-788
lines changed

2 files changed

+0
-788
lines changed

src/lib/dns/master_loader.cc

-329
Original file line numberDiff line numberDiff line change
@@ -222,20 +222,6 @@ class MasterLoader::MasterLoaderImpl {
222222
/// handled in \c loadIncremental().
223223
MasterToken handleInitialToken();
224224

225-
/// \brief Helper method for \c doGenerate().
226-
///
227-
/// This is a helper method for \c doGenerate() that processes the
228-
/// LHS or RHS for a single iteration in the range that is requested
229-
/// by the $GENERATE directive and returns a generated string (that
230-
/// is used to build a name (LHS) or RDATA (RHS) for an RR). See the
231-
/// commented implementation for details.
232-
std::string generateForIter(const std::string& str, const int it);
233-
234-
/// \brief Process the $GENERATE directive.
235-
///
236-
/// See the commented implementation for details.
237-
void doGenerate();
238-
239225
/// \brief Process the $ORIGIN directive.
240226
void doOrigin(bool is_optional) {
241227
// Parse and create the new origin. It is relative to the previous
@@ -458,9 +444,6 @@ class MasterLoader::MasterLoaderImpl {
458444
} else if (iequals(directive, "ORIGIN")) {
459445
doOrigin(false);
460446
eatUntilEOL(true);
461-
} else if (iequals(directive, "GENERATE")) {
462-
doGenerate();
463-
eatUntilEOL(true);
464447
} else if (iequals(directive, "TTL")) {
465448
setDefaultTTL(RRTTL(getString()), false);
466449
eatUntilEOL(true);
@@ -551,318 +534,6 @@ class MasterLoader::MasterLoaderImpl {
551534
size_t rr_count_; // number of RRs successfully loaded
552535
};
553536

554-
namespace { // begin unnamed namespace
555-
556-
/// \brief Generate a dotted nibble sequence.
557-
///
558-
/// This method generates a dotted nibble sequence and returns it as a
559-
/// string. The nibbles are appended from the least significant digit
560-
/// (in hex representation of \c num) to the most significant digit with
561-
/// dots ('.') to separate the digits. If \c width is non-zero and the
562-
/// dotted nibble sequence has not filled the requested width, the rest
563-
/// of the width is filled with a dotted nibble sequence of 0 nibbles.
564-
///
565-
/// Some sample representations:
566-
///
567-
/// num = 0x1234, width = 0
568-
/// "4.3.2.1"
569-
///
570-
/// num = 0x1234, width = 1
571-
/// "4.3.2.1"
572-
///
573-
/// num = 0x1234, width = 8
574-
/// "4.3.2.1"
575-
///
576-
/// num = 0x1234, width = 9
577-
/// "4.3.2.1."
578-
///
579-
/// num = 0x1234, width = 10
580-
/// "4.3.2.1.0"
581-
///
582-
/// num = 0x1234, width = 11
583-
/// "4.3.2.1.0."
584-
///
585-
/// num = 0xabcd, width = 0, uppercase = true
586-
/// "D.C.B.A"
587-
///
588-
/// num = 0, width = 0
589-
/// "0"
590-
///
591-
/// num = 0, width = 1
592-
/// "0"
593-
///
594-
/// num = 0, width = 2
595-
/// "0."
596-
///
597-
/// num = 0, width = 3
598-
/// "0.0"
599-
///
600-
/// \param num The number for which the dotted nibble sequence should be
601-
/// generated.
602-
/// \param width The width of the generated string. This is only
603-
/// meaningful when it is larger than the dotted nibble sequence
604-
/// representation of \c num.
605-
/// \param uppercase Whether to use uppercase characters in nibble
606-
/// sequence.
607-
/// \return A string containing the dotted nibble sequence.
608-
std::string
609-
genNibbles(int num, unsigned int width, bool uppercase) {
610-
static const char *hex = "0123456789abcdef0123456789ABCDEF";
611-
std::string rstr;
612-
613-
do {
614-
char ch = hex[(num & 0x0f) + (uppercase ? 16 : 0)];
615-
num >>= 4;
616-
rstr.push_back(ch);
617-
618-
if (width > 0) {
619-
--width;
620-
}
621-
622-
// If width is non zero then we need to add a label separator.
623-
// If value is non zero then we need to add another label and
624-
// that requires a label separator.
625-
if (width > 0 || num != 0) {
626-
rstr.push_back('.');
627-
628-
if (width > 0) {
629-
--width;
630-
}
631-
}
632-
} while ((num != 0) || (width > 0));
633-
634-
return (rstr);
635-
}
636-
637-
} // end unnamed namespace
638-
639-
std::string
640-
MasterLoader::MasterLoaderImpl::generateForIter(const std::string& str,
641-
const int num) {
642-
std::string rstr;
643-
644-
for (auto it = str.begin(); it != str.end();) {
645-
switch (*it) {
646-
case '$':
647-
// This is the case when the '$' character is encountered in
648-
// the LHS or RHS. A computed value is added in its place in
649-
// the generated string.
650-
++it;
651-
if ((it != str.end()) && (*it == '$')) {
652-
rstr.push_back('$');
653-
++it;
654-
continue;
655-
}
656-
657-
// The str.end() check is required.
658-
if ((it == str.end()) || (*it != '{')) {
659-
// There is no modifier (between {}), so just copy the
660-
// passed number into the generated string.
661-
rstr += boost::str(boost::format("%d") % num);
662-
} else {
663-
// There is a modifier (between {}). Parse it and handle
664-
// the various cases below.
665-
const char* scan_str =
666-
str.c_str() + std::distance(str.begin(), it);
667-
int offset = 0;
668-
unsigned int width;
669-
char base[2] = {'d', 0}; // char plus null byte
670-
// cppcheck-suppress invalidscanf_libc
671-
const int n = sscanf(scan_str, "{%d,%u,%1[doxXnN]}",
672-
&offset, &width, base);
673-
switch (n) {
674-
case 1:
675-
// Only 1 item was matched (the offset). Copy (num +
676-
// offset) into the generated string.
677-
rstr += boost::str(boost::format("%d") % (num + offset));
678-
break;
679-
680-
case 2: {
681-
// 2 items were matched (the offset and width). Copy
682-
// (num + offset) and format it according to the width
683-
// into the generated string.
684-
const std::string fmt =
685-
boost::str(boost::format("%%0%ud") % width);
686-
rstr += boost::str(boost::format(fmt) % (num + offset));
687-
break;
688-
}
689-
690-
case 3:
691-
// 3 items were matched (offset, width and base).
692-
if ((base[0] == 'n') || (base[0] == 'N')) {
693-
// The base is requesting nibbles. Format it
694-
// specially (see genNibbles() documentation).
695-
rstr += genNibbles(num + offset, width, (base[0] == 'N'));
696-
} else {
697-
// The base is not requesting nibbles. Copy (num +
698-
// offset) and format it according to the width
699-
// and base into the generated string.
700-
const std::string fmt =
701-
boost::str(boost::format("%%0%u%c") % width % base[0]);
702-
rstr += boost::str(boost::format(fmt) % (num + offset));
703-
}
704-
break;
705-
706-
default:
707-
// Any other case in the modifiers is an error.
708-
reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
709-
"Invalid $GENERATE format modifiers");
710-
return ("");
711-
}
712-
713-
// Find the closing brace. Careful that 'it' can be equal
714-
// to str.end() here.
715-
while ((it != str.end()) && (*it != '}')) {
716-
++it;
717-
}
718-
// Skip past the closing brace (if there is one).
719-
if (it != str.end()) {
720-
++it;
721-
}
722-
}
723-
break;
724-
725-
case '\\':
726-
// This is the case when the '\' character is encountered in
727-
// the LHS or RHS. The '\' and the following character are
728-
// copied as-is into the generated string. This is usually
729-
// used for escaping the $ character.
730-
rstr.push_back(*it);
731-
++it;
732-
if (it == str.end()) {
733-
continue;
734-
}
735-
rstr.push_back(*it);
736-
++it;
737-
break;
738-
739-
default:
740-
// This is the default case that handles all other
741-
// characters. They are copied as-is into the generated
742-
// string.
743-
rstr.push_back(*it);
744-
++it;
745-
break;
746-
}
747-
}
748-
749-
return (rstr);
750-
}
751-
752-
void
753-
MasterLoader::MasterLoaderImpl::doGenerate() {
754-
// Parse the range token
755-
const MasterToken& range_token = lexer_.getNextToken(MasterToken::STRING);
756-
if (range_token.getType() != MasterToken::STRING) {
757-
reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
758-
"Invalid $GENERATE syntax");
759-
return;
760-
}
761-
const std::string range = range_token.getString();
762-
763-
// Parse the LHS token
764-
const MasterToken& lhs_token = lexer_.getNextToken(MasterToken::STRING);
765-
if (lhs_token.getType() != MasterToken::STRING) {
766-
reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
767-
"Invalid $GENERATE syntax");
768-
return;
769-
}
770-
const std::string lhs = lhs_token.getString();
771-
772-
// Parse the TTL, RR class and RR type tokens. Note that TTL and RR
773-
// class may come in any order, or may be missing (either or
774-
// both). If TTL is missing, we expect that it was either specified
775-
// explicitly using $TTL, or is implicitly known from a previous RR,
776-
// or that this is the SOA RR from which the MINIMUM field is
777-
// used. It's unlikely that $GENERATE will be used with an SOA RR,
778-
// but it's possible. The parsing happens within the parseRRParams()
779-
// helper method which is called below.
780-
const MasterToken& param_token = lexer_.getNextToken(MasterToken::STRING);
781-
if (param_token.getType() != MasterToken::STRING) {
782-
reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
783-
"Invalid $GENERATE syntax");
784-
return;
785-
}
786-
787-
bool explicit_ttl = false;
788-
const RRType rrtype = parseRRParams(explicit_ttl, param_token);
789-
790-
// Parse the RHS token. It can be a quoted string.
791-
const MasterToken& rhs_token = lexer_.getNextToken(MasterToken::QSTRING);
792-
if ((rhs_token.getType() != MasterToken::QSTRING) &&
793-
(rhs_token.getType() != MasterToken::STRING))
794-
{
795-
reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
796-
"Invalid $GENERATE syntax");
797-
return;
798-
}
799-
const std::string rhs = rhs_token.getString();
800-
801-
// Range can be one of two forms: start-stop or start-stop/step. If
802-
// the first form is used, then step is set to 1. All of start, stop
803-
// and step must be positive.
804-
unsigned int start;
805-
unsigned int stop;
806-
unsigned int step;
807-
// cppcheck-suppress invalidscanf_libc
808-
const int n = sscanf(range.c_str(), "%u-%u/%u", &start, &stop, &step);
809-
if ((n < 2) || (stop < start)) {
810-
reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
811-
"$GENERATE: invalid range: " + range);
812-
return;
813-
}
814-
815-
if (n == 2) {
816-
step = 1;
817-
}
818-
819-
// Generate and add the records.
820-
for (unsigned int i = start; i <= stop; i += step) {
821-
// Get generated strings for LHS and RHS. LHS goes to form the
822-
// name, RHS goes to form the RDATA of the RR.
823-
const std::string generated_name = generateForIter(lhs, i);
824-
const std::string generated_rdata = generateForIter(rhs, i);
825-
if (generated_name.empty() || generated_rdata.empty()) {
826-
// The error should have been sent to the callbacks already
827-
// by generateForIter().
828-
reportError(lexer_.getSourceName(), lexer_.getSourceLine(),
829-
"$GENERATE error");
830-
return;
831-
}
832-
833-
// generateForIter() can return a string with a trailing '.' in
834-
// case of a nibble representation. So we cannot use the
835-
// relative Name constructor. We use concatenate() which is
836-
// expensive, but keeps the generated LHS-based Name within the
837-
// active origin.
838-
last_name_.reset
839-
(new Name(Name(generated_name).concatenate(active_origin_)));
840-
previous_name_ = true;
841-
842-
const rdata::RdataPtr rdata =
843-
rdata::createRdata(rrtype, zone_class_, generated_rdata);
844-
// In case we get null, it means there was error creating the
845-
// Rdata. The errors should have been reported by callbacks_
846-
// already. We need to decide if we want to continue or not.
847-
if (rdata) {
848-
add_callback_(*last_name_, zone_class_, rrtype,
849-
getCurrentTTL(explicit_ttl, rrtype, rdata),
850-
rdata);
851-
// Good, we added another one
852-
++rr_count_;
853-
} else {
854-
seen_error_ = true;
855-
if (!many_errors_) {
856-
ok_ = false;
857-
complete_ = true;
858-
// We don't have the exact error here, but it was
859-
// reported by the error callback.
860-
isc_throw(MasterLoaderError, "Invalid RR data");
861-
}
862-
}
863-
}
864-
}
865-
866537
MasterToken
867538
MasterLoader::MasterLoaderImpl::handleInitialToken() {
868539
const MasterToken& initial_token =

0 commit comments

Comments
 (0)