Repository: avro Updated Branches: refs/heads/master e9fd99ffa -> ce36fffca
Fixed AVRO-1937, C++ code genrator now handles recursive structures well Project: http://git-wip-us.apache.org/repos/asf/avro/repo Commit: http://git-wip-us.apache.org/repos/asf/avro/commit/ce36fffc Tree: http://git-wip-us.apache.org/repos/asf/avro/tree/ce36fffc Diff: http://git-wip-us.apache.org/repos/asf/avro/diff/ce36fffc Branch: refs/heads/master Commit: ce36fffca8dd0bf8f5282041ba473e84193483c1 Parents: e9fd99f Author: Thiruvalluvan M G <[email protected]> Authored: Tue Feb 14 17:16:59 2017 +0530 Committer: Thiruvalluvan M G <[email protected]> Committed: Sat Feb 18 08:10:50 2017 +0530 ---------------------------------------------------------------------- CHANGES.txt | 2 ++ lang/c++/CMakeLists.txt | 6 ++++- lang/c++/impl/avrogencpp.cc | 40 +++++++++++++++++++++++++-------- lang/c++/jsonschemas/crossref | 28 +++++++++++++++++++++++ lang/c++/jsonschemas/padded_record | 14 ++++++++++++ lang/c++/jsonschemas/tree1 | 25 +++++++++++++++++++++ lang/c++/jsonschemas/tree2 | 18 +++++++++++++++ lang/c++/test/AvrogencppTests.cc | 2 ++ 8 files changed, 125 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 622f42f..a7cfb38 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -137,6 +137,8 @@ Trunk (not yet released) AVRO-1813: Incorrect link to build instructions in Java Getting Started (Pietro Menna via gabor) + AVRO-1937: C++ generator for recursive structure crashes (thiru) + Avro 1.8.1 (14 May 2016) INCOMPATIBLE CHANGES http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/lang/c++/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/lang/c++/CMakeLists.txt b/lang/c++/CMakeLists.txt index e8efe86..c9ba587 100644 --- a/lang/c++/CMakeLists.txt +++ b/lang/c++/CMakeLists.txt @@ -125,6 +125,9 @@ gen (union_conflict uc) gen (recursive rec) gen (reuse ru) gen (circulardep cd) +gen (tree1 tr1) +gen (tree2 tr2) +gen (crossref cr) add_executable (avrogencpp impl/avrogencpp.cc) target_link_libraries (avrogencpp avrocpp_s ${Boost_LIBRARIES}) @@ -153,7 +156,8 @@ unittest (CompilerTests) add_dependencies (AvrogencppTests bigrecord_hh bigrecord_r_hh bigrecord2_hh tweet_hh union_array_union_hh union_map_union_hh union_conflict_hh - recursive_hh reuse_hh circulardep_hh empty_record_hh) + recursive_hh reuse_hh circulardep_hh tree1_hh tree2_hh crossref_hh + empty_record_hh) include (InstallRequiredSystemLibraries) http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/lang/c++/impl/avrogencpp.cc ---------------------------------------------------------------------- diff --git a/lang/c++/impl/avrogencpp.cc b/lang/c++/impl/avrogencpp.cc index a6a858d..1bf0e19 100644 --- a/lang/c++/impl/avrogencpp.cc +++ b/lang/c++/impl/avrogencpp.cc @@ -215,6 +215,7 @@ static string cppNameOf(const NodePtr& n) string CodeGen::generateRecordType(const NodePtr& n) { size_t c = n->leaves(); + string decoratedName = decorate(n->name()); vector<string> types; for (size_t i = 0; i < c; ++i) { types.push_back(generateType(n->leafAt(i))); @@ -225,7 +226,6 @@ string CodeGen::generateRecordType(const NodePtr& n) return it->second; } - string decoratedName = decorate(n->name()); os_ << "struct " << decoratedName << " {\n"; if (! noUnion_) { for (size_t i = 0; i < c; ++i) { @@ -264,7 +264,7 @@ string CodeGen::generateRecordType(const NodePtr& n) } os_ << " { }\n"; os_ << "};\n\n"; - return decorate(n->name()); + return decoratedName; } void makeCanonical(string& s, bool foldCase) @@ -391,7 +391,7 @@ string CodeGen::generateUnionType(const NodePtr& n) pendingConstructors.push_back(PendingConstructor(result, types[0], n->leafAt(0)->type() != avro::AVRO_NULL)); os_ << "};\n\n"; - + return result; } @@ -425,9 +425,31 @@ string CodeGen::doGenerateType(const NodePtr& n) case avro::AVRO_FIXED: return cppTypeOf(n); case avro::AVRO_ARRAY: - return "std::vector<" + generateType(n->leafAt(0)) + " >"; + { + const NodePtr& ln = n->leafAt(0); + string dn; + if (doing.find(n) == doing.end()) { + doing.insert(n); + dn = generateType(ln); + doing.erase(n); + } else { + dn = generateDeclaration(ln); + } + return "std::vector<" + dn + " >"; + } case avro::AVRO_MAP: - return "std::map<std::string, " + generateType(n->leafAt(1)) + " >"; + { + const NodePtr& ln = n->leafAt(1); + string dn; + if (doing.find(n) == doing.end()) { + doing.insert(n); + dn = generateType(ln); + doing.erase(n); + } else { + dn = generateDeclaration(ln); + } + return "std::map<std::string, " + dn + " >"; + } case avro::AVRO_RECORD: return generateRecordType(n); case avro::AVRO_ENUM: @@ -478,7 +500,7 @@ void CodeGen::generateEnumTraits(const NodePtr& n) string dname = decorate(n->name()); string fn = fullname(dname); size_t c = n->names(); - string first; + string first; string last; if (!ns_.empty()) { @@ -495,7 +517,7 @@ void CodeGen::generateEnumTraits(const NodePtr& n) } os_ << "template<> struct codec_traits<" << fn << "> {\n" << " static void encode(Encoder& e, " << fn << " v) {\n" - << " if (v < " << first << " || v > " << last << ")\n" + << " if (v < " << first << " || v > " << last << ")\n" << " {\n" << " std::ostringstream error;\n" << " error << \"enum value \" << v << \" is out of bound for " << fn << " and cannot be encoded\";\n" @@ -505,7 +527,7 @@ void CodeGen::generateEnumTraits(const NodePtr& n) << " }\n" << " static void decode(Decoder& d, " << fn << "& v) {\n" << " size_t index = d.decodeEnum();\n" - << " if (index < " << first << " || index > " << last << ")\n" + << " if (index < " << first << " || index > " << last << ")\n" << " {\n" << " std::ostringstream error;\n" << " error << \"enum value \" << index << \" is out of bound for " << fn << " and cannot be decoded\";\n" @@ -650,7 +672,7 @@ void CodeGen::generateTraits(const NodePtr& n) void CodeGen::emitCopyright() { - os_ << + os_ << "/**\n" " * Licensed to the Apache Software Foundation (ASF) under one\n" " * or more contributor license agreements. See the NOTICE file\n" http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/lang/c++/jsonschemas/crossref ---------------------------------------------------------------------- diff --git a/lang/c++/jsonschemas/crossref b/lang/c++/jsonschemas/crossref new file mode 100644 index 0000000..fd1d38a --- /dev/null +++ b/lang/c++/jsonschemas/crossref @@ -0,0 +1,28 @@ +{ + "name": "A", + "type": "record", + "fields": [ + { + "name": "edges", + "type": { + "type": "array", + "items": { + "type": "record", + "name": "B", + "fields": [ + { "name": "child", + "type": [{ + "type": "record", + "name": "C", + "fields": [ + { "name": "x", "type": { "type": "map", "values": "A" } } + ] + }, "int"] + } + ] + } + } + } + ] +} + http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/lang/c++/jsonschemas/padded_record ---------------------------------------------------------------------- diff --git a/lang/c++/jsonschemas/padded_record b/lang/c++/jsonschemas/padded_record new file mode 100644 index 0000000..cac0e97 --- /dev/null +++ b/lang/c++/jsonschemas/padded_record @@ -0,0 +1,14 @@ +{ + "type" : "record", + "name" : "PaddedRecord", + "fields" : [ + { + "type" : "int", + "name" : "index" + }, + { + "type" : "bytes", + "name" : "padding" + } + ] +} http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/lang/c++/jsonschemas/tree1 ---------------------------------------------------------------------- diff --git a/lang/c++/jsonschemas/tree1 b/lang/c++/jsonschemas/tree1 new file mode 100644 index 0000000..3add01d --- /dev/null +++ b/lang/c++/jsonschemas/tree1 @@ -0,0 +1,25 @@ +{ + "name": "Node", + "type": "record", + "fields": [ + { + "name": "payload", + "type": "int", + "default": 0 + }, + { + "name": "edges", + "type": { + "type": "array", + "items": { + "type": "record", + "name": "Edge", + "fields": [ + { "name": "child", "type": "Node" }, + { "name": "label", "type": "string" } + ] + } + } + } + ] +} http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/lang/c++/jsonschemas/tree2 ---------------------------------------------------------------------- diff --git a/lang/c++/jsonschemas/tree2 b/lang/c++/jsonschemas/tree2 new file mode 100644 index 0000000..1cb69b4 --- /dev/null +++ b/lang/c++/jsonschemas/tree2 @@ -0,0 +1,18 @@ +{ + "name": "Node", + "type": "record", + "fields": [ + { + "name": "payload", + "type": "int", + "default": 0 + }, + { + "name": "edges", + "type": { + "type": "map", + "values": "Node" + } + } + ] +} http://git-wip-us.apache.org/repos/asf/avro/blob/ce36fffc/lang/c++/test/AvrogencppTests.cc ---------------------------------------------------------------------- diff --git a/lang/c++/test/AvrogencppTests.cc b/lang/c++/test/AvrogencppTests.cc index 26d0155..24c5870 100644 --- a/lang/c++/test/AvrogencppTests.cc +++ b/lang/c++/test/AvrogencppTests.cc @@ -27,6 +27,8 @@ #include "recursive.hh" #include "circulardep.hh" #include "reuse.hh" +#include "tree.hh" +#include "crossref.hh" #include "Compiler.hh" #include <fstream>
