From f0510d2f90467de8e8f260b47d79a9baaf9bef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2009 07:15:29 +0200 Subject: Start tracking XSD with git --- xsd/cxx/tree/cli.hxx | 220 ++ xsd/cxx/tree/counter.cxx | 265 ++ xsd/cxx/tree/counter.hxx | 28 + xsd/cxx/tree/elements.cxx | 1327 ++++++++++ xsd/cxx/tree/elements.hxx | 2030 ++++++++++++++++ xsd/cxx/tree/fundamental-header.hxx | 1186 +++++++++ xsd/cxx/tree/generator.cxx | 1689 +++++++++++++ xsd/cxx/tree/generator.hxx | 49 + xsd/cxx/tree/name-processor.cxx | 2100 ++++++++++++++++ xsd/cxx/tree/name-processor.hxx | 34 + xsd/cxx/tree/parser-header.cxx | 474 ++++ xsd/cxx/tree/parser-header.hxx | 23 + xsd/cxx/tree/parser-source.cxx | 544 +++++ xsd/cxx/tree/parser-source.hxx | 24 + xsd/cxx/tree/serialization-header.cxx | 581 +++++ xsd/cxx/tree/serialization-header.hxx | 22 + xsd/cxx/tree/serialization-source.cxx | 1342 ++++++++++ xsd/cxx/tree/serialization-source.hxx | 24 + xsd/cxx/tree/stream-extraction-source.cxx | 754 ++++++ xsd/cxx/tree/stream-extraction-source.hxx | 22 + xsd/cxx/tree/stream-header.cxx | 183 ++ xsd/cxx/tree/stream-header.hxx | 22 + xsd/cxx/tree/stream-insertion-header.cxx | 178 ++ xsd/cxx/tree/stream-insertion-header.hxx | 22 + xsd/cxx/tree/stream-insertion-source.cxx | 532 ++++ xsd/cxx/tree/stream-insertion-source.hxx | 22 + xsd/cxx/tree/stream-source.cxx | 489 ++++ xsd/cxx/tree/stream-source.hxx | 24 + xsd/cxx/tree/tree-forward.cxx | 324 +++ xsd/cxx/tree/tree-forward.hxx | 22 + xsd/cxx/tree/tree-header.cxx | 3778 +++++++++++++++++++++++++++++ xsd/cxx/tree/tree-header.hxx | 22 + xsd/cxx/tree/tree-inline.cxx | 1025 ++++++++ xsd/cxx/tree/tree-inline.hxx | 22 + xsd/cxx/tree/tree-source.cxx | 3461 ++++++++++++++++++++++++++ xsd/cxx/tree/tree-source.hxx | 24 + xsd/cxx/tree/validator.cxx | 675 ++++++ xsd/cxx/tree/validator.hxx | 33 + 38 files changed, 23596 insertions(+) create mode 100644 xsd/cxx/tree/cli.hxx create mode 100644 xsd/cxx/tree/counter.cxx create mode 100644 xsd/cxx/tree/counter.hxx create mode 100644 xsd/cxx/tree/elements.cxx create mode 100644 xsd/cxx/tree/elements.hxx create mode 100644 xsd/cxx/tree/fundamental-header.hxx create mode 100644 xsd/cxx/tree/generator.cxx create mode 100644 xsd/cxx/tree/generator.hxx create mode 100644 xsd/cxx/tree/name-processor.cxx create mode 100644 xsd/cxx/tree/name-processor.hxx create mode 100644 xsd/cxx/tree/parser-header.cxx create mode 100644 xsd/cxx/tree/parser-header.hxx create mode 100644 xsd/cxx/tree/parser-source.cxx create mode 100644 xsd/cxx/tree/parser-source.hxx create mode 100644 xsd/cxx/tree/serialization-header.cxx create mode 100644 xsd/cxx/tree/serialization-header.hxx create mode 100644 xsd/cxx/tree/serialization-source.cxx create mode 100644 xsd/cxx/tree/serialization-source.hxx create mode 100644 xsd/cxx/tree/stream-extraction-source.cxx create mode 100644 xsd/cxx/tree/stream-extraction-source.hxx create mode 100644 xsd/cxx/tree/stream-header.cxx create mode 100644 xsd/cxx/tree/stream-header.hxx create mode 100644 xsd/cxx/tree/stream-insertion-header.cxx create mode 100644 xsd/cxx/tree/stream-insertion-header.hxx create mode 100644 xsd/cxx/tree/stream-insertion-source.cxx create mode 100644 xsd/cxx/tree/stream-insertion-source.hxx create mode 100644 xsd/cxx/tree/stream-source.cxx create mode 100644 xsd/cxx/tree/stream-source.hxx create mode 100644 xsd/cxx/tree/tree-forward.cxx create mode 100644 xsd/cxx/tree/tree-forward.hxx create mode 100644 xsd/cxx/tree/tree-header.cxx create mode 100644 xsd/cxx/tree/tree-header.hxx create mode 100644 xsd/cxx/tree/tree-inline.cxx create mode 100644 xsd/cxx/tree/tree-inline.hxx create mode 100644 xsd/cxx/tree/tree-source.cxx create mode 100644 xsd/cxx/tree/tree-source.hxx create mode 100644 xsd/cxx/tree/validator.cxx create mode 100644 xsd/cxx/tree/validator.hxx (limited to 'xsd/cxx/tree') diff --git a/xsd/cxx/tree/cli.hxx b/xsd/cxx/tree/cli.hxx new file mode 100644 index 0000000..9ccf405 --- /dev/null +++ b/xsd/cxx/tree/cli.hxx @@ -0,0 +1,220 @@ +// file : xsd/cxx/tree/cli.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_TREE_CLI_HXX +#define CXX_TREE_CLI_HXX + +#include + +#include + +#include +#include + +namespace CXX +{ + namespace Tree + { + namespace CLI + { + using namespace Cult::Types; + + typedef Char const Key[]; + + extern Key char_type; + extern Key output_dir; + extern Key generate_polymorphic; + extern Key generate_serialization; + extern Key generate_inline; + extern Key generate_ostream; + extern Key generate_doxygen; + extern Key generate_comparison; + extern Key generate_default_ctor; + extern Key generate_from_base_ctor; + extern Key generate_wildcard; + extern Key generate_insertion; + extern Key generate_extraction; + extern Key generate_forward; + extern Key generate_xml_schema; + extern Key extern_xml_schema; + extern Key suppress_parsing; + extern Key generate_element_type; + extern Key generate_element_map; + extern Key generate_intellisense; + extern Key omit_default_attributes; + extern Key namespace_map; + extern Key namespace_regex; + extern Key namespace_regex_trace; + extern Key reserved_name; + extern Key type_naming; + extern Key function_naming; + extern Key type_regex; + extern Key accessor_regex; + extern Key one_accessor_regex; + extern Key opt_accessor_regex; + extern Key seq_accessor_regex; + extern Key modifier_regex; + extern Key one_modifier_regex; + extern Key opt_modifier_regex; + extern Key seq_modifier_regex; + extern Key parser_regex; + extern Key serializer_regex; + extern Key enumerator_regex; + extern Key element_type_regex; + extern Key name_regex_trace; + extern Key include_with_brackets; + extern Key include_prefix; + extern Key include_regex; + extern Key include_regex_trace; + extern Key guard_prefix; + extern Key root_element_first; + extern Key root_element_last; + extern Key root_element_all; + extern Key root_element_none; + extern Key root_element; + extern Key custom_type; + extern Key custom_type_regex; + extern Key hxx_suffix; + extern Key ixx_suffix; + extern Key cxx_suffix; + extern Key fwd_suffix; + extern Key hxx_regex; + extern Key ixx_regex; + extern Key cxx_regex; + extern Key fwd_regex; + extern Key hxx_prologue; + extern Key ixx_prologue; + extern Key cxx_prologue; + extern Key fwd_prologue; + extern Key prologue; + extern Key hxx_epilogue; + extern Key ixx_epilogue; + extern Key cxx_epilogue; + extern Key fwd_epilogue; + extern Key epilogue; + extern Key hxx_prologue_file; + extern Key ixx_prologue_file; + extern Key cxx_prologue_file; + extern Key fwd_prologue_file; + extern Key prologue_file; + extern Key hxx_epilogue_file; + extern Key ixx_epilogue_file; + extern Key cxx_epilogue_file; + extern Key fwd_epilogue_file; + extern Key epilogue_file; + extern Key parts; + extern Key parts_suffix; + extern Key export_symbol; + extern Key export_xml_schema; + extern Key export_maps; + extern Key import_maps; + extern Key show_anonymous; + extern Key show_sloc; + extern Key proprietary_license; + extern Key disable_multi_import; // Undocumented. + + + typedef Cult::CLI::Options< + + char_type, NarrowString, + output_dir, NarrowString, + generate_polymorphic, Boolean, + generate_serialization, Boolean, + generate_inline, Boolean, + generate_ostream, Boolean, + generate_doxygen, Boolean, + generate_comparison, Boolean, + generate_default_ctor, Boolean, + generate_from_base_ctor, Boolean, + generate_wildcard, Boolean, + generate_insertion, Cult::Containers::Vector, + generate_extraction, Cult::Containers::Vector, + generate_forward, Boolean, + generate_xml_schema, Boolean, + extern_xml_schema, NarrowString, + suppress_parsing, Boolean, + generate_element_type, Boolean, + generate_element_map, Boolean, + generate_intellisense, Boolean, + omit_default_attributes, Boolean, + namespace_map, Cult::Containers::Vector, + namespace_regex, Cult::Containers::Vector, + namespace_regex_trace, Boolean, + reserved_name, Cult::Containers::Vector, + type_naming, NarrowString, + function_naming, NarrowString, + type_regex, Cult::Containers::Vector, + accessor_regex, Cult::Containers::Vector, + one_accessor_regex, Cult::Containers::Vector, + opt_accessor_regex, Cult::Containers::Vector, + seq_accessor_regex, Cult::Containers::Vector, + modifier_regex, Cult::Containers::Vector, + one_modifier_regex, Cult::Containers::Vector, + opt_modifier_regex, Cult::Containers::Vector, + seq_modifier_regex, Cult::Containers::Vector, + parser_regex, Cult::Containers::Vector, + serializer_regex, Cult::Containers::Vector, + enumerator_regex, Cult::Containers::Vector, + element_type_regex, Cult::Containers::Vector, + name_regex_trace, Boolean, + include_with_brackets, Boolean, + include_prefix, NarrowString, + include_regex, Cult::Containers::Vector, + include_regex_trace, Boolean, + guard_prefix, NarrowString, + root_element_first, Boolean, + root_element_last, Boolean, + root_element_all, Boolean, + root_element_none, Boolean, + root_element, Cult::Containers::Vector, + custom_type, Cult::Containers::Vector, + custom_type_regex, Cult::Containers::Vector, + hxx_suffix, NarrowString, + ixx_suffix, NarrowString, + cxx_suffix, NarrowString, + fwd_suffix, NarrowString, + hxx_regex, NarrowString, + ixx_regex, NarrowString, + cxx_regex, NarrowString, + fwd_regex, NarrowString, + hxx_prologue, Cult::Containers::Vector, + ixx_prologue, Cult::Containers::Vector, + cxx_prologue, Cult::Containers::Vector, + fwd_prologue, Cult::Containers::Vector, + prologue, Cult::Containers::Vector, + hxx_epilogue, Cult::Containers::Vector, + ixx_epilogue, Cult::Containers::Vector, + cxx_epilogue, Cult::Containers::Vector, + fwd_epilogue, Cult::Containers::Vector, + epilogue, Cult::Containers::Vector, + hxx_prologue_file, NarrowString, + ixx_prologue_file, NarrowString, + cxx_prologue_file, NarrowString, + fwd_prologue_file, NarrowString, + prologue_file, NarrowString, + hxx_epilogue_file, NarrowString, + ixx_epilogue_file, NarrowString, + cxx_epilogue_file, NarrowString, + fwd_epilogue_file, NarrowString, + epilogue_file, NarrowString, + parts, UnsignedLong, + parts_suffix, NarrowString, + export_symbol, NarrowString, + export_xml_schema, Boolean, + export_maps, Boolean, + import_maps, Boolean, + show_anonymous, Boolean, + show_sloc, Boolean, + proprietary_license, Boolean, + disable_multi_import, Boolean + + > Options; + + struct OptionsSpec: Cult::CLI::OptionsSpec {}; + } + } +} + +#endif // CXX_TREE_CLI_HXX diff --git a/xsd/cxx/tree/counter.cxx b/xsd/cxx/tree/counter.cxx new file mode 100644 index 0000000..d8223bb --- /dev/null +++ b/xsd/cxx/tree/counter.cxx @@ -0,0 +1,265 @@ +// file : xsd/cxx/tree/counter.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include + +namespace CXX +{ + namespace Tree + { + namespace + { + struct Member: Traversal::Member + { + Member (UnsignedLong& complexity) + : complexity_ (complexity) + { + } + + virtual Void + traverse (Type&) + { + complexity_++; + } + + UnsignedLong& complexity_; + }; + + struct Any: Traversal::Any, Traversal::AnyAttribute + { + Any (UnsignedLong& complexity) + : complexity_ (complexity) + { + } + + virtual Void + traverse (SemanticGraph::Any&) + { + complexity_++; + } + + virtual Void + traverse (SemanticGraph::AnyAttribute&) + { + complexity_++; + } + + UnsignedLong& complexity_; + }; + + struct TypeBase: Traversal::List, + Traversal::Union, + Traversal::Enumeration, + Traversal::Complex, + Context + { + TypeBase (Context& c, UnsignedLong& complexity) + : Context (c), complexity_ (complexity) + { + } + + virtual Void + traverse (SemanticGraph::List&) + { + complexity_++; + } + + virtual Void + traverse (SemanticGraph::Union&) + { + complexity_++; + } + + virtual Void + traverse (SemanticGraph::Enumeration& e) + { + Boolean 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.value ()) + names >> any; + + Complex::names (c, names); + } + + private: + UnsignedLong& complexity_; + }; + + + // + // + struct GlobalType: Traversal::Type, Context + + { + GlobalType (Context& c, Counts& counts) + : Context (c), counts_ (counts) + { + } + + virtual Void + traverse (SemanticGraph::Type& t) + { + counts_.global_types++; + + UnsignedLong 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++; + + UnsignedLong complexity (0); + + if (doc_root_p (*last_)) + { + if (options.value ()) + { + complexity += 1; // For c-tors and d-tor. + + if (!options.value ()) + complexity += 1; + + if (options.value ()) + complexity += 1; + } + else + { + if (!options.value ()) + complexity += 6; // 13 parsing functions. + + if (options.value ()) + 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_; + }; + } + + Counter:: + Counter () + { + } + + Counts Counter:: + count (CLI::Options const& options, SemanticGraph::Schema& tu) + { + Counts counts; + Context ctx (std::wcerr, tu, options, counts, false, 0, 0, 0); + + Traversal::Schema schema; + Traversal::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; + } + } +} diff --git a/xsd/cxx/tree/counter.hxx b/xsd/cxx/tree/counter.hxx new file mode 100644 index 0000000..f4186ba --- /dev/null +++ b/xsd/cxx/tree/counter.hxx @@ -0,0 +1,28 @@ +// file : xsd/cxx/tree/counter.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_TREE_COUNTER_HXX +#define CXX_TREE_COUNTER_HXX + +#include +#include + +namespace CXX +{ + namespace Tree + { + class Counter + { + public: + Counter (); // Dummy ctor, helps with long symbols on HP-UX. + + Counts + count (CLI::Options const& options, + SemanticGraph::Schema&); + }; + } +} + +#endif // CXX_TREE_COUNTER_HXX diff --git a/xsd/cxx/tree/elements.cxx b/xsd/cxx/tree/elements.cxx new file mode 100644 index 0000000..5e85087 --- /dev/null +++ b/xsd/cxx/tree/elements.cxx @@ -0,0 +1,1327 @@ +// file : xsd/cxx/tree/elements.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace CXX +{ + namespace Tree + { + // Context + // + Void Context:: + update_ns_scope () // Keeping this function first helps HP-UX + { // (long symbols). + ns_scope.clear (); + + Boolean first (true); + + for (NamespaceStack::Iterator i (ns_scope_stack.begin ()); + i != ns_scope_stack.end (); + ++i) + { + // We only qualify names until the namespace level. + // + if (first) + first = false; + else + ns_scope += L"::"; + + ns_scope += *i; + } + } + + Context:: + Context (std::wostream& o, + SemanticGraph::Schema& root, + CLI::Options const& ops, + Counts const& counts_, + Boolean generate_xml_schema__, + Regex const* fe, + Regex const* he, + Regex const* ie) + : CXX::Context (o, + root, + ops.value (), + ops.value (), + ops.value (), + ops.value (), + ops.value (), + ops.value (), + ops.value (), + ops.value (), + ops.value (), + ops.value (), + ops.value ()), + options (ops), + counts (counts_), + any_type (any_type_), + any_simple_type (any_simple_type_), + element_type (element_type_), + container (container_), + flags_type (flags_type_), + qname_type (qname_type_), + xs_string_type (xs_string_type_), + properties_type (properties_type_), + error_handler_type (error_handler_type_), + list_stream_type (list_stream_type_), + namespace_infomap_type (namespace_infomap_type_), + parser_type (parser_type_), + std_ostream_type (std_ostream_type_), + ostream_type (ostream_type_), + istream_type (istream_type_), + xerces_ns (xerces_ns_), + dom_auto_ptr (dom_auto_ptr_), + dom_node_key (dom_node_key_), + as_double_type (as_double_type_), + as_decimal_type (as_decimal_type_), + generate_xml_schema (generate_xml_schema_), + doxygen (doxygen_), + polymorphic (ops.value ()), + fwd_expr (fe), + hxx_expr (he), + ixx_expr (ie), + ns_scope (ns_scope_), + regex_custom_type_map (regex_custom_type_map_), + direct_custom_type_map (direct_custom_type_map_), + qname_type_ (L"::xsd::cxx::xml::qualified_name< " + char_type + L" >"), + parser_type_ (L"::xsd::cxx::xml::dom::parser< " + char_type + L" >"), + generate_xml_schema_ (generate_xml_schema__), + doxygen_ (ops.value ()), + ns_scope_stack (ns_scope_stack_), + cxx_uq_id_expr_ (L"^[a-zA-Z_]\\w*$"), + cxx_uq_id_expr (cxx_uq_id_expr_) + { + SemanticGraph::Namespace& xs (xs_ns ()); + SemanticGraph::Context& xsc (xs.context ()); + + // Cache some often-used names from the XML Schema namespace + // if names have already been processed. + // + if (xsc.count ("container")) + { + String xs_name (ns_name (xs)); + + any_type = fq_name (xs.find ("anyType").first->named ()); + any_simple_type = fq_name (xs.find ("anySimpleType").first->named ()); + xs_string_type = fq_name (xs.find ("string").first->named ()); + + container = xs_name + L"::" + xsc.get ("container"); + flags_type = xs_name + L"::" + xsc.get ("flags"); + + if (ops.value ()) + element_type = xs_name + L"::" + xsc.get ("element-type"); + + properties_type = xs_name + L"::" + xsc.get ("properties"); + + if (!ops.value () || + ops.value ()) + { + error_handler_type = xs_name + L"::" + + xsc.get ("error-handler"); + } + + dom_auto_ptr_ = xs_name + L"::dom::auto_ptr"; + dom_node_key_ = xs_name + L"::dom::" + + xsc.get ("tree-node-key"); + + if (ops.value ()) + { + as_double_type_ = xs_name + L"::" + + xsc.get ("as-double"); + + as_decimal_type_ = xs_name + L"::" + + xsc.get ("as-decimal"); + + list_stream_type = xs_name + L"::" + + xsc.get ("list-stream"); + + namespace_infomap_type = xs_name + L"::" + + xsc.get ("namespace-infomap"); + } + + // istream and ostream are templates and for now use the same + // names regardless of the naming convention. + // + if (!ops.value ().empty ()) + istream_type = xs_name + L"::istream"; + + if (!ops.value ().empty ()) + ostream_type = xs_name + L"::ostream"; + } + + // Xerces-C++ namespace. IntelliSense for some reason does not like + // it fully-qualified (maybe because it's a namespace alias). + // + if (ops.value ()) + xerces_ns = "xercesc"; + else + xerces_ns = "::xercesc"; + + // + // + if (char_type == L"char") + std_ostream_type_ = L"::std::ostream"; + else if (char_type == L"wchar_t") + std_ostream_type_ = L"::std::wostream"; + else + std_ostream_type_ = L"::std::basic_ostream< " + char_type + L" >"; + + // Custom type mapping. + // + typedef Containers::Vector Vector; + + // Direct custom type mapping. + // + { + Vector const& v (ops.value ()); + + for (Vector::ConstIterator i (v.begin ()), e (v.end ()); i != e; ++i) + { + String s (*i); + + if (s.empty ()) + throw InvalidCustomTypeMapping (s, "mapping string is empty"); + + // Split the string in two parts at the last '='. + // + Size pos (s.rfind ('=')); + + // If no delimiter found then both type and base are empty. + // + if (pos == String::npos) + { + direct_custom_type_map[s].type.clear (); + direct_custom_type_map[s].base.clear (); + continue; + } + + String name (s, 0, pos); + String rest (s, pos + 1); + + // See if we've got the base part after '/'. + // + pos = rest.rfind ('/'); + + String type, base; + + if (pos != String::npos) + { + type.assign (rest, 0, pos); + base.assign (rest, pos + 1, String::npos); + } + else + type = rest; + + // type can be a potentially-qualified template-id. base is + // an unqualified C++ name. + // + + if (!base.empty () && !cxx_uq_id_expr.match (base)) + throw InvalidCustomTypeMapping (s, "invalid C++ identifier"); + + direct_custom_type_map[name].type = type; + direct_custom_type_map[name].base = base; + } + } + + // Regex custom type mapping. + // + { + Vector const& v (ops.value ()); + + for (Vector::ConstIterator i (v.begin ()), e (v.end ()); i != e; ++i) + { + String s (*i); + + if (s.empty ()) + throw InvalidCustomTypeMapping (s, "mapping string is empty"); + + WideChar delimiter (s[0]); + + // First get pattern. + // + Size pos (s.find (delimiter, 1)); + + if (pos == String::npos) + throw InvalidCustomTypeMapping ( + s, "missing pattern-substitution separator"); + + String pat (s, 1, pos - 1); + String rest (s, pos + 1); + + String type, base; + + // See if we've got type and base. + // + if (!rest.empty ()) + { + pos = rest.find (delimiter); + + if (pos == String::npos) + throw InvalidCustomTypeMapping ( + s, "missing pattern-substitution separator"); + + type.assign (rest, 0, pos); + rest = String (rest, pos + 1); + + if (!rest.empty ()) + { + pos = rest.find (delimiter); + + if (pos == String::npos) + throw InvalidCustomTypeMapping ( + s, "missing pattern-substitution separator"); + + base.assign (rest, 0, pos); + rest = String (rest, pos + 1); + + if (!rest.empty ()) + throw InvalidCustomTypeMapping (s, "invalid format"); + } + } + + regex_custom_type_map.push_back ( + RegexCustomTypeMapInfo (pat, type, base)); + } + } + } + + Context:: + Context (Context& c) + : CXX::Context (c), + options (c.options), + counts (c.counts), + any_type (c.any_type), + any_simple_type (c.any_simple_type), + element_type (c.element_type), + container (c.container), + flags_type (c.flags_type), + qname_type (c.qname_type), + xs_string_type (c.xs_string_type), + properties_type (c.properties_type), + error_handler_type (c.error_handler_type), + list_stream_type (c.list_stream_type), + namespace_infomap_type (c.namespace_infomap_type), + parser_type (c.parser_type), + std_ostream_type (c.std_ostream_type), + ostream_type (c.ostream_type), + istream_type (c.istream_type), + xerces_ns (c.xerces_ns), + dom_auto_ptr (c.dom_auto_ptr), + dom_node_key (c.dom_node_key), + as_double_type (c.as_double_type), + as_decimal_type (c.as_decimal_type), + generate_xml_schema (c.generate_xml_schema), + doxygen (c.doxygen), + polymorphic (c.polymorphic), + fwd_expr (c.fwd_expr), + hxx_expr (c.hxx_expr), + ixx_expr (c.ixx_expr), + ns_scope (c.ns_scope), + regex_custom_type_map (c.regex_custom_type_map), + direct_custom_type_map (c.direct_custom_type_map), + ns_scope_stack (c.ns_scope_stack), + cxx_uq_id_expr (c.cxx_uq_id_expr) + { + } + + Context:: + Context (Context& c, std::wostream& o) + : CXX::Context (c, o), + options (c.options), + counts (c.counts), + any_type (c.any_type), + any_simple_type (c.any_simple_type), + element_type (c.element_type), + container (c.container), + flags_type (c.flags_type), + qname_type (c.qname_type), + xs_string_type (c.xs_string_type), + properties_type (c.properties_type), + error_handler_type (c.error_handler_type), + list_stream_type (c.list_stream_type), + namespace_infomap_type (c.namespace_infomap_type), + parser_type (c.parser_type), + std_ostream_type (c.std_ostream_type), + ostream_type (c.ostream_type), + istream_type (c.istream_type), + xerces_ns (c.xerces_ns), + dom_auto_ptr (c.dom_auto_ptr), + dom_node_key (c.dom_node_key), + as_double_type (c.as_double_type), + as_decimal_type (c.as_decimal_type), + generate_xml_schema (c.generate_xml_schema), + doxygen (c.doxygen), + polymorphic (c.polymorphic), + fwd_expr (c.fwd_expr), + hxx_expr (c.hxx_expr), + ixx_expr (c.ixx_expr), + ns_scope (c.ns_scope), + regex_custom_type_map (c.regex_custom_type_map), + direct_custom_type_map (c.direct_custom_type_map), + ns_scope_stack (c.ns_scope_stack), + cxx_uq_id_expr (c.cxx_uq_id_expr) + { + } + + Boolean Context:: + custom_type (SemanticGraph::Type const& t, String& r) const + { + String const& name (t.name ()); + + // First search the direct mapping. + // + { + DirectCustomTypeMap::ConstIterator i ( + direct_custom_type_map.find (name)); + + if (i != direct_custom_type_map.end ()) + { + r = i->second.type; + return true; + } + } + + + // Second search the regex mapping. + // + for (RegexCustomTypeMap::ConstIterator + i (regex_custom_type_map.begin ()), + e (regex_custom_type_map.end ()); + i != e; ++i) + { + if (i->pat.match (name)) + { + // Empty type sub tells us to use the original name. + // + if (i->type_sub.empty ()) + { + r.clear (); + return true; + } + + r = i->pat.merge (name, i->type_sub); + return true; + } + } + + return false; + } + + String Context:: + custom_type (SemanticGraph::Type const& t) const + { + String r; + if (custom_type (t, r)) + { + // Empty type name tells us to use the original name. + // + if (r.empty ()) + r = ename (t); + } + + return r; + } + + Boolean Context:: + renamed_type (SemanticGraph::Type const& t, String& r) const + { + String const& name (t.name ()); + + // First search the direct mapping. + // + { + DirectCustomTypeMap::ConstIterator i ( + direct_custom_type_map.find (name)); + + if (i != direct_custom_type_map.end ()) + { + r = i->second.base; + return true; + } + } + + + // Second search the regex mapping. + // + for (RegexCustomTypeMap::ConstIterator + i (regex_custom_type_map.begin ()), + e (regex_custom_type_map.end ()); + i != e; ++i) + { + if (i->pat.match (name)) + { + if (!i->base_sub.empty ()) + { + r = i->pat.merge (name, i->base_sub); + } + else + r.clear (); + + return true; + } + } + + return false; + } + + Boolean Context:: + is_qname (SemanticGraph::Type& t) + { + using SemanticGraph::Complex; + using SemanticGraph::Fundamental::QName; + + if (t.is_a ()) + return true; + + if (Complex* c = dynamic_cast (&t)) + { + if (c->inherits_p () && ultimate_base (*c).is_a ()) + return true; + } + + return false; + } + + + Void Context:: + write_annotation (SemanticGraph::Annotation& a) + { + String const& doc (a.documentation ()); + WideChar const* s (doc.c_str ()); + Size size (doc.size ()); + + // Remove leading and trailing whitespaces. + // + while (*s == WideChar (0x20) || *s == WideChar (0x0A) || + *s == WideChar (0x0D) || *s == WideChar (0x09)) + { + s++; + size--; + } + + if (size != 0) + { + WideChar const* e (s + size - 1); + + while (e > s && + (*e == WideChar (0x20) || *e == WideChar (0x0A) || + *e == WideChar (0x0D) || *e == WideChar (0x09))) + --e; + + size = s <= e ? e - s + 1 : 0; + } + + if (size != 0) + { + os << " * "; + + // Go over the data, forcing newline after 80 chars and adding + // ' * ' after each new line. + // + WideChar const* last_space (0); + WideChar const* b (s); + WideChar const* e (s); + Boolean after_newline (false); + Boolean rogue (false); + + for (; e < s + size; ++e) + { + UnsignedLong u (unicode_char (e)); // May advance e. + + // We are going to treat \v and \f as rogue here even though + // they can be present in C++ source code. + // + if (u > 127 || (u < 32 && u != '\t' && u != '\n')) + rogue = true; + + if (u == ' ' || u == '\t') + { + if (after_newline) + { + if (e == b) + b++; // Skip leading spaces after newline. + + continue; + } + else + last_space = e; + } + else if (after_newline) + { + os << " * "; + after_newline = false; + } + + if (u == '\n') + { + write_rogue_text (b, e - b + 1, rogue); + + b = e + 1; + last_space = 0; + after_newline = true; + rogue = false; + continue; + } + + if (e - b >= 70 && last_space != 0) + { + write_rogue_text (b, last_space - b, rogue); + os << endl; + + b = last_space + 1; + last_space = 0; + after_newline = true; + // Cannot reset rogue since we don't output the whole string. + } + } + + if (e != b) + write_rogue_text (b, e - b, rogue); + + if (!after_newline) + os << endl; + } + } + + Void Context:: + write_rogue_text (WideChar const* s, Size size, Boolean rogue) + { + if (!rogue) + os.write (s, size); + else + { + for (WideChar const* p (s); p < s + size; ++p) + { + UnsignedLong u (unicode_char (p)); // May advance p. + + // We are going to treat \v and \f as rogue here even though + // they can be present in C++ source code. + // + if (u > 127 || (u < 32 && u != '\t' && u != '\n')) + os.put ('?'); + else + os.put (static_cast (u)); + } + } + } + + // GenerateDefautCtor + // + GenerateDefaultCtor:: + GenerateDefaultCtor (Context& c, Boolean& generate, Boolean no_base) + : Context (c), generate_ (generate), no_base_ (no_base) + { + *this >> inherits_ >> *this; + *this >> names_ >> *this; + } + + Void GenerateDefaultCtor:: + traverse (SemanticGraph::Complex& c) + { + // Make sure we figure out if we have any required members before + // we base our decision on the base type. + // + Complex::names (c, names_); + + if (!generate_) + Complex::inherits (c, inherits_); + } + + Void GenerateDefaultCtor:: + traverse (SemanticGraph::Type&) + { + if (!no_base_) + generate_ = true; + } + + Void GenerateDefaultCtor:: + traverse (SemanticGraph::Enumeration&) + { + if (!no_base_) + generate_ = true; + } + + Void GenerateDefaultCtor:: + traverse (SemanticGraph::Element& e) + { + if (!skip (e) && min (e) == 1 && max (e) == 1) + generate_ = true; + } + + Void GenerateDefaultCtor:: + traverse (SemanticGraph::Attribute& a) + { + if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ()))) + generate_ = true; + } + + Void GenerateDefaultCtor:: + traverse (SemanticGraph::Any& a) + { + if (options.value () && + min (a) == 1 && max (a) == 1) + generate_ = true; + } + + + // GenerateFromBaseCtor + // + GenerateFromBaseCtor:: + GenerateFromBaseCtor (Context& c, Boolean& generate) + : traverser_ (c, generate) + { + inherits_ >> traverser_; + } + + Void GenerateFromBaseCtor:: + traverse (SemanticGraph::Complex& c) + { + inherits (c, inherits_); + } + + GenerateFromBaseCtor::Traverser:: + Traverser (Context& c, Boolean& generate) + : Context (c), generate_ (generate) + { + *this >> inherits_ >> *this; + *this >> names_ >> *this; + } + + Void GenerateFromBaseCtor::Traverser:: + traverse (SemanticGraph::Complex& c) + { + names (c, names_); + + if (!generate_) + inherits (c, inherits_); + } + + Void GenerateFromBaseCtor::Traverser:: + traverse (SemanticGraph::Element& e) + { + if (!skip (e) && min (e) == 1 && max (e) == 1) + generate_ = true; + } + + Void GenerateFromBaseCtor::Traverser:: + traverse (SemanticGraph::Attribute& a) + { + if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ()))) + generate_ = true; + } + + Void GenerateFromBaseCtor::Traverser:: + traverse (SemanticGraph::Any& a) + { + if (options.value () && + min (a) == 1 && max (a) == 1) + generate_ = true; + } + + // HasComplexNonOptArgs + // + HasComplexNonFundNonOptArgs:: + HasComplexNonFundNonOptArgs (Context& c, + Boolean base, + Boolean& complex, + Boolean& non_fund, + Boolean& clash) + : Context (c), + complex_ (complex), + non_fund_ (non_fund), + clash_ (clash) + { + if (base) + *this >> inherits_ >> *this; + + *this >> names_ >> *this; + } + + Void HasComplexNonFundNonOptArgs:: + traverse (SemanticGraph::Complex& c) + { + // No optimizations: need to check every arg for clashes. + // + inherits (c, inherits_); + names (c, names_); + } + + Void HasComplexNonFundNonOptArgs:: + traverse (SemanticGraph::Element& e) + { + if (!skip (e) && min (e) == 1 && max (e) == 1) + { + Boolean fund (false); + IsFundamentalType t (fund); + t.dispatch (e.type ()); + + if (!fund) + { + non_fund_ = true; + + Boolean simple (true); + IsSimpleType t (simple); + t.dispatch (e.type ()); + + if (!simple) + complex_ = true; + else + clash_ = false; + } + } + } + + // FromBaseCtorArg + // + FromBaseCtorArg:: + FromBaseCtorArg (Context& c, ArgType at, Boolean arg) + : Context (c), arg_type_ (at), arg_ (arg) + { + } + + Void FromBaseCtorArg:: + traverse (SemanticGraph::Any& a) + { + if (!options.value ()) + return; + + if (min (a) == 1 && max (a) == 1) + { + String const& name (ename (a)); + + os << "," << endl + << "const " << xerces_ns << "::DOMElement&"; + + if (arg_) + os << " " << name; + } + } + + Void FromBaseCtorArg:: + traverse (SemanticGraph::Element& e) + { + if (skip (e)) + return; + + if (min (e) == 1 && max (e) == 1) + { + String const& name (ename (e)); + + os << "," << endl; + + Boolean auto_ptr (false); + + switch (arg_type_) + { + case arg_complex_auto_ptr: + { + Boolean simple (true); + IsSimpleType t (simple); + t.dispatch (e.type ()); + auto_ptr = !simple; + break; + } + case arg_non_fund_auto_ptr: + { + Boolean fund (false); + IsFundamentalType t (fund); + t.dispatch (e.type ()); + auto_ptr = !fund; + break; + } + case arg_type: + break; + } + + if (auto_ptr) + os << "::std::auto_ptr< " << etype (e) << " >&"; + else + os << "const " << etype (e) << "&"; + + if (arg_) + os << " " << name; + } + } + + Void FromBaseCtorArg:: + traverse (SemanticGraph::Attribute& a) + { + // Note that we are not going to include attributes with + // default or required fixed values here. Instead we are + // going to default-initialize them. + // + if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ()))) + { + String const& name (ename (a)); + + os << "," << endl + << "const " << etype (a) << "&"; + + if (arg_) + os << " " << name; + } + } + + // CtorArgs + // + CtorArgs:: + CtorArgs (Context& c, ArgType at) + : Context (c), + arg_type_ (at), + base_arg_ (0), + first_ (true), + member_name_ (c) + { + *this >> inherits_ >> *this; + *this >> names_ >> *this; + } + + CtorArgs:: + CtorArgs (Context& c, ArgType at, String& base_arg) + : Context (c), + arg_type_ (at), + base_arg_ (&base_arg), + first_ (true), + member_name_ (c) + { + *this >> inherits_ >> *this; + *this >> names_ >> *this; + } + + Void CtorArgs:: + traverse (SemanticGraph::Type& t) + { + os << comma () << "const "; + + member_name_.dispatch (t); + + os << "&"; + + if (base_arg_ != 0) + { + *base_arg_ = L"_xsd_" + ename (t) + L"_base"; + + os << " " << *base_arg_; + } + } + + Void CtorArgs:: + traverse (SemanticGraph::Enumeration& e) + { + os << comma () << "const "; + + member_name_.traverse (e); + + os << "&"; + + if (base_arg_ != 0) + { + *base_arg_ = L"_xsd_" + ename (e) + L"_base"; + + os << " " << *base_arg_; + } + } + + Void CtorArgs:: + traverse (SemanticGraph::Any& a) + { + if (!options.value ()) + return; + + if (min (a) == 1 && max (a) == 1) + { + os << comma () << "const " << xerces_ns << "::DOMElement&"; + + if (base_arg_ != 0) + os << " " << ename (a); + } + } + + Void CtorArgs:: + traverse (SemanticGraph::Element& e) + { + if (skip (e)) + return; + + if (min (e) == 1 && max (e) == 1) + { + Boolean auto_ptr (false); + + switch (arg_type_) + { + case arg_complex_auto_ptr: + { + Boolean simple (true); + IsSimpleType t (simple); + t.dispatch (e.type ()); + auto_ptr = !simple; + break; + } + case arg_non_fund_auto_ptr: + { + Boolean fund (false); + IsFundamentalType t (fund); + t.dispatch (e.type ()); + auto_ptr = !fund; + break; + } + case arg_type: + break; + } + + if (auto_ptr) + os << comma () << "::std::auto_ptr< " << etype (e) << " >&"; + else + os << comma () << "const " << etype (e) << "&"; + + if (base_arg_ != 0) + os << " " << ename (e); + } + } + + Void CtorArgs:: + traverse (SemanticGraph::Attribute& a) + { + // Note that we are not going to include attributes with + // default or required fixed values here. Instead we are + // going to default-initialize them. + // + if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ()))) + { + os << comma () << "const " << etype (a) << "&"; + + if (base_arg_ != 0) + os << " " << ename (a); + } + } + + String CtorArgs:: + comma () + { + Boolean tmp (first_); + first_ = false; + return tmp ? "" : ",\n"; + } + + + // CtorArgsWithoutBase + // + CtorArgsWithoutBase:: + CtorArgsWithoutBase (Context& c, ArgType at, Boolean arg, Boolean first) + : Context (c), arg_type_ (at), arg_ (arg), first_ (first) + { + *this >> inherits_ >> *this; + *this >> names_ >> *this; + } + + Void CtorArgsWithoutBase:: + traverse (SemanticGraph::Any& a) + { + if (!options.value ()) + return; + + if (min (a) == 1 && max (a) == 1) + { + os << comma () << "const " << xerces_ns << "::DOMElement&"; + + if (arg_) + os << " " << ename (a); + } + } + + Void CtorArgsWithoutBase:: + traverse (SemanticGraph::Element& e) + { + if (skip (e)) + return; + + if (min (e) == 1 && max (e) == 1) + { + Boolean auto_ptr (false); + + switch (arg_type_) + { + case arg_complex_auto_ptr: + { + Boolean simple (true); + IsSimpleType t (simple); + t.dispatch (e.type ()); + auto_ptr = !simple; + break; + } + case arg_non_fund_auto_ptr: + { + Boolean fund (false); + IsFundamentalType t (fund); + t.dispatch (e.type ()); + auto_ptr = !fund; + break; + } + case arg_type: + break; + } + + if (auto_ptr) + os << comma () << "::std::auto_ptr< " << etype (e) << " >&"; + else + os << comma () << "const " << etype (e) << "&"; + + if (arg_) + os << " " << ename (e); + } + } + + Void CtorArgsWithoutBase:: + traverse (SemanticGraph::Attribute& a) + { + // Note that we are not going to include attributes with + // default or required fixed values here. Instead we are + // going to default-initialize them. + // + if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ()))) + { + os << comma () << "const " << etype (a) << "&"; + + if (arg_) + os << " " << ename (a); + } + } + + String CtorArgsWithoutBase:: + comma () + { + Boolean tmp (first_); + first_ = false; + return tmp ? "" : ",\n"; + } + + // GlobalElementBase + // + Boolean GlobalElementBase:: + generate_p (SemanticGraph::Element& e) + { + if (e.substitutes_p () && ctx_.polymorphic) + return true; + + if (!doc_root_p (e)) + return false; + + // If we are not generating element types nor parsing/serialization + // code then we won't generate anything from it. + // + if (!ctx_.options.value () && + ctx_.options.value () && + !ctx_.options.value ()) + return false; + + return true; + } + + Boolean GlobalElementBase:: + doc_root_p (SemanticGraph::Element& e) + { + if (!ctx_.options.value () && + !ctx_.options.value () && + !ctx_.options.value () && + !ctx_.options.value () && + ctx_.options.value ().empty ()) + return true; // By default treat them all. + + if (ctx_.options.value ()) + return false; + + if (ctx_.options.value ()) + return true; + + if (ctx_.options.value () && + e.context ().count ("first") != 0) + return true; + + if (ctx_.options.value () && + e.context ().count ("last") != 0) + return true; + + typedef Cult::Containers::Vector Names; + Names const& names (ctx_.options.value ()); + + // Hopefully nobody will specify more than a handful of names ;-). + // + for (Names::ConstIterator i (names.begin ()); i != names.end (); ++i) + { + String name (*i); + + if (e.name () == name) + return true; + } + + return false; + } + + // Namespace + // + Namespace:: + Namespace (Context& c, + UnsignedLong first, + UnsignedLong last) + : CXX::Namespace (c, *this), + GlobalElementBase (c), + ctx_ (c), + first_ (first), + last_ (last), + count_ (0) + { + } + + Void Namespace:: + traverse (Type& ns) + { + using SemanticGraph::Element; + + if (first_ > last_) + CXX::Namespace::traverse (ns); + else + { + Boolean opened (false); + + for (Type::NamesIterator i (ns.names_begin ()); + i != ns.names_end (); ++i) + { + SemanticGraph::Nameable& n (i->named ()); + + if (n.is_a () || + (n.is_a () && generate_p (dynamic_cast (n)))) + { + if (count_ >= first_ && count_ <= last_) + { + if (!opened) + { + opened = true; + pre (ns); + } + + edge_traverser ().dispatch (*i); + } + + ++count_; + } + } + + if (opened) + post (ns); + } + } + + Void Namespace:: + enter (Type&, String const& name, Boolean) + { + ctx_.enter_ns_scope (name); + } + + Void Namespace:: + leave () + { + ctx_.leave_ns_scope (); + } + + // Includes + // + Void TypeForward:: + traverse (SemanticGraph::Type& t) + { + String const& name (ename (t)); + + if (String custom = custom_type (t)) + { + String new_name; + renamed_type (t, new_name); + + if (new_name) + os << "class " << new_name << ";"; + + if (custom == name) + os << "class " << name << ";"; + else + os << "typedef " << custom << " " << name << ";"; + } + else + os << "class " << name << ";"; + } + + Void Includes:: + traverse_ (SemanticGraph::Uses& u) + { + // Support for weak (forward) inclusion used in the file-per-type + // compilation model. + // + Type t (type_); + Boolean weak (u.context ().count ("weak")); + + if (weak && t == header) + { + // Generate forward declarations. + // + if (forward_) + t = forward; + else + { + schema_.dispatch (u.schema ()); + return; + } + } + + if (t == source && !weak) + return; + + SemanticGraph::Path path (u.path ()); + + // Try to use the portable representation of the path. If that + // fails, fall back to the native representation. + // + NarrowString path_str; + try + { + path_str = path.string (); + } + catch (SemanticGraph::InvalidPath const&) + { + path_str = path.native_file_string (); + } + + String inc_path; + + switch (t) + { + case forward: + { + inc_path = ctx_.fwd_expr->merge (path_str); + break; + } + case header: + case source: + { + inc_path = ctx_.hxx_expr->merge (path_str); + break; + } + case inline_: + { + if (weak) + { + inc_path = ctx_.hxx_expr->merge (path_str); + ctx_.os << "#include " << ctx_.process_include_path (inc_path) + << endl; + } + + inc_path = ctx_.ixx_expr->merge (path_str); + break; + } + } + + ctx_.os << "#include " << ctx_.process_include_path (inc_path) << endl + << endl; + } + } +} diff --git a/xsd/cxx/tree/elements.hxx b/xsd/cxx/tree/elements.hxx new file mode 100644 index 0000000..3d70aab --- /dev/null +++ b/xsd/cxx/tree/elements.hxx @@ -0,0 +1,2030 @@ +// file : xsd/cxx/tree/elements.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_TREE_ELEMENTS_HXX +#define CXX_TREE_ELEMENTS_HXX + +#include + +#include +#include +#include + +#include + +#include + +#include + + +namespace CXX +{ + namespace Tree + { + struct Counts + { + Counts () + : global_types (0), + global_elements (0), + generated_global_elements (0), + complexity_total (0) + { + } + + UnsignedLong global_types; + UnsignedLong global_elements; + UnsignedLong generated_global_elements; + + // Complexity value for each global type and generated global + // element, in order. + // + Cult::Containers::Vector complexity; + UnsignedLong complexity_total; + }; + + struct InvalidCustomTypeMapping + { + InvalidCustomTypeMapping (String const& mapping, + String const& reason) + : mapping_ (mapping), reason_ (reason) + { + } + + String const& + mapping () const + { + return mapping_; + } + + String const& + reason () const + { + return reason_; + } + + private: + String mapping_; + String reason_; + }; + + // + // + class Context: public CXX::Context + { + public: + typedef BackendElements::Regex::Expression Regex; + typedef BackendElements::Regex::Pattern WideRegexPat; + + struct DirectCustomTypeMapInfo + { + DirectCustomTypeMapInfo (String const& t = L"", + String const& b = L"") + : type (t), base (b) + { + } + + String type; + String base; + }; + + struct RegexCustomTypeMapInfo + { + RegexCustomTypeMapInfo (WideRegexPat const& p, + String const& t, + String const& b) + : pat (p), type_sub (t), base_sub (b) + { + } + + WideRegexPat pat; + String type_sub; + String base_sub; + }; + + typedef + Cult::Containers::Vector + RegexCustomTypeMap; + + typedef + Cult::Containers::Map + DirectCustomTypeMap; + + public: + Context (std::wostream& o, + SemanticGraph::Schema& root, + CLI::Options const& ops, + Counts const& counts_, + Boolean generate_xml_schema, + Regex const* fwd_expr, + Regex const* hxx_expr, + Regex const* ixx_expr); + + protected: + Context (Context& c); + Context (Context& c, std::wostream& o); + + // Custom type mapping. + // + public: + // Returns empty string if custom mapping is not required. + // + String + custom_type (SemanticGraph::Type const&) const; + + // Returns true if custom mapping is required. name is + // populated with the custom type name or empty if the + // original name should be used. + // + Boolean + custom_type (SemanticGraph::Type const&, String& name) const; + + // Returns true if this type has been renamed as part of the + // customization process. If the function returns true, the + // name string is populated with the new name or empty if + // the type should not be generated at all. + // + Boolean + renamed_type (SemanticGraph::Type const&, String& name) const; + + public: + // Return true if this type is-a QName. + // + Boolean + is_qname (SemanticGraph::Type&); + + public: + // Performs a number of processing steps, including forcing a new + // line after 80 characters as well as "commentizing" the text by + // adding '* ' after each newline. + // + Void + write_annotation (SemanticGraph::Annotation&); + + // Escaped names. + // + public: + // Accessor name. + // + static String const& + eaname (SemanticGraph::Member const& m) + { + return m.context ().get ("aname"); + } + + static String const& + eaname (SemanticGraph::Any const& a) + { + return a.context ().get ("aname"); + } + + static String const& + eaname (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("aname"); + } + + // Modifier name. + // + static String const& + emname (SemanticGraph::Member const& m) + { + return m.context ().get ("mname"); + } + + static String const& + emname (SemanticGraph::Any const& a) + { + return a.context ().get ("mname"); + } + + static String const& + emname (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("mname"); + } + + // + // + static String const& + etype (SemanticGraph::Member const& m) + { + return m.context ().get ("type"); + } + + static String const& + etraits (SemanticGraph::Member const& m) + { + return m.context ().get ("traits"); + } + + static String const& + econtainer (SemanticGraph::Member const& m) + { + return m.context ().get ("container"); + } + + static String const& + econtainer (SemanticGraph::Any const& a) + { + return a.context ().get ("container"); + } + + static String const& + econtainer (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("container"); + } + + static String const& + eiterator (SemanticGraph::Member const& m) + { + return m.context ().get ("iterator"); + } + + static String const& + eiterator (SemanticGraph::Any const& a) + { + return a.context ().get ("iterator"); + } + + static String const& + eiterator (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("iterator"); + } + + static String const& + econst_iterator (SemanticGraph::Member const& m) + { + return m.context ().get ("const-iterator"); + } + + static String const& + econst_iterator (SemanticGraph::Any const& a) + { + return a.context ().get ("const-iterator"); + } + + static String const& + econst_iterator (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("const-iterator"); + } + + static String const& + emember (SemanticGraph::Member const& m) + { + return m.context ().get ("member"); + } + + static String const& + emember (SemanticGraph::Any const& a) + { + return a.context ().get ("member"); + } + + static String const& + emember (SemanticGraph::AnyAttribute const& a) + { + return a.context ().get ("member"); + } + + static String const& + edefault_value (SemanticGraph::Member const& m) + { + return m.context ().get ("default-value"); + } + + static String const& + edefault_value_member (SemanticGraph::Member const& m) + { + return m.context ().get ("default-value-member"); + } + + // Underlying enum value type. + // + static String const& + evalue (SemanticGraph::Enumeration const& e) + { + return e.context ().get ("value"); + } + + // dom_document + // + static Boolean + edom_document_p (SemanticGraph::Complex const& c) + { + return c.context ().count ("dom-document"); + } + + static String const& + edom_document (SemanticGraph::Complex const& c) + { + return c.context ().get ("dom-document"); + } + + static Boolean + edom_document_member_p (SemanticGraph::Complex const& c) + { + return c.context ().count ("dom-document-member"); + } + + static String const& + edom_document_member (SemanticGraph::Complex const& c) + { + return c.context ().get ("dom-document-member"); + } + + // Parsing and serialization function names. + // + static String const& + eparser (SemanticGraph::Element const& e) + { + return e.context ().get ("parser"); + } + + static String const& + eserializer (SemanticGraph::Element const& e) + { + return e.context ().get ("serializer"); + } + + public: + Void + enter_ns_scope (String const& name) + { + ns_scope_stack.push_back (name); + update_ns_scope (); + } + + Void + leave_ns_scope () + { + ns_scope_stack.pop_back (); + update_ns_scope (); + } + + private: + Void + update_ns_scope (); + + private: + // Write text that may contain characters that we will have + // to escape (indicated by the rogue flag). + // + Void + write_rogue_text (WideChar const* s, Size size, Boolean rogue); + + public: + CLI::Options const& options; + Counts const& counts; + String& any_type; + String& any_simple_type; + String& element_type; + String& container; + String& flags_type; + String& qname_type; + String& xs_string_type; + String& properties_type; + String& error_handler_type; + String& list_stream_type; + String& namespace_infomap_type; + String& parser_type; + String& std_ostream_type; + String& ostream_type; + String& istream_type; + String& xerces_ns; + String& dom_auto_ptr; + String& dom_node_key; + String& as_double_type; + String& as_decimal_type; + + Boolean& generate_xml_schema; + Boolean& doxygen; + Boolean polymorphic; + + Regex const* fwd_expr; + Regex const* hxx_expr; + Regex const* ixx_expr; + + String& ns_scope; + + RegexCustomTypeMap& regex_custom_type_map; + DirectCustomTypeMap& direct_custom_type_map; + + private: + String any_type_; + String any_simple_type_; + String element_type_; + String container_; + String flags_type_; + String qname_type_; + String xs_string_type_; + String properties_type_; + String error_handler_type_; + String list_stream_type_; + String namespace_infomap_type_; + String parser_type_; + String std_ostream_type_; + String ostream_type_; + String istream_type_; + String xerces_ns_; + String dom_auto_ptr_; + String dom_node_key_; + String as_double_type_; + String as_decimal_type_; + + Boolean generate_xml_schema_; + Boolean doxygen_; + + typedef + Cult::Containers::Deque + NamespaceStack; + + typedef + Cult::Containers::Deque + ScopeStack; + + String ns_scope_; + + NamespaceStack& ns_scope_stack; + NamespaceStack ns_scope_stack_; + + RegexCustomTypeMap regex_custom_type_map_; + DirectCustomTypeMap direct_custom_type_map_; + + private: + WideRegexPat const cxx_uq_id_expr_; + WideRegexPat const& cxx_uq_id_expr; + }; + + // Check whether this Schema type maps to a fundamental C++ type. + // + struct IsFundamentalType : Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal + + { + IsFundamentalType (Boolean& r) + : r_ (r) + { + } + + // Integral types. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger&) + { + r_ = true; + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean&) + { + r_ = true; + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal&) + { + r_ = true; + } + + private: + Boolean& r_; + }; + + // Check whether this is a string-based type. + // + struct IsStringBasedType : Traversal::Complex, + Traversal::Union, + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language + { + IsStringBasedType (Boolean& r) + : r_ (r) + { + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c, inherits_); + } + + virtual Void + traverse (SemanticGraph::Union&) + { + // Current mapping of union is string-based. + // + r_ = true; + } + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Name&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NCName&) + { + r_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Language&) + { + r_ = true; + } + + private: + Boolean& r_; + Traversal::Inherits inherits_; + }; + + + // Check whether this is a enumeration-based type. + // + struct IsEnumBasedType : Traversal::Complex + { + IsEnumBasedType (SemanticGraph::Enumeration*& e) + : enum_ (e) + { + *this >> inherits_; + + inherits_ >> *this; + inherits_ >> enum_; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c, inherits_); + } + + private: + struct Enumeration: Traversal::Enumeration + { + Enumeration (SemanticGraph::Enumeration*& e) + : e_ (e) + { + } + + virtual Void + traverse (Type& e) + { + if (e_ == 0) + e_ = &e; + } + + private: + SemanticGraph::Enumeration*& e_; + }; + + + private: + Enumeration enum_; + Traversal::Inherits inherits_; + }; + + + // + // + struct MemberTypeName : protected Context, + Traversal::Type, + Traversal::List, + Traversal::Union, + Traversal::Complex, + + Traversal::AnyType, + Traversal::AnySimpleType, + + Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + + Traversal::Fundamental::QName, + + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::IdRefs, + + Traversal::Fundamental::AnyURI, + + Traversal::Fundamental::Base64Binary, + Traversal::Fundamental::HexBinary, + + Traversal::Fundamental::Date, + Traversal::Fundamental::DateTime, + Traversal::Fundamental::Duration, + Traversal::Fundamental::Day, + Traversal::Fundamental::Month, + Traversal::Fundamental::MonthDay, + Traversal::Fundamental::Year, + Traversal::Fundamental::YearMonth, + Traversal::Fundamental::Time, + + Traversal::Fundamental::Entity, + Traversal::Fundamental::Entities + + { + MemberTypeName (Context& c) + : Context (c) + { + } + + MemberTypeName (Context& c, std::wostream& o) + : Context (c, o) + { + } + + virtual Void + traverse (SemanticGraph::Type&) + { + abort (); + } + + virtual Void + traverse (SemanticGraph::List& l) + { + os << fq_name (l); + } + + virtual Void + traverse (SemanticGraph::Union& u) + { + os << fq_name (u); + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + os << fq_name (c); + } + + // anyType & anySimpleType. + // + virtual Void + traverse (SemanticGraph::AnyType& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::AnySimpleType& t) + { + os << fq_name (t); + } + + // Integral types. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger& t) + { + os << fq_name (t); + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean& t) + { + os << fq_name (t); + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal& t) + { + os << fq_name (t); + } + + // Strings. + // + virtual Void + traverse (SemanticGraph::Fundamental::String& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameTokens& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Name& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NCName& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Language& t) + { + os << fq_name (t); + } + + + // Qualified name. + // + virtual Void + traverse (SemanticGraph::Fundamental::QName& t) + { + os << fq_name (t); + } + + + // ID/IDREF. + // + virtual Void + traverse (SemanticGraph::Fundamental::Id& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRef& t) + { + if (t.named ()) + { + // IDREF + // + os << fq_name (t); + } + else + { + SemanticGraph::Nameable& ncname ( + xs_ns ().find ("NCName").first->named ()); + + os << "::xsd::cxx::tree::idref< " << + type_name (t.argumented ().type ()) << ", " << + char_type << ", " << fq_name (ncname) << " >"; + } + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs& t) + { + if (t.named ()) + { + // IDREFS + // + os << fq_name (t); + } + else + { + SemanticGraph::Nameable& ncname ( + xs_ns ().find ("NCName").first->named ()); + + os << "::xsd::cxx::tree::idrefs< " << char_type << ", " << + any_simple_type << ", ::xsd::cxx::tree::idref< " << + type_name (t.argumented ().type ()) << ", " << char_type << + ", " << fq_name (ncname) << " > >"; + } + } + + // URI. + // + virtual Void + traverse (SemanticGraph::Fundamental::AnyURI& t) + { + os << fq_name (t); + } + + // Binary. + // + virtual Void + traverse (SemanticGraph::Fundamental::Base64Binary& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::HexBinary& t) + { + os << fq_name (t); + } + + + // Date/time. + // + virtual Void + traverse (SemanticGraph::Fundamental::Date& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::DateTime& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Duration& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Day& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Month& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::MonthDay& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Year& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::YearMonth& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Time& t) + { + os << fq_name (t); + } + + // Entity. + // + virtual Void + traverse (SemanticGraph::Fundamental::Entity& t) + { + os << fq_name (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Entities& t) + { + os << fq_name (t); + } + + private: + // For idref/idrefs + // + String + type_name (SemanticGraph::Type& t) + { + // This type is always named. + // + std::wostringstream o; + + MemberTypeName type (*this, o); + type.dispatch (t); + + return o.str (); + } + }; + + + // + // + struct BaseTypeName : MemberTypeName + { + BaseTypeName (Context& c) + : MemberTypeName (c) + { + } + + BaseTypeName (Context& c, std::wostream& o) + : MemberTypeName (c, o) + { + } + + virtual Void + fundamental_base (SemanticGraph::Type& t) + { + os << "::xsd::cxx::tree::fundamental_base< " << + fq_name (t) << ", " << char_type << ", " << + any_simple_type << " >"; + } + + // Integrals. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger& t) + { + fundamental_base (t); + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean& t) + { + fundamental_base (t); + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float& t) + { + fundamental_base (t); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double& t) + { + os << "::xsd::cxx::tree::fundamental_base< " << + fq_name (t) << ", " << char_type << ", " << + any_simple_type << ", " << + "::xsd::cxx::tree::schema_type::double_ >"; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal& t) + { + os << "::xsd::cxx::tree::fundamental_base< " << + fq_name (t) << ", " << char_type << ", " << + any_simple_type << ", " << + "::xsd::cxx::tree::schema_type::decimal >"; + } + }; + + // Initial value should be true. + // + struct IsSimpleType : Traversal::Complex, + Traversal::Member, + Traversal::Any, + Traversal::AnyAttribute + { + IsSimpleType (Boolean& v) + : v_ (v) + { + *this >> names_ >> *this; + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + names (c, names_); + + if (v_) + inherits (c, inherits_); + } + + virtual Void + traverse (SemanticGraph::Member&) + { + v_ = false; + } + + virtual Void + traverse (SemanticGraph::Any&) + { + v_ = false; + } + + virtual Void + traverse (SemanticGraph::AnyAttribute&) + { + v_ = false; + } + + private: + Boolean& v_; + Traversal::Names names_; + Traversal::Inherits inherits_; + }; + + // Test whether we need to generate default c-tor. Note that we are not + // interested in anyAttribute since it is always mapped to a sequence. + // + struct GenerateDefaultCtor: Traversal::Complex, + Traversal::Enumeration, + Traversal::Type, + Traversal::Element, + Traversal::Attribute, + Traversal::Any, + protected virtual Context + { + // generate should initially be false. + // + GenerateDefaultCtor (Context&, Boolean& generate, Boolean no_base); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Type&); + + virtual Void + traverse (SemanticGraph::Enumeration&); + + virtual Void + traverse (SemanticGraph::Element&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Any&); + + private: + Boolean& generate_; + Boolean no_base_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + }; + + // Test whether we need to generate from-base c-tor. + // + struct GenerateFromBaseCtor: Traversal::Complex + { + // generate should initially be false. + // + GenerateFromBaseCtor (Context& c, Boolean& generate); + + virtual Void + traverse (SemanticGraph::Complex& c); + + private: + // Note that we are not interested in anyAttribute since it is always + // mapped to a sequence. + // + struct Traverser: Traversal::Complex, + Traversal::Element, + Traversal::Attribute, + Traversal::Any, + protected virtual Context + { + Traverser (Context& c, Boolean& generate); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Element&); + + virtual Void + traverse (SemanticGraph::Any&); + + private: + Boolean& generate_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + } traverser_; + + Traversal::Inherits inherits_; + }; + + // Test whether the type has any non-optional element of complex + // (has attributes/elements) and non-fundamental types. + // + struct HasComplexNonFundNonOptArgs: Traversal::Complex, + Traversal::Element, + protected virtual Context + { + // complex and non_fund should initially be false. clash + // should initially be true. + // + HasComplexNonFundNonOptArgs (Context& c, + Boolean including_base, + Boolean& complex, + Boolean& non_fund, + Boolean& clash); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Element&); + + private: + Boolean& complex_; + Boolean& non_fund_; + Boolean& clash_; + + Traversal::Inherits inherits_; + Traversal::Names names_; + }; + + // Immediate non-optional member. Note that AnyAttribute is always + // mapped to a sequence. + // + struct FromBaseCtorArg : Traversal::Any, + Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + enum ArgType + { + arg_type, + arg_complex_auto_ptr, + arg_non_fund_auto_ptr + }; + + FromBaseCtorArg (Context& c, ArgType, Boolean arg); + + virtual Void + traverse (SemanticGraph::Any&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Element&); + + private: + ArgType arg_type_; + Boolean arg_; + }; + + // List of all non-optional members and a simple base. Note that + // AnyAttribute is always mapped to a sequence. + // + struct CtorArgs : Traversal::Complex, + Traversal::Enumeration, + Traversal::Type, + Traversal::Any, + Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + enum ArgType + { + arg_type, + arg_complex_auto_ptr, + arg_non_fund_auto_ptr + }; + + // The second version outputs the argument name and stores + // in in the base_arg string. + // + CtorArgs (Context&, ArgType); + CtorArgs (Context&, ArgType, String& base_arg); + + virtual Void + traverse (SemanticGraph::Type&); + + virtual Void + traverse (SemanticGraph::Enumeration&); + + virtual Void + traverse (SemanticGraph::Any&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + virtual Void + traverse (SemanticGraph::Element&); + + private: + String + comma (); + + private: + ArgType arg_type_; + String base_; + String* base_arg_; + Boolean first_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + + MemberTypeName member_name_; + }; + + + // Check whether we need to generate c-tor without the base argument. + // + struct GenerateWithoutBaseCtor: Traversal::List, + Traversal::Union, + Traversal::Complex, + Traversal::Enumeration, + + Traversal::AnyType, + Traversal::AnySimpleType, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::IdRefs, + + Traversal::Fundamental::Base64Binary, + Traversal::Fundamental::HexBinary + { + // generate should initially be false. + // + GenerateWithoutBaseCtor (Boolean& generate) + : generate_ (generate) + { + *this >> inherits_ >> *this; + } + + virtual Void + traverse (SemanticGraph::List&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Union&) + { + // No default initialization. + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + Complex::inherits (c); + } + + virtual Void + traverse (SemanticGraph::Enumeration&) + { + // No default initialization. + } + + virtual Void + traverse (SemanticGraph::AnyType&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::AnySimpleType&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::String&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameTokens&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Base64Binary&) + { + generate_ = true; + } + + virtual Void + traverse (SemanticGraph::Fundamental::HexBinary&) + { + generate_ = true; + } + + private: + Boolean& generate_; + Traversal::Inherits inherits_; + }; + + + // List of all non-optional members sans simple base. Note that + // AnyAttribute is always mapped to a sequence. + // + struct CtorArgsWithoutBase: Traversal::Complex, + Traversal::Any, + Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + enum ArgType + { + arg_type, + arg_complex_auto_ptr, + arg_non_fund_auto_ptr + }; + + CtorArgsWithoutBase (Context& c, ArgType, Boolean arg, Boolean first); + + virtual Void + traverse (SemanticGraph::Any&); + + virtual Void + traverse (SemanticGraph::Element&); + + virtual Void + traverse (SemanticGraph::Attribute&); + + private: + String + comma (); + + private: + ArgType arg_type_; + Boolean arg_; + Boolean first_; + + private: + Traversal::Inherits inherits_; + Traversal::Names names_; + }; + + // + // + struct GlobalElementBase + { + GlobalElementBase (Context& c) + : ctx_ (c) + { + } + + Boolean + generate_p (SemanticGraph::Element&); + + Boolean + doc_root_p (SemanticGraph::Element&); + + private: + Context& ctx_; + }; + + + // + // + struct Namespace: CXX::Namespace, + GlobalElementBase, + CXX::Namespace::ScopeTracker + { + Namespace (Context&, + UnsignedLong first = 1, + UnsignedLong last = 0); + + virtual Void + traverse (Type&); + + protected: + virtual Void + enter (Type&, String const& name, Boolean last); + + virtual Void + leave (); + + protected: + Context& ctx_; + + private: + UnsignedLong first_; + UnsignedLong last_; + UnsignedLong count_; + }; + + // + // + struct DocumentedNamespace: Namespace + { + DocumentedNamespace (Context& c) + : Namespace (c) + { + } + + virtual Void + enter (Type& ns, String const& name, Boolean last) + { + Namespace::enter (ns, name, last); + + // Only add documentation to the innermost namespace. + // + if (ctx_.doxygen && name && last) + { + ctx_.os << "/**" << endl + << " * @brief C++ namespace for the %" << + ctx_.comment (ns.name ()) << endl + << " * schema namespace." << endl + << " */" << endl; + } + } + }; + + // + // + struct TypeForward: Traversal::Type, Context + { + TypeForward (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Type& t); + }; + + struct Includes : Traversal::Imports, + Traversal::Includes + { + enum Type + { + forward, + header, + inline_, + source + }; + + Includes (Context& c, Type type) + : ctx_ (c), + type_ (type), + forward_ (c.options.value ()), + namespace_ (c), + type_forward_ (c) + { + schema_ >> schema_names_ >> namespace_ >> names_ >> type_forward_; + } + + virtual Void + traverse (SemanticGraph::Imports& i) + { + traverse_ (i); + } + + virtual Void + traverse (SemanticGraph::Includes& i) + { + traverse_ (i); + } + + private: + Void + traverse_ (SemanticGraph::Uses&); + + private: + Context& ctx_; + Type type_; + Boolean forward_; + + Traversal::Schema schema_; + Traversal::Names schema_names_; + Namespace namespace_; + Traversal::Names names_; + TypeForward type_forward_; + }; + + // + // + struct FundIncludes : Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal, + Context + + { + FundIncludes (Context& c, String const& prefix) + : Context (c), prefix_ (prefix), + long_ (false), unsigned_long_ (false) + { + } + + // Integral types. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte& t) + { + gen_include (t, "byte.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte& t) + { + gen_include (t, "unsigned-byte.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short& t) + { + gen_include (t, "short.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort& t) + { + gen_include (t, "unsigned-short.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int& t) + { + gen_include (t, "int.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt& t) + { + gen_include (t, "unsigned-int.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedLong& t) + { + if (!unsigned_long_) + unsigned_long_ = gen_include (t, "unsigned-long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Integer& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonPositiveInteger& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NonNegativeInteger& t) + { + if (!unsigned_long_) + unsigned_long_ = gen_include (t, "unsigned-long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::PositiveInteger& t) + { + if (!unsigned_long_) + unsigned_long_ = gen_include (t, "unsigned-long.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NegativeInteger& t) + { + if (!long_) + long_ = gen_include (t, "long.hxx"); + } + + // Boolean. + // + virtual Void + traverse (SemanticGraph::Fundamental::Boolean& t) + { + gen_include (t, "boolean.hxx"); + } + + // Floats. + // + virtual Void + traverse (SemanticGraph::Fundamental::Float& t) + { + gen_include (t, "float.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Double& t) + { + gen_include (t, "double.hxx"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Decimal& t) + { + gen_include (t, "decimal.hxx"); + } + + private: + Boolean + gen_include (SemanticGraph::Type& t, String const& file) + { + String custom; + + // XML Schema built-in type customization is only possible when + // we are generating separate header. + // + if (generate_xml_schema && custom_type (t, custom)) + { + String new_name; + renamed_type (t, new_name); + + if (!new_name) + return false; + } + + os << "#include " + << endl; + + return true; + } + + private: + String prefix_; + Boolean long_; + Boolean unsigned_long_; + }; + } +} + +#endif // CXX_TREE_ELEMENTS_HXX diff --git a/xsd/cxx/tree/fundamental-header.hxx b/xsd/cxx/tree/fundamental-header.hxx new file mode 100644 index 0000000..5ea3596 --- /dev/null +++ b/xsd/cxx/tree/fundamental-header.hxx @@ -0,0 +1,1186 @@ +// file : xsd/cxx/tree/fundamental-header.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CXX_TREE_FUNDAMENTAL_HEADER_HXX +#define CXX_TREE_FUNDAMENTAL_HEADER_HXX + +#include +#include + +#include + +namespace CXX +{ + namespace Tree + { + struct FundamentalNamespace : DocumentedNamespace, + + Traversal::AnyType, + Traversal::AnySimpleType, + + Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::IdRefs, + + Traversal::Fundamental::AnyURI, + + Traversal::Fundamental::QName, + + Traversal::Fundamental::Base64Binary, + Traversal::Fundamental::HexBinary, + + Traversal::Fundamental::Date, + Traversal::Fundamental::DateTime, + Traversal::Fundamental::Duration, + Traversal::Fundamental::Day, + Traversal::Fundamental::Month, + Traversal::Fundamental::MonthDay, + Traversal::Fundamental::Year, + Traversal::Fundamental::YearMonth, + Traversal::Fundamental::Time, + + Traversal::Fundamental::Entity, + Traversal::Fundamental::Entities, + protected virtual Context + { + FundamentalNamespace (Context& c) + : Context (c), + DocumentedNamespace (c), + export_ (c.options.value () && type_exp) + { + *this >> names_ >> *this; + } + + Void + gen_typedef (String const& type, String const& name) + { + os << "typedef " << type << " " << name << ";"; + + if (export_ && type.find (L'<') != String::npos) + os << "template class " << type_exp << type << ";"; + } + + String + built_in_type (SemanticGraph::Type& t, String const& type) + { + String custom; + + String name (ename (t)); + + // XML Schema built-in type customization is only possible when + // we are generating separate header. + // + if (generate_xml_schema && custom_type (t, custom)) + { + if (custom.empty ()) + custom = name; + + String new_name; + renamed_type (t, new_name); + + if (new_name) + { + gen_typedef (type, new_name); + + if (doxygen) + os << endl; + } + + if (doxygen) + os << "/**" << endl + << " * @brief C++ type corresponding to the " << + comment (t.name ()) << " XML Schema" << endl + << " * built-in type." << endl + << " */" << endl; + + if (custom == name) + os << "class " << name << ";"; + else + os << "typedef " << custom << " " << name << ";"; + + if (doxygen) + os << endl; + } + else + { + // Otherwise generate simple typedef. + // + + if (doxygen) + os << "/**" << endl + << " * @brief C++ type corresponding to the " << + comment (t.name ()) << " XML Schema" << endl + << " * built-in type." << endl + << " */" << endl; + + gen_typedef (type, name); + + if (doxygen) + os << endl; + } + + return name; + } + + // anyType and anySimpleType + // + virtual Void + traverse (SemanticGraph::AnyType& t) + { + os << "// anyType and anySimpleType." << endl + << "//" << endl; + + if (doxygen) + os << endl; + + type_ = built_in_type (t, "::xsd::cxx::tree::type"); + } + + virtual Void + traverse (SemanticGraph::AnySimpleType& t) + { + simple_type_ = built_in_type ( + t, L"::xsd::cxx::tree::simple_type< " + type_ + L" >"); + + if (doxygen) + os << "/**" << endl + << " * @brief Alias for the anyType type." << endl + << " */" << endl; + + gen_typedef ("::xsd::cxx::tree::type", + xs_ns ().context().get ("container")); + + os << endl; + + if (doxygen) + os << endl; + } + + // Integrals. + // + virtual Void + traverse (SemanticGraph::Fundamental::Byte& t) + { + os << "// 8-bit" << endl + << "//" << endl; + + if (doxygen) + os << endl; + + built_in_type (t, "signed char"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedByte& t) + { + built_in_type (t, "unsigned char"); + os << endl; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Short& t) + { + os << "// 16-bit" << endl + << "//" << endl; + + if (doxygen) + os << endl; + + built_in_type (t, "short"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedShort& t) + { + built_in_type (t, "unsigned short"); + os << endl; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Int& t) + { + os << "// 32-bit" << endl + << "//" << endl; + + if (doxygen) + os << endl; + + built_in_type (t, "int"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::UnsignedInt& t) + { + built_in_type (t, "unsigned int"); + os << endl; + } + + virtual Void + traverse (SemanticGraph::Fundamental::Long& t) + { + os << "// 64-bit" << endl + << "//" <"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NormalizedString& t) + { + norm_string_ = built_in_type ( + t, + L"::xsd::cxx::tree::normalized_string< " + char_type + + L", " + string_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Token& t) + { + token_ = built_in_type ( + t, + L"::xsd::cxx::tree::token< " + char_type + L", " + + norm_string_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameToken& t) + { + nmtoken_ = built_in_type ( + t, + L"::xsd::cxx::tree::nmtoken< " + char_type + L", " + + token_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NameTokens& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::nmtokens< " + char_type + + L", " + simple_type_ + L", " + nmtoken_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Name& t) + { + name_ = built_in_type ( + t, + L"::xsd::cxx::tree::name< " + char_type + L", " + token_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::NCName& t) + { + ncname_ = built_in_type ( + t, + L"::xsd::cxx::tree::ncname< " + char_type + L", " + name_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Language& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::language< " + char_type + L", " + + token_ + L" >"); + + os << endl; + } + + // ID/IDREF. + // + virtual Void + traverse (SemanticGraph::Fundamental::Id& t) + { + os << "// ID/IDREF." << endl + << "//" << endl; + + if (doxygen) + os << endl; + + built_in_type ( + t, + L"::xsd::cxx::tree::id< " + char_type + L", " + ncname_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRef& t) + { + idref_ = built_in_type ( + t, + L"::xsd::cxx::tree::idref< " + type_ + L", " + char_type + L", " + + ncname_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::idrefs< " + char_type + + L", " + simple_type_ + L", " + idref_ + L" >"); + + os << endl; + } + + + // URI. + // + virtual Void + traverse (SemanticGraph::Fundamental::AnyURI& t) + { + os << "// URI." << endl + << "//" << endl; + + if (doxygen) + os << endl; + + uri_ = built_in_type ( + t, + L"::xsd::cxx::tree::uri< " + char_type + L", " + + simple_type_ + L" >"); + + os << endl; + } + + // Qualified name. + // + virtual Void + traverse (SemanticGraph::Fundamental::QName& t) + { + os << "// Qualified name." << endl + << "//" << endl; + + if (doxygen) + os << endl; + + built_in_type ( + t, + L"::xsd::cxx::tree::qname< " + char_type + + L", " + simple_type_ + L", " + uri_ + L", " + ncname_ + L" >"); + + os << endl; + } + + // Binary. + // + virtual Void + traverse (SemanticGraph::Fundamental::Base64Binary& t) + { + os << "// Binary." << endl + << "//" << endl; + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Binary buffer type." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::buffer< " + char_type + L" >", + xs_ns ().context().get ("buffer")); + + if (doxygen) + os << endl; + + built_in_type ( + t, + L"::xsd::cxx::tree::base64_binary< " + char_type + + L", " + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::HexBinary& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::hex_binary< " + char_type + + L", " + simple_type_ + L" >"); + + os << endl; + } + + + // Date/time. + // + virtual Void + traverse (SemanticGraph::Fundamental::Date& t) + { + os << "// Date/time." << endl + << "//" << endl; + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Time zone type." << endl + << " */" << endl; + + gen_typedef ("::xsd::cxx::tree::time_zone", + xs_ns ().context().get ("time-zone")); + + if (doxygen) + os << endl; + + built_in_type ( + t, + L"::xsd::cxx::tree::date< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::DateTime& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::date_time< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Duration& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::duration< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Day& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::gday< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Month& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::gmonth< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::MonthDay& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::gmonth_day< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Year& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::gyear< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::YearMonth& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::gyear_month< " + char_type + L", " + + simple_type_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Time& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::time< " + char_type + L", " + + simple_type_ + L" >"); + + os << endl; + } + + // Entity. + // + virtual Void + traverse (SemanticGraph::Fundamental::Entity& t) + { + os << "// Entity." << endl + << "//" << endl; + + if (doxygen) + os << endl; + + entity_ = built_in_type ( + t, + L"::xsd::cxx::tree::entity< " + char_type + L", " + + ncname_ + L" >"); + } + + virtual Void + traverse (SemanticGraph::Fundamental::Entities& t) + { + built_in_type ( + t, + L"::xsd::cxx::tree::entities< " + char_type + + L", " + simple_type_ + L", " + entity_ + L" >"); + + os << endl; + } + + virtual Void + post (SemanticGraph::Namespace& n) + { + SemanticGraph::Context& c (xs_ns ().context()); + + Boolean parsing (!options.value ()); + Boolean serialization (options.value ()); + Boolean element_map (options.value ()); + + if (options.value ()) + { + if (doxygen) + os << "/**" << endl + << " * @brief Base class for element types." << endl + << " */" << endl; + else + os << "// Base class for element types." << endl + << "//" << endl; + + gen_typedef (L"::xsd::cxx::tree::element_type < " + + char_type + L", " + type_ + L" >", + c.get ("element-type")); + os << endl; + } + + if (element_map) + { + if (doxygen) + os << "/**" << endl + << " * @brief Root element map." << endl + << " */" << endl; + else + os << "// Root element map." << endl + << "//" << endl; + + gen_typedef (L"::xsd::cxx::tree::element_map < " + + char_type + L", " + type_ + L" >", + c.get ("element-map")); + os << endl; + } + + if (serialization) + { + os << "// Namespace information and list stream. Used in" << endl + << "// serialization functions." << endl + << "//" << endl; + + if (doxygen) + os << "/**" << endl + << " * @brief Namespace serialization information." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::xml::dom::namespace_info < " + char_type + L" >", + c.get ("namespace-info")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Namespace serialization information map." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::xml::dom::namespace_infomap < " + + char_type + L" >", + c.get ("namespace-infomap")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief List serialization stream." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::list_stream < " + char_type + L" >", + c.get ("list-stream")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Serialization wrapper for the %double type." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::as_double < " + double_ + L" >", + c.get ("as-double")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Serialization wrapper for the %decimal type." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::as_decimal < " + decimal_ + L" >", + c.get ("as-decimal")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Simple type facet." << endl + << " */" << endl; + + gen_typedef ("::xsd::cxx::tree::facet", c.get ("facet")); + + os << endl; + } + + //@@ Can't change names of ostream/istream since they are + // templates. + // + if (!options.value ().empty ()) + { + if (doxygen) + os << "/**" << endl + << " * @brief Data representation output stream template." << endl + << " */" << endl; + else + os << "// Data representation output stream template." << endl + << "//" << endl; + + os << "using ::xsd::cxx::tree::ostream;" + << endl; + } + + if (!options.value ().empty ()) + { + if (doxygen) + os << "/**" << endl + << " * @brief Data representation input stream template." << endl + << " */" << endl; + else + os << "// Data representation input stream template." << endl + << "//" << endl; + + os << "using ::xsd::cxx::tree::istream;" + << endl; + } + + os << "// Flags and properties." << endl + << "//" << endl; + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Parsing and serialization flags." << endl + << " */" << endl; + + gen_typedef ("::xsd::cxx::tree::flags", c.get ("flags")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Parsing properties." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::properties< " + char_type + L" >", + c.get ("properties")); + os << endl; + + + // + // + os << "// Exceptions." << endl + << "//" << endl; + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Root of the C++/Tree %exception hierarchy." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::exception< " + char_type + L" >", + c.get ("exception")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that the size argument exceeds" << + endl + << " * the capacity argument." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::bounds< " + char_type + L" >", + c.get ("bounds")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that a duplicate ID value" << + endl + << " * was encountered in the object model." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::duplicate_id< " + char_type + L" >", + c.get ("duplicate-id")); + + if (parsing) + { + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating a parsing failure." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::parsing< " + char_type + L" >", + c.get ("parsing")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that an expected element" << + endl + << " * was not encountered." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::expected_element< " + char_type + L" >", + c.get ("expected-element")); + } + + if (parsing || serialization) + { + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that an unexpected " << + "element" << endl + << " * was encountered." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::unexpected_element< " + char_type + L" >", + c.get ("unexpected-element")); + } + + if (parsing) + { + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that an expected " << + "attribute" << endl + << " * was not encountered." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::expected_attribute< " + char_type + L" >", + c.get ("expected-attribute")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that an unexpected " << + "enumerator" << endl + << " * was encountered." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::unexpected_enumerator< " + char_type + L" >", + c.get ("unexpected-enumerator")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that the text content " << + "was" << endl + << " * expected for an element." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::expected_text_content< " + char_type + L" >", + c.get ("expected-text-content")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that a prefix-namespace" << + endl + << " * mapping was not provided." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::no_prefix_mapping< " + char_type + L" >", + c.get ("no-prefix-mapping")); + } + + if (options.value ()) + { + if (parsing || serialization) + { + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that the type " << + "information" << endl + << " * is not available for a type." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::no_type_info< " + char_type + L" >", + c.get ("no-type-info")); + } + + if (parsing) + { + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that the types are not" << + endl + << " * related by inheritance." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::not_derived< " + char_type + L" >", + c.get ("not-derived")); + } + } + + if (element_map) + { + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating that parsing or " << + "serialization" << endl + << " * information is not available for an element." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::no_element_info< " + char_type + L" >", + c.get ("no-element-info")); + } + + if (serialization) + { + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Exception indicating a serialization " << + "failure." << endl + << " */" << endl; + + gen_typedef ( + L"::xsd::cxx::tree::serialization< " + char_type + L" >", + c.get ("serialization")); + } + + os << endl; + + // + // + if (parsing || serialization) + { + os << "// Parsing/serialization diagnostics." << endl + << "//" << endl; + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Error severity." << endl + << " */" << endl; + + gen_typedef ("::xsd::cxx::tree::severity", + c.get ("severity")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief Error condition." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::error< " + char_type + L" >", + c.get ("error")); + + if (doxygen) + os << endl + << "/**" << endl + << " * @brief List of %error conditions." << endl + << " */" << endl; + + gen_typedef (L"::xsd::cxx::tree::diagnostics< " + char_type + L" >", + c.get ("diagnostics")); + os << endl; + } + + if (parsing || serialization) + { + if (doxygen) + os << "/**" << endl + << " * @brief Error handler callback interface." << endl + << " */" << endl; + else + os << "// Error handler callback interface." << endl + << "//" << endl; + + gen_typedef ( + L"::xsd::cxx::xml::error_handler< " + char_type + L" >", + c.get ("error-handler")); + + os << endl; + } + + if (parsing || serialization) + { + if (doxygen) + os << "/**" << endl + << " * @brief DOM interaction." << endl + << " */" << endl; + else + os << "// DOM interaction." << endl + << "//" << endl; + + os << "namespace dom" + << "{"; + + // @@ Disregarding current naming convention by using the + // fixed name (no template typedef). + // + if (doxygen) + os << "/**" << endl + << " * @brief Automatic pointer for DOMDocument." << endl + << " */" << endl; + else + os << "// Automatic pointer for DOMDocument." << endl + << "//" << endl; + + os << "using ::xsd::cxx::xml::dom::auto_ptr;" + << endl; + + if (parsing) + { + if (!generate_xml_schema) + { + String g (L"XSD_CXX_TREE_TREE_NODE_KEY" + ns_name (n)); + + std::transform (g.begin (), g.end(), g.begin (), upcase); + g = escape (g); // Make it a C++ id. + + os << "#ifndef " << g << endl + << "#define " << g << endl; + } + + if (doxygen) + os << "/**" << endl + << " * @brief DOM user data key for back pointers to " << + "tree nodes." << endl + << " */" << endl; + else + os << "// DOM user data key for back pointers to tree nodes." << endl + << "//" << endl; + + os << "const XMLCh* const " << c.get ("tree-node-key") << + " = ::xsd::cxx::tree::user_data_keys::node;"; + + if (!generate_xml_schema) + os << "#endif" << endl; + } + + os << "}"; // namespace dom + } + + if (element_map) + { + if (doxygen) + os << "//@cond" << endl + << endl; + + if (!generate_xml_schema) + { + String g (L"XSD_CXX_TREE_ELEMENT_MAP_INIT" + ns_name (n)); + + std::transform (g.begin (), g.end(), g.begin (), upcase); + g = escape (g); // Make it a C++ id. + + os << "#ifndef " << g << endl + << "#define " << g << endl; + } + + os << "static" << endl + << "const ::xsd::cxx::tree::element_map_init < " << + char_type << ", " << type_ << " >" << endl + << "_xsd_element_map_init;"; + + if (!generate_xml_schema) + os << "#endif" << endl; + + if (doxygen) + os << endl + << "//@endcond" << endl; + } + + Namespace::post (n); + } + + private: + Boolean export_; + + Traversal::Names names_; + + String type_; + String simple_type_; + String string_; + String norm_string_; + String token_; + String nmtoken_; + String name_; + String ncname_; + String idref_; + String uri_; + String entity_; + + String double_; + String decimal_; + }; + } +} + +#endif // CXX_TREE_FUNDAMENTAL_HEADER_HXX diff --git a/xsd/cxx/tree/generator.cxx b/xsd/cxx/tree/generator.cxx new file mode 100644 index 0000000..f9b055e --- /dev/null +++ b/xsd/cxx/tree/generator.cxx @@ -0,0 +1,1689 @@ +// file : xsd/cxx/tree/generator.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include "../../../libxsd/xsd/cxx/version.hxx" + +using std::endl; +using std::wcerr; + +using namespace XSDFrontend::SemanticGraph; + +// +// +typedef +boost::filesystem::wifstream +WideInputFileStream; + +typedef +boost::filesystem::wofstream +WideOutputFileStream; + +namespace CXX +{ + namespace + { + Char const copyright_gpl[] = + "// Copyright (C) 2005-2009 Code Synthesis Tools CC\n" + "//\n" + "// This program was generated by CodeSynthesis XSD, an XML Schema to\n" + "// C++ data binding compiler.\n" + "//\n" + "// This program is free software; you can redistribute it and/or modify\n" + "// it under the terms of the GNU General Public License version 2 as\n" + "// published by the Free Software Foundation.\n" + "//\n" + "// This program is distributed in the hope that it will be useful,\n" + "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "// GNU General Public License for more details.\n" + "//\n" + "// You should have received a copy of the GNU General Public License\n" + "// along with this program; if not, write to the Free Software\n" + "// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" + "//\n" + "// In addition, as a special exception, Code Synthesis Tools CC gives\n" + "// permission to link this program with the Xerces-C++ library (or with\n" + "// modified versions of Xerces-C++ that use the same license as Xerces-C++),\n" + "// and distribute linked combinations including the two. You must obey\n" + "// the GNU General Public License version 2 in all respects for all of\n" + "// the code used other than Xerces-C++. If you modify this copy of the\n" + "// program, you may extend this exception to your version of the program,\n" + "// but you are not obligated to do so. If you do not wish to do so, delete\n" + "// this exception statement from your version.\n" + "//\n" + "// Furthermore, Code Synthesis Tools CC makes a special exception for\n" + "// the Free/Libre and Open Source Software (FLOSS) which is described\n" + "// in the accompanying FLOSSE file.\n" + "//\n\n"; + + Char const copyright_proprietary[] = + "// Copyright (C) 2005-2009 Code Synthesis Tools CC\n" + "//\n" + "// This program was generated by CodeSynthesis XSD, an XML Schema\n" + "// to C++ data binding compiler, in the Proprietary License mode.\n" + "// You should have received a proprietary license from Code Synthesis\n" + "// Tools CC prior to generating this code. See the license text for\n" + "// conditions.\n" + "//\n\n"; + } + + namespace Tree + { + namespace CLI + { + extern Key char_type = "char-type"; + extern Key output_dir = "output-dir"; + extern Key generate_polymorphic = "generate-polymorphic"; + extern Key generate_serialization = "generate-serialization"; + extern Key generate_inline = "generate-inline"; + extern Key generate_ostream = "generate-ostream"; + extern Key generate_doxygen = "generate-doxygen"; + extern Key generate_comparison = "generate-comparison"; + extern Key generate_default_ctor = "generate-default-ctor"; + extern Key generate_from_base_ctor = "generate-from-base-ctor"; + extern Key generate_wildcard = "generate-wildcard"; + extern Key generate_insertion = "generate-insertion"; + extern Key generate_extraction = "generate-extraction"; + extern Key generate_forward = "generate-forward"; + extern Key generate_xml_schema = "generate-xml-schema"; + extern Key extern_xml_schema = "extern-xml-schema"; + extern Key suppress_parsing = "suppress-parsing"; + extern Key generate_element_type = "generate-element-type"; + extern Key generate_element_map = "generate-element-map"; + extern Key generate_intellisense = "generate-intellisense"; + extern Key omit_default_attributes = "omit-default-attributes"; + extern Key namespace_map = "namespace-map"; + extern Key namespace_regex = "namespace-regex"; + extern Key namespace_regex_trace = "namespace-regex-trace"; + extern Key reserved_name = "reserved-name"; + extern Key type_naming = "type-naming"; + extern Key function_naming = "function-naming"; + extern Key type_regex = "type-regex"; + extern Key accessor_regex = "accessor-regex"; + extern Key one_accessor_regex = "one-accessor-regex"; + extern Key opt_accessor_regex = "opt-accessor-regex"; + extern Key seq_accessor_regex = "seq-accessor-regex"; + extern Key modifier_regex = "modifier-regex"; + extern Key one_modifier_regex = "one-modifier-regex"; + extern Key opt_modifier_regex = "opt-modifier-regex"; + extern Key seq_modifier_regex = "seq-modifier-regex"; + extern Key parser_regex = "parser-regex"; + extern Key serializer_regex = "serializer-regex"; + extern Key enumerator_regex = "enumerator-regex"; + extern Key element_type_regex = "element-type-regex"; + extern Key name_regex_trace = "name-regex-trace"; + extern Key include_with_brackets = "include-with-brackets"; + extern Key include_prefix = "include-prefix"; + extern Key include_regex = "include-regex"; + extern Key include_regex_trace = "include-regex-trace"; + extern Key guard_prefix = "guard-prefix"; + extern Key root_element_first = "root-element-first"; + extern Key root_element_last = "root-element-last"; + extern Key root_element_all = "root-element-all"; + extern Key root_element_none = "root-element-none"; + extern Key root_element = "root-element"; + extern Key custom_type = "custom-type"; + extern Key custom_type_regex = "custom-type-regex"; + extern Key hxx_suffix = "hxx-suffix"; + extern Key ixx_suffix = "ixx-suffix"; + extern Key cxx_suffix = "cxx-suffix"; + extern Key fwd_suffix = "fwd-suffix"; + extern Key hxx_regex = "hxx-regex"; + extern Key ixx_regex = "ixx-regex"; + extern Key cxx_regex = "cxx-regex"; + extern Key fwd_regex = "fwd-regex"; + extern Key hxx_prologue = "hxx-prologue"; + extern Key ixx_prologue = "ixx-prologue"; + extern Key cxx_prologue = "cxx-prologue"; + extern Key fwd_prologue = "fwd-prologue"; + extern Key prologue = "prologue"; + extern Key hxx_epilogue = "hxx-epilogue"; + extern Key ixx_epilogue = "ixx-epilogue"; + extern Key cxx_epilogue = "cxx-epilogue"; + extern Key fwd_epilogue = "fwd-epilogue"; + extern Key epilogue = "epilogue"; + extern Key hxx_prologue_file = "hxx-prologue-file"; + extern Key ixx_prologue_file = "ixx-prologue-file"; + extern Key cxx_prologue_file = "cxx-prologue-file"; + extern Key fwd_prologue_file = "fwd-prologue-file"; + extern Key prologue_file = "prologue-file"; + extern Key hxx_epilogue_file = "hxx-epilogue-file"; + extern Key ixx_epilogue_file = "ixx-epilogue-file"; + extern Key cxx_epilogue_file = "cxx-epilogue-file"; + extern Key fwd_epilogue_file = "fwd-epilogue-file"; + extern Key epilogue_file = "epilogue-file"; + extern Key parts = "parts"; + extern Key parts_suffix = "parts-suffix"; + extern Key export_symbol = "export-symbol"; + extern Key export_xml_schema = "export-xml-schema"; + extern Key export_maps = "export-maps"; + extern Key import_maps = "import-maps"; + extern Key show_anonymous = "show-anonymous"; + extern Key show_sloc = "show-sloc"; + extern Key proprietary_license = "proprietary-license"; + extern Key disable_multi_import = "disable-multi-import"; + } + } + + Void Tree::Generator:: + usage () + { + std::wostream& e (wcerr); + ::CLI::Indent::Clip< ::CLI::OptionsUsage, WideChar> clip (e); + + e << "--char-type " << endl + << " Use as the base character type. Valid\n" + << " values are 'char' (default) and 'wchar_t'." + << endl; + + e << "--output-dir " << endl + << " Write generated files to instead of current\n" + << " directory." + << endl; + + + e << "--generate-polymorphic" << endl + << " Generate polymorphism-aware code. Specify this\n" + << " option if you use substitution groups or xsi:type." + << endl; + + e << "--generate-serialization" << endl + << " Generate serialization functions. They convert an\n" + << " in-memory representation back to XML." + << endl; + + e << "--generate-inline" << endl + << " Generate certain functions inline." + << endl; + + e << "--generate-ostream" << endl + << " Generate ostream insertion operators." + << endl; + + e << "--generate-doxygen" << endl + << " Generate documentation comments in the Doxygen\n" + << " format." + << endl; + + e << "--generate-comparison" << endl + << " Generate comparison operators." + << endl; + + e << "--generate-default-ctor" << endl + << " Generate default constructors even for types that\n" + << " have required members." + << endl; + + e << "--generate-from-base-ctor" << endl + << " Generate from-base constructors." + << endl; + + e << "--generate-wildcard" << endl + << " Generate accessors/modifiers as well as parsing\n" + << " and serialization code for XML Schema wildcards." + << endl; + + e << "--generate-insertion " << endl + << " Generate data representation stream insertion\n" + << " operators for the output stream type." + << endl; + + e << "--generate-extraction " << endl + << " Generate data representation stream extraction\n" + << " constructors for the input stream type." + << endl; + + e << "--generate-forward" << endl + << " Generate forward declaration file." + << endl; + + e << "--generate-xml-schema" << endl + << " Generate a C++ header file as if the schema being\n" + << " compiled defines the XML Schema namespace." + << endl; + + e << "--extern-xml-schema " << endl + << " Generate code as if the XML Schema namespace was\n" + << " defined in and xsd:included in the schema\n" + << " being compiled." + << endl; + + e << "--suppress-parsing" << endl + << " Suppress the generation of parsing functions." + << endl; + + e << "--generate-element-type" << endl + << " Generate types instead of parsing/serialization\n" + << " functions for root elements." + << endl; + + e << "--generate-element-map" << endl + << " Generate a root element map that allows uniform\n" + << " parsing/serialization of multiple root elements.\n" + << endl; + + e << "--generate-intellisense" << endl + << " Generate workarounds for IntelliSense bugs in\n" + << " Visual Studio 2005 (8.0)." + << endl; + + e << "--omit-default-attributes" << endl + << " Omit attributes with default and fixed values\n" + << " from serialized XML documents." + << endl; + + e << "--namespace-map =" << endl + << " Map XML Schema namespace to C++ namespace\n" + << " . Repeat this option to specify mapping for\n" + << " more than one XML Schema namespace." + << endl; + + e << "--namespace-regex " << endl + << " Add to the list of regular expressions\n" + << " used to translate XML Schema namespace names to\n" + << " C++ namespace names." + << endl; + + e << "--namespace-regex-trace" << endl + << " Trace the process of applying regular expressions\n" + << " specified with the --namespace-regex option." + << endl; + + e << "--reserved-name " << endl + << " Add to the list of names that should not\n" + << " be used as identifiers. The name can optionally\n" + << " be followed by '=' and the replacement name that\n" + << " should be used instead." + << endl; + + e << "--type-naming