From 2615896faa646e5830abf2c269150e1165c66515 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 18 Dec 2020 18:48:46 +0300 Subject: Switch to build2 --- xsd/xsd/cxx/tree/counter.cxx | 260 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 xsd/xsd/cxx/tree/counter.cxx (limited to 'xsd/xsd/cxx/tree/counter.cxx') diff --git a/xsd/xsd/cxx/tree/counter.cxx b/xsd/xsd/cxx/tree/counter.cxx new file mode 100644 index 0000000..94bcc87 --- /dev/null +++ b/xsd/xsd/cxx/tree/counter.cxx @@ -0,0 +1,260 @@ +// file : xsd/cxx/tree/counter.cxx +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include + +namespace CXX +{ + namespace Tree + { + namespace + { + struct Member: Traversal::Member + { + Member (size_t& complexity) + : complexity_ (complexity) + { + } + + virtual void + traverse (Type&) + { + complexity_++; + } + + size_t& complexity_; + }; + + struct Any: Traversal::Any, Traversal::AnyAttribute + { + Any (size_t& complexity) + : complexity_ (complexity) + { + } + + virtual void + traverse (SemanticGraph::Any&) + { + complexity_++; + } + + virtual void + traverse (SemanticGraph::AnyAttribute&) + { + complexity_++; + } + + size_t& complexity_; + }; + + struct TypeBase: Traversal::List, + Traversal::Union, + Traversal::Enumeration, + Traversal::Complex, + Context + { + TypeBase (Context& c, size_t& complexity) + : Context (c), complexity_ (complexity) + { + } + + virtual void + traverse (SemanticGraph::List&) + { + complexity_++; + } + + virtual void + traverse (SemanticGraph::Union&) + { + complexity_++; + } + + virtual void + traverse (SemanticGraph::Enumeration& e) + { + bool string_based (false); + { + IsStringBasedType t (string_based); + t.dispatch (e); + } + + complexity_ += (string_based ? 1 : 2); + } + + virtual void + traverse (SemanticGraph::Complex& c) + { + complexity_++; // One for the type itself. + + // Plus some for each member. + // + Any any (complexity_); + Member member (complexity_); + Traversal::Names names; + + names >> member; + + if (options.generate_wildcard ()) + names >> any; + + Complex::names (c, names); + } + + private: + size_t& complexity_; + }; + + + // + // + struct GlobalType: Traversal::Type, Context + + { + GlobalType (Context& c, Counts& counts) + : Context (c), counts_ (counts) + { + } + + virtual void + traverse (SemanticGraph::Type& t) + { + counts_.global_types++; + + size_t complexity (0); + TypeBase type (*this, complexity); + type.dispatch (t); + + counts_.complexity_total += complexity; + counts_.complexity.push_back (complexity); + } + + private: + Counts& counts_; + }; + + // + // + struct GlobalElement: Traversal::Element, + GlobalElementBase, + Context + { + GlobalElement (Context& c, Counts& counts) + : GlobalElementBase (c), + Context (c), + counts_ (counts), + last_ (0) + { + } + + ~GlobalElement () + { + if (last_ != 0) + { + last_->context ().set ("last", true); + count_last (); + } + } + + virtual void + traverse (Type& e) + { + // Check if the previous element we saw needs to be generated. + // + if (last_ != 0) + count_last (); + + last_ = &e; + + if (counts_.global_elements == 0) + e.context ().set ("first", true); + + counts_.global_elements++; + } + + private: + void + count_last () + { + if (generate_p (*last_)) + { + counts_.generated_global_elements++; + + size_t complexity (0); + + if (doc_root_p (*last_)) + { + if (options.generate_element_type ()) + { + complexity += 1; // For c-tors and d-tor. + + if (!options.suppress_parsing ()) + complexity += 1; + + if (options.generate_serialization ()) + complexity += 1; + } + else + { + if (!options.suppress_parsing ()) + complexity += 6; // 13 parsing functions. + + if (options.generate_serialization ()) + complexity += 4; // 8 serialization functions. + } + } + + if (complexity == 0) + { + // This element must be a substitution group members. For + // such elements we are only generating an entry in a map. + // We will assign it a complexity of 1 so that we don't + // end up with the total complexity that is less than the + // number of elements and types. + // + complexity = 1; + } + + counts_.complexity_total += complexity; + counts_.complexity.push_back (complexity); + } + } + + private: + Counts& counts_; + SemanticGraph::Element* last_; + }; + } + + Counts Counter:: + count (options const& ops, + SemanticGraph::Schema& tu, + SemanticGraph::Path const& path) + { + Counts counts; + Context ctx (std::wcerr, tu, path, ops, counts, false, 0, 0, 0, 0); + + Traversal::Schema schema; + Sources sources; + + schema >> sources >> schema; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + GlobalType global_type (ctx, counts); + GlobalElement global_element (ctx, counts); + + schema >> schema_names >> ns >> ns_names; + + ns_names >> global_element; + ns_names >> global_type; + + schema.dispatch (tu); + + return counts; + } + } +} -- cgit v1.1