From e07d203edb2d0c16d68ce79fbbd9416fd05769a4 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 16:23:00 +0200 Subject: [PATCH 01/20] Use ACE XML_Utils CDR header and remove unused helper --- XSC/Parser.cpp | 2 +- XSC/be/CXX/Header.cpp | 2 +- XSC/utils/XML_Helper.h | 90 ------------ XSC/utils/XML_Helper_T.cpp | 243 -------------------------------- XSC/utils/XML_Schema_Resolver.h | 1 - XSC/utils/XSC_Utils.mpc | 1 - XSCRT/XMLSchema/CDR_Types.hpp | 75 ---------- 7 files changed, 2 insertions(+), 412 deletions(-) delete mode 100644 XSC/utils/XML_Helper.h delete mode 100644 XSC/utils/XML_Helper_T.cpp delete mode 100644 XSCRT/XMLSchema/CDR_Types.hpp diff --git a/XSC/Parser.cpp b/XSC/Parser.cpp index b495361..77a85fa 100644 --- a/XSC/Parser.cpp +++ b/XSC/Parser.cpp @@ -8,8 +8,8 @@ #include "xercesc/util/XMLString.hpp" #include "xercesc/validators/common/Grammar.hpp" #include "xercesc/validators/schema/XSDDOMParser.hpp" +#include "utils/XML_Error_Handler.h" #include "utils/XML_Schema_Resolver.h" -#include "utils/XML_Helper.h" #include // std::wcstombs #include diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 856abeb..e22d71e 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -950,7 +950,7 @@ generate_header (Context& ctx, if (ctx.cdr_reader_generation_enabled () || ctx.cdr_writer_generation_enabled ()) { - ctx.os << "#include \"XMLSchema/CDR_Types.hpp\"" << std::endl + ctx.os << "#include \"ace/XML_Utils/XMLSchema/CDR_Types.hpp\"" << std::endl << "#include \"XMLSchema/id_map.hpp\"" << std::endl << std::endl; if (ctx.cppmode() == Context::CPPMODE::CPP03) diff --git a/XSC/utils/XML_Helper.h b/XSC/utils/XML_Helper.h deleted file mode 100644 index 3b1c571..0000000 --- a/XSC/utils/XML_Helper.h +++ /dev/null @@ -1,90 +0,0 @@ -//============================================================ -/** - * @file XML_Helper.h - * - * @brief Some helper functions for XML - * - * @author Bala Natarajan - * @author William R. Otte - */ -//============================================================ -#ifndef CIAO_XML_HELPER_H -#define CIAO_XML_HELPER_H - -#include "XML_Error_Handler.h" -#include "XML_Schema_Resolver.h" - -#include - -#include "xercesc/util/XercesDefs.hpp" -#include "xercesc/parsers/XercesDOMParser.hpp" - -namespace XSC -{ - namespace XML - { - /** - * @class XML_Helper - * - * @brief Helper class for some routine XML stuff. - */ - template , - typename Error_Handler = XML_Error_Handler> - class XML_Helper - { - public: - // XML_Helper (); - - // Initialize the resolver we should use. - XML_Helper (Resolver &resolver, Error_Handler &eh); - - ~XML_Helper (); - - /// Create a DOM tree - xercesc::DOMDocument * - create_dom (const char *uri) const; - - xercesc::DOMDocument * - create_dom (const char *root, - const char *ns, - xercesc::DOMDocumentType * doctype = nullptr) const; - - xercesc::DOMDocumentType * - create_doctype (const char *qn, - const char *pid, - const char *sid) const; - - //Writes out a DOMDocument to an XML file - bool write_DOM (xercesc::DOMDocument *doc, - const char *file) const; - - bool is_initialized () const; - - protected: - /// Intialize the parser - void init_parser (); - - /// Terminate the parser - void terminate_parser (); - - private: - XML_Helper (XML_Helper const&) = delete; - XML_Helper& operator= (XML_Helper const&) = delete; - XML_Helper (XML_Helper&&) = delete; - XML_Helper& operator= (XML_Helper&&) = delete; - - bool initialized_ {}; - xercesc::DOMImplementation *impl_ {}; - mutable std::unique_ptr parser_; - - Resolver &resolver_; - Error_Handler &e_handler_; - }; - - - } -} - -#include "XML_Helper_T.cpp" - -#endif/*CIAO_CONFIG_HANDLERS_XML_HELPER_H*/ diff --git a/XSC/utils/XML_Helper_T.cpp b/XSC/utils/XML_Helper_T.cpp deleted file mode 100644 index ec4b0d6..0000000 --- a/XSC/utils/XML_Helper_T.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "XML_Helper.h" -#include "XML_Error_Handler.h" -#include "XML_Schema_Resolver.h" -#include "XercesString.h" -#include "xercesc/dom/DOM.hpp" -#include "xercesc/util/XMLUniDefs.hpp" - -namespace XSC -{ - namespace XML - { - using xercesc::XMLException; - using xercesc::XMLString; - using xercesc::DOMImplementation; - using xercesc::DOMImplementationRegistry; -// using xercesc::DOMBuilder; - using xercesc::DOMDocument; - using xercesc::DOMException; - using xercesc::DOMDocumentType; -/* - template - XML_Helper::XML_Helper () - { - this->init_parser (); - } -*/ - // TODO this is stub implementation - template - XML_Helper::XML_Helper (Resolver &resolver, Error &eh) - : resolver_ (resolver), - e_handler_ (eh) - { - this->init_parser (); - } - - template - XML_Helper::~XML_Helper () - { - this->terminate_parser (); - } - - template - bool - XML_Helper::is_initialized () const - { - return this->initialized_ == true; - } - - template - void - XML_Helper::init_parser () - { - if (this->initialized_) - return; - - /*ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Initializing the Xerces runtime \n"));*/ - // Initialize the Xerces run-time - try - { - xercesc::XMLPlatformUtils::Initialize(); - } - catch (const XMLException& e) - { - char* message = - XMLString::transcode (e.getMessage()); - // ACE_Auto_Basic_Array_Ptr cleanup_message (message); - XMLString::release (std::addressof (message)); - - throw; - } - catch (...) - { - /*ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Some other exception," - " returning\n"));*/ - - return; - } - - // Instantiate the DOM parser. - static const XMLCh gLS[] = { xercesc::chLatin_L, - xercesc::chLatin_S, - xercesc::chNull }; - - // Get an implementation of the Load-Store (LS) interface - // and cache it for later use - impl_ = - DOMImplementationRegistry::getDOMImplementation(gLS); - - this->initialized_ = true; - return; - } - - template - xercesc::DOMDocument * - XML_Helper::create_dom (const char *root, - const char *ns, - DOMDocumentType *doctype) const - { - if (root == nullptr || ns == nullptr) - return nullptr; - - return this->impl_->createDocument (XStr (ns), - XStr (root), - doctype); - } - - template - xercesc::DOMDocumentType * - XML_Helper::create_doctype (const char *qn, - const char *pid, - const char *sid) const - { - return this->impl_->createDocumentType (XStr (qn), - XStr (pid), - XStr (sid)); - } - template - xercesc::DOMDocument * - XML_Helper::create_dom (const char *url) const - { - - if (url == nullptr) - return nullptr; - - try - { - if (this->parser_.get () == nullptr) - this->parser_ = std::make_unique (); - - // Perform Namespace processing. - this->parser_->setDoNamespaces (true); - - // Discard comment nodes in the document - this->parser_->setCreateCommentNodes (false); - - // Disable datatype normalization. The XML 1.0 attribute value - // normalization always occurs though. - // this->parser_->setFeature (XMLUni::fgDOMDatatypeNormalization, true); - - // Do not create EntityReference nodes in the DOM tree. No - // EntityReference nodes will be created, only the nodes - // corresponding to their fully expanded sustitution text will be - // created. - this->parser_->setCreateEntityReferenceNodes (false); - - // Perform Validation - this->parser_->setValidationScheme (xercesc::AbstractDOMParser::Val_Always); - - // Do not include ignorable whitespace in the DOM tree. - this->parser_->setIncludeIgnorableWhitespace (false); - - // Enable the parser's schema support. - this->parser_->setDoSchema (true); - - // Enable full schema constraint checking, including checking which - // may be time-consuming or memory intensive. Currently, particle - // unique attribution constraint checking and particle derivation - // restriction checking are controlled by this option. - this->parser_->setValidationSchemaFullChecking (true); - - // The parser will treat validation error as fatal and will exit. - this->parser_->setValidationConstraintFatal (true); - - this->parser_->setErrorHandler (std::addressof (e_handler_)); - - this->parser_->setEntityResolver (std::addressof (resolver_)); - - this->parser_->parse (url); - - if (e_handler_.getErrors ()) - return nullptr; - - return this->parser_->adoptDocument (); - } - catch (const DOMException& e) - { - const unsigned int maxChars = 2047; - XMLCh errText[maxChars + 1]; - - if (DOMImplementation::loadDOMExceptionMsg (e.code, - errText, - maxChars)) - { - char* message = - XMLString::transcode (errText); -// ACE_Auto_Basic_Array_Ptr cleanup_message (message); - XMLString::release (std::addressof (message)); - } - return nullptr; - - } - catch (const XMLException& e) - { - char* message = XMLString::transcode (e.getMessage()); - // ACE_Auto_Basic_Array_Ptr cleanup_message (message); - XMLString::release (std::addressof (message)); - throw; - } - catch (...) - { - /*ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Caught an unknown exception \n"));*/ - throw; - } - - return nullptr; - } - - template - void - XML_Helper::terminate_parser () - { - try - { - xercesc::XMLPlatformUtils::Terminate(); - } - catch (const XMLException& e) - { - char* message = - XMLString::transcode (e.getMessage()); - //ACE_Auto_Basic_Array_Ptr cleanup_message (message); - XMLString::release (std::addressof (message)); - - throw; - } - - this->initialized_ = false; - return; - } - - template - bool - XML_Helper::write_DOM (xercesc::DOMDocument *doc, - const char *file) const - { - (void) doc; - (void) file; - return false; - } - } -} diff --git a/XSC/utils/XML_Schema_Resolver.h b/XSC/utils/XML_Schema_Resolver.h index 775d2aa..8e76200 100644 --- a/XSC/utils/XML_Schema_Resolver.h +++ b/XSC/utils/XML_Schema_Resolver.h @@ -10,7 +10,6 @@ #include "XSC_Utils_export.h" #include "XercesString.h" -#include "XML_Error_Handler.h" #include "xercesc/sax/EntityResolver.hpp" #include "ace/ace_wchar.h" #include diff --git a/XSC/utils/XSC_Utils.mpc b/XSC/utils/XSC_Utils.mpc index d854131..d52bae9 100644 --- a/XSC/utils/XSC_Utils.mpc +++ b/XSC/utils/XSC_Utils.mpc @@ -8,7 +8,6 @@ project (XSC_Utils) : acelib, xsc_common { } Template_Files { - XML_Helper_T.cpp XML_Schema_Resolver.cpp } } diff --git a/XSCRT/XMLSchema/CDR_Types.hpp b/XSCRT/XMLSchema/CDR_Types.hpp deleted file mode 100644 index f35bac1..0000000 --- a/XSCRT/XMLSchema/CDR_Types.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// file : XMLSchema/CDR_Types.hpp -// author : Arvind S. Krishna - -#ifndef XMLSCHEMA_CDR_TYPES_HPP -#define XMLSCHEMA_CDR_TYPES_HPP - -//-- ACE includes -#include "ace/CDR_Stream.h" - -/* - * Following typedefs define generic Stream interfaces - * for (de) marshaling XML types generated by XSC. - * We leverage the ACE_CDRInput and ACE_CDROutput - * stream classes that provides reusable classes for - * encoding data using the Common Data Representation - * encoding format. - * - * A corresponding traits class for argument passing - * is also provided for enabling a clean CORBA like - * semantics for passing arguments. - * - * Different encoding schemes such as - * XDR encoding schemes should define similar types. - */ - -namespace XMLSchema -{ - // CDR Reader/Writer Stream Type - typedef ACE_OutputCDR CDR_OutputStream; - typedef ACE_InputCDR CDR_InputStream; - - // An argument traits class that defines - // parameter passing in a CORBA like syntax - // NOTE: Mainly in place for reference types. - // Need to specialize for pointer types - template - struct cdr_arg_traits - { - typedef T const & in_type; - typedef T & out_type; - typedef T ret_type; - typedef T *& inout_type; - }; -} - -template -bool -operator << (::XMLSchema::CDR_OutputStream &stream, - const ::XMLSchema::string < T > &element) -{ - // For strings types, conver to the c style string - // representations that can be marshaled - return (stream << element.c_str ()); -} - -template -bool -operator << (::XMLSchema::CDR_OutputStream &stream, - const ::XMLSchema::IDREF < T > &element) -{ - // Marshal the ID stored in the IDREF - // id () operations returns a NCName which - // itself is a string - return (stream << element.id ().c_str ()); -} - -template -void -operator << (::XMLSchema::CDR_OutputStream &stream, - const ::XMLSchema::ID &element) -{ - stream << element.c_str (); -} - -#endif //XMLSCHEMA_CDR_TYPES_HPP From 6cba27c657697581eab305b442fc48a64a1b7441 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 16:24:28 +0200 Subject: [PATCH 02/20] Remove duplicated local XSCRT runtime --- XSCRT/XMLSchema/Traversal.hpp | 75 --- XSCRT/XMLSchema/Traversal.tpp | 10 - XSCRT/XMLSchema/TypeInfo.hpp | 20 - XSCRT/XMLSchema/TypeInfo.tpp | 100 ---- XSCRT/XMLSchema/Types.hpp | 629 --------------------- XSCRT/XMLSchema/Types.tpp | 8 - XSCRT/XMLSchema/Writer.hpp | 94 --- XSCRT/XMLSchema/Writer.tpp | 9 - XSCRT/XMLSchema/id_map.hpp | 163 ------ XSCRT/XSCRT/Elements.hpp | 438 -------------- XSCRT/XSCRT/Elements.tpp | 6 - XSCRT/XSCRT/ExtendedTypeInfo.hpp | 180 ------ XSCRT/XSCRT/ExtendedTypeInfo.ipp | 129 ----- XSCRT/XSCRT/Parser.hpp | 70 --- XSCRT/XSCRT/Parser.tpp | 6 - XSCRT/XSCRT/Traversal.hpp | 273 --------- XSCRT/XSCRT/Traversal.tpp | 194 ------- XSCRT/XSCRT/Writer.hpp | 79 --- XSCRT/XSCRT/Writer.tpp | 6 - XSCRT/XSCRT/XML.hpp | 468 --------------- XSCRT/XSCRT/XML.tpp | 6 - XSCRT/XSCRT/XSCRT.mpc | 34 -- XSCRT/XSCRT/XSCRT_export.h | 38 -- XSCRT/XSCRT/utils/Buffer_Reader_T.cpp | 50 -- XSCRT/XSCRT/utils/Buffer_Reader_T.h | 68 --- XSCRT/XSCRT/utils/Buffer_Writer_T.cpp | 71 --- XSCRT/XSCRT/utils/Buffer_Writer_T.h | 73 --- XSCRT/XSCRT/utils/File_Reader_T.cpp | 38 -- XSCRT/XSCRT/utils/File_Reader_T.h | 61 -- XSCRT/XSCRT/utils/File_Writer_T.cpp | 45 -- XSCRT/XSCRT/utils/File_Writer_T.h | 50 -- XSCRT/XSCRT/utils/Reader_T.cpp | 44 -- XSCRT/XSCRT/utils/Reader_T.h | 87 --- XSCRT/XSCRT/utils/Reader_Writer_Base_T.cpp | 44 -- XSCRT/XSCRT/utils/Reader_Writer_Base_T.h | 56 -- XSCRT/XSCRT/utils/Writer_T.cpp | 58 -- XSCRT/XSCRT/utils/Writer_T.h | 70 --- 37 files changed, 3850 deletions(-) delete mode 100644 XSCRT/XMLSchema/Traversal.hpp delete mode 100644 XSCRT/XMLSchema/Traversal.tpp delete mode 100644 XSCRT/XMLSchema/TypeInfo.hpp delete mode 100644 XSCRT/XMLSchema/TypeInfo.tpp delete mode 100644 XSCRT/XMLSchema/Types.hpp delete mode 100644 XSCRT/XMLSchema/Types.tpp delete mode 100644 XSCRT/XMLSchema/Writer.hpp delete mode 100644 XSCRT/XMLSchema/Writer.tpp delete mode 100644 XSCRT/XMLSchema/id_map.hpp delete mode 100644 XSCRT/XSCRT/Elements.hpp delete mode 100644 XSCRT/XSCRT/Elements.tpp delete mode 100644 XSCRT/XSCRT/ExtendedTypeInfo.hpp delete mode 100644 XSCRT/XSCRT/ExtendedTypeInfo.ipp delete mode 100644 XSCRT/XSCRT/Parser.hpp delete mode 100644 XSCRT/XSCRT/Parser.tpp delete mode 100644 XSCRT/XSCRT/Traversal.hpp delete mode 100644 XSCRT/XSCRT/Traversal.tpp delete mode 100644 XSCRT/XSCRT/Writer.hpp delete mode 100644 XSCRT/XSCRT/Writer.tpp delete mode 100644 XSCRT/XSCRT/XML.hpp delete mode 100644 XSCRT/XSCRT/XML.tpp delete mode 100644 XSCRT/XSCRT/XSCRT.mpc delete mode 100644 XSCRT/XSCRT/XSCRT_export.h delete mode 100644 XSCRT/XSCRT/utils/Buffer_Reader_T.cpp delete mode 100644 XSCRT/XSCRT/utils/Buffer_Reader_T.h delete mode 100644 XSCRT/XSCRT/utils/Buffer_Writer_T.cpp delete mode 100644 XSCRT/XSCRT/utils/Buffer_Writer_T.h delete mode 100644 XSCRT/XSCRT/utils/File_Reader_T.cpp delete mode 100644 XSCRT/XSCRT/utils/File_Reader_T.h delete mode 100644 XSCRT/XSCRT/utils/File_Writer_T.cpp delete mode 100644 XSCRT/XSCRT/utils/File_Writer_T.h delete mode 100644 XSCRT/XSCRT/utils/Reader_T.cpp delete mode 100644 XSCRT/XSCRT/utils/Reader_T.h delete mode 100644 XSCRT/XSCRT/utils/Reader_Writer_Base_T.cpp delete mode 100644 XSCRT/XSCRT/utils/Reader_Writer_Base_T.h delete mode 100644 XSCRT/XSCRT/utils/Writer_T.cpp delete mode 100644 XSCRT/XSCRT/utils/Writer_T.h diff --git a/XSCRT/XMLSchema/Traversal.hpp b/XSCRT/XMLSchema/Traversal.hpp deleted file mode 100644 index f03b843..0000000 --- a/XSCRT/XMLSchema/Traversal.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// file : XMLSchema/Traversal.hpp -// author : Boris Kolpackov - -#ifndef XMLSCHEMA_TRAVERSAL_HPP -#define XMLSCHEMA_TRAVERSAL_HPP - -#include -#include - -namespace XMLSchema -{ - namespace Traversal - { - // Automatic traversal of IDREFs. - // - // - struct IDREF : - XSCRT::Traversal::Traverser - { - virtual void - traverse (XMLSchema::IDREF_Base& r) - { - if (r.get ()) dispatch (*(r.get ())); - } - - virtual void - traverse (XMLSchema::IDREF_Base const& r) - { - if (r.get ()) dispatch (*(r.get ())); - } - }; - - - template - struct Traverser : XSCRT::Traversal::Traverser - { - }; - - typedef Traverser byte; - typedef Traverser unsignedByte; - - typedef Traverser short_; - typedef Traverser unsignedShort; - - typedef Traverser int_; - typedef Traverser unsignedInt; - - typedef Traverser long_; - typedef Traverser unsignedLong; - - typedef Traverser boolean; - - typedef Traverser float_; - typedef Traverser double_; - - template - struct string : Traverser > - { - }; - - template - struct ID : Traverser > - { - }; - - template - struct anyURI : Traverser > - { - }; - } -} - -#include - -#endif // XMLSCHEMA_TRAVERSAL_HPP diff --git a/XSCRT/XMLSchema/Traversal.tpp b/XSCRT/XMLSchema/Traversal.tpp deleted file mode 100644 index 9a8a219..0000000 --- a/XSCRT/XMLSchema/Traversal.tpp +++ /dev/null @@ -1,10 +0,0 @@ -// file : XMLSchema/Traversal.tpp -// author : Boris Kolpackov - -namespace XMLSchema -{ - namespace Traversal - { - - } -} diff --git a/XSCRT/XMLSchema/TypeInfo.hpp b/XSCRT/XMLSchema/TypeInfo.hpp deleted file mode 100644 index bfc1e33..0000000 --- a/XSCRT/XMLSchema/TypeInfo.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// file : XMLSchema/TypeInfo.hpp -// author : Boris Kolpackov - -#ifndef XMLSCHEMA_TYPE_INFO_HPP -#define XMLSCHEMA_TYPE_INFO_HPP - -#include - -namespace XMLSchema -{ - template - struct TypeInfoInitializer - { - TypeInfoInitializer (XSCRT::ExtendedTypeInfoMap&); - }; -} - -#include - -#endif // XMLSCHEMA_TYPE_INFO_HPP diff --git a/XSCRT/XMLSchema/TypeInfo.tpp b/XSCRT/XMLSchema/TypeInfo.tpp deleted file mode 100644 index 3f4a8d2..0000000 --- a/XSCRT/XMLSchema/TypeInfo.tpp +++ /dev/null @@ -1,100 +0,0 @@ -// file : XMLSchema/TypeInfo.tpp -// author : Boris Kolpackov - -namespace XMLSchema -{ - //@@ VC6 - // - template - void - add_info (XSCRT::ExtendedTypeInfoMap& map, T*) - { - using XSCRT::TypeId; - using XSCRT::ExtendedTypeInfo; - using std::make_pair; - - TypeId id (typeid (T)); - ExtendedTypeInfo info (id); - - info.add_base (ExtendedTypeInfo::Access::public_, - false, - typeid (XSCRT::Type)); - - map.insert (make_pair (id, info)); - } - - - template - inline - TypeInfoInitializer:: - TypeInfoInitializer (XSCRT::ExtendedTypeInfoMap& map) - { - using XSCRT::TypeId; - using XSCRT::ExtendedTypeInfo; - using std::make_pair; - - // XSCRT::Type - // - { - TypeId id (typeid (XSCRT::Type)); - map.insert (make_pair (id, ExtendedTypeInfo (id))); - } - - //@@ VC6 - - add_info (map, 0); - add_info (map, 0); - - add_info (map, 0); - add_info (map, 0); - - add_info (map, 0); - add_info (map, 0); - - add_info (map, 0); - add_info (map, 0); - - add_info (map, 0); - - add_info (map, 0);; - add_info (map, 0); - - add_info > (map, 0); - - add_info > (map, 0); - add_info > (map, 0); - add_info > (map, 0); - add_info > (map, 0); - add_info > (map, 0); - - add_info > (map, 0); - - add_info > (map, 0); - - // IDREF_Base - // - { - TypeId id (typeid (IDREF_Base)); - ExtendedTypeInfo info (id); - - info.add_base (ExtendedTypeInfo::Access::public_, - false, - typeid (XSCRT::Type)); - - map.insert (make_pair (id, info)); - } - - // IDREF - // - { - TypeId id (typeid (IDREF)); - ExtendedTypeInfo info (id); - - info.add_base (ExtendedTypeInfo::Access::public_, - false, - typeid (IDREF_Base)); - - map.insert (make_pair (id, info)); - } - } -} diff --git a/XSCRT/XMLSchema/Types.hpp b/XSCRT/XMLSchema/Types.hpp deleted file mode 100644 index a60df08..0000000 --- a/XSCRT/XMLSchema/Types.hpp +++ /dev/null @@ -1,629 +0,0 @@ -// file : XMLSchema/Types.hpp -// author : Boris Kolpackov - -#ifndef XMLSCHEMA_TYPES_HPP -#define XMLSCHEMA_TYPES_HPP - -#include -#include - -namespace XMLSchema -{ - typedef XSCRT::FundamentalType byte; - typedef XSCRT::FundamentalType unsignedByte; - - typedef XSCRT::FundamentalType short_; - typedef XSCRT::FundamentalType unsignedShort; - - typedef XSCRT::FundamentalType int_; - typedef XSCRT::FundamentalType unsignedInt; - - //@@ VC6 -#if defined (_MSC_VER) && (_MSC_VER < 1300) - - typedef XSCRT::FundamentalType<__int64> long_; - typedef XSCRT::FundamentalType unsignedLong; - -#else - - typedef XSCRT::FundamentalType long_; - typedef XSCRT::FundamentalType unsignedLong; - -#endif - - //@@ It would be nice to use some arbitrary-length integer class. - // - typedef long_ decimal; - typedef decimal integer; - typedef integer nonPositiveInteger; - typedef integer nonNegativeInteger; - typedef nonNegativeInteger positiveInteger; - typedef nonPositiveInteger negativeInteger; - - - typedef XSCRT::FundamentalType boolean; - - typedef XSCRT::FundamentalType float_; - typedef XSCRT::FundamentalType double_; - - // Just to make GCC 3.3 and other broken compilers shutup. - // - using std::basic_string; - - template - class string : public XSCRT::Type, public basic_string - { - protected: - typedef basic_string Base__ ; - - public: - // Trait for marshaling string - typedef C CDR_Type__; - - //@@ VC6 does not inject XSCRT::Type into the scope so I have - // to qualify it all the time. - // - - string () - { - } - - string (XSCRT::XML::Element const& e) - : Base__ (e.value ()) - { - } - - string (XSCRT::XML::Attribute const& a) - : Base__ (a.value ()) - { - } - - explicit string (Base__ const& x) - : Base__ (x) - { - } - - explicit string (C const* x) - : Base__ (x) - { - } - - string& - operator= (Base__ const& x) - { - static_cast (*this) = x; - return *this; - } - }; - - - template - class normalizedString : public string - { - protected: - typedef typename string::Base__ Base__; - - public: - normalizedString () - { - } - - explicit normalizedString (XSCRT::XML::Element const& e) - : string (e) - { - } - - normalizedString (XSCRT::XML::Attribute const& a) - : string (a) - { - } - - normalizedString (Base__ const& x) - : string (x) - { - } - - normalizedString (C const* x) - : string (x) - { - } - - normalizedString& - operator= (Base__ const& x) - { - static_cast (*this) = x; - return *this; - } - }; - - - template - class token : public normalizedString - { - protected: - typedef typename normalizedString::Base__ Base__; - - public: - token () - { - } - - explicit token (XSCRT::XML::Element const& e) - : normalizedString (e) - { - } - - token (XSCRT::XML::Attribute const& a) - : normalizedString (a) - { - } - - token (Base__ const& x) - : normalizedString (x) - { - } - - token (C const* x) - : normalizedString (x) - { - } - - token& - operator= (Base__ const& x) - { - static_cast (*this) = x; - return *this; - } - }; - - - template - class NMTOKEN : public token - { - protected: - typedef typename token::Base__ Base__; - - public: - NMTOKEN () - { - } - - NMTOKEN (XSCRT::XML::Element const& e) - : token (e) - { - } - - NMTOKEN (XSCRT::XML::Attribute const& a) - : token (a) - { - } - - NMTOKEN (Base__ const& x) - : token (x) - { - } - - NMTOKEN (C const* x) - : token (x) - { - } - - NMTOKEN& - operator= (Base__ const& x) - { - static_cast (*this) = x; - return *this; - } - }; - - template - class Name: public token - { - protected: - typedef typename token::Base__ Base__; - - public: - Name() - { - } - - Name(XSCRT::XML::Element const& e) - : token (e) - { - } - - Name(XSCRT::XML::Attribute const& a) - : token (a) - { - } - - Name(Base__ const& x) - : token (x) - { - } - - Name (C const* x) - : token (x) - { - } - - Name& - operator= (Base__ const& x) - { - static_cast (*this) = x; - return *this; - } - }; - - - template - class NCName: public Name - { - protected: - typedef typename Name::Base__ Base__; - - public: - NCName() - { - } - - explicit NCName(XSCRT::XML::Element const& e) - : Name (e) - { - } - - explicit NCName(XSCRT::XML::Attribute const& a) - : Name (a) - { - } - - explicit NCName(Base__ const& x) - : Name (x) - { - } - - NCName (C const* x) - : Name (x) - { - } - - NCName& - operator= (Base__ const& x) - { - static_cast (*this) = x; - return *this; - } - }; - - template - struct IdentityProvider : XSCRT::IdentityProvider - { - IdentityProvider (NCName const& id) - : id_ (id) - { - } - - virtual ~IdentityProvider () - { - - } - - virtual bool - before (XSCRT::IdentityProvider const& y) const - { - return id_ < dynamic_cast (y).id_; - } - - private: - NCName const& id_; - - private: - IdentityProvider (IdentityProvider const&); - - IdentityProvider& - operator= (IdentityProvider const&); - }; - - - template - class ID : public NCName - { - protected: - typedef typename NCName::Base__ Base__; - - public: - virtual ~ID() - { - unregister_id (); - } - - ID () - : id_provider_ (*this) - { - } - - explicit ID (XSCRT::XML::Element const& e) - : NCName (e), id_provider_ (*this) - { - } - - explicit ID (XSCRT::XML::Attribute const& a) - : NCName (a), id_provider_ (*this) - { - } - - ID (ID const& x) - : NCName (x), id_provider_ (*this) - { - } - - ID (Base__ const& x) - : NCName (x), id_provider_ (*this) - { - } - - ID (C const* x) - : NCName (x), id_provider_ (*this) - { - } - - ID& - operator= (Base__ const& x) - { - unregister_id (); - - static_cast&>(*this) = x; - - register_id (); - - return *this; - } - - ID& - operator= (ID const& x) - { - unregister_id (); - - static_cast&>(*this) = static_cast const&>(x); - - register_id (); - - return *this; - } - - public: - using NCName::container; - - virtual void - container (XSCRT::Type* c) - { - unregister_id (); - - NCName::container (c); - - register_id (); - } - - private: - using NCName::empty; - using NCName::root; - - void - register_id () - { - if (container () != this && !empty ()) - { - //std::wcerr << "registering " << container () - // << " as '" << *this - // << "' on " << container () << std::endl; - container ()->register_id (id_provider_, container ()); - } - } - - void - unregister_id () - { - if (container () != this && !empty ()) - { - //std::wcerr << "un-registering " << container () - // << " as '" << *this - // << "' on " << container () << std::endl; - container ()->unregister_id (id_provider_); - } - } - - private: - IdentityProvider id_provider_; - }; - - struct IDREF_Base : public XSCRT::Type - { - virtual XSCRT::Type const* - get () const = 0; - - virtual XSCRT::Type* - get () = 0; - }; - - template - class IDREF : public IDREF_Base - { - public: - // Trait for marshaling IDREF - typedef C CDR_Type__; - IDREF () - : id_provider_ (id_) - { - } - - IDREF (XSCRT::XML::Element const& e) - : id_ (e), id_provider_ (id_) - { - } - - IDREF (XSCRT::XML::Attribute const& a) - : id_ (a), id_provider_ (id_) - { - } - - IDREF (IDREF const& x) - : id_ (x.id_), id_provider_ (id_) - { - } - - IDREF (basic_string const& id) - : id_ (id), id_provider_ (id_) - { - } - - IDREF (C const* id) - : id_ (id), id_provider_ (id_) - { - } - - IDREF& - operator= (IDREF const& x) - { - id_ = x.id_; - return *this; - } - - IDREF& - operator= (basic_string const& x) - { - id_ = x; - return *this; - } - - public: - NCName - id () const - { - return id_; - } - - public: - XSCRT::Type const* - operator-> () const - { - return get (); - } - - XSCRT::Type* - operator-> () - { - return get (); - } - - XSCRT::Type const& - operator* () const - { - return *(get ()); - } - - XSCRT::Type& - operator* () - { - return *(get ()); - } - - virtual XSCRT::Type const* - get () const - { - if (!id_.empty () && container () != this) - { - return root ()->lookup_id (id_provider_); - } - else - { - return 0; - } - } - - virtual XSCRT::Type* - get () - { - if (!id_.empty () && container () != this) - { - return root ()->lookup_id (id_provider_); - } - else - { - return 0; - } - } - - // conversion to bool - // - typedef void (IDREF::*bool_convertable)(); - - operator bool_convertable () const - { - return get () ? &IDREF::true_ : 0; - } - - private: - void true_ () - { - } - - private: - NCName id_; - IdentityProvider id_provider_; - }; - - template - class anyURI : public XSCRT::Type, public basic_string - { - protected: - typedef basic_string Base__ ; - - public: - // Trait for marshaling string - typedef C CDR_Type__; - - //@@ VC6 does not inject XSCRT::Type into the scope so I have - // to qualify it all the time. - // - - anyURI () - { - } - - anyURI (XSCRT::XML::Element const& e) - : Base__ (e.value ()) - { - } - - explicit anyURI (XSCRT::XML::Attribute const& a) - : Base__ (a.value ()) - { - } - - anyURI (Base__ const& x) - : Base__ (x) - { - } - - anyURI (C const * x) - : Base__ (x) - { - } - - anyURI (const anyURI& s) - : Base__ (s) - { - - } - - anyURI & operator= (Base__ const& x) - { - static_cast (*this) = x; - return *this; - } - }; -} - -#include - -#endif // XMLSCHEMA_TYPES_HPP diff --git a/XSCRT/XMLSchema/Types.tpp b/XSCRT/XMLSchema/Types.tpp deleted file mode 100644 index 0a42460..0000000 --- a/XSCRT/XMLSchema/Types.tpp +++ /dev/null @@ -1,8 +0,0 @@ -// file : XMLSchema/Types.tpp -// author : Boris Kolpackov - -namespace XMLSchema -{ - -} - diff --git a/XSCRT/XMLSchema/Writer.hpp b/XSCRT/XMLSchema/Writer.hpp deleted file mode 100644 index 40e481f..0000000 --- a/XSCRT/XMLSchema/Writer.hpp +++ /dev/null @@ -1,94 +0,0 @@ -// file : XMLSchema/Writer.hpp -// author : Boris Kolpackov - -#ifndef XMLSCHEMA_WRITER_HPP -#define XMLSCHEMA_WRITER_HPP - -#include - -#include - -#include -#include - -namespace XMLSchema -{ - namespace Writer - { - template - struct FundamentalType : Traversal::Traverser, - virtual XSCRT::Writer - { - FundamentalType (XSCRT::XML::Element& e) - : XSCRT::Writer (e) - { - } - - using XSCRT::Writer::top_; - using XSCRT::Writer::attr_; - - virtual void - traverse (T const& o) - { - using namespace XSCRT::XML; - - std::basic_ostringstream os; - - os << o; - - if (Attribute* a = attr_ ()) - { - a->value (os.str ()); - } - else - { - top_().value (os.str ()); - } - } - - protected: - FundamentalType () - { - } - }; - - - template - struct IDREF : Traversal::Traverser >, - virtual XSCRT::Writer - { - IDREF (XSCRT::XML::Element& e) - : XSCRT::Writer (e) - { - } - - using XSCRT::Writer::top_; - using XSCRT::Writer::attr_; - - virtual void - traverse ( - typename Traversal::Traverser >::Type const& o) - { - using namespace XSCRT::XML; - - if (Attribute* a = attr_ ()) - { - a->value (o.id ()); - } - else - { - top_().value (o.id ()); - } - } - - protected: - IDREF () - { - } - }; - } -} - -#include - -#endif // XMLSCHEMA_WRITER_HPP diff --git a/XSCRT/XMLSchema/Writer.tpp b/XSCRT/XMLSchema/Writer.tpp deleted file mode 100644 index be4736b..0000000 --- a/XSCRT/XMLSchema/Writer.tpp +++ /dev/null @@ -1,9 +0,0 @@ -// file : XMLSchema/Writer.tpp -// author : Boris Kolpackov - -namespace XMLSchema -{ - namespace Writer - { - } -} diff --git a/XSCRT/XMLSchema/id_map.hpp b/XSCRT/XMLSchema/id_map.hpp deleted file mode 100644 index 74a0f7d..0000000 --- a/XSCRT/XMLSchema/id_map.hpp +++ /dev/null @@ -1,163 +0,0 @@ -// -*- C++ -*- -// - -//============================================================================= -/** - * @file id_map.hpp - * - * This file contains the ID_Map class which has the responsibility of linking - * XML IDREF objects to their XML ID counterparts. In the output files, this - * means that a _ptr() will return a pointer to the identified - * object. - * - * Exception NULL_PTR_Entry is thrown when a program attempts to add a NULL_PTR - * to either the id_map or idref_map. - * - * Exception Unresolved_IDREF is thrown if an element in an XML document attempts - * to reference an ID that does not exist. - * - * @author Jason R. Cody - */ -//============================================================================= - -#ifndef _ID_MAP_H -#define _ID_MAP_H - -//ID_Map makes use of the Types::idref_ data member to set it to the appropriate -//object created during parsing -#include "XMLSchema/Types.hpp" - -//The ID_Map is a Thread Specific Storage element. -#include "ace/TSS_T.h" -#include "ace/ace_wchar.h" - - /** - * @class ID_Map - * - * @brief A class that handles the mapping of IDREF objects to objects with the - * respective ID. - */ - class ID_Map - { - public: - - //Trait to allow for ease of thread specific storage. - typedef ACE_TSS TSS_ID_Map; - typedef std::map, XSCRT::Type*>::iterator id_iterator; - typedef std::multimap, XSCRT::Type*>::iterator idref_iterator; - typedef std::map, XSCRT::Type*> ID_MAP; - typedef std::multimap, XSCRT::Type*> IDREF_MAP; - - - //Exception Classes - //NULL_PTR_Entry thrown when a NULL PTR is added to the - //ID_Map - class NULL_PTR_Entry {}; - - //Unresolved_IDREF thrown when there are IDREF's in the - //XML document. - class Unresolved_IDREF { - public: - explicit Unresolved_IDREF(const std::basic_string &message) : message(message) - {} - ~Unresolved_IDREF(){} - std::basic_string get_message () const - { - return message; - } - private: - std::basic_string message; - }; - - //Only a default constructor and destructor are needed - //Constructor - ID_Map () - { - } - - //Destructor - ~ID_Map () - { - } - - //Add an ID to the ID map - void add_id (const std::basic_string& id, XSCRT::Type *obj_ref) - { - if (obj_ref) - { - this->id_map_.insert (ID_MAP::value_type(id, obj_ref)); - } - else - { - throw NULL_PTR_Entry(); - } - return; - } - - //Add an IDREF to the IDREF map - void add_idref (const std::basic_string& idref, XSCRT::Type *obj_ref) - { - if (obj_ref) - { - this->idref_map_.insert (IDREF_MAP::value_type(idref, obj_ref)); - } - else - { - throw NULL_PTR_Entry(); - } - return; - } - - void resolve_single_idref (const std::basic_string& idref, ::XSCRT::Type * element) - { - ID_Map::id_iterator id_iterator = this->id_map_.find(idref); - if (id_iterator != this->id_map_.end()) - { - element->set_idref(idref, id_iterator->second); - } - else - { - throw Unresolved_IDREF(idref); - } - } - - //Sets the referencing elements XSCRT::Type::idref_ to point to the - //referenced element. - //Note: The pointer is of type "XSCRT::Type*" - void resolve_idref () - { - //Declare iterators to navigate the maps - ID_Map::id_iterator id_iterator; - ID_Map::idref_iterator idref_iterator; - - for (idref_iterator = this->idref_map_.begin(); - idref_iterator != this->idref_map_.end(); - ++idref_iterator) - { - //Find the ID that matches the IDREF element - id_iterator = this->id_map_.find(idref_iterator->first); - if (id_iterator != this->id_map_.end()) - { - //Add the IDREF identifier and the reference to the - //identified object - std::basic_string temp_id = id_iterator->first; - idref_iterator->second->set_idref(temp_id, id_iterator->second); - } - else - { - std::basic_string temp (idref_iterator->first); - throw Unresolved_IDREF(temp); - } - } - } - - private: - //id_map_: maps the ID string to the element with the - // ID attribute - //idref_map_: multimap that maps the IDREF string to the - // element with the IDREF attribute - ID_MAP id_map_; - IDREF_MAP idref_map_; - }; - -#endif /* _ID_MAP_HPP */ diff --git a/XSCRT/XSCRT/Elements.hpp b/XSCRT/XSCRT/Elements.hpp deleted file mode 100644 index 689e50e..0000000 --- a/XSCRT/XSCRT/Elements.hpp +++ /dev/null @@ -1,438 +0,0 @@ -// file : XSCRT/Elements.hpp -// author : Boris Kolpackov - -#ifndef XSCRT_ELEMENTS_HPP -#define XSCRT_ELEMENTS_HPP - -#include -#include -#include -#include -#include "ace/ace_wchar.h" -// #include //@@ tmp - -#include -#include "ace/Refcounted_Auto_Ptr.h" - -namespace XSCRT -{ - struct IdentityProvider - { - virtual bool - before (IdentityProvider const&) const = 0; - - virtual ~IdentityProvider () = default; - }; - - class Type - { - public: - - virtual ~Type () = default; - - protected: - Type () - : container_ (nullptr) - { - } - - template - Type (XML::Element const&) - : container_ (nullptr) - { - } - - template - Type (XML::Attribute const&) - : container_ (nullptr) - { - } - - Type (Type const&) - : container_ (nullptr) - { - } - - Type& - operator= (Type const&) - { - return *this; - } - - public: - Type const* - container () const - { - return container_ ? container_ : this; - } - - Type* - container () - { - return container_ ? container_ : this; - } - - - Type const* - root () const - { - Type const* r = container (); - - //@@ VC6 can't handle this inside the loop. - // - Type const* c = r->container (); - - for (; c != r; c = c->container ()) r = c; - - return r; - } - - Type* - root () - { - Type* r = container (); - - for (Type* c = r->container (); c != r; c = c->container ()) r = c; - - return r; - } - - //@@ - //protected: - - public: - virtual void - container (Type* c) - { - if (container_ == c) return; - - // Revoke registrations from our old container. - // - if (container_ != nullptr && map_) - { - for (Map_::iterator i (map_->begin ()); i != map_->end (); ++i) - { - //std::wcerr << "revoking " << i->second - // << " to " << container_ << std::endl; - - container_->unregister_id (*(i->first)); - } - } - - // Copy registrations to our new container. - // - if (c != nullptr && map_) - { - for (Map_::iterator i (map_->begin ()); i != map_->end (); ++i) - { - //std::wcerr << "copying " << i->second - // << " to " << c << std::endl; - - c->register_id (*(i->first), i->second); - } - } - - container_ = c; - } - - //@@ - //protected: - - public: - void - register_id (IdentityProvider const& id, Type* t) - { - if (!map_) - { - map_ = std::make_unique (); - } - - if (!map_->insert ( - std::pair (&id, t)).second) - { - throw 1; - } - - if (container () != this) container ()->register_id (id, t); - } - - void - unregister_id (IdentityProvider const& id) - { - if (map_) - { - Map_::iterator it (map_->find (&id)); - - if (it != map_->end ()) - { - map_->erase (it); - - if (container () != this) container ()->unregister_id (id); - - return; - } - } - - throw 1; - } - - Type* - lookup_id (IdentityProvider const& id) const - { - if (map_) - { - Map_::const_iterator it (map_->find (&id)); - - if (it != map_->end ()) - { - return it->second; - } - } - - return nullptr; - } - - Type* get_idref (const std::basic_string& name) - { - std::map, XSCRT::Type*>::iterator i = - this->idref_map_.find(name); - if (i != idref_map_.end()) - { - return i->second; - } - else - { - return nullptr; - } - } - - //Get and set methods for the idref_map_ data member - Type* get_idref (const char* name) - { - std::basic_string name_string (ACE_TEXT_CHAR_TO_TCHAR(name)); - std::map, XSCRT::Type*>::iterator i = - this->idref_map_.find(name_string); - if (i != idref_map_.end()) - { - return i->second; - } - else - { - return nullptr; - } - } - - Type* get_idref (const wchar_t *name) - { - std::basic_string name_string (ACE_TEXT_WCHAR_TO_TCHAR(name)); - std::map, XSCRT::Type*>::iterator i = - this->idref_map_.find(name_string); - if (i != idref_map_.end()) - { - return i->second; - } - else - { - return nullptr; - } - } - - void set_idref (std::basic_string name, Type* new_idref) - { - this->idref_map_.insert(std::pair,Type*>(name, new_idref)); - return; - } - - private: - - //Data member to handle unbounded IDREF attributes and elements - std::map, XSCRT::Type*> idref_map_; - - Type* container_; - - struct IdentityComparator - { - bool operator () (IdentityProvider const* x, - IdentityProvider const* y) const - { - return x->before (*y); - } - }; - - typedef - std::map - Map_; - - std::unique_ptr map_; - }; - - // Fundamental types template. - // - // - template - class FundamentalType : public Type - { - public: - // Trait for marshaling a FundamentalType X - using CDR_Type__ = X; - - FundamentalType () - { - } - - template - FundamentalType (XML::Element const& e) - { - std::basic_stringstream s; - s << e.value (); - s >> x_; - } - - template - FundamentalType (XML::Attribute const& a) - { - std::basic_stringstream s; - s << a.value (); - s >> x_; - } - - FundamentalType (X const& x) - : x_ (x) - { - } - - FundamentalType& - operator= (X const& x) - { - x_ = x; - return *this; - } - - public: - operator X const& () const - { - return x_; - } - - operator X& () - { - return x_; - } - - protected: - X x_; - }; - - // Stuff for normal compilers. - // - - // Specialization for `signed char' - // - // - template<> - template - inline - FundamentalType:: - FundamentalType (XML::Element const& e) - { - std::basic_stringstream s; - s << e.value (); - - short t; - s >> t; - - x_ = static_cast (t); - } - - template<> - template - inline - FundamentalType:: - FundamentalType (XML::Attribute const& a) - { - std::basic_stringstream s; - s << a.value (); - - short t; - s >> t; - - x_ = static_cast (t); - } - - // Specialization for `unsigned char' - // - // - template<> - template - inline - FundamentalType:: - FundamentalType (XML::Element const& e) - { - std::basic_stringstream s; - s << e.value (); - - unsigned short t; - s >> t; - - x_ = static_cast (t); - } - - template<> - template - inline - FundamentalType:: - FundamentalType (XML::Attribute const& a) - { - std::basic_stringstream s; - s << a.value (); - - unsigned short t; - s >> t; - - x_ = static_cast (t); - } - - // Specialization for bool. - // - // - - template<> - template<> - inline - FundamentalType:: - FundamentalType (XML::Element const& e) - { - x_ = (e.value () == "true") || (e.value () == "1"); - } - - template<> - template<> - inline - FundamentalType:: - FundamentalType (XML::Element const& e) - { - x_ = (e.value () == L"true") || (e.value () == L"1"); - } - - template<> - template<> - inline - FundamentalType:: - FundamentalType (XML::Attribute const& a) - { - x_ = (a.value () == "true") || (a.value () == "1"); - } - - template<> - template<> - inline - FundamentalType:: - FundamentalType (XML::Attribute const& a) - { - x_ = (a.value () == L"true") || (a.value () == L"1"); - } -} - -#include - -#endif // XSCRT_ELEMENTS_HPP diff --git a/XSCRT/XSCRT/Elements.tpp b/XSCRT/XSCRT/Elements.tpp deleted file mode 100644 index 4b90965..0000000 --- a/XSCRT/XSCRT/Elements.tpp +++ /dev/null @@ -1,6 +0,0 @@ -// file : XSC/Elements.tpp -// author : Boris Kolpackov - -namespace XSC -{ -} diff --git a/XSCRT/XSCRT/ExtendedTypeInfo.hpp b/XSCRT/XSCRT/ExtendedTypeInfo.hpp deleted file mode 100644 index 67cc6d2..0000000 --- a/XSCRT/XSCRT/ExtendedTypeInfo.hpp +++ /dev/null @@ -1,180 +0,0 @@ -// file : XSCRT/ExtendedTypeInfo.hpp -// author : Boris Kolpackov - -#ifndef XSCRT_EXTENDED_TYPE_INFO_HPP -#define XSCRT_EXTENDED_TYPE_INFO_HPP - -#include -#include -#include -#include - -namespace XSCRT -{ - class TypeId - { - public: - template - explicit TypeId (T const& t); - - explicit TypeId (std::type_info const& tid); - - public: - bool - operator == (TypeId const& other) const; - - bool - operator != (TypeId const& other) const; - - bool - operator < (TypeId const& other) const; - - /* - friend std::ostream& - operator << (std::ostream& os, TypeId const& t); - */ - - public: - char const* - name () const - { - return tid_->name (); - } - - private: - std::type_info const* tid_; - }; - - - // - // - // - class ExtendedTypeInfo - { - public: - - // - // - // - struct Access - { - enum Value - { - private_, - protected_, - public_ - }; - }; - - - // - // - // - class BaseInfo - { - public: - BaseInfo (Access::Value access, bool virtual_base, TypeId const& tid); - - public: - ExtendedTypeInfo const& - type_info () const; - - Access::Value - access () const; - - bool - virtual_base () const; - - private: - TypeId tid_; - mutable ExtendedTypeInfo const* ti_; - bool virtual_base_; - Access::Value access_; - }; - - private: - typedef - std::vector - BaseInfoList; - - public: - typedef - BaseInfoList::const_iterator - BaseIterator; - - public: - ExtendedTypeInfo (TypeId const& tid); - - TypeId - type_id () const; - - BaseIterator - begin_base () const; - - BaseIterator - end_base () const; - - void - add_base (Access::Value access, bool virtual_base, TypeId const& tid); - - private: - TypeId tid_; - BaseInfoList base_; - }; - - typedef - std::map - ExtendedTypeInfoMap; - - - ExtendedTypeInfoMap& - extended_type_info_map (); - - - class NotAvailable {}; - - - template - ExtendedTypeInfo const& - extended_type_info (T const& t) - { - return extended_type_info (typeid (t)); - } - - template - ExtendedTypeInfo const& - extended_type_info () - { - return extended_type_info (typeid (T)); - } - - //@@ Had to use function template specialization because VC6 - // cannot handle simply overloaded functions. - // - - template <> - inline - ExtendedTypeInfo const& - extended_type_info (TypeId const& tid) - { - ExtendedTypeInfoMap::const_iterator i ( - extended_type_info_map ().find (tid)); - - if (i == extended_type_info_map ().end ()) - throw NotAvailable (); - - return i->second; - } - - template <> - inline - ExtendedTypeInfo const& - extended_type_info (std::type_info const& tid) - { - return extended_type_info (TypeId (tid)); - } -} - -#include - -#endif // XSCRT_EXTENDED_TYPE_INFO_HPP diff --git a/XSCRT/XSCRT/ExtendedTypeInfo.ipp b/XSCRT/XSCRT/ExtendedTypeInfo.ipp deleted file mode 100644 index 3ef181e..0000000 --- a/XSCRT/XSCRT/ExtendedTypeInfo.ipp +++ /dev/null @@ -1,129 +0,0 @@ -// file : XSCRT/ExtendedTypeInfo.ipp -// author : Boris Kolpackov - -namespace XSCRT -{ - // TypeId - // - // - inline - TypeId:: - TypeId (std::type_info const& tid) - : tid_ (&tid) - { - } - - - inline - bool TypeId:: - operator == (TypeId const& other) const - { - return *tid_ == *other.tid_; - } - - inline - bool TypeId:: - operator != (TypeId const& other) const - { - return *tid_ != *other.tid_; - } - - inline - bool TypeId:: - operator < (TypeId const& other) const - { - return tid_->before (*other.tid_); - } - - - // ExtendedTypeInfo::BaseInfo - // - // - - inline - ExtendedTypeInfo::BaseInfo:: - BaseInfo (Access::Value access, bool virtual_base, TypeId const& tid) - : tid_ (tid), - ti_ (nullptr), - virtual_base_ (virtual_base), - access_ (access) - { - } - - inline - ExtendedTypeInfo const& ExtendedTypeInfo::BaseInfo:: - type_info () const - { - if (ti_ == nullptr) ti_ = std::addressof (extended_type_info (tid_)); - - return *ti_; - } - - - inline - ExtendedTypeInfo::Access::Value ExtendedTypeInfo::BaseInfo:: - access () const - { - return access_; - } - - inline - bool ExtendedTypeInfo::BaseInfo:: - virtual_base () const - { - return virtual_base_; - } - - - // ExtendedTypeInfo - // - // - inline - ExtendedTypeInfo:: - ExtendedTypeInfo (TypeId const& tid) - : tid_ (tid) - { - } - - inline - TypeId ExtendedTypeInfo:: - type_id () const - { - return tid_; - } - - inline - ExtendedTypeInfo::BaseIterator ExtendedTypeInfo:: - begin_base () const - { - return base_.begin (); - } - - - inline - ExtendedTypeInfo::BaseIterator ExtendedTypeInfo:: - end_base () const - { - return base_.end (); - } - - inline - void ExtendedTypeInfo:: - add_base (Access::Value access, bool virtual_base, TypeId const& tid) - { - base_.push_back (BaseInfo (access, virtual_base, tid)); - } - - // ExtendedTypeInfoMap - // - // - - inline - ExtendedTypeInfoMap& - extended_type_info_map () - { - static ExtendedTypeInfoMap extended_type_info_map_; - - return extended_type_info_map_; - } -} diff --git a/XSCRT/XSCRT/Parser.hpp b/XSCRT/XSCRT/Parser.hpp deleted file mode 100644 index fe1fda6..0000000 --- a/XSCRT/XSCRT/Parser.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// file : XSCRT/Parser.hpp -// author : Boris Kolpackov - -#ifndef XSCRT_PARSER_HPP -#define XSCRT_PARSER_HPP - -#include - -#include -#include -#include - -namespace XSCRT -{ - template - class Parser - { - public: - Parser (XML::Element const& e) - : e_ (e.dom_element ()->getChildNodes ()), ei_ (0), - a_ (e.dom_element ()->getAttributes ()), ai_ (0) - { - } - - bool - more_elements () const - { - return e_->getLength () > ei_; - } - - XML::Element - next_element () - { - xercesc::DOMNode * node = e_->item (ei_++); - - return XML::Element ( - dynamic_cast (node)); - } - - bool - more_attributes () const - { - return a_->getLength () > ai_; - } - - XML::Attribute - next_attribute () - { - return XML::Attribute ( - dynamic_cast (a_->item (ai_++))); - } - - private: - xercesc::DOMNodeList const* e_; - unsigned long ei_; - - xercesc::DOMNamedNodeMap const* a_; - unsigned long ai_; - - private: - Parser (Parser const&); - - void - operator= (Parser const&); - }; -} - -#include - -#endif // XSCRT_PARSER_HPP diff --git a/XSCRT/XSCRT/Parser.tpp b/XSCRT/XSCRT/Parser.tpp deleted file mode 100644 index 56e3389..0000000 --- a/XSCRT/XSCRT/Parser.tpp +++ /dev/null @@ -1,6 +0,0 @@ -// file : XSCRT/Parser.tpp -// author : Boris Kolpackov - -namespace XSCRT -{ -} diff --git a/XSCRT/XSCRT/Traversal.hpp b/XSCRT/XSCRT/Traversal.hpp deleted file mode 100644 index 10c2579..0000000 --- a/XSCRT/XSCRT/Traversal.hpp +++ /dev/null @@ -1,273 +0,0 @@ -// file : XSCRT/Traversal.hpp -// author : Boris Kolpackov - -#ifndef XSCRT_TRAVERSAL_HPP -#define XSCRT_TRAVERSAL_HPP - -#include -#include -#include - -// #include -// using std::wcerr; -// using std::endl; - -#include - -namespace XSCRT -{ - namespace Traversal - { - // - // - // - template - class TraverserBase - { - protected: - virtual - ~TraverserBase (); - - //@@ VC6 - public: - virtual void - trampoline (B& n) = 0; - - virtual void - trampoline (B const& n) = 0; - - /*@@ VC6 - template - friend class DispatcherBase; - */ - }; - - - // - // - // - template - class DispatcherBase - { - public: - virtual - ~DispatcherBase (); - - virtual void - dispatch (B& n); - - virtual void - dispatch (B const& n); - - void - map (TypeId id, TraverserBase& t) - { - //wcerr << "map for " << id.name () << " to " << &t - // << " in " << &traversal_map_ << endl; - - //@@ VC6 - Traversers& traversers = traversal_map_[id]; - traversers.push_back (&t); - } - - public: - typedef - std::vector*> - Traversers; - - typedef - std::map - TraversalMap; - - typedef - typename TraversalMap::const_iterator - Iterator; - - Iterator - begin () const - { - return traversal_map_.begin (); - } - - Iterator - end () const - { - return traversal_map_.end (); - } - - private: - struct TypeInfoComparator - { - bool - operator () (ExtendedTypeInfo const& x, - ExtendedTypeInfo const& y) const - { - return x.type_id () < y.type_id (); - } - }; - - typedef - std::map - LevelMap; - - typedef - std::set - TypeInfoSet; - - static unsigned long - compute_levels (ExtendedTypeInfo const& ti, - unsigned long cur, - LevelMap& map); - - static void - flatten_tree (ExtendedTypeInfo const& ti, TypeInfoSet& set); - - private: - TraversalMap traversal_map_; - }; - - - // - // - // - template - class Dispatcher : public virtual DispatcherBase - { - public: - Dispatcher () - : merge_ (true) - { - } - - void - traverser (DispatcherBase& d) - { - for (typename DispatcherBase::Iterator - i (d.begin ()), end (d.end ()); - i != end; ++i) - { - for (typename DispatcherBase::Traversers::const_iterator - t (i->second.begin ()), end (i->second.end ()); - t != end; ++t) - { - dispatcher_.map (i->first, **t); - } - } - } - - public: - virtual void - dispatch (B& n) - { - merge (); - dispatcher_.dispatch (n); - } - - virtual void - dispatch (B const& n) - { - merge (); - dispatcher_.dispatch (n); - } - - using DispatcherBase::begin; - using DispatcherBase::end; - - private: - void - merge () - { - if (merge_) - { - for (typename DispatcherBase::Iterator - i (begin ()), e (end ()); i != e; ++i) - { - for (typename DispatcherBase::Traversers::const_iterator - t (i->second.begin ()), e (i->second.end ()); t != e; ++t) - { - dispatcher_.map (i->first, **t); - } - } - - merge_ = false; - } - } - - protected: - // DispatcherBase& - // traverser () - // { - // return dispatcher_; - // } - - template - void - iterate_and_dispatch (I begin, I end, X& x, void (X::*next)(A&), A& a) - { - for (; begin != end;) - { - dispatch (*begin); - - if (++begin != end) (x.*next) (a); - } - } - - private: - bool merge_; - DispatcherBase dispatcher_; - }; - - - - // - // - // - template - struct Traverser : TraverserBase, virtual Dispatcher - { - typedef - T - Type; - - Traverser () - { - map (typeid (Type), *this); - } - - virtual void - traverse (Type&) - { - abort (); - } - - virtual void - traverse (Type const&) - { - abort (); - } - - protected: - virtual void - trampoline (B& n) - { - //wcerr << "trampoline for " << &n << " to type " - // << typeid (Type).name () << endl; - - traverse (dynamic_cast (n)); - } - - virtual void - trampoline (B const& n) - { - //wcerr << "trampoline for " << &n << " to type " - // << typeid (Type).name () << endl; - - traverse (dynamic_cast (n)); - } - }; - } -} - -#include - -#endif // XSCRT_TRAVERSAL_HPP diff --git a/XSCRT/XSCRT/Traversal.tpp b/XSCRT/XSCRT/Traversal.tpp deleted file mode 100644 index dff306d..0000000 --- a/XSCRT/XSCRT/Traversal.tpp +++ /dev/null @@ -1,194 +0,0 @@ -// file : XSCRT/Traversal.txx -// author : Boris Kolpackov - -namespace XSCRT -{ - namespace Traversal - { - // TraverserBase - // - // - - template - TraverserBase:: - ~TraverserBase () = default; - - // DispatcherBase - // - // - - template - DispatcherBase:: - ~DispatcherBase () = default; - - //@@ merge after dropping VC6 - // - // - template - void DispatcherBase:: - dispatch (B& n) - { - LevelMap levels; - - //@@ VC6 - ExtendedTypeInfo const& ti = extended_type_info (n); - - unsigned long max = compute_levels (ti, 0, levels); - - - //wcerr << "starting dispatch process for " - // << typeid (n).name () << " with " - // << max << " levels" << endl; - - for (unsigned long l = 0; l < max + 1; ++l) - { - TypeInfoSet dispatched; - - for (typename LevelMap::const_iterator - i (levels.begin ()), e (levels.end ()); - i != e; ++i) - { - if (i->second == l) - { - typename TraversalMap::const_iterator v ( - traversal_map_.find (i->first.type_id ())); - - if (v != traversal_map_.end ()) - { - //wcerr << "dispatching traversers for " - // << typeid (n).name () << " as " - // << i->first.type_id ().name () << endl; - - //@@ VC6 - Traversers const& traversers = v->second; - for (typename Traversers::const_iterator - ti (traversers.begin ()), te (traversers.end ()); - ti != te; ++ti) - { - (*ti)->trampoline (n); - } - - flatten_tree (i->first, dispatched); - } - } - } - - // Remove traversed types from the level map. - // - - //@@ VC6 - { - for (typename TypeInfoSet::const_iterator i = dispatched.begin (); - i != dispatched.end (); - ++i) - { - levels.erase (*i); - } - } - } - } - - template - void DispatcherBase:: - dispatch (B const& n) - { - LevelMap levels; - - //@@ VC6 - ExtendedTypeInfo const& ti = extended_type_info (n); - - unsigned long max = compute_levels (ti, 0, levels); - - - //wcerr << "starting dispatch process for " - // << typeid (n).name () << " with " - // << max << " levels" << endl; - - //wcerr << "using " << &traversal_map_ << " traversal map" << endl; - - for (unsigned long l = 0; l < max + 1; ++l) - { - TypeInfoSet dispatched; - - for (typename LevelMap::const_iterator - i (levels.begin ()), e (levels.end ()); - i != e; ++i) - { - if (i->second == l) - { - typename TraversalMap::const_iterator v ( - traversal_map_.find (i->first.type_id ())); - - if (v != traversal_map_.end ()) - { - //wcerr << "dispatching traversers for " - // << typeid (n).name () << " as " - // << i->first.type_id ().name () << endl; - - //@@ VC6 - Traversers const& traversers = v->second; - for (typename Traversers::const_iterator - ti (traversers.begin ()), te (traversers.end ()); - ti != te; ++ti) - { - (*ti)->trampoline (n); - } - - flatten_tree (i->first, dispatched); - } - } - } - - // Remove traversed types from the level map. - // - - //@@ VC6 - { - for (typename TypeInfoSet::const_iterator i = dispatched.begin (); - i != dispatched.end (); - ++i) - { - levels.erase (*i); - } - } - } - } - - template - unsigned long DispatcherBase:: - compute_levels (ExtendedTypeInfo const& ti, - unsigned long cur, - LevelMap& map) - { - unsigned long ret = cur; - - if (map.find (ti) == map.end () || map[ti] < cur) map[ti] = cur; - - for (ExtendedTypeInfo::BaseIterator i = ti.begin_base (); - i != ti.end_base (); - i++) - { - unsigned long t = compute_levels (i->type_info (), cur + 1, map); - - if (t > ret) - ret = t; - } - - return ret; - } - - template - void DispatcherBase:: - flatten_tree (ExtendedTypeInfo const& ti, TypeInfoSet& set) - { - set.insert (ti); - - for (ExtendedTypeInfo::BaseIterator i = ti.begin_base (); - i != ti.end_base (); - i++) - { - flatten_tree (i->type_info (), set); - } - } - } -} diff --git a/XSCRT/XSCRT/Writer.hpp b/XSCRT/XSCRT/Writer.hpp deleted file mode 100644 index 9b852ed..0000000 --- a/XSCRT/XSCRT/Writer.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// file : XSCRT/Writer.hpp -// author : Boris Kolpackov - -#ifndef XSCRT_WRITER_HPP -#define XSCRT_WRITER_HPP - -#include -#include - -#include - -namespace XSCRT -{ - template - class Writer - { - public: - Writer (XML::Element& e) - : attr__ (nullptr) - { - push_ (e); - } - - protected: - // This c-tor should never be called. - // - Writer () - { - abort (); - } - - public: - void - push_ (XML::Element const& e) - { - stack_.push (e); - } - - void - pop_ () - { - stack_.pop (); - } - - XML::Element& - top_ () - { - return stack_.top (); - } - - public: - XML::Attribute* - attr_ () - { - return attr__; - } - - void - attr_ (XML::Attribute* a) - { - attr__ = a; - } - - private: - std::stack > stack_; - - XML::Attribute* attr__; - - private: - Writer (Writer const&); - - void - operator= (Writer const&); - }; -} - -#include - -#endif // XSCRT_WRITER_HPP diff --git a/XSCRT/XSCRT/Writer.tpp b/XSCRT/XSCRT/Writer.tpp deleted file mode 100644 index 120a830..0000000 --- a/XSCRT/XSCRT/Writer.tpp +++ /dev/null @@ -1,6 +0,0 @@ -// file : XSCRT/Writer.tpp -// author : Boris Kolpackov - -namespace XSCRT -{ -} diff --git a/XSCRT/XSCRT/XML.hpp b/XSCRT/XSCRT/XML.hpp deleted file mode 100644 index effcfa4..0000000 --- a/XSCRT/XSCRT/XML.hpp +++ /dev/null @@ -1,468 +0,0 @@ -// file : XSCRT/XML.hpp -// author : Boris Kolpackov - -#ifndef XSCRT_XML_HPP -#define XSCRT_XML_HPP - -#include -#include -#include "xercesc/dom/DOM.hpp" -#include "xercesc/util/XMLString.hpp" - -//@@ VC6 -#if defined (_MSC_VER) && (_MSC_VER < 1300) -namespace std -{ - using size_t = std::size_t; -} -#endif - -namespace XSCRT -{ - namespace XML - { - //@@ VC6 - // - template - std::basic_string - transcode (XMLCh const* s, C*); - - template - XMLCh* - transcode (std::basic_string const& s); - - // - // - // - class string - { - public : - template - string (std::basic_string const& s) - : s_ (XSCRT::XML::transcode (s)) - { - } - - template - string (C const* s) - : s_ (XSCRT::XML::transcode (s)) - { - } - - ~string () - { - delete[] s_; - } - - XMLCh const* - c_str () const - { - return s_; - } - - private : - XMLCh* s_; - }; - - - template <> - inline - std::basic_string - transcode (XMLCh const* s, char*) - { - if (s == 0) return std::basic_string (); - - char* buf = xercesc::XMLString::transcode (s); - - std::basic_string r (buf); - - xercesc::XMLString::release (&buf); - - return r; - } - - template <> - inline - std::basic_string - transcode (XMLCh const* s, wchar_t*) - { - if (s == 0) return std::basic_string (); - - // std::wcerr << s << std::endl; - - std::basic_string r (xercesc::XMLString::stringLen (s), L'0'); - - for (std::size_t i (0); *s != XMLCh (0); ++s, ++i) - { - r[i] = *s; - } - - return r; - } - - template <> - inline - XMLCh* - transcode (std::basic_string const& s) - { - return xercesc::XMLString::transcode (s.c_str ()); - } - - template <> - inline - XMLCh* - transcode (std::basic_string const& s) - { - //@@ VC6 - std::size_t l = s.length (); - - //@@ VC6 - XMLCh* r = new XMLCh[l + 1]; - XMLCh* ir = r; - - for (std::size_t i (0); i < l; ++ir, ++i) - { - *ir = static_cast(s[i]); - //std::wcerr << s[i] << "->" << *ir << std::endl; - //std::wcerr << s[i]; - } - //std::wcerr << std::endl; - - *ir = XMLCh (0); - - //std::wcerr << r << std::endl; - - return r; - } - - - template - class Element; - - template - std::basic_string - ns_prefix (std::basic_string const& ns, Element const& e); - - template - class Element - { - using string_ = std::basic_string; - - public: - Element (xercesc::DOMElement const* e) - : e_ (nullptr), - ce_ (e), - name_ (transcode (e->getLocalName (), 0)), - namespace__ (transcode (e->getNamespaceURI (), 0)) - { - } - - Element (xercesc::DOMElement* e) - : e_ (e), - ce_ (e), - name_ (transcode (e->getLocalName (), 0)), - namespace__ (transcode (e->getNamespaceURI (), 0)) - { - } - - Element (string_ const& name, Element& parent) - : e_ (nullptr), - ce_ (nullptr), - name_ (name) - { - xercesc::DOMDocument* doc ( - parent.dom_element ()->getOwnerDocument ()); - - e_ = doc->createElement (string (name).c_str ()); - - parent.dom_element ()->appendChild (e_); - - ce_ = e_; - } - - Element (string_ const& name, string_ const& ns, Element& parent) - : e_ (nullptr), - ce_ (nullptr), - name_ (name), - namespace__ (ns) - { - string_ prefix (ns_prefix (ns, parent)); - - xercesc::DOMDocument* doc ( - parent.dom_element ()->getOwnerDocument ()); - - e_ = doc->createElementNS ( - string (ns).c_str (), - string (prefix.empty () - ? name - : prefix + string_ (1, ':') + name).c_str ()); - - parent.dom_element ()->appendChild (e_); - - ce_ = e_; - } - - public: - string_ - name () const - { - return name_; - } - - string_ - namespace_ () const - { - return namespace__; - } - - public: - Element - parent () const - { - return dynamic_cast(ce_->getParentNode ()); - } - - public: - string_ - value () const - { - return XML::transcode (dom_element ()->getTextContent (), 0); - } - - void - value (string_ const& v) - { - xercesc::DOMText* text ( - dom_element ()->getOwnerDocument ()->createTextNode( - string (v).c_str ())); - - dom_element ()->appendChild (text); - } - - public: - string_ - operator[] (string_ const& s) const - { - //@@ VC6 - XMLCh const* value = ce_->getAttribute (string (s).c_str ()); - - return transcode (value, 0); - } - - public: - xercesc::DOMElement const* - dom_element () const - { - return ce_; - } - - xercesc::DOMElement* - dom_element () - { - return e_; - } - - private: - xercesc::DOMElement* e_; - xercesc::DOMElement const* ce_; - - string_ name_; - string_ namespace__; - }; - - - template - class Attribute - { - using string_ = std::basic_string; - - public: - Attribute (xercesc::DOMAttr const* a) - : a_ (nullptr), - ca_ (a), - name_ (transcode (a->getLocalName (), 0)), - value_ (transcode (a->getValue (), 0)) - { - } - - Attribute (xercesc::DOMAttr* a) - : a_ (a), - ca_ (a), - name_ (transcode (a->getLocalName (), 0)), - value_ (transcode (a->getValue (), 0)) - { - } - - Attribute (string_ const& name, - string_ const& v, - Element& parent) - : a_ (nullptr), - ca_ (nullptr), - name_ (name), - value_ () - { - xercesc::DOMDocument* doc ( - parent.dom_element ()->getOwnerDocument ()); - - a_ = doc->createAttribute (string (name).c_str ()); - - value (v); - - parent.dom_element ()->setAttributeNode (a_); - - ca_ = a_; - } - - Attribute (string_ const& name, - string_ const& ns, - string_ const& v, - Element& parent) - : a_ (nullptr), - ca_ (nullptr), - name_ (name), - value_ () - { - string_ prefix (ns_prefix (ns, parent)); - - xercesc::DOMDocument* doc ( - parent.dom_element ()->getOwnerDocument ()); - - a_ = doc->createAttributeNS ( - string (ns).c_str (), - string (prefix.empty () - ? name - : prefix + string_ (1, ':') + name).c_str ()); - - value (v); - - parent.dom_element ()->setAttributeNodeNS (a_); - - ca_ = a_; - } - - string_ - name () const - { - return name_; - } - - string_ - value () const - { - return value_; - } - - void - value (string_ const& v) - { - value_ = v; - a_->setValue (string (v).c_str ()); - } - - public: - xercesc::DOMAttr const* - dom_attribute () const - { - return ca_; - } - - xercesc::DOMAttr* - dom_attribute () - { - return a_; - } - - private: - - private: - xercesc::DOMAttr* a_; - xercesc::DOMAttr const* ca_; - - string_ name_; - string_ value_; - }; - - template - std::basic_string - prefix (std::basic_string const& n) - { - std::size_t i (0); - while (i < n.length () && n[i] != ':') ++i; - - //std::wcerr << "prefix " << n << " " - // << std::wstring (n, i == n.length () ? i : 0, i) << std::endl; - - return std::basic_string (n, i == n.length () ? i : 0, i); - } - - template - std::basic_string - uq_name (std::basic_string const& n) - { - std::size_t i (0); - while (i < n.length () && n[i] != ':') ++i; - - return std::basic_string (n.c_str () + (i == n.length () ? 0 : i + 1)); - } - - template - std::basic_string - ns_name (Element const& e, std::basic_string const& n) - { - std::basic_string wp (prefix (n)); - - //@@ VC6 - XMLCh const* xns = e.dom_element ()->lookupNamespaceURI ( - wp.empty () ? 0 : string (wp).c_str ()); - - - std::basic_string ns ( - xns ? transcode (xns, 0) : std::basic_string ()); - - return ns; - - } - - template - std::basic_string - fq_name (Element const& e, std::basic_string const& n) - { - std::basic_string ns (ns_name (e, n)); - std::basic_string un (uq_name (n)); - - return ns.empty () ? un : (ns + C ('#') + un); - } - - class no_prefix {}; - - template - std::basic_string - ns_prefix (std::basic_string const& ns, Element const& e) - { - string xns (ns); - - XMLCh const* p ( - e.dom_element ()->lookupPrefix (xns.c_str ())); - - if (p == 0) - { - bool r (e.dom_element ()->isDefaultNamespace (xns.c_str ())); - - if (r) - { - return std::basic_string (); - } - else - { - throw no_prefix (); - } - } - - return transcode (p, 0); - } - } -} - -#include - -#endif // XSCRT_XML_HPP diff --git a/XSCRT/XSCRT/XML.tpp b/XSCRT/XSCRT/XML.tpp deleted file mode 100644 index 58019d4..0000000 --- a/XSCRT/XSCRT/XML.tpp +++ /dev/null @@ -1,6 +0,0 @@ -// file : XSCRT/XML.tpp -// author : Boris Kolpackov - -namespace XSCRT -{ -} diff --git a/XSCRT/XSCRT/XSCRT.mpc b/XSCRT/XSCRT/XSCRT.mpc deleted file mode 100644 index ae9f33f..0000000 --- a/XSCRT/XSCRT/XSCRT.mpc +++ /dev/null @@ -1,34 +0,0 @@ -project (XSCRT) : xerces, xsc_utils, xsc_common { - sharedname = XSCRT - after += libXSC - - includes += $(XSC_ROOT) $(XSC_ROOT)/XSCRT - - dynamicflags += XSCRT_HAS_DLL XSCRT_BUILD_DLL - staticflags += XSCRT_AS_STATIC_LIBS - - Source_Files { - - } - - Template_Files { - ./*.tpp - ../XMLSchema/*.tpp - - utils/Buffer_Reader_T.cpp - utils/Buffer_Writer_T.cpp - utils/File_T.cpp - utils/File_Reader_T.cpp - utils/File_Writer_T.cpp - utils/Reader_T.cpp - utils/Writer_T.cpp - utils/Reader_Writer_Base_T.cpp - } - - Inline_Files { - } - - Header_Files { - XSCRT_export.h - } -} diff --git a/XSCRT/XSCRT/XSCRT_export.h b/XSCRT/XSCRT/XSCRT_export.h deleted file mode 100644 index 194fc72..0000000 --- a/XSCRT/XSCRT/XSCRT_export.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef XSCRT_EXPORT_H -#define XSCRT_EXPORT_H - -#if !defined(XSCRT_HAS_DLL) -# if defined(XSCRT_AS_STATIC_LIBS) -# define XSCRT_HAS_DLL 0 -# else -# define XSCRT_HAS_DLL 1 -# endif -#endif - -#if (XSCRT_HAS_DLL == 1) -# if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x550) -# if defined(XSCRT_BUILD_DLL) -# define XSCRT_Export __symbolic -# else -# define XSCRT_Export __global -# endif -# elif defined(WIN32) || defined(UNDER_CE) || defined(__CYGWIN__) -# if defined(XSCRT_BUILD_DLL) -# define XSCRT_Export __declspec(dllexport) -# else -# define XSCRT_Export __declspec(dllimport) -# endif -# elif (defined(__GNUC__) && (__GNUC__ >= 4)) -# if defined(XSCRT_BUILD_DLL) -# define XSCRT_Export __attribute__((visibility("default"))) -# else -# define XSCRT_Export -# endif -# else -# define XSCRT_Export -# endif -#else -# define XSCRT_Export -#endif - -#endif diff --git a/XSCRT/XSCRT/utils/Buffer_Reader_T.cpp b/XSCRT/XSCRT/utils/Buffer_Reader_T.cpp deleted file mode 100644 index 5db251f..0000000 --- a/XSCRT/XSCRT/utils/Buffer_Reader_T.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "xercesc/framework/MemBufInputSource.hpp" -#include "xercesc/framework/Wrapper4InputSource.hpp" -#include "XSC/utils/XercesString.h" -#include - -namespace XSCRT -{ -namespace utils -{ -// -// Buffer_Reader_T -// -template -Buffer_Reader_T :: -Buffer_Reader_T (typename reader_function ::result_type reader, - const CHAR_TYPE * fake_id) -: Reader_T (reader), - fake_id_ (fake_id) -{ - -} - -// -// ~Buffer_Reader_T -// -template -Buffer_Reader_T ::~Buffer_Reader_T () = default; - -// -// open -// -template -bool Buffer_Reader_T ::read (const char * buffer, size_t size) -{ - using namespace xercesc; - - // Open the file for reading. - MemBufInputSource input (reinterpret_cast (buffer), - size, - this->fake_id_); - - this->parser_->parse (input); - - // Get the document. - this->document_ = this->parser_->adoptDocument (); - return this->document_ != nullptr; -} - -} -} diff --git a/XSCRT/XSCRT/utils/Buffer_Reader_T.h b/XSCRT/XSCRT/utils/Buffer_Reader_T.h deleted file mode 100644 index c688d9b..0000000 --- a/XSCRT/XSCRT/utils/Buffer_Reader_T.h +++ /dev/null @@ -1,68 +0,0 @@ -// -*- C++ -*- - -//============================================================================= -/** - * @file Buffer_Reader_T.h - * - * @author James H. Hill - */ -//============================================================================= - -#ifndef _XSCRT_BUFFER_READER_T_H_ -#define _XSCRT_BUFFER_READER_T_H_ - -#include "Reader_T.h" -#include "XSC/utils/XercesString.h" - -namespace XSCRT -{ -namespace utils -{ -/** - * @class Buffer_Reader_T - * - * Utility class for reading a XML document from a file. - */ -template -class Buffer_Reader_T : public Reader_T -{ -public: - /// Type definition of the character type. - using char_type = typename Reader_T::char_type; - - /// Type definition of the entity type. - using entity_type = typename Reader_T::entity_type; - - /** - * Initializing constructor. - * - * @param[in] reader Target reader function - */ - Buffer_Reader_T (typename reader_function ::result_type reader, - const CHAR_TYPE * fake_id); - - /// Destructor. - ~Buffer_Reader_T (); - - /** - * Open the file for reading. This will open the \a filename if - * it exists, and populate contained Xerces-C document. - * - * @param[in] buffer Buffer with XML document. - * @param[in] size Size of XML document. - * @retval true Successfully read XML document. - * @retval false Failed to read XML document. - */ - bool read (const char * buffer, size_t size); - -private: - /// Fake system id for the reader. - XSC::XStr fake_id_; -}; - -} -} - -#include "Buffer_Reader_T.cpp" - -#endif // !defined _XSCRT_BUFFER_READER_T_H_ diff --git a/XSCRT/XSCRT/utils/Buffer_Writer_T.cpp b/XSCRT/XSCRT/utils/Buffer_Writer_T.cpp deleted file mode 100644 index 28f4e23..0000000 --- a/XSCRT/XSCRT/utils/Buffer_Writer_T.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include - -namespace XSCRT -{ -namespace utils -{ -// -// Buffer_Writer_T -// -template -Buffer_Writer_T :: -Buffer_Writer_T (const CHAR_TYPE * ns, - const CHAR_TYPE * root, - typename writer_function ::result_type writer) -: Writer_T (ns, root, writer), - target_ (std::make_unique ()) -{ - this->output_.reset ( - static_cast (this->impl_)->createLSOutput ()); - this->output_->setByteStream (this->target_.get ()); -} - -// -// Buffer_Writer_T -// -template -Buffer_Writer_T ::~Buffer_Writer_T () = default; - -// -// open -// -template -bool Buffer_Writer_T ::write (char * buffer, size_t & size) -{ - // Get the size of the XML document. - size_t copy_n = this->get_buffer_size (); - - if (copy_n > size) - return false; - - // Copy the buffer, and set the size. - ::memcpy (buffer, this->target_->getRawBuffer (), copy_n); - size = copy_n; - return true; -} - -// -// operator <<= -// -template -void Buffer_Writer_T ::operator <<= (const T & entity) -{ - // First, let the base class construct the DOM object. - Writer_T ::operator <<= (entity); - - // Now, save the XML document into an internal buffer. - if (this->dom_writer_) - this->dom_writer_->write (this->document_, this->output_.get ()); -} - -// -// get_buffer_size -// -template -size_t Buffer_Writer_T ::get_buffer_size () const -{ - return this->target_->getLen (); -} - -} -} diff --git a/XSCRT/XSCRT/utils/Buffer_Writer_T.h b/XSCRT/XSCRT/utils/Buffer_Writer_T.h deleted file mode 100644 index 0aa5614..0000000 --- a/XSCRT/XSCRT/utils/Buffer_Writer_T.h +++ /dev/null @@ -1,73 +0,0 @@ -// -*- C++ -*- - -//============================================================================= -/** - * @file Buffer_Writer_T.h - * - * @author James H. Hill - */ -//============================================================================= - -#ifndef _XSCRT_BUFFER_WRITER_H_ -#define _XSCRT_BUFFER_WRITER_H_ - -#include - -#include "Writer_T.h" -#include "xercesc/framework/MemBufFormatTarget.hpp" - -namespace XSCRT -{ -namespace utils -{ - -/** - * @class Buffer_Writer_T - */ -template -class Buffer_Writer_T : public Writer_T -{ -public: - /** - * Initializing constructor. - * - * @param[in] ns Target namespace - * @param[in] root Name of root element - * @param[in] writer Writer function - */ - Buffer_Writer_T (const CHAR_TYPE * ns, - const CHAR_TYPE * root, - typename writer_function ::result_type writer); - - /// Destructor. - ~Buffer_Writer_T (); - - bool write (char * buffer, size_t & size); - - /** - * Insertion operator. - * - * @param[in] entity Target entity. - * @return Reference to the file reader. - */ - void operator <<= (const T & entity); - - /** - * Get the size of the buffer. - * - * @return Size of the buffer in bytes. - */ - size_t get_buffer_size () const; - -private: - std::unique_ptr target_; - - std::unique_ptr output_; -}; - -} -} - -#include "Buffer_Writer_T.cpp" - -#endif // !defined _XSCRT_BUFFER_WRITER_H_ diff --git a/XSCRT/XSCRT/utils/File_Reader_T.cpp b/XSCRT/XSCRT/utils/File_Reader_T.cpp deleted file mode 100644 index deb9f1f..0000000 --- a/XSCRT/XSCRT/utils/File_Reader_T.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "XSC/utils/XercesString.h" - -namespace XSCRT -{ -namespace utils -{ -// -// File_Reader_T -// -template -File_Reader_T :: -File_Reader_T (typename reader_function ::result_type reader) -: Reader_T (reader) -{ - -} - -// -// ~File_Reader_T -// -template -File_Reader_T ::~File_Reader_T () = default; - -// -// open -// -template -bool File_Reader_T ::read (const CHAR_TYPE * filename) -{ - // Parse the specified file. - this->parser_->parse (filename); - this->document_ = this->parser_->adoptDocument (); - - return this->document_ != nullptr; -} - -} -} diff --git a/XSCRT/XSCRT/utils/File_Reader_T.h b/XSCRT/XSCRT/utils/File_Reader_T.h deleted file mode 100644 index bab3eec..0000000 --- a/XSCRT/XSCRT/utils/File_Reader_T.h +++ /dev/null @@ -1,61 +0,0 @@ -// -*- C++ -*- - -//============================================================================= -/** - * @file File_Reader_T.h - * - * @author James H. Hill - */ -//============================================================================= - -#ifndef _XSCRT_FILE_READER_T_H_ -#define _XSCRT_FILE_READER_T_H_ - -#include "Reader_T.h" - -namespace XSCRT -{ -namespace utils -{ -/** - * @class File_Reader_T - * - * Utility class for reading a XML document from a file. - */ -template -class File_Reader_T : public Reader_T -{ -public: - /// Type definition of the character type. - using char_type = typename Reader_T::char_type; - - /// Type definition of the entity type. - using entity_type = typename Reader_T::entity_type; - - /** - * Initializing constructor. - * - * @param[in] reader Target reader function - */ - File_Reader_T (typename reader_function ::result_type reader); - - /// Destructor. - ~File_Reader_T (); - - /** - * Open the file for reading. This will open the \a filename if - * it exists, and populate contained Xerces-C document. - * - * @param[in] filename Name of the XML file. - * @retval true Successfully opened file. - * @retval false Failed to open file. - */ - bool read (const CHAR_TYPE * filename); -}; - -} -} - -#include "File_Reader_T.cpp" - -#endif // !defined _XSCRT_FILE_READER_T_H_ diff --git a/XSCRT/XSCRT/utils/File_Writer_T.cpp b/XSCRT/XSCRT/utils/File_Writer_T.cpp deleted file mode 100644 index a2f6a63..0000000 --- a/XSCRT/XSCRT/utils/File_Writer_T.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include - -#include "xercesc/framework/LocalFileFormatTarget.hpp" - -namespace XSCRT -{ -namespace utils -{ -// -// File_Writer_T -// -template -File_Writer_T :: -File_Writer_T (const CHAR_TYPE * ns, - const CHAR_TYPE * root, - typename writer_function ::result_type writer) -: Writer_T (ns, root, writer) -{ - -} - -// -// File_Writer_T -// -template -File_Writer_T ::~File_Writer_T () = default; - -// -// open -// -template -bool File_Writer_T ::write (const CHAR_TYPE * filename) -{ - auto target_file = std::make_unique ( - XSC::XStr (filename)); - - // Write the element to the target. - if (this->dom_writer_) - return this->dom_writer_->writeNode (target_file.get (), *this->document_); - - return false; -} - -} -} diff --git a/XSCRT/XSCRT/utils/File_Writer_T.h b/XSCRT/XSCRT/utils/File_Writer_T.h deleted file mode 100644 index 50e4369..0000000 --- a/XSCRT/XSCRT/utils/File_Writer_T.h +++ /dev/null @@ -1,50 +0,0 @@ -// -*- C++ -*- - -//============================================================================= -/** - * @file File_Writer_T.h - * - * @author James H. Hill - */ -//============================================================================= - -#ifndef _XSCRT_FILE_WRITER_H_ -#define _XSCRT_FILE_WRITER_H_ - -#include "Writer_T.h" - -namespace XSCRT -{ -namespace utils -{ - -/** - * @class File_Writer_T - */ -template -class File_Writer_T : public Writer_T -{ -public: - /** - * Initializing constructor. - * - * @param[in] ns Target namespace - * @param[in] root Name of root element - * @param[in] writer Writer function - */ - File_Writer_T (const CHAR_TYPE * ns, - const CHAR_TYPE * root, - typename writer_function ::result_type writer); - - /// Destructor. - ~File_Writer_T (); - - bool write (const CHAR_TYPE * filename); -}; - -} -} - -#include "File_Writer_T.cpp" - -#endif // !defined _XSCRT_FILE_WRITER_H_ diff --git a/XSCRT/XSCRT/utils/Reader_T.cpp b/XSCRT/XSCRT/utils/Reader_T.cpp deleted file mode 100644 index 104d91d..0000000 --- a/XSCRT/XSCRT/utils/Reader_T.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "xercesc/util/XMLUniDefs.hpp" - -namespace XSCRT -{ -namespace utils -{ -// -// File_Reader_T -// -template -Reader_T :: -Reader_T (typename reader_function ::result_type reader) -: parser_ (std::make_unique ()), - reader_ (reader) -{ -} - -// -// ~File_Reader_T -// -template -Reader_T ::~Reader_T () = default; - -// -// operator >>= -// -template -void Reader_T ::operator >>= (T & entity) const -{ - if (this->reader_ && this->document_) - entity = (*this->reader_) (this->document_); -} - -// -// parser -// -template -xercesc::XercesDOMParser * Reader_T ::operator -> () -{ - return this->parser_.get (); -} - -} -} diff --git a/XSCRT/XSCRT/utils/Reader_T.h b/XSCRT/XSCRT/utils/Reader_T.h deleted file mode 100644 index 14a23e4..0000000 --- a/XSCRT/XSCRT/utils/Reader_T.h +++ /dev/null @@ -1,87 +0,0 @@ -// -*- C++ -*- - -//============================================================================= -/** - * @file Reader_T.h - * - * @author James H. Hill - */ -//============================================================================= - -#ifndef _XSCRT_READER_T_H_ -#define _XSCRT_READER_T_H_ - -#include "Reader_Writer_Base_T.h" -#include "xercesc/util/XercesDefs.hpp" -#include "xercesc/parsers/XercesDOMParser.hpp" -#include - -namespace XSCRT -{ -namespace utils -{ -/** - * @struct reader_function - * - * Trait for determining an XSC element's reader function signature. - */ -template -struct reader_function -{ - /// Type definition of the reading function signature. - using result_type = T (*) (const xercesc::DOMDocument *); -}; - -/** - * @class Reader_T - * - * Base class for reading data from an XML document. - */ -template -class Reader_T : public Reader_Writer_Base_T -{ -public: - /// Type definition of the entity type. - using entity_type = typename Reader_Writer_Base_T::entity_type; - - /// Type definition of the character type. - using char_type = typename Reader_Writer_Base_T::char_type; - - /// Destructor. - virtual ~Reader_T (); - - /** - * Extraction operator. - * - * @param[in] entity Target entity. - */ - void operator >>= (T & entity) const; - - /** - * Get the underlying parser. This will allow the client to - * modify its properties. - * - * @return Pointer to the parser. - */ - xercesc::XercesDOMParser * operator -> (); - -protected: - /** - * Default constructor. - * - * @param[in] reader Reader function. - */ - Reader_T (typename reader_function ::result_type reader); - - /// DOM parser for the reader. - std::unique_ptr parser_; - - /// The entity read from the document. - typename reader_function ::result_type reader_; -}; -} -} - -#include "Reader_T.cpp" - -#endif // !defined _XSCRT_READER_T_H_ diff --git a/XSCRT/XSCRT/utils/Reader_Writer_Base_T.cpp b/XSCRT/XSCRT/utils/Reader_Writer_Base_T.cpp deleted file mode 100644 index 69de7fb..0000000 --- a/XSCRT/XSCRT/utils/Reader_Writer_Base_T.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "xercesc/util/XMLUniDefs.hpp" - -namespace XSCRT -{ -namespace utils -{ -// -// Reader_Writer_Base_T -// -template -Reader_Writer_Base_T ::Reader_Writer_Base_T () -: impl_ (nullptr), - document_ (nullptr) -{ - xercesc::XMLPlatformUtils::Initialize (); - - // Get default implementation, which is Load-Store (LS) interface. - static const XMLCh gLS[] = { xercesc::chLatin_L, - xercesc::chLatin_S, - xercesc::chNull }; - - this->impl_ = - xercesc::DOMImplementationRegistry::getDOMImplementation (gLS); -} - -// -// ~Reader_Writer_Base_T -// -template -Reader_Writer_Base_T ::~Reader_Writer_Base_T () -{ - if (this->document_ != nullptr) - this->document_->release (); -} - -template -xercesc::DOMDocument * const -Reader_Writer_Base_T ::document () -{ - return this->document_; -} - -} -} diff --git a/XSCRT/XSCRT/utils/Reader_Writer_Base_T.h b/XSCRT/XSCRT/utils/Reader_Writer_Base_T.h deleted file mode 100644 index 0916d70..0000000 --- a/XSCRT/XSCRT/utils/Reader_Writer_Base_T.h +++ /dev/null @@ -1,56 +0,0 @@ -// -*- C++ -*- - -//============================================================================= -/** - * @file Reader_Writer_Base_T.h - * - * - * - * @author James H. Hill - */ -//============================================================================= - -#ifndef _READER_WRITER_BASE_T_H_ -#define _READER_WRITER_BASE_T_H_ - -#include "xercesc/dom/DOM.hpp" - -namespace XSCRT -{ -namespace utils -{ -/** - * @class Reader_Writer_Base_T - */ -template -class Reader_Writer_Base_T -{ -public: - /// Type definition of the entity type. - using entity_type = T; - - /// Type definition of the char type. - using char_type = CHAR_TYPE; - - /// Destructor. - ~Reader_Writer_Base_T (); - - xercesc::DOMDocument * const document (); - -protected: - /// Default constructor. - Reader_Writer_Base_T (); - - /// Implementation shared between all files. - xercesc::DOMImplementation * impl_; - - /// The underlying Xerces-C document. - xercesc::DOMDocument * document_; -}; - -} -} - -#include "Reader_Writer_Base_T.cpp" - -#endif // !defined _READER_WRITER_BASE_T_H_ diff --git a/XSCRT/XSCRT/utils/Writer_T.cpp b/XSCRT/XSCRT/utils/Writer_T.cpp deleted file mode 100644 index 13229bc..0000000 --- a/XSCRT/XSCRT/utils/Writer_T.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "XSC/utils/XercesString.h" - -namespace XSCRT -{ -namespace utils -{ - -// -// Writer_T -// -template -Writer_T :: -Writer_T (const CHAR_TYPE * ns, - const CHAR_TYPE * root, - typename writer_function ::result_type writer) -: writer_ (writer), - dom_writer_ (nullptr) -{ - // Create an empty XML document. - this->document_ = - this->impl_->createDocument (XSC::XStr (ns), XSC::XStr (root), nullptr); - - // Create a DOMWriter for this writer. - this->dom_writer_ = - ((xercesc::DOMImplementationLS *)this->impl_)->createLSSerializer (); -} - -// -// ~Writer_T -// -template -Writer_T ::~Writer_T () -{ - if (this->dom_writer_ != nullptr) - this->dom_writer_->release (); -} - -// -// operator <<= -// -template -void Writer_T ::operator <<= (const T & entity) -{ - if (this->writer_ != nullptr && this->document_ != nullptr) - (*this->writer_) (entity, this->document_); -} - -// -// writer -// -template -xercesc::DOMLSSerializer * const Writer_T ::writer () -{ - return this->dom_writer_; -} - -} -} diff --git a/XSCRT/XSCRT/utils/Writer_T.h b/XSCRT/XSCRT/utils/Writer_T.h deleted file mode 100644 index 2734c63..0000000 --- a/XSCRT/XSCRT/utils/Writer_T.h +++ /dev/null @@ -1,70 +0,0 @@ -//============================================================================= -/** - * @file Writer_T.h - * - * @author James H. Hill - */ -//============================================================================= - -#ifndef _XSCRT_WRITER_T_H_ -#define _XSCRT_WRITER_T_H_ - -#include -#include "xercesc/framework/XMLFormatter.hpp" -#include "Reader_Writer_Base_T.h" - -namespace XSCRT -{ -namespace utils -{ -/** - * @struct writer_function - * - * Trait for determining an XSC element's writer function signature. - */ -template -struct writer_function -{ - /// Type definition of the writing function signature. - using result_type = void (*) (T const &, xercesc::DOMDocument *); -}; - -/** - * @class Writer_T - */ -template -class Writer_T : public Reader_Writer_Base_T -{ -public: - /// Destructor. - ~Writer_T (); - - /** - * Insertion operator. - * - * @param[in] entity Target entity. - * @return Reference to the file reader. - */ - void operator <<= (const T & entity); - - xercesc::DOMLSSerializer * const writer (); - -protected: - /** - * - */ - Writer_T (const CHAR_TYPE * ns, - const CHAR_TYPE * root, - typename writer_function ::result_type writer); - - typename writer_function ::result_type writer_; - - xercesc::DOMLSSerializer * dom_writer_; -}; - -} -} - -#include "Writer_T.cpp" - -#endif // !defined _XSCRT_WRITER_T_H_ From 75eabbb7c49abba264f36b90fa3774efe1b98194 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 16:25:03 +0200 Subject: [PATCH 03/20] Keep local CDR types pending ACE release --- XSC/be/CXX/Header.cpp | 2 +- XSCRT/XMLSchema/CDR_Types.hpp | 75 +++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 XSCRT/XMLSchema/CDR_Types.hpp diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index e22d71e..856abeb 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -950,7 +950,7 @@ generate_header (Context& ctx, if (ctx.cdr_reader_generation_enabled () || ctx.cdr_writer_generation_enabled ()) { - ctx.os << "#include \"ace/XML_Utils/XMLSchema/CDR_Types.hpp\"" << std::endl + ctx.os << "#include \"XMLSchema/CDR_Types.hpp\"" << std::endl << "#include \"XMLSchema/id_map.hpp\"" << std::endl << std::endl; if (ctx.cppmode() == Context::CPPMODE::CPP03) diff --git a/XSCRT/XMLSchema/CDR_Types.hpp b/XSCRT/XMLSchema/CDR_Types.hpp new file mode 100644 index 0000000..f35bac1 --- /dev/null +++ b/XSCRT/XMLSchema/CDR_Types.hpp @@ -0,0 +1,75 @@ +// file : XMLSchema/CDR_Types.hpp +// author : Arvind S. Krishna + +#ifndef XMLSCHEMA_CDR_TYPES_HPP +#define XMLSCHEMA_CDR_TYPES_HPP + +//-- ACE includes +#include "ace/CDR_Stream.h" + +/* + * Following typedefs define generic Stream interfaces + * for (de) marshaling XML types generated by XSC. + * We leverage the ACE_CDRInput and ACE_CDROutput + * stream classes that provides reusable classes for + * encoding data using the Common Data Representation + * encoding format. + * + * A corresponding traits class for argument passing + * is also provided for enabling a clean CORBA like + * semantics for passing arguments. + * + * Different encoding schemes such as + * XDR encoding schemes should define similar types. + */ + +namespace XMLSchema +{ + // CDR Reader/Writer Stream Type + typedef ACE_OutputCDR CDR_OutputStream; + typedef ACE_InputCDR CDR_InputStream; + + // An argument traits class that defines + // parameter passing in a CORBA like syntax + // NOTE: Mainly in place for reference types. + // Need to specialize for pointer types + template + struct cdr_arg_traits + { + typedef T const & in_type; + typedef T & out_type; + typedef T ret_type; + typedef T *& inout_type; + }; +} + +template +bool +operator << (::XMLSchema::CDR_OutputStream &stream, + const ::XMLSchema::string < T > &element) +{ + // For strings types, conver to the c style string + // representations that can be marshaled + return (stream << element.c_str ()); +} + +template +bool +operator << (::XMLSchema::CDR_OutputStream &stream, + const ::XMLSchema::IDREF < T > &element) +{ + // Marshal the ID stored in the IDREF + // id () operations returns a NCName which + // itself is a string + return (stream << element.id ().c_str ()); +} + +template +void +operator << (::XMLSchema::CDR_OutputStream &stream, + const ::XMLSchema::ID &element) +{ + stream << element.c_str (); +} + +#endif //XMLSCHEMA_CDR_TYPES_HPP From 69361413b51de9a526b0a95d01f75f339be177eb Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 16:45:07 +0200 Subject: [PATCH 04/20] Modernize C++17 generated code --- .github/workflows/linux.yml | 11 ++++++++++ Tests/DanceX11/README.md | 4 +++- Tests/DanceX11/dancex11.mpc | 12 +++++++++++ Tests/DanceX11/optional_copy.cpp | 14 +++++++++++++ Tests/DanceX11/run_test.pl | 35 ++++++++++++++++++++++++++++++++ XSC/be/CXX/Generator.cpp | 1 + XSC/be/CXX/Inline.cpp | 8 ++++---- XSC/be/CXX/ParserSource.cpp | 5 +++-- XSC/be/CXX/Source.cpp | 31 +++++++++++++++++++--------- XSC/be/CXX/WriterSource.cpp | 5 +++-- 10 files changed, 107 insertions(+), 19 deletions(-) create mode 100644 Tests/DanceX11/optional_copy.cpp create mode 100644 Tests/DanceX11/run_test.pl diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 6322164..2721797 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -117,3 +117,14 @@ jobs: Pop-Location } shell: pwsh + - name: Run DanceX11 generated-code test + run: | + Push-Location ${env:XSC_ROOT}/Tests/DanceX11 + try { + perl run_test.pl + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + } + finally { + Pop-Location + } + shell: pwsh diff --git a/Tests/DanceX11/README.md b/Tests/DanceX11/README.md index bf01aca..8d3f833 100644 --- a/Tests/DanceX11/README.md +++ b/Tests/DanceX11/README.md @@ -4,4 +4,6 @@ This directory archives the XSD inputs listed in the `DANCEX11_XSC_XML_Generatio project in [DanceX11's config-handler build](https://github.com/RemedyIT/dancex11/blob/master/tools/config_handlers/config_handlers.mpc). They provide a regression corpus for XSC generation and C++17 compilation. The schemas were imported from `etc/schema` in the DanceX11 repository; no generated -C++ is checked in here. +C++ is checked in here. The MPC test explicitly requests C++17 output and +generates writer types. Its runtime test verifies that copy-assigning an unset +optional member clears a previously set value. diff --git a/Tests/DanceX11/dancex11.mpc b/Tests/DanceX11/dancex11.mpc index fe14888..42fd92f 100644 --- a/Tests/DanceX11/dancex11.mpc +++ b/Tests/DanceX11/dancex11.mpc @@ -4,7 +4,9 @@ project (xsc_test_dancex11): xscdefaults { requires += xsc custom_only = 1 + xscflags += --cxx-cpp17 xscflags += --cxx-char-type char + xscflags += --cxx-generate-writer-types xscflags += --search-path . XSC_Files { @@ -42,3 +44,13 @@ project (xsc_test_dancex11_generated): xscrt { toplevel.cpp } } + +project (xsc_test_dancex11_optional_copy): xscrt { + after += xsc_test_dancex11_generated + libs += CXX IDL + + Source_Files { + Basic_Deployment_Data.cpp + optional_copy.cpp + } +} diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp new file mode 100644 index 0000000..d48d45c --- /dev/null +++ b/Tests/DanceX11/optional_copy.cpp @@ -0,0 +1,14 @@ +#include "Basic_Deployment_Data.hpp" + +int +main () +{ + Deployment::IdRef destination; + XMLSchema::string href ("urn:destination"); + destination.href (href); + + Deployment::IdRef source; + destination = source; + + return destination.href_p () ? 1 : 0; +} diff --git a/Tests/DanceX11/run_test.pl b/Tests/DanceX11/run_test.pl new file mode 100644 index 0000000..225fdb8 --- /dev/null +++ b/Tests/DanceX11/run_test.pl @@ -0,0 +1,35 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +use strict; +use warnings; + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +my $status = 0; +my $target = PerlACE::TestTarget::create_target (1) + || die "Create target 1 failed\n"; + +my $test = "$ENV{XSC_ROOT}/Tests/DanceX11/optional_copy"; +unless (-x $test) { + die "ERROR: Cannot find executable $test\n"; +} + +my $process = $target->CreateProcess ($test); +my $result = $process->SpawnWaitKill ($target->ProcessStartWaitInterval ()); + +if ($result == -1) { + print STDERR "ERROR: DanceX11 optional-copy test could not be started or timed out\n"; + $status = 1; +} +elsif ($result != 0) { + print STDERR "ERROR: generated copy assignment did not clear the optional href\n"; + $status = 1; +} +else { + print "DanceX11 generated copy assignment passed\n"; +} + +exit $status; diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index ca9cc0e..741912c 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -409,6 +409,7 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con // CXX // cxx << "#include \"" << hxx_name.c_str () << "\"" << std::endl + << "#include " << std::endl << std::endl; { diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 35f57da..0570583 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -57,7 +57,7 @@ namespace if (this->cppmode_ != CPPMODE::CPP03) { - os << "return !!" << id (name) << "_;"; + os << "return static_cast (" << id (name) << "_);"; } else { @@ -300,7 +300,7 @@ namespace << "bool " << scope << "::" << std::endl << name << "_p () const" << "{" - << "return !!" << id (name) << "_;" + << "return static_cast (" << id (name) << "_);" << "}"; } else @@ -1160,7 +1160,7 @@ namespace os << "if (s." << name << "_)" << std::endl << " " << name << " (*(s." << name << "_));" << "else" << std::endl - << " " << name << "_.release ();" + << " " << name << "_.reset ();" << std::endl; } else @@ -1203,7 +1203,7 @@ namespace { os << "if (s." << name << "_) " << name << " (*(s." << name << "_));" - << "else " << name << "_.release ();" + << "else " << name << "_.reset ();" << std::endl; } else diff --git a/XSC/be/CXX/ParserSource.cpp b/XSC/be/CXX/ParserSource.cpp index db8f3b2..1e64bb1 100644 --- a/XSC/be/CXX/ParserSource.cpp +++ b/XSC/be/CXX/ParserSource.cpp @@ -52,7 +52,7 @@ namespace os << "xercesc::DOMElement* dom_element = d->getDocumentElement ();" << "if (!dom_element)" << "{" - << "throw 1;" + << "throw std::runtime_error (\"XML document has no root element\");" << "}" << xml_element_type << " e (dom_element);" << "if (e.name () == " << compare_name << ")" @@ -67,7 +67,8 @@ namespace << "}" << "else" << "{" - << "throw 1;" + << "throw std::runtime_error (\"unexpected XML root element; expected <" + << name << ">\");" << "}" << "}" << "}"; diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 06c27b2..89ac589 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -64,8 +64,7 @@ namespace // if (this->cppmode_ != CPPMODE::CPP03) { - os << type << " t (e);"; - os << id (name) << "_.push_back (t);"; + os << id (name) << "_.emplace_back (e);"; } else @@ -583,6 +582,14 @@ namespace } } + string + smart_pointer_type () const + { + return this->cppmode_ == CPPMODE::CPP03 + ? L"std::auto_ptr" + : L"std::unique_ptr"; + } + /* * Reading a pointer type. * A type which is read in via the pointer semantics. This @@ -599,7 +606,7 @@ namespace read_pointer_type (string &element_name, string &type) { os << "stream >> " << element_name << "_tmp;" - << "std::auto_ptr < " << type << "::CDR_Type__ > " + << this->smart_pointer_type () << " < " << type << "::CDR_Type__ > " << "auto_" << element_name << " (" << element_name << "_tmp);" << type << " " << element_name << " (" << element_name << "_tmp);" @@ -614,7 +621,7 @@ namespace read_complex_type (string &element_name, string &type) { os << "stream >> " << element_name << ";" - << "std::auto_ptr < " << type << " > " + << this->smart_pointer_type () << " < " << type << " > " << "auto_" << element_name << " (" << element_name << ");" << std::endl; } @@ -682,13 +689,17 @@ namespace bool pointer_semantics = read_type_as_pointer (type); if (pointer_semantics) - os << type << "::CDR_Type__ *" << element_name << "_tmp (0)" - << ";" - << "std::auto_ptr < " << type << "::CDR_Type__ > " - << "auto_" << element_name << " (" << element_name << "_tmp);"; + { + os << type << "::CDR_Type__ *" << element_name << "_tmp (0)" + << ";" + << this->smart_pointer_type () << " < " << type << "::CDR_Type__ > " + << "auto_" << element_name << " (" << element_name << "_tmp);"; + } else - os << type << "::CDR_Type__ " << element_name << "_tmp" - << ";" ; + { + os << type << "::CDR_Type__ " << element_name << "_tmp" + << ";"; + } os << "if (" << element_name << "_p)" << "{"; diff --git a/XSC/be/CXX/WriterSource.cpp b/XSC/be/CXX/WriterSource.cpp index f9d3b7a..a5c2e03 100644 --- a/XSC/be/CXX/WriterSource.cpp +++ b/XSC/be/CXX/WriterSource.cpp @@ -540,12 +540,13 @@ namespace << "xercesc::DOMElement* dom_element = d->getDocumentElement ();" << "if (!dom_element)" << "{" - << "throw 1;" + << "throw std::runtime_error (\"XML document has no root element\");" << "}" << xml_element_type << " e (dom_element);" << "if (e.name () != " << L << " (\"" << name << "\"))" << "{" - << "throw 1;" + << "throw std::runtime_error (\"unexpected XML root element; expected <" + << name << ">\");" << "}"; os << "struct W : "; From 77f9b658ead4dc9373ec4d3c324da6e483acd23d Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 16:47:49 +0200 Subject: [PATCH 05/20] Modernize generated declarations --- XSC/be/CXX/Source.cpp | 22 ++++++++++++++++------ XSC/be/CXX/TraversalHeader.cpp | 5 +++-- XSC/be/CXX/WriterHeader.cpp | 6 ++++-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 89ac589..9e80493 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -590,6 +590,12 @@ namespace : L"std::unique_ptr"; } + string + null_pointer () const + { + return this->cppmode_ == CPPMODE::CPP03 ? L"0" : L"nullptr"; + } + /* * Reading a pointer type. * A type which is read in via the pointer semantics. This @@ -660,7 +666,8 @@ namespace bool pointer_semantics = read_type_as_pointer (type); if (pointer_semantics) - os << type << "::CDR_Type__ *" << element_name << "_tmp (0)" + os << type << "::CDR_Type__ *" << element_name << "_tmp (" + << this->null_pointer () << ")" << ";" ; else os << type << "::CDR_Type__ " << element_name << "_tmp" @@ -690,7 +697,8 @@ namespace if (pointer_semantics) { - os << type << "::CDR_Type__ *" << element_name << "_tmp (0)" + os << type << "::CDR_Type__ *" << element_name << "_tmp (" + << this->null_pointer () << ")" << ";" << this->smart_pointer_type () << " < " << type << "::CDR_Type__ > " << "auto_" << element_name << " (" << element_name << "_tmp);"; @@ -765,7 +773,7 @@ namespace if (b == e) { - os << type << " *" << name << " (0);"; + os << type << " *" << name << " (" << this->null_pointer () << ");"; read_complex_type (name, type); this->type_name_list_.push_back (L"*" + name); return; @@ -782,7 +790,7 @@ namespace if (has (*c) || dynamic_cast (&t)) { - os << type << " *" << name << "(0);"; + os << type << " *" << name << " (" << this->null_pointer () << ");"; read_complex_type (name, type); this->type_name_list_.push_back (L"*" + name); return; @@ -797,7 +805,8 @@ namespace string base_type (type_name ((**b).inheritee ())); if (read_type_as_pointer (base_type)) { - os << base_type << "::CDR_Type__ *" << name << "_tmp (0);"; + os << base_type << "::CDR_Type__ *" << name << "_tmp (" + << this->null_pointer () << ");"; read_pointer_type (name, base_type); } else @@ -813,7 +822,8 @@ namespace // Simple type: i.e. XMLSchema::boolean, XMLSchema::integer if (read_type_as_pointer (type)) { - os << type << "::CDR_Type__ *" << name << "_tmp (0);"; + os << type << "::CDR_Type__ *" << name << "_tmp (" + << this->null_pointer () << ");"; read_pointer_type (name, type); } else diff --git a/XSC/be/CXX/TraversalHeader.cpp b/XSC/be/CXX/TraversalHeader.cpp index 2d7a569..d96f9ad 100644 --- a/XSC/be/CXX/TraversalHeader.cpp +++ b/XSC/be/CXX/TraversalHeader.cpp @@ -258,6 +258,7 @@ namespace virtual void pre (Type& c) { + string virtual_string (this->cppmode_ == CPPMODE::CPP03 ? L"virtual " : L""); string override_string (this->cppmode_ != CPPMODE::CPP03 ? L" override" : L""); os << "struct " << e << name_ @@ -266,11 +267,11 @@ namespace // traverse () // - os << "virtual void" << std::endl + os << virtual_string << "void" << std::endl << "traverse (Type&)" << override_string << ";" << std::endl; - os << "virtual void" << std::endl + os << virtual_string << "void" << std::endl << "traverse (Type const&)" << override_string << ";" << std::endl; diff --git a/XSC/be/CXX/WriterHeader.cpp b/XSC/be/CXX/WriterHeader.cpp index b6a4edc..930de3a 100644 --- a/XSC/be/CXX/WriterHeader.cpp +++ b/XSC/be/CXX/WriterHeader.cpp @@ -280,11 +280,12 @@ namespace << "}"; } + string virtual_string (this->cppmode_ == CPPMODE::CPP03 ? L"virtual " : L""); string override_string (this->cppmode_ != CPPMODE::CPP03 ? L" override" : L""); // traverse // - os << "virtual void" << std::endl + os << virtual_string << "void" << std::endl << "traverse (Type const&)" << override_string << ";" << std::endl; } @@ -323,6 +324,7 @@ namespace { string name ((this->name_ != L"") ? name_ : id (e.name ())); string type (type_name (e)); + string virtual_string (this->cppmode_ == CPPMODE::CPP03 ? L"virtual " : L""); string override_string (this->cppmode_ != CPPMODE::CPP03 ? L" override" : L""); string default_string (this->cppmode_ != CPPMODE::CPP03 ? L" = default" : L""); @@ -350,7 +352,7 @@ namespace // traverse // - os << "virtual void" << std::endl + os << virtual_string << "void" << std::endl << "traverse (Type const&)" << override_string << ";" << std::endl; From 155d503edcb27a048bc8c07324651c4ebd6ef7a4 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 16:51:00 +0200 Subject: [PATCH 06/20] Default copies for sequence-only schema types --- Tests/DanceX11/optional_copy.cpp | 4 ++ XSC/be/CXX/Elements.hpp | 30 +++++++++++ XSC/be/CXX/Header.cpp | 9 +++- XSC/be/CXX/Inline.cpp | 86 +++++++++++++++++--------------- 4 files changed, 87 insertions(+), 42 deletions(-) diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp index d48d45c..7e6580d 100644 --- a/Tests/DanceX11/optional_copy.cpp +++ b/Tests/DanceX11/optional_copy.cpp @@ -3,6 +3,10 @@ int main () { + Deployment::DataValue sequence; + Deployment::DataValue sequence_copy (sequence); + sequence_copy = sequence; + Deployment::IdRef destination; XMLSchema::string href ("urn:destination"); destination.href (href); diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index fcb5504..a9ca6ee 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -480,6 +480,36 @@ has (Y& y) return r; } +struct CopyRequiredMembers : Traversal::Element, Traversal::Attribute +{ + void + traverse (SemanticGraph::Element& e) override + { + if (e.max () == 1) + required = true; + } + + void + traverse (SemanticGraph::Attribute&) override + { + required = true; + } + + bool required {}; +}; + +inline bool +has_copy_required_members (SemanticGraph::Complex& c) +{ + CopyRequiredMembers t; + Traversal::Scope s; + Traversal::Names n; + s.edge_traverser (n); + n.node_traverser (t); + s.traverse (c); + return t.required; +} + // Fundamental type mapping helper. // struct Fundamental : Traversal::FundamentalType, diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 856abeb..11c6207 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -594,11 +594,16 @@ namespace // copy c-tor // - os << name << " (" << name << " const& s);"; + bool const default_copy (this->cppmode_ == CPPMODE::CPP17 && + !has_copy_required_members (c)); + + os << name << " (" << name << " const& s)" + << (default_copy ? " = default;" : ";"); // operator= // - os << name << "& operator= (" << name << " const& s);" + os << name << "& operator= (" << name << " const& s)" + << (default_copy ? " = default;" : ";") << std::endl; if (this->cppmode_ != CPPMODE::CPP03) diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 0570583..9a45caa 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -595,59 +595,65 @@ namespace os << "}"; - // copy c-tor - // - os << i - << scope << "::" - << name << " (" << type << " const& s)" << std::endl; + bool const default_copy (this->cppmode_ == CPPMODE::CPP17 && + !has_copy_required_members (c)); - if (!has_base) + if (!default_copy) { - os << ": ::XSCRT::Type (s)" << std::endl; - } + // copy c-tor + // + os << i + << scope << "::" + << name << " (" << type << " const& s)" << std::endl; - // Resets a flag that determines if a Complex Type's - // copy constructor has inherited from the base XSCRT::Type - // class. - copy_.reset_base_class_initialization (); + if (!has_base) + { + os << ": ::XSCRT::Type (s)" << std::endl; + } - inherits (c, copy_base_); + // Resets a flag that determines if a Complex Type's + // copy constructor has inherited from the base XSCRT::Type + // class. + copy_.reset_base_class_initialization (); - names (c, copy_member_); + inherits (c, copy_base_); - os << "{"; + names (c, copy_member_); - names (c, copy_body_member_); + os << "{"; - os << "}"; + names (c, copy_body_member_); - std::wstring selfcheck; - if (this->cppmode_ != CPPMODE::CPP03) - { - selfcheck = L"if (std::addressof(s) != this)"; - } - else - { - selfcheck = L"if (&s != this)"; - } + os << "}"; - // operator= - // - os << i - << scope << "&" << std::endl - << scope << "::operator= (" << type << " const& s)" - << "{" - << selfcheck - << "{"; + std::wstring selfcheck; + if (this->cppmode_ != CPPMODE::CPP03) + { + selfcheck = L"if (std::addressof(s) != this)"; + } + else + { + selfcheck = L"if (&s != this)"; + } - inherits (c, assign_base_); - names (c, assign_member_); + // operator= + // + os << i + << scope << "&" << std::endl + << scope << "::operator= (" << type << " const& s)" + << "{" + << selfcheck + << "{"; - os << "}" - << "return *this;" - << "}"; + inherits (c, assign_base_); + names (c, assign_member_); - os << std::endl; + os << "}" + << "return *this;" + << "}"; + + os << std::endl; + } } void From deb84d3c206481c1933287dd83a457c2e51d421e Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 17:05:37 +0200 Subject: [PATCH 07/20] Use range loops in CDR sequence writers --- XSC/be/CXX/Source.cpp | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 9e80493..c2fe54a 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -358,26 +358,40 @@ namespace // Write length first os << "// " << name << std::endl; os << "size_t " << name << "_size = " - << "this->" << name << "_.size ();" + << "this->" << id (name) << "_.size ();" << "stream << " << name << "_size;" << std::endl; // Write each member next - os << "for (" << name << "_const_iterator " - << name << "_iter = " << "this->begin_" << name << " ();" - << " " << name << "_iter != this->end_" << name - << " ();" - << " ++" << name << "_iter)" - << "{"; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << "for (" << name << "_const_iterator " + << name << "_iter = " << "this->begin_" << name << " ();" + << " " << name << "_iter != this->end_" << name + << " ();" + << " ++" << name << "_iter)" + << "{"; - // Check if the type being written is a boolean - // type - if (type_is_boolean (type)) - os << "stream.write_boolean (*" << name << ");"; + if (type_is_boolean (type)) + os << "stream.write_boolean (*" << name << "_iter);"; + else + os << "stream << (*" << name << "_iter);"; + + os << "}"; + } else - os << "stream << (*" << name << "_iter);"; + { + os << "for (auto const& " << name << "_value : this->" + << id (name) << "_)" + << "{"; - os << "}"; + if (type_is_boolean (type)) + os << "stream.write_boolean (" << name << "_value);"; + else + os << "stream << " << name << "_value;"; + + os << "}"; + } } virtual void From 9baca710fbbb40bda80b778e675ba65ba5b0b79a Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 17:15:49 +0200 Subject: [PATCH 08/20] Replace unsafe optional field accessors --- XSC/be/CXX/Header.cpp | 28 +++++++++--- XSC/be/CXX/Inline.cpp | 74 +++++++++++++++++-------------- XSC/be/CXX/Source.cpp | 58 ++++++++++++++++++------ XSC/be/CXX/TraversalSource.cpp | 80 ++++++++++++++++++++++++---------- 4 files changed, 165 insertions(+), 75 deletions(-) diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 856abeb..de6e871 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -237,8 +237,17 @@ namespace { // optional // - os << "bool " << name << "_p () const;"; - os << type << " const& " << id (name) << " () const;"; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << "bool " << name << "_p () const;"; + os << type << " const& " << id (name) << " () const;"; + } + else + { + os << "bool has_" << id (name) << " () const noexcept;"; + os << type << " const* " << id (name) << "_if_set () const noexcept;"; + os << type << "* " << id (name) << "_if_set () noexcept;"; + } // os << type << "& " << id (name) << " ();"; // Lets just have one mutator os << "void " << id (name) << " (" << type << " const&);"; @@ -339,9 +348,18 @@ namespace if (a.optional ()) { - os << "bool " << name << "_p () const;"; - os << type << " const& " << id (name) << " () const;"; - os << type << "& " << id (name) << " ();"; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << "bool " << name << "_p () const;"; + os << type << " const& " << id (name) << " () const;"; + os << type << "& " << id (name) << " ();"; + } + else + { + os << "bool has_" << id (name) << " () const noexcept;"; + os << type << " const* " << id (name) << "_if_set () const noexcept;"; + os << type << "* " << id (name) << "_if_set () noexcept;"; + } os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 35f57da..fd8079a 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -50,28 +50,32 @@ namespace { // optional // - os << i - << "bool " << scope << "::" << std::endl - << name << "_p () const" - << "{"; - if (this->cppmode_ != CPPMODE::CPP03) { - os << "return !!" << id (name) << "_;"; + os << i + << "bool " << scope << "::has_" << id (name) << " () const noexcept" + << "{return " << id (name) << "_ != nullptr;}"; + + os << i << type << " const* " << scope << "::" << id (name) + << "_if_set () const noexcept" + << "{return " << id (name) << "_.get ();}"; + + os << i << type << "* " << scope << "::" << id (name) + << "_if_set () noexcept" + << "{return " << id (name) << "_.get ();}"; } else { - os << "return " << id (name) << "_.get () != 0;"; - } - - os << "}"; + os << i + << "bool " << scope << "::" << std::endl + << name << "_p () const" + << "{return " << id (name) << "_.get () != 0;}"; - os << i - << type << " const& " << scope << "::" << std::endl - << id (name) << " () const" - << "{" - << "return *" << id (name) << "_;" - << "}"; + os << i + << type << " const& " << scope << "::" << std::endl + << id (name) << " () const" + << "{return *" << id (name) << "_;}"; + } // Return referenced item if an IDREF if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) @@ -297,11 +301,16 @@ namespace if (this->cppmode_ != CPPMODE::CPP03) { os << i - << "bool " << scope << "::" << std::endl - << name << "_p () const" - << "{" - << "return !!" << id (name) << "_;" - << "}"; + << "bool " << scope << "::has_" << id (name) << " () const noexcept" + << "{return " << id (name) << "_ != nullptr;}"; + + os << i << type << " const* " << scope << "::" << id (name) + << "_if_set () const noexcept" + << "{return " << id (name) << "_.get ();}"; + + os << i << type << "* " << scope << "::" << id (name) + << "_if_set () noexcept" + << "{return " << id (name) << "_.get ();}"; } else { @@ -313,19 +322,18 @@ namespace << "}"; } - os << i - << type << " const& " << scope << "::" << std::endl - << id (name) << " () const" - << "{" - << "return *" << id (name) << "_;" - << "}"; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << i + << type << " const& " << scope << "::" << std::endl + << id (name) << " () const" + << "{return *" << id (name) << "_;}"; - os << i - << type << "& " << scope << "::" << std::endl - << id (name) << " ()" - << "{" - << "return *" << id (name) << "_;" - << "}"; + os << i + << type << "& " << scope << "::" << std::endl + << id (name) << " ()" + << "{return *" << id (name) << "_;}"; + } // Return a pointer to the referenced item if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 06c27b2..0e9e988 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -445,16 +445,30 @@ namespace // optional // os << " // " << name << std::endl; - os << "bool " << name << "_p = this->" << name << "_p ();"; - os << "stream.write_boolean (" << name << "_p" << ");"; - - os << "if (" << name << "_p)" - << "{"; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << "bool " << name << "_p = this->" << name << "_p ();"; + os << "stream.write_boolean (" << name << "_p" << ");"; + os << "if (" << name << "_p)" << "{"; + } + else + { + os << "auto const* " << name << "_value = this->" << name + << "_if_set ();"; + os << "stream.write_boolean (" << name << "_value != nullptr);"; + os << "if (" << name << "_value != nullptr)" << "{"; + } // check if the type is a boolean type - if (type_is_boolean (type)) - os << "stream.write_boolean (this->" << name - << " ());" << std::endl; + if (this->cppmode_ != CPPMODE::CPP03) + { + if (type_is_boolean (type)) + os << "stream.write_boolean (*" << name << "_value);" << std::endl; + else + os << "stream << *" << name << "_value;"; + } + else if (type_is_boolean (type)) + os << "stream.write_boolean (this->" << name << " ());" << std::endl; else os << "stream << this->" << name << " ();"; @@ -510,13 +524,31 @@ namespace os << "// " << name << std::endl; // First write out the boolean value - os << "stream.write_boolean (" << name << "_p ());"; - - os << "if (" << name << "_p ())" - << std::endl; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << "stream.write_boolean (" << name << "_p ());"; + os << "if (" << name << "_p ())" << std::endl; + } + else + { + os << "auto const* " << id (name) << "_value = this->" + << id (name) << "_if_set ();"; + os << "stream.write_boolean (" << id (name) + << "_value != nullptr);"; + os << "if (" << id (name) << "_value != nullptr)" + << std::endl; + } // check if the type is a boolean type - if (type_is_boolean (type)) + if (this->cppmode_ != CPPMODE::CPP03) + { + if (type_is_boolean (type)) + os << " stream.write_boolean (*" << id (name) + << "_value);" << std::endl; + else + os << " stream << *" << id (name) << "_value;" << std::endl; + } + else if (type_is_boolean (type)) os << " stream.write_boolean (this->" << name << " ());" << std::endl; else diff --git a/XSC/be/CXX/TraversalSource.cpp b/XSC/be/CXX/TraversalSource.cpp index 23da4ae..a6a84c7 100644 --- a/XSC/be/CXX/TraversalSource.cpp +++ b/XSC/be/CXX/TraversalSource.cpp @@ -45,17 +45,28 @@ namespace // name // - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" - << "{" - << "dispatch (o." << id (name) << " ());" - << "}"; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << "void " << scope << "::" << std::endl + << id (name) << " (Type& o)" + << "{dispatch (o." << id (name) << " ());}"; - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" - << "{" - << "dispatch (o." << id (name) << " ());" - << "}"; + os << "void " << scope << "::" << std::endl + << id (name) << " (Type const& o)" + << "{dispatch (o." << id (name) << " ());}"; + } + else + { + os << "void " << scope << "::" << std::endl + << id (name) << " (Type& o)" + << "{if (auto* value = o." << id (name) + << "_if_set ()) dispatch (*value);}"; + + os << "void " << scope << "::" << std::endl + << id (name) << " (Type const& o)" + << "{if (auto const* value = o." << id (name) + << "_if_set ()) dispatch (*value);}"; + } // name_none // @@ -76,17 +87,28 @@ namespace // name // - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" - << "{" - << "dispatch (o." << id (name) << " ());" - << "}"; + if (this->cppmode_ == CPPMODE::CPP03) + { + os << "void " << scope << "::" << std::endl + << id (name) << " (Type& o)" + << "{dispatch (o." << id (name) << " ());}"; - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" - << "{" - << "dispatch (o." << id (name) << " ());" - << "}"; + os << "void " << scope << "::" << std::endl + << id (name) << " (Type const& o)" + << "{dispatch (o." << id (name) << " ());}"; + } + else + { + os << "void " << scope << "::" << std::endl + << id (name) << " (Type& o)" + << "{if (auto* value = o." << id (name) + << "_if_set ()) dispatch (*value);}"; + + os << "void " << scope << "::" << std::endl + << id (name) << " (Type const& o)" + << "{if (auto const* value = o." << id (name) + << "_if_set ()) dispatch (*value);}"; + } } else { @@ -318,8 +340,13 @@ namespace { // optional // - os << "if (o." << name << "_p ()) " << id (name) << " (o);" - << "else " << name << "_none (o);"; + if (this->cppmode_ == CPPMODE::CPP03) + os << "if (o." << name << "_p ()) " << id (name) << " (o);" + << "else " << name << "_none (o);"; + else + os << "if (o." << id (name) << "_if_set () != nullptr) " + << id (name) << " (o);" + << "else " << id (name) << "_none (o);"; } else if (e.min () == 1 && e.max () == 1) { @@ -348,8 +375,13 @@ namespace { // optional // - os << "if (o." << name << "_p ()) " << id (name) << " (o);" - << "else " << name << "_none (o);"; + if (this->cppmode_ == CPPMODE::CPP03) + os << "if (o." << name << "_p ()) " << id (name) << " (o);" + << "else " << name << "_none (o);"; + else + os << "if (o." << id (name) << "_if_set () != nullptr) " + << id (name) << " (o);" + << "else " << id (name) << "_none (o);"; } else { From a8c15853bcfcc194c529c814222f2c15d8786c60 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 17:50:16 +0200 Subject: [PATCH 09/20] Refine generated C++ API and formatting --- .github/workflows/linux.yml | 3 +- CCF/CodeGenerationKit/IndentationCxx.hpp | 35 +- Examples/Recursive/recursive.cpp | 476 +---------------------- Examples/Recursive/recursive.hpp | 258 +----------- Tests/DanceX11/optional_copy.cpp | 20 + Tests/ReadOnly/readonly.mpc | 22 ++ Tests/ReadOnly/readonly.xsd | 12 + Tests/ReadOnly/readonly_api.cpp | 45 +++ Tests/Tests.mwc | 1 + XSC/be/CXX/Elements.hpp | 19 +- XSC/be/CXX/Generator.cpp | 6 +- XSC/be/CXX/Header.cpp | 205 +++++++--- XSC/be/CXX/Inline.cpp | 277 ++++++------- XSC/be/CXX/Source.cpp | 126 +++--- XSC/xsc.cpp | 2 + 15 files changed, 549 insertions(+), 958 deletions(-) create mode 100644 Tests/DanceX11/optional_copy.cpp create mode 100644 Tests/ReadOnly/readonly.mpc create mode 100644 Tests/ReadOnly/readonly.xsd create mode 100644 Tests/ReadOnly/readonly_api.cpp diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 6322164..692aad4 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -51,7 +51,7 @@ jobs: if: matrix.Repo != '' - name: Add packages run: | - sudo apt-get --yes install libxerces-c-dev libssl-dev ${{ matrix.PackageDeps }} + sudo apt-get --yes install libxerces-c-dev ${{ matrix.PackageDeps }} - name: create $ACE_ROOT/ace/config.h run: | '#include "ace/config-linux.h"' > ${env:ACE_ROOT}/ace/config.h @@ -59,7 +59,6 @@ jobs: - name: create $ACE_ROOT/include/makeinclude/platform_macros.GNU run: | 'xerces3=1' > ${env:ACE_ROOT}/include/makeinclude/platform_macros.GNU - 'ssl=1' >> ${env:ACE_ROOT}/include/makeinclude/platform_macros.GNU 'xsc=1' >> ${env:ACE_ROOT}/include/makeinclude/platform_macros.GNU shell: pwsh - name: add optional optional macros diff --git a/CCF/CodeGenerationKit/IndentationCxx.hpp b/CCF/CodeGenerationKit/IndentationCxx.hpp index 3e2c88d..a4b087d 100644 --- a/CCF/CodeGenerationKit/IndentationCxx.hpp +++ b/CCF/CodeGenerationKit/IndentationCxx.hpp @@ -44,7 +44,9 @@ namespace Indentation position_ (0), paren_balance_ (0), spaces_ (2), - construct_ (OTHER) + construct_ (OTHER), + last_non_whitespace_ (0), + inline_initializer_ (false) { indentation_.push (0); } @@ -94,6 +96,16 @@ namespace Indentation if (this->construct_ != CXX_COMMENT && this->construct_ != STRING_LITERAL) { + if (this->last_non_whitespace_ == '=' || + this->last_non_whitespace_ == '_') + { + this->output_indentation (); + result = this->write (c); + ++ this->position_; + this->inline_initializer_ = true; + break; + } + // Make sure there is a new line in the buffer. We then need to // move the correct position on the newline. this->ensure_new_line (); @@ -114,6 +126,15 @@ namespace Indentation case '}': if (!(this->construct_ == CXX_COMMENT || this->construct_ == STRING_LITERAL)) { + if (this->inline_initializer_) + { + this->output_indentation (); + result = this->write (c); + ++ this->position_; + this->inline_initializer_ = false; + break; + } + // Remove the current indentation value, if it exists. if (this->indentation_.size () > 1) this->indentation_.pop (); @@ -138,8 +159,7 @@ namespace Indentation this->hold_.push_back (c); - // Add double newline after '}'. - this->hold_.push_back ('\n'); + // Add a newline after '}'. this->hold_.push_back ('\n'); // Set position to the start of the line. @@ -319,6 +339,9 @@ namespace Indentation // Update the position. ++ this->position_; } + + if (c != ' ' && c != '\t' && c != '\n' && c != '\r') + this->last_non_whitespace_ = c; } catch (const Full &) { @@ -431,6 +454,12 @@ namespace Indentation /// The type of construct. Construct construct_; + /// Last non-whitespace input character. + char_type last_non_whitespace_; + + /// Whether the current brace pair is an inline initializer. + bool inline_initializer_; + /// Type definition of the holding queue. using Hold = std::deque; diff --git a/Examples/Recursive/recursive.cpp b/Examples/Recursive/recursive.cpp index 3ee96ee..8f977db 100644 --- a/Examples/Recursive/recursive.cpp +++ b/Examples/Recursive/recursive.cpp @@ -1,10 +1,6 @@ #include "recursive.hpp" #include "ace/ace_wchar.h" -#include "ace/Null_Mutex.h" -#include "ace/TSS_T.h" -#include "ace/Singleton.h" - namespace Recursive { // Element @@ -17,8 +13,8 @@ namespace Recursive { } - Element::Element (Element const& s) : - ::XSCRT::Type (s) + Element::Element (Element const& s) + : ::XSCRT::Type (s) , value_ (s.value_) , long__ (s.long__) , el_ (s.el_) @@ -28,7 +24,7 @@ namespace Recursive Element& Element::operator= (Element const& s) { - if (&s != this) + if (std::addressof(s) != this) { value_ = s.value_; @@ -57,23 +53,17 @@ namespace Recursive Element::value_const_iterator Element:: begin_value () const { - return value_.begin (); + return value_.cbegin (); } Element::value_const_iterator Element:: end_value () const { - return value_.end (); - } - - void Element:: - add_value (Element::value_value_type const& e) - { - value_.push_back (e); + return value_.cend (); } size_t Element:: - count_value(void) const + count_value() const { return value_.size (); } @@ -94,23 +84,17 @@ namespace Recursive Element::long_const_iterator Element:: begin_long () const { - return long__.begin (); + return long__.cbegin (); } Element::long_const_iterator Element:: end_long () const { - return long__.end (); - } - - void Element:: - add_long (Element::long_value_type const& e) - { - long__.push_back (e); + return long__.cend (); } size_t Element:: - count_long(void) const + count_long() const { return long__.size (); } @@ -131,23 +115,17 @@ namespace Recursive Element::el_const_iterator Element:: begin_el () const { - return el_.begin (); + return el_.cbegin (); } Element::el_const_iterator Element:: end_el () const { - return el_.end (); - } - - void Element:: - add_el (Element::el_value_type const& e) - { - el_.push_back (e); + return el_.cend (); } size_t Element:: - count_el(void) const + count_el() const { return el_.size (); } @@ -158,11 +136,11 @@ namespace Recursive // Element Element:: - Element (::XSCRT::XML::Element const& e) - :Base (e) + Element (::XSCRT::XML::Element const& element) + :Base (element) { - ::XSCRT::Parser p (e); + ::XSCRT::Parser p (element); while (p.more_elements ()) { @@ -171,20 +149,20 @@ namespace Recursive if (n == ACE_TEXT("value")) { - value_value_type t (new ::XMLSchema::string (e)); - add_value (t); + ::XMLSchema::string t (e); + value_.push_back (t); } else if (n == ACE_TEXT("long")) { - long_value_type t (new ::XMLSchema::long_ (e)); - add_long (t); + ::XMLSchema::long_ t (e); + long__.push_back (t); } else if (n == ACE_TEXT("el")) { - el_value_type t (new ::Recursive::Element (e)); - add_el (t); + ::Recursive::Element t (e); + el_.push_back (t); } else @@ -201,9 +179,6 @@ namespace Recursive ::Recursive::Element el (xercesc::DOMDocument const* d) { - // Initiate our Singleton as an ACE_TSS object (ensures thread - // specific storage - ID_Map::TSS_ID_Map* TSS_ID_Map (ACE_Singleton::instance()); xercesc::DOMElement* dom_element = d->getDocumentElement (); if (!dom_element) { @@ -215,8 +190,6 @@ namespace Recursive { ::Recursive::Element r (e); - (*TSS_ID_Map)->resolve_idref(); - return r; } @@ -228,410 +201,3 @@ namespace Recursive } } -#include "ace/XML_Utils/XMLSchema/TypeInfo.hpp" - -namespace Recursive -{ - namespace - { - ::XMLSchema::TypeInfoInitializer < ACE_TCHAR > XMLSchemaTypeInfoInitializer_ (::XSCRT::extended_type_info_map ()); - - struct ElementTypeInfoInitializer - { - ElementTypeInfoInitializer () - { - ::XSCRT::TypeId id (typeid (::Recursive::Element)); - ::XSCRT::ExtendedTypeInfo nf (id); - - nf.add_base (::XSCRT::ExtendedTypeInfo::Access::public_, false, typeid (::XSCRT::Type)); - ::XSCRT::extended_type_info_map ().insert (std::make_pair (id, nf)); - } - }; - - ElementTypeInfoInitializer ElementTypeInfoInitializer_; - } -} - -namespace Recursive -{ - namespace Traversal - { - // Element - - void Element:: - traverse (Type& o) - { - pre (o); - value (o); - long_ (o); - el (o); - post (o); - } - - void Element:: - traverse (Type const& o) - { - pre (o); - value (o); - long_ (o); - el (o); - post (o); - } - - void Element:: - pre (Type&) - { - } - - void Element:: - pre (Type const&) - { - } - - void Element:: - value (Type& o) - { - // VC6 anathema strikes again - ::Recursive::Element::value_iterator b (o.begin_value()), e (o.end_value()); - - if (b != e) - { - value_pre (o); - for (; b != e;) - { - dispatch (*(*b)); - if (++b != e) value_next (o); - } - - value_post (o); - } - } - - void Element:: - value (Type const& o) - { - // VC6 anathema strikes again - ::Recursive::Element::value_const_iterator b (o.begin_value()), e (o.end_value()); - - if (b != e) - { - value_pre (o); - for (; b != e;) - { - dispatch (*(*b)); - if (++b != e) value_next (o); - } - - value_post (o); - } - } - - void Element:: - value_pre (Type&) - { - } - - void Element:: - value_pre (Type const&) - { - } - - void Element:: - value_next (Type&) - { - } - - void Element:: - value_next (Type const&) - { - } - - void Element:: - value_post (Type&) - { - } - - void Element:: - value_post (Type const&) - { - } - - void Element:: - long_ (Type& o) - { - // VC6 anathema strikes again - ::Recursive::Element::long_iterator b (o.begin_long()), e (o.end_long()); - - if (b != e) - { - long_pre (o); - for (; b != e;) - { - dispatch (*(*b)); - if (++b != e) long_next (o); - } - - long_post (o); - } - } - - void Element:: - long_ (Type const& o) - { - // VC6 anathema strikes again - ::Recursive::Element::long_const_iterator b (o.begin_long()), e (o.end_long()); - - if (b != e) - { - long_pre (o); - for (; b != e;) - { - dispatch (*(*b)); - if (++b != e) long_next (o); - } - - long_post (o); - } - } - - void Element:: - long_pre (Type&) - { - } - - void Element:: - long_pre (Type const&) - { - } - - void Element:: - long_next (Type&) - { - } - - void Element:: - long_next (Type const&) - { - } - - void Element:: - long_post (Type&) - { - } - - void Element:: - long_post (Type const&) - { - } - - void Element:: - el (Type& o) - { - // VC6 anathema strikes again - ::Recursive::Element::el_iterator b (o.begin_el()), e (o.end_el()); - - if (b != e) - { - el_pre (o); - for (; b != e;) - { - dispatch (*(*b)); - if (++b != e) el_next (o); - } - - el_post (o); - } - - else el_none (o); - } - - void Element:: - el (Type const& o) - { - // VC6 anathema strikes again - ::Recursive::Element::el_const_iterator b (o.begin_el()), e (o.end_el()); - - if (b != e) - { - el_pre (o); - for (; b != e;) - { - dispatch (*(*b)); - if (++b != e) el_next (o); - } - - el_post (o); - } - - else el_none (o); - } - - void Element:: - el_pre (Type&) - { - } - - void Element:: - el_pre (Type const&) - { - } - - void Element:: - el_next (Type&) - { - } - - void Element:: - el_next (Type const&) - { - } - - void Element:: - el_post (Type&) - { - } - - void Element:: - el_post (Type const&) - { - } - - void Element:: - el_none (Type&) - { - } - - void Element:: - el_none (Type const&) - { - } - - void Element:: - post (Type&) - { - } - - void Element:: - post (Type const&) - { - } - } -} - -namespace Recursive -{ - namespace Writer - { - // Element - Element:: - Element (::XSCRT::XML::Element& e) - : ::XSCRT::Writer (e) - { - } - - Element:: - Element () - { - } - - void Element:: - traverse (Type const& o) - { - Traversal::Element::traverse (o); - } - - void Element:: - value_pre (Type const&) - { - push_ (::XSCRT::XML::Element (ACE_TEXT("value"), top_ ())); - } - - void Element:: - value_next (Type const& o) - { - value_post (o); - value_pre (o); - } - - void Element:: - value_post (Type const&) - { - pop_ (); - } - - void Element:: - long_pre (Type const&) - { - push_ (::XSCRT::XML::Element (ACE_TEXT("long"), top_ ())); - } - - void Element:: - long_next (Type const& o) - { - long_post (o); - long_pre (o); - } - - void Element:: - long_post (Type const&) - { - pop_ (); - } - - void Element:: - el_pre (Type const&) - { - push_ (::XSCRT::XML::Element (ACE_TEXT("el"), top_ ())); - } - - void Element:: - el_next (Type const& o) - { - el_post (o); - el_pre (o); - } - - void Element:: - el_post (Type const&) - { - pop_ (); - } - } -} - -namespace Recursive -{ - namespace writer - { - void - el (::Recursive::Element const& s, xercesc::DOMDocument* d) - { - xercesc::DOMElement* dom_element = d->getDocumentElement (); - if (!dom_element) - { - throw 1; - } - - ::XSCRT::XML::Element e (dom_element); - if (e.name () != ACE_TEXT ("el")) - { - throw 1; - } - - struct W : virtual ::Recursive::Writer::Element, - virtual ::XMLSchema::Writer::FundamentalType< ::XMLSchema::string< ACE_TCHAR >, ACE_TCHAR >, - virtual ::XMLSchema::Writer::FundamentalType< ::XMLSchema::long_, ACE_TCHAR >, - virtual ::XSCRT::Writer - { - explicit W (::XSCRT::XML::Element& e) - : ::XSCRT::Writer (e) - { - } - }; - - W w (e); - w.dispatch (s); - } - } -} - diff --git a/Examples/Recursive/recursive.hpp b/Examples/Recursive/recursive.hpp index d1d2180..803af05 100644 --- a/Examples/Recursive/recursive.hpp +++ b/Examples/Recursive/recursive.hpp @@ -12,30 +12,23 @@ namespace Recursive #include #include "ace/XML_Utils/XMLSchema/Types.hpp" #include "ace/XML_Utils/XMLSchema/id_map.hpp" -#include "ace/Refcounted_Auto_Ptr.h" -#include "ace/Null_Mutex.h" #include "ace/ace_wchar.h" namespace Recursive { class Element : public ::XSCRT::Type { - typedef ::XSCRT::Type Base; - - public: - typedef ACE_Refcounted_Auto_Ptr < ::Recursive::Element, ACE_Null_Mutex> _ptr; + using Base = ::XSCRT::Type; // value public: - typedef ACE_Refcounted_Auto_Ptr < ::XMLSchema::string, ACE_Null_Mutex> value_value_type; - typedef std::list value_container_type; - typedef value_container_type::iterator value_iterator; - typedef value_container_type::const_iterator value_const_iterator; + using value_container_type = std::list<::XMLSchema::string>; + using value_iterator = value_container_type::iterator; + using value_const_iterator = value_container_type::const_iterator; value_iterator begin_value (); value_iterator end_value (); value_const_iterator begin_value () const; value_const_iterator end_value () const; - void add_value (value_value_type const&); size_t count_value () const; protected: @@ -43,15 +36,13 @@ namespace Recursive // long public: - typedef ACE_Refcounted_Auto_Ptr < ::XMLSchema::long_, ACE_Null_Mutex> long_value_type; - typedef std::list long_container_type; - typedef long_container_type::iterator long_iterator; - typedef long_container_type::const_iterator long_const_iterator; + using long_container_type = std::list<::XMLSchema::long_>; + using long_iterator = long_container_type::iterator; + using long_const_iterator = long_container_type::const_iterator; long_iterator begin_long (); long_iterator end_long (); long_const_iterator begin_long () const; long_const_iterator end_long () const; - void add_long (long_value_type const&); size_t count_long () const; protected: @@ -59,15 +50,13 @@ namespace Recursive // el public: - typedef ACE_Refcounted_Auto_Ptr < ::Recursive::Element, ACE_Null_Mutex> el_value_type; - typedef std::list el_container_type; - typedef el_container_type::iterator el_iterator; - typedef el_container_type::const_iterator el_const_iterator; + using el_container_type = std::list<::Recursive::Element>; + using el_iterator = el_container_type::iterator; + using el_const_iterator = el_container_type::const_iterator; el_iterator begin_el (); el_iterator end_el (); el_const_iterator begin_el () const; el_const_iterator end_el () const; - void add_el (el_value_type const&); size_t count_el () const; protected: @@ -80,6 +69,9 @@ namespace Recursive explicit Element (::XSCRT::XML::Element const&); Element (Element const& s); Element& operator= (Element const& s); + + Element (Element&&) = default; + Element& operator= (Element&&) = default; }; } @@ -92,228 +84,4 @@ namespace Recursive } } -#include "ace/XML_Utils/XMLSchema/Traversal.hpp" - -namespace Recursive -{ - namespace Traversal - { - struct Element : ::XMLSchema::Traversal::Traverser< ::Recursive::Element > - { - virtual void - traverse (Type&); - - virtual void - traverse (Type const&); - - virtual void - pre (Type&); - - virtual void - pre (Type const&); - - virtual void - value (Type&); - - virtual void - value (Type const&); - - virtual void - value_pre (Type&); - - virtual void - value_pre (Type const&); - - virtual void - value_next (Type&); - - virtual void - value_next (Type const&); - - virtual void - value_post (Type&); - - virtual void - value_post (Type const&); - - virtual void - long_ (Type&); - - virtual void - long_ (Type const&); - - virtual void - long_pre (Type&); - - virtual void - long_pre (Type const&); - - virtual void - long_next (Type&); - - virtual void - long_next (Type const&); - - virtual void - long_post (Type&); - - virtual void - long_post (Type const&); - - virtual void - el (Type&); - - virtual void - el (Type const&); - - virtual void - el_pre (Type&); - - virtual void - el_pre (Type const&); - - virtual void - el_next (Type&); - - virtual void - el_next (Type const&); - - virtual void - el_post (Type&); - - virtual void - el_post (Type const&); - - virtual void - el_none (Type&); - - virtual void - el_none (Type const&); - - virtual void - post (Type&); - - virtual void - post (Type const&); - }; - } -} - -#include "ace/XML_Utils/XMLSchema/Writer.hpp" - -namespace Recursive -{ - namespace Writer - { - struct Element : Traversal::Element, - virtual ::XSCRT::Writer - { - typedef ::Recursive::Element Type; - explicit Element (::XSCRT::XML::Element&); - - virtual void - traverse (Type &o) - { - this->traverse (const_cast (o)); - } - - virtual void - traverse (Type const&); - - virtual void - value_pre (Type &o) - { - this->value_pre (const_cast (o)); - } - - virtual void - value_pre (Type const&); - - virtual void - value_next (Type &o) - { - this->value_next (const_cast (o)); - } - - virtual void - value_next (Type const&); - - virtual void - value_post (Type &o) - { - this->value_post (const_cast (o)); - } - - virtual void - value_post (Type const&); - - virtual void - long_pre (Type &o) - { - this->long_pre (const_cast (o)); - } - - virtual void - long_pre (Type const&); - - virtual void - long_next (Type &o) - { - this->long_next (const_cast (o)); - } - - virtual void - long_next (Type const&); - - virtual void - long_post (Type &o) - { - this->long_post (const_cast (o)); - } - - virtual void - long_post (Type const&); - - virtual void - el_pre (Type &o) - { - this->el_pre (const_cast (o)); - } - - virtual void - el_pre (Type const&); - - virtual void - el_next (Type &o) - { - this->el_next (const_cast (o)); - } - - virtual void - el_next (Type const&); - - virtual void - el_post (Type &o) - { - this->el_post (const_cast (o)); - } - - virtual void - el_post (Type const&); - - protected: - Element (); - }; - } -} - -namespace Recursive -{ - namespace writer - { - void - el (::Recursive::Element const&, xercesc::DOMDocument*); - } -} - #endif // RECURSIVE_HPP diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp new file mode 100644 index 0000000..523a2c8 --- /dev/null +++ b/Tests/DanceX11/optional_copy.cpp @@ -0,0 +1,20 @@ +#include "Basic_Deployment_Data.hpp" + +int +main () +{ + Deployment::DataValue sequence; + Deployment::DataValue sequence_copy (sequence); + sequence_copy = sequence; + + Deployment::IdRef destination; + XMLSchema::string href ("urn:destination"); + destination.href (href); + if (destination.href_if_set () == nullptr) + return 1; + + Deployment::IdRef source; + destination = source; + + return destination.href_if_set () != nullptr; +} diff --git a/Tests/ReadOnly/readonly.mpc b/Tests/ReadOnly/readonly.mpc new file mode 100644 index 0000000..bdace96 --- /dev/null +++ b/Tests/ReadOnly/readonly.mpc @@ -0,0 +1,22 @@ +project (xsc_test_readonly): xscdefaults { + requires += xsc + custom_only = 1 + xscflags += --cxx-char-type char + xscflags += --cxx-read-only + xscflags += --cxx-generate-cdr-reader-types + + XSC_Files { + readonly.xsd + } + Source_Files { + } +} + +project (xsc_test_readonly_generated): xscrt { + after += xsc_test_readonly + + Source_Files { + readonly.cpp + readonly_api.cpp + } +} diff --git a/Tests/ReadOnly/readonly.xsd b/Tests/ReadOnly/readonly.xsd new file mode 100644 index 0000000..a163b82 --- /dev/null +++ b/Tests/ReadOnly/readonly.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp new file mode 100644 index 0000000..6a5eeb3 --- /dev/null +++ b/Tests/ReadOnly/readonly_api.cpp @@ -0,0 +1,45 @@ +#include "readonly.hpp" + +#include +#include + +namespace +{ + template + struct has_name_setter : std::false_type + { + }; + + template + struct has_name_setter ().name ( + std::declval<::XMLSchema::string const&> ()))>> : std::true_type + { + }; + + template + struct has_optionalValue_presence_accessor : std::false_type + { + }; + + template + struct has_optionalValue_presence_accessor ().has_optionalValue ())>> : std::true_type + { + }; + + using ReadOnly = ReadOnlyType; + + static_assert (!std::is_default_constructible_v); + static_assert (!std::is_copy_constructible_v); + static_assert (!std::is_move_constructible_v); + static_assert (!std::is_copy_assignable_v); + static_assert (!std::is_move_assignable_v); + static_assert (!has_name_setter::value); + static_assert (!has_optionalValue_presence_accessor::value); + static_assert (std::is_same_v ().name ()), + ::XMLSchema::string const&>); + static_assert (std::is_same_v ().optionalValue_if_set ()), + ::XMLSchema::string const*>); + static_assert (std::is_same_v ().begin_item ()), + ::XMLSchema::string const&>); +} diff --git a/Tests/Tests.mwc b/Tests/Tests.mwc index 140a54b..6f4738e 100644 --- a/Tests/Tests.mwc +++ b/Tests/Tests.mwc @@ -11,6 +11,7 @@ workspace (Tests) { Import Include NoNamespace + ReadOnly UnqualifiedImport Validation } diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index fcb5504..7df7e8d 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -72,7 +72,8 @@ class Context cdr_writer_generation_ (false), cppmode_ (CPPMODE::CPP17), orb_ (ORB::TAO), - generate_ra_sequences_ (false) + generate_ra_sequences_ (false), + read_only_ (false) { if (char_type == L"wchar_t") { @@ -119,7 +120,8 @@ class Context cdr_writer_generation_ (c.cdr_writer_generation_), cppmode_ (c.cppmode_), orb_ (c.orb_), - generate_ra_sequences_ (c.generate_ra_sequences_) + generate_ra_sequences_ (c.generate_ra_sequences_), + read_only_ (c.read_only_) { } @@ -273,6 +275,18 @@ class Context return this->generate_ra_sequences_; } + void + read_only (bool flag) + { + this->read_only_ = flag; + } + + bool + read_only () + { + return this->read_only_; + } + public: std::wostream& os; string& scope; @@ -342,6 +356,7 @@ class Context ORB orb_; bool generate_ra_sequences_; + bool read_only_; }; struct Anonymous : Traversal::Element, diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index ca9cc0e..1e5bfe7 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -249,7 +249,8 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con traversal); // Check if cdr reader/writer options are set - bool cdr_reader (options.count ("cxx-generate-cdr-reader-types")); + bool read_only (options.count ("cxx-read-only")); + bool cdr_reader (options.count ("cxx-generate-cdr-reader-types") && !read_only); bool cdr_writer (options.count ("cxx-generate-cdr-writer-types")); ::Context::CPPMODE cppmode_ { ::Context::CPPMODE::CPP17 }; @@ -355,6 +356,7 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con ctx.cppmode (cppmode_); ctx.orb (orb_); + ctx.read_only (read_only); // Add additional information to the context: ctx.generate_ra_sequences (ra_sequences); @@ -398,6 +400,7 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con ctx.cppmode (cppmode_); ctx.orb (orb_); + ctx.read_only (read_only); // Add additional information to the context: ctx.generate_ra_sequences (ra_sequences); @@ -423,6 +426,7 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con ctx.cppmode (cppmode_); ctx.orb (orb_); + ctx.read_only (read_only); if (!inline_) { diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index de6e871..b1cf226 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -170,8 +170,7 @@ namespace else container = L"std::list"; - os << "// " << name << std::endl - << "public:" << std::endl; + os << "public:" << std::endl; if (c.max () != 1) @@ -192,17 +191,25 @@ namespace switch(this->cppmode_) { case CPPMODE::CPP03: - os << "typedef " << name << "_container_type::iterator " << name << "_iterator;"; + if (!this->read_only_) + os << "typedef " << name << "_container_type::iterator " << name << "_iterator;"; os << "typedef " << name << "_container_type::const_iterator " << name << "_const_iterator;"; - os << name << "_iterator begin_" << name << " ();"; - os << name << "_iterator end_" << name << " ();"; + if (!this->read_only_) + { + os << name << "_iterator begin_" << name << " ();"; + os << name << "_iterator end_" << name << " ();"; + } break; case CPPMODE::CPP11: case CPPMODE::CPP17: - os << "using " << name << "_iterator = " << name << "_container_type::iterator;"; + if (!this->read_only_) + os << "using " << name << "_iterator = " << name << "_container_type::iterator;"; os << "using " << name << "_const_iterator = " << name << "_container_type::const_iterator;"; - os << name << "_iterator begin_" << name << " ();"; - os << name << "_iterator end_" << name << " ();"; + if (!this->read_only_) + { + os << name << "_iterator begin_" << name << " ();"; + os << name << "_iterator end_" << name << " ();"; + } break; } @@ -212,15 +219,19 @@ namespace switch(this->cppmode_) { case CPPMODE::CPP03: - os << "void add_" << name << " (" << name << "_value_type const&);"; - os << "void del_" << name << " (" << name << "_value_type const&);"; + if (!this->read_only_) + { + os << "void add_" << name << " (" << name << "_value_type const&);"; + os << "void del_" << name << " (" << name << "_value_type const&);"; + } break; case CPPMODE::CPP11: case CPPMODE::CPP17: break; } //Return referenced item if an IDREF - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << "XSCRT::Type* get_" << name << "_ptr (const " << string_type <<"& idref);"; os << "void set_" << name << "_ptr (const " << string_type << "& idref);"; @@ -229,37 +240,47 @@ namespace os << "size_t count_" << name << " () const;"; os << std::endl - << "protected:" << std::endl; + << (this->read_only_ ? "private:" : "protected:") << std::endl; - os << name << "_container_type " << id(name) << "_;"; + os << name << "_container_type " << id(name) << "_" + << (this->read_only_ && this->cppmode_ != CPPMODE::CPP03 ? L" {};" : L";"); } else if (c.min () == 0) { // optional // - if (this->cppmode_ == CPPMODE::CPP03) + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) { os << "bool " << name << "_p () const;"; os << type << " const& " << id (name) << " () const;"; } else { - os << "bool has_" << id (name) << " () const noexcept;"; - os << type << " const* " << id (name) << "_if_set () const noexcept;"; - os << type << "* " << id (name) << "_if_set () noexcept;"; + string noexcept_suffix (this->cppmode_ == CPPMODE::CPP03 ? L"" : L" noexcept"); + os << type << " const* " << id (name) << "_if_set () const" + << noexcept_suffix << ";"; + if (!this->read_only_) + os << type << "* " << id (name) << "_if_set ()" + << noexcept_suffix << ";"; } // os << type << "& " << id (name) << " ();"; // Lets just have one mutator - os << "void " << id (name) << " (" << type << " const&);"; + if (this->read_only_) + os << "private:" << std::endl; + else + os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) { - os << "::XSCRT::Type* get_" << id (name) << "_ptr ();\n"; - os << "void set_" << id (name) << "_ptr (const " << string_type << "& idref);"; + if (!this->read_only_) + { + os << "::XSCRT::Type* get_" << id (name) << "_ptr ();\n"; + os << "void set_" << id (name) << "_ptr (const " << string_type << "& idref);"; + } } - os << std::endl - << "protected:" << std::endl; + if (!this->read_only_) + os << std::endl << "protected:" << std::endl; switch(this->cppmode_) { case CPPMODE::CPP03: @@ -269,7 +290,8 @@ namespace case CPPMODE::CPP11: case CPPMODE::CPP17: os << "using " << id (name) << "_type = std::unique_ptr<" << type << ">;"; - os << id (name) << "_type " << id (name) << "_;"; + os << id (name) << "_type " << id (name) << "_" + << (this->read_only_ ? L" {};" : L";"); break; } } @@ -279,17 +301,21 @@ namespace // os << type << " const& " << id (name) << " () const;"; // os << type << "& " << id (name) << " ();"; // Lets just have one mutator. - os << "void " << id (name) << " (" << type << " const&);"; + if (this->read_only_) + os << "private:" << std::endl; + else + os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << "::XSCRT::Type* get_" << id (name) << "_ptr ( void );\n"; os << "void set_" << id(name) << "_ptr (const " << string_type << "& idref);"; } - os << std::endl - << "protected:" << std::endl; + if (!this->read_only_) + os << std::endl << "protected:" << std::endl; switch(this->cppmode_) { @@ -300,7 +326,8 @@ namespace case CPPMODE::CPP11: case CPPMODE::CPP17: os << "using " << id (name) << "_type = std::unique_ptr<" << type << ">;"; - os << id (name) << "_type " << id (name) << "_;"; + os << id (name) << "_type " << id (name) << "_" + << (this->read_only_ ? L" {};" : L";"); break; } } @@ -342,13 +369,12 @@ namespace std::wstring idref_str (L"::XMLSchema::IDREF<"); idref_ptr = type.find(idref_str); - os << "// " << name << std::endl - << "public:" << std::endl; + os << "public:" << std::endl; if (a.optional ()) { - if (this->cppmode_ == CPPMODE::CPP03) + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) { os << "bool " << name << "_p () const;"; os << type << " const& " << id (name) << " () const;"; @@ -356,21 +382,28 @@ namespace } else { - os << "bool has_" << id (name) << " () const noexcept;"; - os << type << " const* " << id (name) << "_if_set () const noexcept;"; - os << type << "* " << id (name) << "_if_set () noexcept;"; + string noexcept_suffix (this->cppmode_ == CPPMODE::CPP03 ? L"" : L" noexcept"); + os << type << " const* " << id (name) << "_if_set () const" + << noexcept_suffix << ";"; + if (!this->read_only_) + os << type << "* " << id (name) << "_if_set ()" + << noexcept_suffix << ";"; } - os << "void " << id (name) << " (" << type << " const&);"; + if (this->read_only_) + os << "private:" << std::endl; + else + os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << "::XSCRT::Type* get_" << id (name) << "_ptr ();\n"; os << "void set_" << id(name) << "_ptr (const " << string_type << "& idref);"; } - os << std::endl - << "protected:" << std::endl; + if (!this->read_only_) + os << std::endl << "protected:" << std::endl; switch(this->cppmode_) { @@ -381,25 +414,31 @@ namespace case CPPMODE::CPP11: case CPPMODE::CPP17: os << "using " << id (name) << "_type = std::unique_ptr<" << type << ">;"; - os << id (name) << "_type " << id (name) << "_;"; + os << id (name) << "_type " << id (name) << "_" + << (this->read_only_ ? L" {};" : L";"); break; } } else { os << type << " const& " << id (name) << " () const;"; - os << type << "& " << id (name) << " ();"; - os << "void " << id (name) << " (" << type << " const&);"; + if (!this->read_only_) + os << type << "& " << id (name) << " ();"; + if (this->read_only_) + os << "private:" << std::endl; + else + os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << "::XSCRT::Type* get_" << id (name) << "_ptr ( void );\n"; os << "void set_" << id (name) << "_ptr (const " << string_type << "& idref);"; } - os << std::endl - << "protected:" << std::endl; + if (!this->read_only_) + os << std::endl << "protected:" << std::endl; switch(this->cppmode_) { @@ -410,7 +449,8 @@ namespace case CPPMODE::CPP11: case CPPMODE::CPP17: os << "using " << id (name) << "_type = std::unique_ptr<" << type << ">;"; - os << id (name) << "_type " << id (name) << "_;"; + os << id (name) << "_type " << id (name) << "_" + << (this->read_only_ ? L" {};" : L";"); break; } } @@ -563,6 +603,16 @@ namespace // c-tor (all-non-optional-members) // + if (this->read_only_) + { + if (this->cppmode_ == CPPMODE::CPP03) + os << "private:" << std::endl + << name << " ();" + << "public:" << std::endl; + else + os << name << " () = delete;"; + } + os << name << " ("; ctor_args_.traverse (c); @@ -612,19 +662,43 @@ namespace // copy c-tor // - os << name << " (" << name << " const& s);"; + if (this->read_only_) + { + if (this->cppmode_ == CPPMODE::CPP03) + os << "private:" << std::endl + << name << " (" << name << " const&);"; + else + { + os << name << " (" << name << " const&) = delete;"; + os << name << " (" << name << "&&) = delete;"; + } + } + else + os << name << " (" << name << " const& s);"; // operator= // - os << name << "& operator= (" << name << " const& s);" - << std::endl; - - if (this->cppmode_ != CPPMODE::CPP03) + if (this->read_only_) { - os << name << " (" << name << "&&) = default;"; - os << name << "& operator= (" << name << "&&) = default;" - << std::endl; + if (this->cppmode_ == CPPMODE::CPP03) + os << "private:" << std::endl + << name << "& operator= (" << name << " const&);"; + else + { + os << name << "& operator= (" << name << " const&) = delete;"; + os << name << "& operator= (" << name << "&&) = delete;"; + } + } + else + { + os << name << "& operator= (" << name << " const& s);"; + if (this->cppmode_ != CPPMODE::CPP03) + { + os << name << " (" << name << "&&) = default;"; + os << name << "& operator= (" << name << "&&) = default;"; + } } + os << std::endl; // Closing brace for the class declaration // Example: class Foo { @@ -742,6 +816,16 @@ namespace enter_scope (name); + if (this->read_only_) + { + if (this->cppmode_ == CPPMODE::CPP03) + os << "private:" << std::endl + << name << " ();" + << "public:" << std::endl; + else + os << name << " () = delete;"; + } + // c-tor (Element const&) // os << "explicit " << name << " (" << xml_element_type << " const&);"; @@ -769,6 +853,21 @@ namespace << "integral () const;" << std::endl; + if (this->read_only_) + { + if (this->cppmode_ == CPPMODE::CPP03) + os << "private:" << std::endl + << name << " (" << name << " const&);" + << name << "& operator= (" << name << " const&);"; + else + { + os << name << " (" << name << " const&) = delete;"; + os << name << " (" << name << "&&) = delete;"; + os << name << "& operator= (" << name << " const&) = delete;"; + os << name << "& operator= (" << name << "&&) = delete;"; + } + } + os << "friend bool " << ex_ << std::endl << "operator== (" << name << " const& a, " << name << " const& b);" << std::endl; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index fd8079a..3d1adf3 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -44,41 +44,39 @@ namespace std::wstring idref_str (L"::XMLSchema::IDREF<"); idref_ptr = type.find(idref_str); - os << "// " << scope << std::endl; + if (!this->read_only_) + os << "// " << scope << std::endl; if (e.min () == 0 && e.max () == 1) { // optional // - if (this->cppmode_ != CPPMODE::CPP03) + if (this->cppmode_ != CPPMODE::CPP03 || this->read_only_) { - os << i - << "bool " << scope << "::has_" << id (name) << " () const noexcept" - << "{return " << id (name) << "_ != nullptr;}"; - + string noexcept_suffix (this->cppmode_ == CPPMODE::CPP03 ? L"" : L" noexcept"); os << i << type << " const* " << scope << "::" << id (name) - << "_if_set () const noexcept" + << "_if_set () const" << noexcept_suffix << "{return " << id (name) << "_.get ();}"; - os << i << type << "* " << scope << "::" << id (name) - << "_if_set () noexcept" - << "{return " << id (name) << "_.get ();}"; + if (!this->read_only_) + os << i << type << "* " << scope << "::" << id (name) + << "_if_set ()" << noexcept_suffix + << "{return " << id (name) << "_.get ();}"; } else { os << i - << "bool " << scope << "::" << std::endl - << name << "_p () const" + << "bool " << scope << "::" << name << "_p () const" << "{return " << id (name) << "_.get () != 0;}"; os << i - << type << " const& " << scope << "::" << std::endl - << id (name) << " () const" + << type << " const& " << scope << "::" << id (name) << " () const" << "{return *" << id (name) << "_;}"; } // Return referenced item if an IDREF - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << i << "::XSCRT::Type* " << scope << "::get_" @@ -99,15 +97,15 @@ namespace } /* Lets just have one accessor. WRO os << i - << type << "& " << scope << "::" << std::endl - << id (name) << " ()" + << type << "& " << scope << "::" << id (name) << " ()" << "{" << "return *" << id (name) << "_;" << "}"; */ + if (!this->read_only_) + { os << i - << "void " << scope << "::" << std::endl - << id (name) << " (" << type << " const& e)" + << "void " << scope << "::" << id (name) << " (" << type << " const& e)" << "{"; if (this->cppmode_ != CPPMODE::CPP03) @@ -138,18 +136,19 @@ namespace } os << "}" << "}"; + } } else if (e.min () == 1 && e.max () == 1) { // one // os << i - << type << " const& " << scope << "::" << std::endl - << id (name) << " () const" + << type << " const& " << scope << "::" << id (name) << " () const" << "{" << "return *" << id (name) << "_;" << "}"; - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << i << "::XSCRT::Type* " << scope << "::get_" @@ -169,24 +168,24 @@ namespace << "}\n"; } - os << i - << "void " << scope << "::" << std::endl - << id (name) << " (" << type << " const& e)" - << "{" - << "*" << id (name) << "_ = e;" - << "}"; + if (!this->read_only_) + os << i + << "void " << scope << "::" << id (name) << " (" << type << " const& e)" + << "{" + << "*" << id (name) << "_ = e;" + << "}"; } else { // sequence // + if (!this->read_only_) { // begin_typename // os << i - << scope << "::" << name << "_iterator " << scope << "::" << std::endl - << "begin_" << name << " ()" + << scope << "::" << name << "_iterator " << scope << "::begin_" << name << " ()" << "{" << "return " << id(name) << "_.begin ();" << "}"; @@ -194,8 +193,7 @@ namespace // end_typename // os << i - << scope << "::" << name << "_iterator " << scope << "::" << std::endl - << "end_" << name << " ()" + << scope << "::" << name << "_iterator " << scope << "::end_" << name << " ()" << "{" << "return " << id(name) << "_.end ();" << "}"; @@ -203,8 +201,7 @@ namespace // begin_typename const os << i - << scope << "::" << name << "_const_iterator " << scope << "::" << std::endl - << "begin_" << name << " () const" + << scope << "::" << name << "_const_iterator " << scope << "::begin_" << name << " () const" << "{"; if (this->cppmode_ != CPPMODE::CPP03) @@ -219,8 +216,7 @@ namespace // end_typename const os << i - << scope << "::" << name << "_const_iterator " << scope << "::" << std::endl - << "end_" << name << " () const" + << scope << "::" << name << "_const_iterator " << scope << "::end_" << name << " () const" << "{"; if (this->cppmode_ != CPPMODE::CPP03) @@ -234,7 +230,8 @@ namespace os << "}"; // add IDREF access method - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << i << "XSCRT::Type* " << scope << "::get_" << name @@ -252,19 +249,17 @@ namespace << "}\n"; } - if (this->cppmode_ == CPPMODE::CPP03) + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) { // add_typename os << i - << "void " << scope << "::" << std::endl - << "add_" << name << " (" << scope << "::" << name << "_value_type const& e)" + << "void " << scope << "::add_" << name << " (" << scope << "::" << name << "_value_type const& e)" << "{"; os << id(name) << "_.push_back (e);"; os << "}"; // del_typename os << i - << "void " << scope << "::" << std::endl - << "del_" << name << " (" << scope << "::" << name << "_value_type const& e)" + << "void " << scope << "::del_" << name << " (" << scope << "::" << name << "_value_type const& e)" << "{"; os << id(name) << "_.remove (e);"; os << "}"; @@ -274,8 +269,7 @@ namespace // count_typename // os << i - << "size_t " << scope << "::" << std::endl - << "count_" << name << "() const" + << "size_t " << scope << "::count_" << name << "() const" << "{" << "return " << id(name) << "_.size ();" << "}"; @@ -289,7 +283,8 @@ namespace string name (a.name ()); string type (type_name (a)); - os << "// " << scope << std::endl; + if (!this->read_only_) + os << "// " << scope << std::endl; //Check if the type is an IDREF std::string::size_type idref_ptr = 0; @@ -298,45 +293,41 @@ namespace if (a.optional ()) { - if (this->cppmode_ != CPPMODE::CPP03) + if (this->cppmode_ != CPPMODE::CPP03 || this->read_only_) { - os << i - << "bool " << scope << "::has_" << id (name) << " () const noexcept" - << "{return " << id (name) << "_ != nullptr;}"; - + string noexcept_suffix (this->cppmode_ == CPPMODE::CPP03 ? L"" : L" noexcept"); os << i << type << " const* " << scope << "::" << id (name) - << "_if_set () const noexcept" + << "_if_set () const" << noexcept_suffix << "{return " << id (name) << "_.get ();}"; - os << i << type << "* " << scope << "::" << id (name) - << "_if_set () noexcept" - << "{return " << id (name) << "_.get ();}"; + if (!this->read_only_) + os << i << type << "* " << scope << "::" << id (name) + << "_if_set ()" << noexcept_suffix + << "{return " << id (name) << "_.get ();}"; } else { os << i - << "bool " << scope << "::" << std::endl - << name << "_p () const" + << "bool " << scope << "::" << name << "_p () const" << "{" << "return " << id (name) << "_.get () != 0;" << "}"; } - if (this->cppmode_ == CPPMODE::CPP03) + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) { os << i - << type << " const& " << scope << "::" << std::endl - << id (name) << " () const" + << type << " const& " << scope << "::" << id (name) << " () const" << "{return *" << id (name) << "_;}"; os << i - << type << "& " << scope << "::" << std::endl - << id (name) << " ()" + << type << "& " << scope << "::" << id (name) << " ()" << "{return *" << id (name) << "_;}"; } // Return a pointer to the referenced item - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << i << "::XSCRT::Type* " << scope << "::get_" @@ -356,9 +347,10 @@ namespace << "}\n"; } + if (!this->read_only_) + { os << i - << "void " << scope << "::" << std::endl - << id (name) << " (" << type << " const& e)" + << "void " << scope << "::" << id (name) << " (" << type << " const& e)" << "{"; if (this->cppmode_ != CPPMODE::CPP03) @@ -387,25 +379,26 @@ namespace } os << "}" << "}"; + } } else { os << i - << type << " const& " << scope << "::" << std::endl - << id (name) << " () const" + << type << " const& " << scope << "::" << id (name) << " () const" << "{" << "return *" << id (name) << "_;" << "}"; - os << i - << type << "& " << scope << "::" << std::endl - << id (name) << " ()" - << "{" - << "return *" << id (name) << "_;" - << "}"; + if (!this->read_only_) + os << i + << type << "& " << scope << "::" << id (name) << " ()" + << "{" + << "return *" << id (name) << "_;" + << "}"; // Return a pointer to the referenced item - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + !this->read_only_) { os << i << "::XSCRT::Type* " << scope << "::get_" @@ -425,12 +418,12 @@ namespace << "}\n"; } - os << i - << "void " << scope << "::" << std::endl - << id (name) << " (" << type << " const& e)" - << "{" - << "*" << id (name) << "_ = e;" - << "}"; + if (!this->read_only_) + os << i + << "void " << scope << "::" << id (name) << " (" << type << " const& e)" + << "{" + << "*" << id (name) << "_ = e;" + << "}"; } } @@ -573,8 +566,9 @@ namespace { string type (name); - os << "// " << scope << std::endl - << std::endl; + if (!this->read_only_) + os << "// " << scope << std::endl + << std::endl; // c-tor // @@ -603,59 +597,61 @@ namespace os << "}"; - // copy c-tor - // - os << i - << scope << "::" - << name << " (" << type << " const& s)" << std::endl; - - if (!has_base) + if (!this->read_only_) { - os << ": ::XSCRT::Type (s)" << std::endl; - } + // copy c-tor + // + os << i + << scope << "::" + << name << " (" << type << " const& s)" << std::endl; - // Resets a flag that determines if a Complex Type's - // copy constructor has inherited from the base XSCRT::Type - // class. - copy_.reset_base_class_initialization (); + if (!has_base) + { + os << ": ::XSCRT::Type (s)" << std::endl; + } - inherits (c, copy_base_); + // Resets a flag that determines if a Complex Type's + // copy constructor has inherited from the base XSCRT::Type + // class. + copy_.reset_base_class_initialization (); - names (c, copy_member_); + inherits (c, copy_base_); - os << "{"; + names (c, copy_member_); - names (c, copy_body_member_); + os << "{"; - os << "}"; + names (c, copy_body_member_); - std::wstring selfcheck; - if (this->cppmode_ != CPPMODE::CPP03) - { - selfcheck = L"if (std::addressof(s) != this)"; - } - else - { - selfcheck = L"if (&s != this)"; - } + os << "}"; - // operator= - // - os << i - << scope << "&" << std::endl - << scope << "::operator= (" << type << " const& s)" - << "{" - << selfcheck - << "{"; + std::wstring selfcheck; + if (this->cppmode_ != CPPMODE::CPP03) + { + selfcheck = L"if (std::addressof(s) != this)"; + } + else + { + selfcheck = L"if (&s != this)"; + } - inherits (c, assign_base_); - names (c, assign_member_); + // operator= + // + os << i + << scope << "& " << scope << "::operator= (" << type << " const& s)" + << "{" + << selfcheck + << "{"; - os << "}" - << "return *this;" - << "}"; + inherits (c, assign_base_); + names (c, assign_member_); - os << std::endl; + os << "}" + << "return *this;" + << "}"; + + os << std::endl; + } } void @@ -690,10 +686,7 @@ namespace string type (type_name (c)); if (this->cdr_reader_generation_) - os << "bool" << std::endl - << "operator >> (::XMLSchema::CDR_InputStream &stream," - << std::endl - << " ::XMLSchema::cdr_arg_traits < " + os << "bool operator >> (::XMLSchema::CDR_InputStream &stream, ::XMLSchema::cdr_arg_traits < " << type << " >::inout_type element)" << std::endl << "{" @@ -703,10 +696,7 @@ namespace << "}"; if (this->cdr_writer_generation_) - os << "bool" << std::endl - << "operator << (::XMLSchema::CDR_OutputStream &stream," - << std::endl - << " ::XMLSchema::cdr_arg_traits < " + os << "bool operator << (::XMLSchema::CDR_OutputStream &stream, ::XMLSchema::cdr_arg_traits < " << type << " >::in_type element)" << std::endl << "{" @@ -1276,34 +1266,31 @@ namespace string type (type_name (e)); - os << "// " << scope << std::endl - << std::endl; + if (!this->read_only_) + os << "// " << scope << std::endl + << std::endl; os << i - << scope << "::Value " << scope << "::" << std::endl - << "integral () const" + << scope << "::Value " << scope << "::integral () const" << "{" << "return v_;" << "}"; os << i - << "bool" << std::endl - << "operator== (" << type << " const& a, " << type << " const& b)" + << "bool operator== (" << type << " const& a, " << type << " const& b)" << "{" << "return a.v_ == b.v_;" << "}"; os << i - << "bool" << std::endl - << "operator!= (" << type << " const& a, " << type << " const& b)" + << "bool operator!= (" << type << " const& a, " << type << " const& b)" << "{" << "return a.v_ != b.v_;" << "}"; os << i - << scope << "::" << std::endl - << name << " (" << scope << "::Value v)" << std::endl + << scope << "::" << name << " (" << scope << "::Value v)" << std::endl << ": v_ (v)" << std::endl << "{" << "}"; @@ -1312,10 +1299,7 @@ namespace // CDR Insertion extraction operations if needed if (this->cdr_reader_generation_) - os << "bool" << std::endl - << "operator >> (::XMLSchema::CDR_InputStream &stream," - << std::endl - << " ::XMLSchema::cdr_arg_traits < " + os << "bool operator >> (::XMLSchema::CDR_InputStream &stream, ::XMLSchema::cdr_arg_traits < " << type << " >::inout_type element)" << std::endl << "{" @@ -1325,10 +1309,7 @@ namespace << "}"; if (this->cdr_writer_generation_) - os << "bool" << std::endl - << "operator << (::XMLSchema::CDR_OutputStream &stream," - << std::endl - << " ::XMLSchema::cdr_arg_traits < " + os << "bool operator << (::XMLSchema::CDR_OutputStream &stream, ::XMLSchema::cdr_arg_traits < " << type << " >::in_type element)" << std::endl << "{" diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 0e9e988..6c8b714 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -26,8 +26,14 @@ namespace struct Element : Traversal::Element, protected virtual Context { explicit Element (Context& c) - : Context (c) + : Context (c), first_ (true) + { + } + + void + reset () { + first_ = true; } virtual void @@ -55,8 +61,10 @@ namespace //@@ need to use FQ-names. // - os << "if (n == " << compare_name << ")" + os << (first_ ? "if (n == " : "else if (n == ") + << compare_name << ")" << "{"; + first_ = false; if (c.max () != 1) { @@ -64,8 +72,7 @@ namespace // if (this->cppmode_ != CPPMODE::CPP03) { - os << type << " t (e);"; - os << id (name) << "_.push_back (t);"; + os << id (name) << "_.emplace_back (e);"; } else @@ -78,8 +85,18 @@ namespace { // optional // - os << type << " t (e);" - << id (name) << " (t);"; + if (this->read_only_) + { + if (this->cppmode_ != CPPMODE::CPP03) + os << id (name) << "_ = std::make_unique<" << type << "> (e);"; + else + os << id (name) << "_ = " << scope << "::" << id(name) + << "_type (new " << type << " (e));" + << id (name) << "_->container (this);"; + } + else + os << type << " t (e);" + << id (name) << " (t);"; } else { @@ -195,16 +212,24 @@ namespace } - os <<"}" - << "else "; + os << "}"; } + + private: + bool first_; }; struct Attribute : Traversal::Attribute, protected virtual Context { explicit Attribute (Context& c) - : Context (c) + : Context (c), first_ (true) + { + } + + void + reset () { + first_ = true; } virtual void @@ -215,13 +240,25 @@ namespace //@@ need to use FQ-names. // - os << "if (n == " << L << " (\"" << name << "\"))" + os << (first_ ? "if (n == " : "else if (n == ") + << L << " (\"" << name << "\"))" << "{"; + first_ = false; if (a.optional ()) { - os << type << " t (a);" - << id (name) << " (t);"; + if (this->read_only_) + { + if (this->cppmode_ != CPPMODE::CPP03) + os << id (name) << "_ = std::make_unique<" << type << "> (a);"; + else + os << id (name) << "_ = " << scope << "::" << id(name) + << "_type (new " << type << " (a));" + << id (name) << "_->container (this);"; + } + else + os << type << " t (a);" + << id (name) << " (t);"; } else { @@ -294,9 +331,11 @@ namespace << ", this);"; } - os << "}" - << "else "; + os << "}"; } + + private: + bool first_; }; // Traverser for CDR write operations @@ -1173,14 +1212,13 @@ namespace { string type (type_name (c)); - os << "// " << scope << std::endl - << std::endl; + if (!this->read_only_) + os << "// " << scope << std::endl + << std::endl; - os << scope << "::" << std::endl - << name << " (" << xml_element_type << " const& element)" << std::endl + os << scope << "::" << name << " (" << xml_element_type << " const& element)" << std::endl << ":" << "Base (element)" - << "{" - << std::endl; + << "{"; } using Traversal::Complex::names; @@ -1201,13 +1239,13 @@ namespace os << "while (p.more_elements ())" << "{" << xml_element_type << " e (p.next_element ());" - << string_type << " n (::XSCRT::XML::uq_name (e.name ()));" + << string_type << " const n (::XSCRT::XML::uq_name (e.name ()));" << std::endl; + element_.reset (); names (c, names_elements_); - os << "{}" // else block - << "}"; // while loop + os << "}"; // while loop } if (ha) @@ -1215,12 +1253,12 @@ namespace os << "while (p.more_attributes ())" << "{" << xml_attribute_type << " a (p.next_attribute ());" - << string_type << " n (::XSCRT::XML::uq_name (a.name ()));"; + << string_type << " const n (::XSCRT::XML::uq_name (a.name ()));"; + attribute_.reset (); names (c, names_attributes_); - os << "{}" // else block - << "}"; // while loop + os << "}"; // while loop } } } @@ -1258,7 +1296,7 @@ namespace // pre os << "// write " << name << std::endl; - os << "bool" << std::endl << name << "::write_" << name + os << "bool " << name << "::write_" << name << " (::XMLSchema::CDR_OutputStream &stream) const" << "{"; @@ -1284,15 +1322,9 @@ namespace { // pre os << "// read " << name << std::endl; - os << "bool" << std::endl << name << "::" << std::endl - << "read_" << name - << " (::XMLSchema::CDR_InputStream &stream," << std::endl; - - for (size_t j =0; j < name.length () + 5; j++) - os << " "; - - os << "::XMLSchema::cdr_arg_traits < " << name - << " >::inout_type element)" + os << "bool " << name << "::read_" << name + << " (::XMLSchema::CDR_InputStream &stream, ::XMLSchema::cdr_arg_traits < " + << name << " >::inout_type element)" << "{"; { @@ -1382,8 +1414,7 @@ namespace virtual void pre (Type&) { - os << scope << "::" << std::endl - << name << " (" << xml_attribute_type << " const& a)" << std::endl + os << scope << "::" << name << " (" << xml_attribute_type << " const& a)" << std::endl << ":" << std::endl << "Base (a)" << std::endl << "{"; @@ -1452,13 +1483,13 @@ namespace enter_scope (name); - os << "// " << scope << std::endl - << std::endl; + if (!this->read_only_) + os << "// " << scope << std::endl + << std::endl; // c-tor (Element const&) // - os << scope << "::" << std::endl - << name << " (" << xml_element_type << " const& e)" << std::endl + os << scope << "::" << name << " (" << xml_element_type << " const& e)" << std::endl << ": ::XSCRT::Type (e)" << std::endl << "{" << string_type << " v (e.value ());" @@ -1471,8 +1502,7 @@ namespace // c-tor (Attribute const&) // - os << scope << "::" << std::endl - << name << " (" << xml_attribute_type << " const& a)" << std::endl + os << scope << "::" << name << " (" << xml_attribute_type << " const& a)" << std::endl << ": ::XSCRT::Type (a)" << std::endl << "{" << string_type << " v (a.value ());" @@ -1492,7 +1522,7 @@ namespace { // pre os << "// write " << name << std::endl; - os << "bool" << std::endl << name << "::write_" << name + os << "bool " << name << "::write_" << name << " (::XMLSchema::CDR_OutputStream &stream) const" << "{"; @@ -1514,10 +1544,8 @@ namespace { // pre os << "// read " << name << std::endl; - os << "bool" << std::endl << name << "::read_" << name - << " (::XMLSchema::CDR_InputStream &stream, " - << std::endl - << "::XMLSchema::cdr_arg_traits < " << name + os << "bool " << name << "::read_" << name + << " (::XMLSchema::CDR_InputStream &stream, ::XMLSchema::cdr_arg_traits < " << name << " >::inout_type element)" << std::endl << "{"; diff --git a/XSC/xsc.cpp b/XSC/xsc.cpp index 3142305..44dd5c2 100644 --- a/XSC/xsc.cpp +++ b/XSC/xsc.cpp @@ -140,6 +140,8 @@ namespace {"cxx-cpp03", ACE_Get_Opt::NO_ARG, "Generate C++03-compatible code."}, {"cxx-cpp11", ACE_Get_Opt::NO_ARG, "Generate C++11 code."}, {"cxx-cpp17", ACE_Get_Opt::NO_ARG, "Generate C++17 code."}, + {"cxx-read-only", ACE_Get_Opt::NO_ARG, + "Generate read-only C++ data types (omit CDR reader APIs)."}, {"idl-char-type", ACE_Get_Opt::ARG_REQUIRED, "Generated IDL character type."}, {"idl-namespace-regex", ACE_Get_Opt::ARG_REQUIRED, "IDL namespace mapping regex (repeatable)."}, {"idl-file-suffix", ACE_Get_Opt::ARG_REQUIRED, "Generated IDL suffix."}, From e74e1225278b35d82caec2e4563c4b7c19f90471 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 18:00:53 +0200 Subject: [PATCH 10/20] Add read-only DanceX11 API assertions --- Tests/DanceX11/dancex11.mpc | 52 +++++++++++++++++++++++++++++++++ Tests/DanceX11/readonly_api.cpp | 18 ++++++++++++ Tests/ReadOnly/readonly_api.cpp | 3 ++ XSC/be/CXX/Header.cpp | 11 ++++--- XSC/be/CXX/Inline.cpp | 37 ++++++++++++----------- XSC/be/CXX/ParserSource.cpp | 15 +++++++--- 6 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 Tests/DanceX11/readonly_api.cpp diff --git a/Tests/DanceX11/dancex11.mpc b/Tests/DanceX11/dancex11.mpc index fe14888..fb23687 100644 --- a/Tests/DanceX11/dancex11.mpc +++ b/Tests/DanceX11/dancex11.mpc @@ -42,3 +42,55 @@ project (xsc_test_dancex11_generated): xscrt { toplevel.cpp } } + +project (xsc_test_dancex11_readonly): xscdefaults { + requires += xsc + custom_only = 1 + + Modify_Custom (XSC) { + source_outputext = .readonly.cpp, + header_outputext = .readonly.hpp, + } + + xscflags += --cxx-char-type char + xscflags += --search-path . + xscflags += --cxx-read-only + xscflags += --cxx-header-suffix .readonly.hpp + xscflags += --cxx-source-suffix .readonly.cpp + + XSC_Files { + Basic_Deployment_Data.xsd + Deployment.xsd + XMI.xsd + ccd.xsd + cdd.xsd + cdp.xsd + cid.xsd + cpd.xsd + iad.xsd + pcd.xsd + toplevel.xsd + } + + Source_Files { + } +} + +project (xsc_test_dancex11_readonly_generated): xscrt { + after += xsc_test_dancex11_readonly + + Source_Files { + Basic_Deployment_Data.readonly.cpp + Deployment.readonly.cpp + XMI.readonly.cpp + ccd.readonly.cpp + cdd.readonly.cpp + cdp.readonly.cpp + cid.readonly.cpp + cpd.readonly.cpp + iad.readonly.cpp + pcd.readonly.cpp + toplevel.readonly.cpp + readonly_api.cpp + } +} diff --git a/Tests/DanceX11/readonly_api.cpp b/Tests/DanceX11/readonly_api.cpp new file mode 100644 index 0000000..ca417ee --- /dev/null +++ b/Tests/DanceX11/readonly_api.cpp @@ -0,0 +1,18 @@ +#include "toplevel.readonly.hpp" + +#include +#include +#include + +namespace +{ + using TopLevel = Deployment::TopLevelPackageDescription; + using Package = Deployment::PackageConfiguration; + using Packages = TopLevel::package_container_type; + + static_assert (std::is_same_v>); + static_assert (!std::is_copy_constructible_v); + static_assert (!std::is_move_constructible_v); + static_assert (std::is_same_v ().begin ()), + Package const&>); +} diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index 6a5eeb3..a88f8be 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -1,5 +1,6 @@ #include "readonly.hpp" +#include #include #include @@ -36,6 +37,8 @@ namespace static_assert (!std::is_move_assignable_v); static_assert (!has_name_setter::value); static_assert (!has_optionalValue_presence_accessor::value); + static_assert (std::is_same_v>>); static_assert (std::is_same_v ().name ()), ::XMLSchema::string const&>); static_assert (std::is_same_v ().optionalValue_if_set ()), diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index b1cf226..a0548ad 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -613,12 +613,15 @@ namespace os << name << " () = delete;"; } - os << name << " ("; + if (!this->read_only_) + { + os << name << " ("; - ctor_args_.traverse (c); + ctor_args_.traverse (c); - os << ");" - << std::endl; + os << ");" + << std::endl; + } // c-tor (Element const&) // diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 3d1adf3..35597b9 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -570,32 +570,35 @@ namespace os << "// " << scope << std::endl << std::endl; - // c-tor - // - os << i - << scope << "::" << name << " ("; + bool const has_base (c.inherits_begin () != c.inherits_end ()); - ctor_args_.traverse (c); + if (!this->read_only_) + { + // c-tor + // + os << i + << scope << "::" << name << " ("; - os << ")" << std::endl; + ctor_args_.traverse (c); - bool const has_base (c.inherits_begin () != c.inherits_end ()); + os << ")" << std::endl; - inherits (c, ctor_base_); + inherits (c, ctor_base_); - // Resets a flag that determines if a Complex Type's constructor - // has inherited from the base XSCRT::Type class. Right now, this - // is commented out since it was producing a bug when complex types - // extended another complete type. + // Resets a flag that determines if a Complex Type's constructor + // has inherited from the base XSCRT::Type class. Right now, this + // is commented out since it was producing a bug when complex types + // extended another complete type. - ctor_member__.reset_base_class_initialization (has_base); - names (c, ctor_member_); + ctor_member__.reset_base_class_initialization (has_base); + names (c, ctor_member_); - os << "{"; + os << "{"; - names (c, ctor_body_); + names (c, ctor_body_); - os << "}"; + os << "}"; + } if (!this->read_only_) { diff --git a/XSC/be/CXX/ParserSource.cpp b/XSC/be/CXX/ParserSource.cpp index db8f3b2..44e3584 100644 --- a/XSC/be/CXX/ParserSource.cpp +++ b/XSC/be/CXX/ParserSource.cpp @@ -56,15 +56,22 @@ namespace << "}" << xml_element_type << " e (dom_element);" << "if (e.name () == " << compare_name << ")" - << "{" - << type << " r (e);\n"; + << "{"; + + if (!this->read_only_) + os << type << " r (e);"; if (this->cppmode_ == CPPMODE::CPP03) { os << "(*TSS_ID_Map)->resolve_idref();" << std::endl; } - os << "return r;" - << "}" + + if (this->read_only_) + os << "return " << type << " (e);"; + else + os << "return r;"; + + os << "}" << "else" << "{" << "throw 1;" From 78763c38932a2d7097c341d34eb7165b42d67468 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 18:07:43 +0200 Subject: [PATCH 11/20] Fix traversal generation for read-only types --- Examples/Recursive/recursive.cpp | 93 +++++++--------------------- Examples/Recursive/recursive.hpp | 7 --- Tests/ReadOnly/readonly.mpc | 33 ++++++++++ XSC/be/CXX/Source.cpp | 5 +- XSC/be/CXX/TraversalSource.cpp | 103 ++++++++++++++----------------- 5 files changed, 104 insertions(+), 137 deletions(-) diff --git a/Examples/Recursive/recursive.cpp b/Examples/Recursive/recursive.cpp index 8f977db..18a6765 100644 --- a/Examples/Recursive/recursive.cpp +++ b/Examples/Recursive/recursive.cpp @@ -12,7 +12,6 @@ namespace Recursive , long__ (long___) { } - Element::Element (Element const& s) : ::XSCRT::Type (s) , value_ (s.value_) @@ -20,9 +19,7 @@ namespace Recursive , el_ (s.el_) { } - - Element& - Element::operator= (Element const& s) + Element& Element::operator= (Element const& s) { if (std::addressof(s) != this) { @@ -32,146 +29,102 @@ namespace Recursive el_ = s.el_; } - return *this; } - // Element - Element::value_iterator Element:: - begin_value () + Element::value_iterator Element::begin_value () { return value_.begin (); } - - Element::value_iterator Element:: - end_value () + Element::value_iterator Element::end_value () { return value_.end (); } - - Element::value_const_iterator Element:: - begin_value () const + Element::value_const_iterator Element::begin_value () const { return value_.cbegin (); } - - Element::value_const_iterator Element:: - end_value () const + Element::value_const_iterator Element::end_value () const { return value_.cend (); } - - size_t Element:: - count_value() const + size_t Element::count_value() const { return value_.size (); } - // Element - Element::long_iterator Element:: - begin_long () + Element::long_iterator Element::begin_long () { return long__.begin (); } - - Element::long_iterator Element:: - end_long () + Element::long_iterator Element::end_long () { return long__.end (); } - - Element::long_const_iterator Element:: - begin_long () const + Element::long_const_iterator Element::begin_long () const { return long__.cbegin (); } - - Element::long_const_iterator Element:: - end_long () const + Element::long_const_iterator Element::end_long () const { return long__.cend (); } - - size_t Element:: - count_long() const + size_t Element::count_long() const { return long__.size (); } - // Element - Element::el_iterator Element:: - begin_el () + Element::el_iterator Element::begin_el () { return el_.begin (); } - - Element::el_iterator Element:: - end_el () + Element::el_iterator Element::end_el () { return el_.end (); } - - Element::el_const_iterator Element:: - begin_el () const + Element::el_const_iterator Element::begin_el () const { return el_.cbegin (); } - - Element::el_const_iterator Element:: - end_el () const + Element::el_const_iterator Element::end_el () const { return el_.cend (); } - - size_t Element:: - count_el() const + size_t Element::count_el() const { return el_.size (); } } - namespace Recursive { // Element - Element:: - Element (::XSCRT::XML::Element const& element) + Element::Element (::XSCRT::XML::Element const& element) :Base (element) { - ::XSCRT::Parser p (element); while (p.more_elements ()) { ::XSCRT::XML::Element e (p.next_element ()); - std::basic_string n (::XSCRT::XML::uq_name (e.name ())); + std::basic_string const n (::XSCRT::XML::uq_name (e.name ())); if (n == ACE_TEXT("value")) { - ::XMLSchema::string t (e); - value_.push_back (t); + value_.emplace_back (e); } - else if (n == ACE_TEXT("long")) { - ::XMLSchema::long_ t (e); - long__.push_back (t); + long__.emplace_back (e); } - else if (n == ACE_TEXT("el")) { - ::Recursive::Element t (e); - el_.push_back (t); - } - - else - { + el_.emplace_back (e); } } } } - namespace Recursive { namespace reader @@ -184,15 +137,12 @@ namespace Recursive { throw 1; } - ::XSCRT::XML::Element e (dom_element); if (e.name () == ACE_TEXT("el")) { ::Recursive::Element r (e); - return r; } - else { throw 1; @@ -200,4 +150,3 @@ namespace Recursive } } } - diff --git a/Examples/Recursive/recursive.hpp b/Examples/Recursive/recursive.hpp index 803af05..2353ee2 100644 --- a/Examples/Recursive/recursive.hpp +++ b/Examples/Recursive/recursive.hpp @@ -6,7 +6,6 @@ namespace Recursive { class Element; } - #include #include #include @@ -20,7 +19,6 @@ namespace Recursive { using Base = ::XSCRT::Type; - // value public: using value_container_type = std::list<::XMLSchema::string>; using value_iterator = value_container_type::iterator; @@ -34,7 +32,6 @@ namespace Recursive protected: value_container_type value_; - // long public: using long_container_type = std::list<::XMLSchema::long_>; using long_iterator = long_container_type::iterator; @@ -48,7 +45,6 @@ namespace Recursive protected: long_container_type long__; - // el public: using el_container_type = std::list<::Recursive::Element>; using el_iterator = el_container_type::iterator; @@ -69,12 +65,10 @@ namespace Recursive explicit Element (::XSCRT::XML::Element const&); Element (Element const& s); Element& operator= (Element const& s); - Element (Element&&) = default; Element& operator= (Element&&) = default; }; } - namespace Recursive { namespace reader @@ -83,5 +77,4 @@ namespace Recursive el (xercesc::DOMDocument const*); } } - #endif // RECURSIVE_HPP diff --git a/Tests/ReadOnly/readonly.mpc b/Tests/ReadOnly/readonly.mpc index bdace96..ac74dd5 100644 --- a/Tests/ReadOnly/readonly.mpc +++ b/Tests/ReadOnly/readonly.mpc @@ -4,6 +4,7 @@ project (xsc_test_readonly): xscdefaults { xscflags += --cxx-char-type char xscflags += --cxx-read-only xscflags += --cxx-generate-cdr-reader-types + xscflags += --cxx-generate-traversal-types XSC_Files { readonly.xsd @@ -20,3 +21,35 @@ project (xsc_test_readonly_generated): xscrt { readonly_api.cpp } } + +project (xsc_test_readonly_cpp03): xscdefaults { + requires += xsc + custom_only = 1 + + Modify_Custom (XSC) { + source_outputext = .cpp03.cpp, + header_outputext = .cpp03.hpp, + } + + xscflags += --cxx-char-type char + xscflags += --cxx-cpp03 + xscflags += --cxx-read-only + xscflags += --cxx-generate-traversal-types + xscflags += --cxx-header-suffix .cpp03.hpp + xscflags += --cxx-source-suffix .cpp03.cpp + + XSC_Files { + readonly.xsd + } + + Source_Files { + } +} + +project (xsc_test_readonly_cpp03_generated): xscrt { + after += xsc_test_readonly_cpp03 + + Source_Files { + readonly.cpp03.cpp + } +} diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 6c8b714..81c970e 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -78,7 +78,10 @@ namespace else { os << name << "_value_type t (new " << type << " (e));"; - os << "add_" << name << " (t);"; + if (this->read_only_) + os << id (name) << "_.push_back (t);"; + else + os << "add_" << name << " (t);"; } } else if (c.min () == 0) diff --git a/XSC/be/CXX/TraversalSource.cpp b/XSC/be/CXX/TraversalSource.cpp index a6a84c7..350cf67 100644 --- a/XSC/be/CXX/TraversalSource.cpp +++ b/XSC/be/CXX/TraversalSource.cpp @@ -26,6 +26,38 @@ namespace { } + void + optional_member (string const& name, string const& type) + { + os << "void " << scope << "::" << std::endl + << id (name) << " (Type& o)" << "{"; + + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + os << "dispatch (o." << id (name) << " ());"; + else if (this->cppmode_ == CPPMODE::CPP03 || this->read_only_) + os << type << " const* value = o." << id (name) + << "_if_set (); if (value) dispatch (*value);"; + else + os << "if (auto* value = o." << id (name) + << "_if_set ()) dispatch (*value);"; + + os << "}"; + + os << "void " << scope << "::" << std::endl + << id (name) << " (Type const& o)" << "{"; + + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + os << "dispatch (o." << id (name) << " ());"; + else if (this->cppmode_ == CPPMODE::CPP03) + os << type << " const* value = o." << id (name) + << "_if_set (); if (value) dispatch (*value);"; + else + os << "if (auto const* value = o." << id (name) + << "_if_set ()) dispatch (*value);"; + + os << "}"; + } + virtual void traverse (SemanticGraph::Element& e) { @@ -45,28 +77,7 @@ namespace // name // - if (this->cppmode_ == CPPMODE::CPP03) - { - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" - << "{dispatch (o." << id (name) << " ());}"; - - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" - << "{dispatch (o." << id (name) << " ());}"; - } - else - { - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" - << "{if (auto* value = o." << id (name) - << "_if_set ()) dispatch (*value);}"; - - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" - << "{if (auto const* value = o." << id (name) - << "_if_set ()) dispatch (*value);}"; - } + optional_member (name, type); // name_none // @@ -87,28 +98,13 @@ namespace // name // - if (this->cppmode_ == CPPMODE::CPP03) - { - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" - << "{dispatch (o." << id (name) << " ());}"; - - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" - << "{dispatch (o." << id (name) << " ());}"; - } - else - { - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" - << "{if (auto* value = o." << id (name) - << "_if_set ()) dispatch (*value);}"; + os << "void " << scope << "::" << std::endl + << id (name) << " (Type& o)" + << "{dispatch (o." << id (name) << " ());}"; - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" - << "{if (auto const* value = o." << id (name) - << "_if_set ()) dispatch (*value);}"; - } + os << "void " << scope << "::" << std::endl + << id (name) << " (Type const& o)" + << "{dispatch (o." << id (name) << " ());}"; } else { @@ -117,11 +113,14 @@ namespace // name // + string iterator_type (fq_name (e, L"", false)); + iterator_type += this->read_only_ ? L"_const_iterator" : L"_iterator"; + os << "void " << scope << "::" << std::endl << id (name) << " (Type& o)" << "{" << "// VC6 anathema strikes again" << std::endl - << fq_name (e, L"", false) << "_iterator " + << iterator_type << " " << "b (o.begin_" << name << "()), " << "e (o.end_" << name << "());" << std::endl @@ -252,17 +251,7 @@ namespace { // name // - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" - << "{" - << "dispatch (o." << id (name) << " ());" - << "}"; - - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" - << "{" - << "dispatch (o." << id (name) << " ());" - << "}"; + optional_member (name, type_name (a)); // name_none // @@ -340,7 +329,7 @@ namespace { // optional // - if (this->cppmode_ == CPPMODE::CPP03) + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) os << "if (o." << name << "_p ()) " << id (name) << " (o);" << "else " << name << "_none (o);"; else @@ -375,7 +364,7 @@ namespace { // optional // - if (this->cppmode_ == CPPMODE::CPP03) + if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) os << "if (o." << name << "_p ()) " << id (name) << " (o);" << "else " << name << "_none (o);"; else From e868d5e0c438991da5b22beeacf8f8673fe88e94 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 18:49:05 +0200 Subject: [PATCH 12/20] Stamp generated files with XSC version --- Examples/Recursive/recursive.cpp | 33 ++++---------------------------- Examples/Recursive/recursive.hpp | 8 ++++---- XSC/Version.hpp | 9 +++++++++ XSC/be/CXX/Generator.cpp | 14 +++++++++++++- XSC/be/CXX/Inline.cpp | 14 -------------- XSC/be/CXX/ParserHeader.cpp | 2 +- XSC/be/CXX/Source.cpp | 8 -------- XSC/be/CXX/TraversalSource.cpp | 3 --- XSC/be/CXX/WriterSource.cpp | 5 ----- XSC/be/IDL/Generator.cpp | 4 +++- XSC/xsc.cpp | 5 ++--- 11 files changed, 36 insertions(+), 69 deletions(-) create mode 100644 XSC/Version.hpp diff --git a/Examples/Recursive/recursive.cpp b/Examples/Recursive/recursive.cpp index 18a6765..69d7f71 100644 --- a/Examples/Recursive/recursive.cpp +++ b/Examples/Recursive/recursive.cpp @@ -1,10 +1,10 @@ +// Generated by XSC version 2.0.0 #include "recursive.hpp" +#include #include "ace/ace_wchar.h" namespace Recursive { - // Element - Element::Element (value_container_type const& value__, long_container_type const& long___) : ::XSCRT::Type () @@ -12,27 +12,6 @@ namespace Recursive , long__ (long___) { } - Element::Element (Element const& s) - : ::XSCRT::Type (s) - , value_ (s.value_) - , long__ (s.long__) - , el_ (s.el_) - { - } - Element& Element::operator= (Element const& s) - { - if (std::addressof(s) != this) - { - value_ = s.value_; - - long__ = s.long__; - - el_ = s.el_; - } - return *this; - } - - // Element Element::value_iterator Element::begin_value () { return value_.begin (); @@ -53,7 +32,6 @@ namespace Recursive { return value_.size (); } - // Element Element::long_iterator Element::begin_long () { return long__.begin (); @@ -74,7 +52,6 @@ namespace Recursive { return long__.size (); } - // Element Element::el_iterator Element::begin_el () { return el_.begin (); @@ -98,8 +75,6 @@ namespace Recursive } namespace Recursive { - // Element - Element::Element (::XSCRT::XML::Element const& element) :Base (element) { @@ -135,7 +110,7 @@ namespace Recursive xercesc::DOMElement* dom_element = d->getDocumentElement (); if (!dom_element) { - throw 1; + throw std::runtime_error ("XML document has no root element"); } ::XSCRT::XML::Element e (dom_element); if (e.name () == ACE_TEXT("el")) @@ -145,7 +120,7 @@ namespace Recursive } else { - throw 1; + throw std::runtime_error ("unexpected XML root element; expected "); } } } diff --git a/Examples/Recursive/recursive.hpp b/Examples/Recursive/recursive.hpp index 2353ee2..3066c83 100644 --- a/Examples/Recursive/recursive.hpp +++ b/Examples/Recursive/recursive.hpp @@ -1,3 +1,4 @@ +// Generated by XSC version 2.0.0 #ifndef RECURSIVE_HPP #define RECURSIVE_HPP @@ -63,8 +64,8 @@ namespace Recursive long_container_type const& long___); explicit Element (::XSCRT::XML::Element const&); - Element (Element const& s); - Element& operator= (Element const& s); + Element (Element const& s) = default; + Element& operator= (Element const& s) = default; Element (Element&&) = default; Element& operator= (Element&&) = default; }; @@ -73,8 +74,7 @@ namespace Recursive { namespace reader { - ::Recursive::Element - el (xercesc::DOMDocument const*); + ::Recursive::Element el (xercesc::DOMDocument const*); } } #endif // RECURSIVE_HPP diff --git a/XSC/Version.hpp b/XSC/Version.hpp new file mode 100644 index 0000000..e7ec807 --- /dev/null +++ b/XSC/Version.hpp @@ -0,0 +1,9 @@ +#ifndef XSC_VERSION_HPP +#define XSC_VERSION_HPP + +namespace XSC +{ + inline constexpr wchar_t wide_version[] {L"2.0.0"}; +} + +#endif // XSC_VERSION_HPP diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index ef7b588..ce7775d 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -8,6 +8,7 @@ #include #include #include "XSC/SemanticGraph.hpp" +#include "XSC/Version.hpp" #include "CCF/CodeGenerationKit/Regex.hpp" #include "CCF/CodeGenerationKit/IndentationCxx.hpp" @@ -115,6 +116,18 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con return; } + auto write_version = [] (std::wostream& output) + { + output << L"// Generated by XSC version " << XSC::wide_version << std::endl; + }; + + write_version (hxx); + if (inline_) + { + write_version (ixx); + } + write_version (cxx); + // Banner. // //Takes in the name of a "banner" file. This banner, if it exists, will @@ -221,7 +234,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con } } - // // string char_type; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 30a0c26..026d1fd 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -44,9 +44,6 @@ namespace std::wstring idref_str (L"::XMLSchema::IDREF<"); idref_ptr = type.find(idref_str); - if (!this->read_only_) - os << "// " << scope << std::endl; - if (e.min () == 0 && e.max () == 1) { // optional @@ -283,9 +280,6 @@ namespace string name (a.name ()); string type (type_name (a)); - if (!this->read_only_) - os << "// " << scope << std::endl; - //Check if the type is an IDREF std::string::size_type idref_ptr = 0; std::wstring idref_str (L"::XMLSchema::IDREF<"); @@ -566,10 +560,6 @@ namespace { string type (name); - if (!this->read_only_) - os << "// " << scope << std::endl - << std::endl; - bool const has_base (c.inherits_begin () != c.inherits_end ()); if (!this->read_only_) @@ -1272,10 +1262,6 @@ namespace string type (type_name (e)); - if (!this->read_only_) - os << "// " << scope << std::endl - << std::endl; - os << i << scope << "::Value " << scope << "::integral () const" << "{" diff --git a/XSC/be/CXX/ParserHeader.cpp b/XSC/be/CXX/ParserHeader.cpp index a871c44..0f7db85 100644 --- a/XSC/be/CXX/ParserHeader.cpp +++ b/XSC/be/CXX/ParserHeader.cpp @@ -25,7 +25,7 @@ namespace os << "namespace reader" << "{" << e - << type << std::endl + << type << " " << id (name) << " (xercesc::DOMDocument const*);" << "}" << std::endl; diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 126acae..67078bc 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -1251,10 +1251,6 @@ namespace { string type (type_name (c)); - if (!this->read_only_) - os << "// " << scope << std::endl - << std::endl; - os << scope << "::" << name << " (" << xml_element_type << " const& element)" << std::endl << ":" << "Base (element)" << "{"; @@ -1522,10 +1518,6 @@ namespace enter_scope (name); - if (!this->read_only_) - os << "// " << scope << std::endl - << std::endl; - // c-tor (Element const&) // os << scope << "::" << name << " (" << xml_element_type << " const& e)" << std::endl diff --git a/XSC/be/CXX/TraversalSource.cpp b/XSC/be/CXX/TraversalSource.cpp index d3153e6..19e4da1 100644 --- a/XSC/be/CXX/TraversalSource.cpp +++ b/XSC/be/CXX/TraversalSource.cpp @@ -456,9 +456,6 @@ namespace //enter_scope (name); - os << "// " << scope << std::endl - << std::endl; - // traverse (Type&) // os << "void " << scope << "::" << std::endl diff --git a/XSC/be/CXX/WriterSource.cpp b/XSC/be/CXX/WriterSource.cpp index a5c2e03..d48b15f 100644 --- a/XSC/be/CXX/WriterSource.cpp +++ b/XSC/be/CXX/WriterSource.cpp @@ -229,8 +229,6 @@ namespace { string name (id (name_)); - os << "// " << name << std::endl; - // c-tor (XML::Element&) // os << scope << "::" << std::endl @@ -307,9 +305,6 @@ namespace { string name ((this->name_ != L"") ? id(name_) : id (c.name ())); - os << "// " << name << std::endl - << std::endl; - // c-tor (XML::Element&) // os << name << "::" << std::endl diff --git a/XSC/be/IDL/Generator.cpp b/XSC/be/IDL/Generator.cpp index a9ba7ae..f53c743 100644 --- a/XSC/be/IDL/Generator.cpp +++ b/XSC/be/IDL/Generator.cpp @@ -6,6 +6,7 @@ #include "Declaration.hpp" #include "Definition.hpp" #include "XSC/SemanticGraph.hpp" +#include "XSC/Version.hpp" #include "CCF/CodeGenerationKit/Regex.hpp" #include "CCF/CodeGenerationKit/IndentationIDL.hpp" #include "CCF/CodeGenerationKit/IndentationImplanter.hpp" @@ -55,6 +56,8 @@ namespace IDL return; } + idl << L"// Generated by XSC version " << XSC::wide_version << std::endl; + // Banner. // { @@ -78,7 +81,6 @@ namespace IDL } } - // // string char_type; diff --git a/XSC/xsc.cpp b/XSC/xsc.cpp index 44dd5c2..22d2706 100644 --- a/XSC/xsc.cpp +++ b/XSC/xsc.cpp @@ -32,6 +32,7 @@ #include "ace/Get_Opt.h" #include "XSC/Options.hpp" +#include "XSC/Version.hpp" #include "XSC/Parser.hpp" #include "XSC/be/CXX/Validator.hpp" #include "XSC/be/CXX/Generator.hpp" @@ -39,8 +40,6 @@ using namespace XSC; -wchar_t const* const version = L"0.0.8"; - /** * @class ErrorDetector * @@ -221,7 +220,7 @@ int main (int argc, char* argv[]) if (command_line.count ("version")) { - std::wcerr << "XML Schema compiler " << version << std::endl; + std::wcerr << "XML Schema compiler " << XSC::wide_version << std::endl; return 0; } From 88ba352aa9aebd641849d0c414e31b085b0b3fc8 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 18:50:37 +0200 Subject: [PATCH 13/20] Record invocation in generated files --- Examples/Recursive/recursive.cpp | 1 + Examples/Recursive/recursive.hpp | 1 + XSC/be/CXX/Generator.cpp | 9 +++++++-- XSC/be/IDL/Generator.cpp | 7 ++++++- XSC/xsc.cpp | 31 +++++++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Examples/Recursive/recursive.cpp b/Examples/Recursive/recursive.cpp index 69d7f71..2b9fbd5 100644 --- a/Examples/Recursive/recursive.cpp +++ b/Examples/Recursive/recursive.cpp @@ -1,4 +1,5 @@ // Generated by XSC version 2.0.0 +// Command line: '/home/johnny/ACE/XSC/bin/xsc' '--backend' 'cxx' 'recursive.xsd' #include "recursive.hpp" #include diff --git a/Examples/Recursive/recursive.hpp b/Examples/Recursive/recursive.hpp index 3066c83..fee82ec 100644 --- a/Examples/Recursive/recursive.hpp +++ b/Examples/Recursive/recursive.hpp @@ -1,4 +1,5 @@ // Generated by XSC version 2.0.0 +// Command line: '/home/johnny/ACE/XSC/bin/xsc' '--backend' 'cxx' 'recursive.xsd' #ifndef RECURSIVE_HPP #define RECURSIVE_HPP diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index ce7775d..ba511a1 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -116,9 +116,14 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con return; } - auto write_version = [] (std::wostream& output) + auto write_version = [&options] (std::wostream& output) { - output << L"// Generated by XSC version " << XSC::wide_version << std::endl; + output << L"// Generated by XSC version " << XSC::wide_version << std::endl + << L"// Command line: "; + std::string const& command_line {options.value ("command-line")}; + for (char c : command_line) + output << static_cast (c); + output << std::endl; }; write_version (hxx); diff --git a/XSC/be/IDL/Generator.cpp b/XSC/be/IDL/Generator.cpp index f53c743..3a9ba30 100644 --- a/XSC/be/IDL/Generator.cpp +++ b/XSC/be/IDL/Generator.cpp @@ -56,7 +56,12 @@ namespace IDL return; } - idl << L"// Generated by XSC version " << XSC::wide_version << std::endl; + idl << L"// Generated by XSC version " << XSC::wide_version << std::endl + << L"// Command line: "; + std::string const& command_line {options.value ("command-line")}; + for (char c : command_line) + idl << static_cast (c); + idl << std::endl; // Banner. // diff --git a/XSC/xsc.cpp b/XSC/xsc.cpp index 22d2706..e3bfb56 100644 --- a/XSC/xsc.cpp +++ b/XSC/xsc.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -155,6 +156,34 @@ namespace name == "idl-namespace-regex"; } + std::string + shell_quote (std::string_view argument) + { + std::string quoted ("'"); + for (char c : argument) + { + if (c == '\'') + quoted += "'\\''"; + else + quoted += c; + } + quoted += '\''; + return quoted; + } + + std::string + invocation (int argc, char* argv[]) + { + std::string result; + for (int i {}; i != argc; ++i) + { + if (i != 0) + result += ' '; + result += shell_quote (argv[i]); + } + return result; + } + void print_help (std::string_view backend) { @@ -188,6 +217,7 @@ int main (int argc, char* argv[]) { try { + std::string const original_invocation {invocation (argc, argv)}; XSC::Options command_line; ACE_Get_Opt get_opt (argc, argv, "", 1, 0, ACE_Get_Opt::PERMUTE_ARGS); @@ -236,6 +266,7 @@ int main (int argc, char* argv[]) return 1; } + command_line.set ("command-line", original_invocation); command_line.set ("input-file", get_opt.argv ()[get_opt.opt_ind ()]); auto set_default = [&command_line] (std::string const& name, std::string const& value) From 6838162de06aa61459fdf209719f507d9d6d2ea4 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 18:52:27 +0200 Subject: [PATCH 14/20] Make generated invocation arguments portable --- Examples/Recursive/recursive.cpp | 2 +- Examples/Recursive/recursive.hpp | 2 +- XSC/be/CXX/Generator.cpp | 6 +++--- XSC/be/IDL/Generator.cpp | 6 +++--- XSC/xsc.cpp | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Examples/Recursive/recursive.cpp b/Examples/Recursive/recursive.cpp index 2b9fbd5..7daf47b 100644 --- a/Examples/Recursive/recursive.cpp +++ b/Examples/Recursive/recursive.cpp @@ -1,5 +1,5 @@ // Generated by XSC version 2.0.0 -// Command line: '/home/johnny/ACE/XSC/bin/xsc' '--backend' 'cxx' 'recursive.xsd' +// Arguments: '--backend' 'cxx' 'recursive.xsd' #include "recursive.hpp" #include diff --git a/Examples/Recursive/recursive.hpp b/Examples/Recursive/recursive.hpp index fee82ec..88e74b7 100644 --- a/Examples/Recursive/recursive.hpp +++ b/Examples/Recursive/recursive.hpp @@ -1,5 +1,5 @@ // Generated by XSC version 2.0.0 -// Command line: '/home/johnny/ACE/XSC/bin/xsc' '--backend' 'cxx' 'recursive.xsd' +// Arguments: '--backend' 'cxx' 'recursive.xsd' #ifndef RECURSIVE_HPP #define RECURSIVE_HPP diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index ba511a1..22ef07b 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -119,9 +119,9 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con auto write_version = [&options] (std::wostream& output) { output << L"// Generated by XSC version " << XSC::wide_version << std::endl - << L"// Command line: "; - std::string const& command_line {options.value ("command-line")}; - for (char c : command_line) + << L"// Arguments: "; + std::string const& arguments {options.value ("arguments")}; + for (char c : arguments) output << static_cast (c); output << std::endl; }; diff --git a/XSC/be/IDL/Generator.cpp b/XSC/be/IDL/Generator.cpp index 3a9ba30..fddc8b4 100644 --- a/XSC/be/IDL/Generator.cpp +++ b/XSC/be/IDL/Generator.cpp @@ -57,9 +57,9 @@ namespace IDL } idl << L"// Generated by XSC version " << XSC::wide_version << std::endl - << L"// Command line: "; - std::string const& command_line {options.value ("command-line")}; - for (char c : command_line) + << L"// Arguments: "; + std::string const& arguments {options.value ("arguments")}; + for (char c : arguments) idl << static_cast (c); idl << std::endl; diff --git a/XSC/xsc.cpp b/XSC/xsc.cpp index e3bfb56..a44d66e 100644 --- a/XSC/xsc.cpp +++ b/XSC/xsc.cpp @@ -175,9 +175,9 @@ namespace invocation (int argc, char* argv[]) { std::string result; - for (int i {}; i != argc; ++i) + for (int i {1}; i != argc; ++i) { - if (i != 0) + if (i != 1) result += ' '; result += shell_quote (argv[i]); } @@ -217,7 +217,7 @@ int main (int argc, char* argv[]) { try { - std::string const original_invocation {invocation (argc, argv)}; + std::string const original_arguments {invocation (argc, argv)}; XSC::Options command_line; ACE_Get_Opt get_opt (argc, argv, "", 1, 0, ACE_Get_Opt::PERMUTE_ARGS); @@ -266,7 +266,7 @@ int main (int argc, char* argv[]) return 1; } - command_line.set ("command-line", original_invocation); + command_line.set ("arguments", original_arguments); command_line.set ("input-file", get_opt.argv ()[get_opt.opt_ind ()]); auto set_default = [&command_line] (std::string const& name, std::string const& value) From f3242b39b5e349604813dde5c75548a394ede5e9 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 19:11:02 +0200 Subject: [PATCH 15/20] Modernize generated C++ output --- XSC/be/CXX/Elements.cpp | 8 ++ XSC/be/CXX/Elements.hpp | 45 ++++++++++++ XSC/be/CXX/Header.cpp | 37 +++------- XSC/be/CXX/Inline.cpp | 20 ++--- XSC/be/CXX/Source.cpp | 6 +- XSC/be/CXX/TraversalHeader.cpp | 130 +++++++++------------------------ XSC/be/CXX/TraversalSource.cpp | 72 ++++++++---------- XSC/be/CXX/WriterSource.cpp | 34 +++++---- 8 files changed, 159 insertions(+), 193 deletions(-) diff --git a/XSC/be/CXX/Elements.cpp b/XSC/be/CXX/Elements.cpp index f58e7ae..eaacb4e 100644 --- a/XSC/be/CXX/Elements.cpp +++ b/XSC/be/CXX/Elements.cpp @@ -337,6 +337,14 @@ type_name (SemanticGraph::Type& t, string const& nss) return anon_prefix_ + id (t.name ()) + anon_suffix_; } +string Context:: +base_type_name (SemanticGraph::Complex& t) +{ + auto b (t.inherits_begin ()), e (t.inherits_end ()); + + return b == e ? L"::XSCRT::Type" : type_name ((**b).inheritee ()); +} + string Context:: type_name (SemanticGraph::Instance& i, string const& nss) { diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index 891ee30..74097f5 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -173,6 +173,9 @@ class Context string type_name (SemanticGraph::Type& t, string const& ns_suffix = L""); + string + base_type_name (SemanticGraph::Complex& t); + protected: string fq_name (SemanticGraph::Nameable& n, string const& ns_suffix = L"", bool mangle = true); @@ -525,6 +528,48 @@ has_copy_required_members (SemanticGraph::Complex& c) return t.required; } +struct ConstructorRequiredMembers : Traversal::Enumeration, + Traversal::Element, + Traversal::Attribute +{ + void + traverse (SemanticGraph::Enumeration&) override + { + required = true; + } + + void + traverse (SemanticGraph::Element& e) override + { + if (e.min () >= 1) + required = true; + } + + void + traverse (SemanticGraph::Attribute& a) override + { + if (!a.optional ()) + required = true; + } + + bool required {}; +}; + +inline bool +has_constructor_required_members (SemanticGraph::Complex& c) +{ + ConstructorRequiredMembers t; + Traversal::Complex complex; + Traversal::Inherits inherits; + Traversal::Names names; + complex.edge_traverser (inherits); + complex.edge_traverser (names); + inherits.node_traverser (t); + names.node_traverser (t); + complex.traverse (c); + return t.required; +} + // Fundamental type mapping helper. // struct Fundamental : Traversal::FundamentalType, diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 3de9d50..c78e912 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -36,16 +36,6 @@ namespace os << " : public " << name << "{"; - switch(this->cppmode_) - { - case CPPMODE::CPP03: - os << "typedef " << name << " Base;" << std::endl; - break; - case CPPMODE::CPP11: - case CPPMODE::CPP17: - os << "using Base = " << name << ";" << std::endl; - break; - } } }; @@ -511,9 +501,7 @@ namespace inherits_none (Type &c) override { os << " : public ::XSCRT::Type" - << "{" - << (this->cppmode_ != CPPMODE::CPP03 ? "using Base = ::XSCRT::Type;" : "typedef ::XSCRT::Type Base;" ) - << std::endl; + << "{" << std::endl; switch(this->cppmode_) { case CPPMODE::CPP03: @@ -619,7 +607,9 @@ namespace ctor_args_.traverse (c); - os << ");" + bool const default_constructor (this->cppmode_ != CPPMODE::CPP03 && + !has_constructor_required_members (c)); + os << ")" << (default_constructor ? " = default;" : ";") << std::endl; } @@ -817,8 +807,7 @@ namespace name = id (e.name ()); os << "class " << ex_sp_ << name << " : public ::XSCRT::Type" - << "{" - << "public:" << std::endl; + << "{" << "public:" << std::endl; enter_scope (name); @@ -852,12 +841,7 @@ namespace label_.reset (); names (e, names_labels_); - os << std::endl << "};" - << std::endl; - - os << "Value" << std::endl - << "integral () const;" - << std::endl; + os << L"};\nValue integral () const;\n"; if (this->read_only_) { @@ -874,13 +858,12 @@ namespace } } - os << "friend bool " << ex_ << std::endl + os << "friend bool " << ex_ << "operator== (" << name << " const& a, " << name << " const& b);" - << std::endl; - - os << "friend bool " << ex_ << std::endl + << L'\n' + << "friend bool " << ex_ << "operator!= (" << name << " const& a, " << name << " const& b);" - << std::endl; + << L'\n'; os << "private:" << std::endl; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 026d1fd..c5d5a2a 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -561,8 +561,10 @@ namespace string type (name); bool const has_base (c.inherits_begin () != c.inherits_end ()); + bool const default_constructor (this->cppmode_ != CPPMODE::CPP03 && + !has_constructor_required_members (c)); - if (!this->read_only_) + if (!this->read_only_ && !default_constructor) { // c-tor // @@ -715,15 +717,15 @@ namespace } void - traverse (SemanticGraph::Enumeration&) override + traverse (SemanticGraph::Enumeration& e) override { - os << ": Base (b__)" << std::endl; + os << ": " << type_name (e) << " (b__)" << std::endl; } void - traverse (SemanticGraph::Type&) override + traverse (SemanticGraph::Type& t) override { - os << ": Base ()" << std::endl; + os << ": " << type_name (t) << " ()" << std::endl; } void @@ -942,11 +944,11 @@ namespace } void - traverse (SemanticGraph::Type&) override + traverse (SemanticGraph::Type& t) override { if (!this->base_class_initialized_) { - os << ": Base (s)" << std::endl; + os << ": " << type_name (t) << " (s)" << std::endl; this->base_class_initialized_ = true; } } @@ -1132,9 +1134,9 @@ namespace } void - traverse (SemanticGraph::Type&) override + traverse (SemanticGraph::Type& t) override { - os << "Base::operator= (s);" << std::endl; + os << type_name (t) << "::operator= (s);" << std::endl; } void diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 67078bc..ec43c72 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -1252,7 +1252,7 @@ namespace string type (type_name (c)); os << scope << "::" << name << " (" << xml_element_type << " const& element)" << std::endl - << ":" << "Base (element)" + << ": " << base_type_name (c) << " (element)" << "{"; } @@ -1447,11 +1447,11 @@ namespace virtual void - pre (Type&) + pre (Type& c) { os << scope << "::" << name << " (" << xml_attribute_type << " const& a)" << std::endl << ":" << std::endl - << "Base (a)" << std::endl + << base_type_name (c) << " (a)" << std::endl << "{"; } diff --git a/XSC/be/CXX/TraversalHeader.cpp b/XSC/be/CXX/TraversalHeader.cpp index d96f9ad..6577c28 100644 --- a/XSC/be/CXX/TraversalHeader.cpp +++ b/XSC/be/CXX/TraversalHeader.cpp @@ -26,6 +26,12 @@ namespace { } + void + declaration (string const& name, string const& type) + { + os << "virtual void " << name << " (" << type << ");" << std::endl; + } + virtual void traverse (SemanticGraph::Element& e) { @@ -43,59 +49,34 @@ namespace // name // - os << "virtual void" << std::endl - << id (name) << " (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << id (name) << " (Type const&);" - << std::endl; + declaration (id (name), L"Type&"); + declaration (id (name), L"Type const&"); // name_pre // - os << "virtual void" << std::endl - << name << "_pre (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << name << "_pre (Type const&);" - << std::endl; + declaration (name + L"_pre", L"Type&"); + declaration (name + L"_pre", L"Type const&"); // name_next // - os << "virtual void" << std::endl - << name << "_next (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << name << "_next (Type const&);" - << std::endl; + declaration (name + L"_next", L"Type&"); + declaration (name + L"_next", L"Type const&"); // name_post // - os << "virtual void" << std::endl - << name << "_post (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << name << "_post (Type const&);" - << std::endl; + declaration (name + L"_post", L"Type&"); + declaration (name + L"_post", L"Type const&"); // name_none // if (e.min () == 0) { - os << "virtual void" << std::endl - << name << "_none (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << name << "_none (Type const&);" - << std::endl; + declaration (name + L"_none", L"Type&"); + declaration (name + L"_none", L"Type const&"); } } else if (e.min () == 0) @@ -105,24 +86,14 @@ namespace // name // - os << "virtual void" << std::endl - << id (name) << " (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << id (name) << " (Type const&);" - << std::endl; + declaration (id (name), L"Type&"); + declaration (id (name), L"Type const&"); // name_none // - os << "virtual void" << std::endl - << name << "_none (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << name << "_none (Type const&);" - << std::endl; + declaration (name + L"_none", L"Type&"); + declaration (name + L"_none", L"Type const&"); } else { @@ -131,13 +102,8 @@ namespace // name // - os << "virtual void" << std::endl - << id (name) << " (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << id (name) << " (Type const&);" - << std::endl; + declaration (id (name), L"Type&"); + declaration (id (name), L"Type const&"); } } @@ -156,35 +122,20 @@ namespace { // name // - os << "virtual void" << std::endl - << id (name) << " (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << id (name) << " (Type const&);" - << std::endl; + declaration (id (name), L"Type&"); + declaration (id (name), L"Type const&"); // name_none // - os << "virtual void" << std::endl - << name << "_none (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << name << "_none (Type const&);" - << std::endl; + declaration (name + L"_none", L"Type&"); + declaration (name + L"_none", L"Type const&"); } else { // name // - os << "virtual void" << std::endl - << id (name) << " (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << id (name) << " (Type const&);" - << std::endl; + declaration (id (name), L"Type&"); + declaration (id (name), L"Type const&"); } } }; @@ -267,23 +218,15 @@ namespace // traverse () // - os << virtual_string << "void" << std::endl - << "traverse (Type&)" << override_string << ";" + os << virtual_string << "void traverse (Type&)" << override_string << ";" << std::endl; - - os << virtual_string << "void" << std::endl - << "traverse (Type const&)" << override_string << ";" + os << virtual_string << "void traverse (Type const&)" << override_string << ";" << std::endl; // pre () // - os << "virtual void" << std::endl - << "pre (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << "pre (Type const&);" - << std::endl; + os << "virtual void pre (Type&);" << std::endl; + os << "virtual void pre (Type const&);" << std::endl; } virtual void @@ -291,13 +234,8 @@ namespace { // post () // - os << "virtual void" << std::endl - << "post (Type&);" - << std::endl; - - os << "virtual void" << std::endl - << "post (Type const&);" - << std::endl; + os << "virtual void post (Type&);" << std::endl; + os << "virtual void post (Type const&);" << std::endl; os << "};"; } diff --git a/XSC/be/CXX/TraversalSource.cpp b/XSC/be/CXX/TraversalSource.cpp index 19e4da1..b096075 100644 --- a/XSC/be/CXX/TraversalSource.cpp +++ b/XSC/be/CXX/TraversalSource.cpp @@ -29,7 +29,7 @@ namespace void optional_member (string const& name, string const& type) { - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type& o)" << "{"; if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) @@ -43,7 +43,7 @@ namespace os << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{"; if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) @@ -81,12 +81,12 @@ namespace // name_none // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_none (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_none (Type const&)" << "{" << "}"; @@ -98,11 +98,11 @@ namespace // name // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type& o)" << "{dispatch (o." << id (name) << " ());}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{dispatch (o." << id (name) << " ());}"; } @@ -116,11 +116,9 @@ namespace string iterator_type (fq_name (e, L"", false)); iterator_type += this->read_only_ ? L"_const_iterator" : L"_iterator"; - os << "void " << scope << "::" << std::endl - << id (name) << " (Type& o)" + os << "void " << scope << "::" << id (name) << " (Type& o)" << "{" - << "// VC6 anathema strikes again" << std::endl - << iterator_type << " " + << (this->cppmode_ == CPPMODE::CPP03 ? iterator_type : L"auto") << " " << "b (o.begin_" << name << "()), " << "e (o.end_" << name << "());" << std::endl @@ -128,11 +126,6 @@ namespace << "{" << name << "_pre (o);" - //@@ VC6 - // - // << "iterate_and_dispatch< " << scope << ", Type > " << - //"(b, e, *this, &" << scope << "::" << name << "_next, o);" - << "for (; b != e;)" << "{" << (this->cppmode_ == CPPMODE::CPP03 ? "dispatch (*(*b));" : "dispatch (*b);") @@ -148,11 +141,11 @@ namespace os << "}"; - os << "void " << scope << "::" << std::endl - << id (name) << " (Type const& o)" + os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{" - << "// VC6 anathema strikes again" << std::endl - << fq_name (e, L"", false) << "_const_iterator " + << (this->cppmode_ == CPPMODE::CPP03 + ? fq_name (e, L"", false) + L"_const_iterator" + : L"auto") << " " << "b (o.begin_" << name << "()), " << "e (o.end_" << name << "());" << std::endl @@ -160,11 +153,6 @@ namespace << "{" << name << "_pre (o);" - //@@ VC6 - // - // << "iterate_and_dispatch< " << scope << ", Type const > " << - //"(b, e, *this, &" << scope << "::" << name << "_next, o);" - << "for (; b != e;)" << "{" << (this->cppmode_ == CPPMODE::CPP03 ? "dispatch (*(*b));" : "dispatch (*b);") @@ -182,12 +170,12 @@ namespace // name_pre // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_pre (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_pre (Type const&)" << "{" << "}"; @@ -195,12 +183,12 @@ namespace // name_next // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_next (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_next (Type const&)" << "{" << "}"; @@ -208,12 +196,12 @@ namespace // name_post // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_post (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_post (Type const&)" << "{" << "}"; @@ -222,12 +210,12 @@ namespace // if (e.min () == 0) { - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_none (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_none (Type const&)" << "{" << "}"; @@ -255,12 +243,12 @@ namespace // name_none // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_none (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_none (Type const&)" << "{" << "}"; @@ -269,14 +257,14 @@ namespace { // name // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type& o)" << "{" << "dispatch (o." << id (name) << " ());" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{" << "dispatch (o." << id (name) << " ());" @@ -458,7 +446,7 @@ namespace // traverse (Type&) // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << "traverse (Type& o)" << "{" << "pre (o);"; @@ -471,7 +459,7 @@ namespace // traverse (Type const&) // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << "traverse (Type const& o)" << "{" << "pre (o);"; @@ -485,12 +473,12 @@ namespace // pre () // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << "pre (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << "pre (Type const&)" << "{" << "}"; @@ -503,12 +491,12 @@ namespace // post () // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << "post (Type&)" << "{" << "}"; - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << "post (Type const&)" << "{" << "}"; diff --git a/XSC/be/CXX/WriterSource.cpp b/XSC/be/CXX/WriterSource.cpp index d48b15f..dd7f9e2 100644 --- a/XSC/be/CXX/WriterSource.cpp +++ b/XSC/be/CXX/WriterSource.cpp @@ -47,7 +47,7 @@ namespace // pre // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_pre (Type const&)" << "{" << "push_ (" << xml_element_type << " (" << @@ -58,7 +58,7 @@ namespace // next // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_next (Type const& o)" << "{" << name << "_post (o);" @@ -68,7 +68,7 @@ namespace // post // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << name << "_post (Type const&)" << "{" << "pop_ ();" @@ -78,7 +78,7 @@ namespace { // optional & one // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{" << "push_ (" << xml_element_type << " (" << @@ -114,7 +114,7 @@ namespace bool q (a.qualified ()); - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{" << xml_attribute_type << " a (" << @@ -231,7 +231,7 @@ namespace // c-tor (XML::Element&) // - os << scope << "::" << std::endl + os << scope << "::" << name << " (" << xml_element_type << "& e)" << std::endl << ": ::XSCRT::Writer<" << char_type << "> (e)" << std::endl << "{" @@ -241,7 +241,7 @@ namespace // if (this->cppmode_ == CPPMODE::CPP03) { - os << scope << "::" << std::endl + os << scope << "::" << name << " ()" << "{" << "}"; @@ -249,7 +249,7 @@ namespace // traverse // - os << "void " << scope << "::" << std::endl + os << "void " << scope << "::" << "traverse (Type const& o)" << "{"; @@ -284,9 +284,9 @@ namespace string name (e.name ()); string type (type_name (e)); - os << "if (o == " << type << "::" << id (name) << ") " << - "s = " << L << " (\"" << name << "\")" << ";" - << "else "; + os << "case " << type << "::" << id (name) << "_l: " + << "s = " << L << " (\"" << name << "\"); " + << "break;"; } }; @@ -307,7 +307,7 @@ namespace // c-tor (XML::Element&) // - os << name << "::" << std::endl + os << name << "::" << name << " (" << xml_element_type << "& e)" << std::endl << ": ::XSCRT::Writer<" << char_type << "> (e)" << std::endl << "{" @@ -317,7 +317,7 @@ namespace // if (this->cppmode_ == CPPMODE::CPP03) { - os << name << "::" << std::endl + os << name << "::" << name << " ()" << "{" << "}"; @@ -325,15 +325,17 @@ namespace // traverse // - os << "void " << name << "::" << std::endl + os << "void " << name << "::" << "traverse (Type const& o)" << "{" << string_type << " s;" - << std::endl; + << "switch (o.integral ())" + << "{"; names (c, names_); - os << "{}" + os << "default: break;" + << "}" << "if (::XSCRT::XML::Attribute< " << char_type << " >* a = attr_ ())" << "{" << "a->value (s);" From 9aa9e1c63174effe8c1a9cdee0c408e2c581f70b Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 19:14:35 +0200 Subject: [PATCH 16/20] Mark generated sequence counts noexcept --- XSC/be/CXX/Header.cpp | 3 ++- XSC/be/CXX/Inline.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index c78e912..b098e0a 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -227,7 +227,8 @@ namespace os << "void set_" << name << "_ptr (const " << string_type << "& idref);"; } - os << "size_t count_" << name << " () const;"; + os << "size_t count_" << name << " () const" + << (this->cppmode_ == CPPMODE::CPP17 ? " noexcept;" : ";"); os << std::endl << (this->read_only_ ? "private:" : "protected:") << std::endl; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index c5d5a2a..8e04032 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -267,6 +267,7 @@ namespace // os << i << "size_t " << scope << "::count_" << name << "() const" + << (this->cppmode_ == CPPMODE::CPP17 ? " noexcept" : "") << "{" << "return " << id(name) << "_.size ();" << "}"; From 5d51d24d577b2ff888c1b07744c9c083eaae8f83 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 20:53:45 +0200 Subject: [PATCH 17/20] Fix read-only compatibility generation --- .github/workflows/linux.yml | 11 +++++ Tests/ReadOnly/readonly.mpc | 10 ++-- Tests/ReadOnly/run_test.pl | 85 ++++++++++++++++++++++++++++++++++ XSC/be/CXX/Elements.hpp | 6 +++ XSC/be/CXX/Generator.cpp | 25 +++++----- XSC/be/CXX/Header.cpp | 4 +- XSC/be/CXX/Inline.cpp | 8 ++-- XSC/be/CXX/Source.cpp | 38 ++++++++++----- XSC/be/CXX/TraversalSource.cpp | 18 +++---- XSC/xsc.cpp | 6 +++ 10 files changed, 167 insertions(+), 44 deletions(-) create mode 100644 Tests/ReadOnly/run_test.pl diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 2ebada9..68d519f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -105,6 +105,17 @@ jobs: Pop-Location } shell: pwsh + - name: Run read-only mode compatibility tests + run: | + Push-Location ${env:XSC_ROOT}/Tests/ReadOnly + try { + perl run_test.pl + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + } + finally { + Pop-Location + } + shell: pwsh - name: Build XSC generated schema tests run: | Push-Location ${env:XSC_ROOT}/Tests diff --git a/Tests/ReadOnly/readonly.mpc b/Tests/ReadOnly/readonly.mpc index ac74dd5..343e7da 100644 --- a/Tests/ReadOnly/readonly.mpc +++ b/Tests/ReadOnly/readonly.mpc @@ -4,6 +4,7 @@ project (xsc_test_readonly): xscdefaults { xscflags += --cxx-char-type char xscflags += --cxx-read-only xscflags += --cxx-generate-cdr-reader-types + xscflags += --cxx-generate-cdr-writer-types xscflags += --cxx-generate-traversal-types XSC_Files { @@ -15,6 +16,7 @@ project (xsc_test_readonly): xscdefaults { project (xsc_test_readonly_generated): xscrt { after += xsc_test_readonly + includes += $(ACE_ROOT)/ace/XML_Utils Source_Files { readonly.cpp @@ -22,7 +24,7 @@ project (xsc_test_readonly_generated): xscrt { } } -project (xsc_test_readonly_cpp03): xscdefaults { +project (xsc_test_cpp03_compatibility): xscdefaults { requires += xsc custom_only = 1 @@ -33,7 +35,6 @@ project (xsc_test_readonly_cpp03): xscdefaults { xscflags += --cxx-char-type char xscflags += --cxx-cpp03 - xscflags += --cxx-read-only xscflags += --cxx-generate-traversal-types xscflags += --cxx-header-suffix .cpp03.hpp xscflags += --cxx-source-suffix .cpp03.cpp @@ -46,8 +47,9 @@ project (xsc_test_readonly_cpp03): xscdefaults { } } -project (xsc_test_readonly_cpp03_generated): xscrt { - after += xsc_test_readonly_cpp03 +project (xsc_test_cpp03_compatibility_generated): xscrt { + after += xsc_test_cpp03_compatibility + includes += $(ACE_ROOT)/ace/XML_Utils Source_Files { readonly.cpp03.cpp diff --git a/Tests/ReadOnly/run_test.pl b/Tests/ReadOnly/run_test.pl new file mode 100644 index 0000000..0a205ea --- /dev/null +++ b/Tests/ReadOnly/run_test.pl @@ -0,0 +1,85 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +use strict; +use warnings; + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +my $target = PerlACE::TestTarget::create_target (1) + || die "Create target 1 failed\n"; + +my $xsc = "$ENV{XSC_ROOT}/bin/xsc"; +unless (-x $xsc) { + die "ERROR: Cannot find executable $xsc\n"; +} + +my $status = 0; +my $index = 0; +for my $mode ('--cxx-cpp03', '--cxx-cpp11') { + my $suffix = ".reject" . $$ . "_" . $index; + ++$index; + my $header = "readonly$suffix.hpp"; + my $source = "readonly$suffix.cpp"; + my $process = $target->CreateProcess ( + $xsc, "--backend cxx --cxx-read-only $mode " . + "--cxx-header-suffix $suffix.hpp --cxx-source-suffix $suffix.cpp " . + "readonly.xsd"); + my $result = $process->SpawnWaitKill ( + $target->ProcessStartWaitInterval ()); + + if ($result == -1) { + print STDERR "ERROR: XSC $mode read-only rejection test timed out\n"; + $status = 1; + } + elsif ($result == 0) { + print STDERR "ERROR: XSC accepted read-only mode with $mode\n"; + $status = 1; + } + else { + print "XSC rejected read-only mode with $mode as expected\n"; + } + + if (-e $header || -e $source) { + print STDERR "ERROR: XSC generated output for unsupported read-only $mode\n"; + unlink $header if -e $header; + unlink $source if -e $source; + $status = 1; + } +} + +my $compat_suffix = ".compat" . $$; +my $compat_header = "readonly$compat_suffix.hpp"; +my $compat_source = "readonly$compat_suffix.cpp"; +my $compat_process = $target->CreateProcess ( + $xsc, "--backend cxx --cxx-char-type char --cxx-cpp03 " . + "--cxx-generate-traversal-types --cxx-header-suffix " . + "$compat_suffix.hpp --cxx-source-suffix $compat_suffix.cpp readonly.xsd"); +my $compat_result = $compat_process->SpawnWaitKill ( + $target->ProcessStartWaitInterval ()); + +if ($compat_result != 0) { + print STDERR "ERROR: XSC failed to generate writable C++03 traversal code\n"; + $status = 1; +} +elsif (open my $source_file, '<', $compat_source) { + local $/; + my $source_text = <$source_file>; + close $source_file; + + if ($source_text =~ /\bnullptr\b/) { + print STDERR "ERROR: C++03 traversal output contains nullptr\n"; + $status = 1; + } +} +else { + print STDERR "ERROR: XSC did not create C++03 traversal output\n"; + $status = 1; +} + +unlink $compat_header if -e $compat_header; +unlink $compat_source if -e $compat_source; + +exit $status; diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index 74097f5..2c45abb 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -290,6 +290,12 @@ class Context return this->read_only_; } + bool + optional_via_if_set () + { + return this->cppmode_ != CPPMODE::CPP03 || this->read_only_; + } + public: std::wostream& os; string& scope; diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index 22ef07b..3f652e5 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -58,6 +58,17 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con throw std::invalid_argument ("invalid value for --cxx-orb: " + orb); } + ::Context::CPPMODE cppmode_ { ::Context::CPPMODE::CPP17 }; + if (options.count ("cxx-cpp03")) + cppmode_ = ::Context::CPPMODE::CPP03; + if (options.count ("cxx-cpp11")) + cppmode_ = ::Context::CPPMODE::CPP11; + if (options.count ("cxx-cpp17")) + cppmode_ = ::Context::CPPMODE::CPP17; + + if (options.count ("cxx-read-only") && cppmode_ != ::Context::CPPMODE::CPP17) + throw std::invalid_argument ("--cxx-read-only requires C++17 mode"); + //Stores file suffixes (defaults are .hpp, ipp, and cpp) std::string hxx_suffix (options.value ("cxx-header-suffix")); std::string ixx_suffix (options.value ("cxx-inline-suffix")); @@ -270,20 +281,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con bool cdr_reader (options.count ("cxx-generate-cdr-reader-types") && !read_only); bool cdr_writer (options.count ("cxx-generate-cdr-writer-types")); - ::Context::CPPMODE cppmode_ { ::Context::CPPMODE::CPP17 }; - if (options.count ("cxx-cpp03")) - { - cppmode_ = ::Context::CPPMODE::CPP03; - } - if (options.count ("cxx-cpp11")) - { - cppmode_ = ::Context::CPPMODE::CPP11; - } - if (options.count ("cxx-cpp17")) - { - cppmode_ = ::Context::CPPMODE::CPP17; - } - // Check about random access sequences bool ra_sequences (options.count ("cxx-enable-random-access-sequences")); diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index b098e0a..97e6d2b 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -240,7 +240,7 @@ namespace { // optional // - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) { os << "bool " << name << "_p () const;"; os << type << " const& " << id (name) << " () const;"; @@ -365,7 +365,7 @@ namespace if (a.optional ()) { - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) { os << "bool " << name << "_p () const;"; os << type << " const& " << id (name) << " () const;"; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 8e04032..e7b03ea 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -48,7 +48,7 @@ namespace { // optional // - if (this->cppmode_ != CPPMODE::CPP03 || this->read_only_) + if (this->optional_via_if_set ()) { string noexcept_suffix (this->cppmode_ == CPPMODE::CPP03 ? L"" : L" noexcept"); os << i << type << " const* " << scope << "::" << id (name) @@ -246,7 +246,7 @@ namespace << "}\n"; } - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) { // add_typename os << i @@ -288,7 +288,7 @@ namespace if (a.optional ()) { - if (this->cppmode_ != CPPMODE::CPP03 || this->read_only_) + if (this->optional_via_if_set ()) { string noexcept_suffix (this->cppmode_ == CPPMODE::CPP03 ? L"" : L" noexcept"); os << i << type << " const* " << scope << "::" << id (name) @@ -309,7 +309,7 @@ namespace << "}"; } - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) { os << i << type << " const& " << scope << "::" << id (name) << " () const" diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index ec43c72..6ca7179 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -501,7 +501,7 @@ namespace // optional // os << " // " << name << std::endl; - if (this->cppmode_ == CPPMODE::CPP03) + if (!this->optional_via_if_set ()) { os << "bool " << name << "_p = this->" << name << "_p ();"; os << "stream.write_boolean (" << name << "_p" << ");"; @@ -509,14 +509,20 @@ namespace } else { - os << "auto const* " << name << "_value = this->" << name - << "_if_set ();"; - os << "stream.write_boolean (" << name << "_value != nullptr);"; - os << "if (" << name << "_value != nullptr)" << "{"; + if (this->cppmode_ == CPPMODE::CPP03) + os << type << " const* " << name << "_value = this->" << name + << "_if_set ();"; + else + os << "auto const* " << name << "_value = this->" << name + << "_if_set ();"; + os << "stream.write_boolean (" << name << "_value != " + << (this->cppmode_ == CPPMODE::CPP03 ? "0" : "nullptr") << ");"; + os << "if (" << name << "_value != " + << (this->cppmode_ == CPPMODE::CPP03 ? "0" : "nullptr") << ")" << "{"; } // check if the type is a boolean type - if (this->cppmode_ != CPPMODE::CPP03) + if (this->optional_via_if_set ()) { if (type_is_boolean (type)) os << "stream.write_boolean (*" << name << "_value);" << std::endl; @@ -580,23 +586,31 @@ namespace os << "// " << name << std::endl; // First write out the boolean value - if (this->cppmode_ == CPPMODE::CPP03) + if (!this->optional_via_if_set ()) { os << "stream.write_boolean (" << name << "_p ());"; os << "if (" << name << "_p ())" << std::endl; } else { - os << "auto const* " << id (name) << "_value = this->" - << id (name) << "_if_set ();"; + if (this->cppmode_ == CPPMODE::CPP03) + os << type << " const* " << id (name) << "_value = this->" + << id (name) << "_if_set ();"; + else + os << "auto const* " << id (name) << "_value = this->" + << id (name) << "_if_set ();"; os << "stream.write_boolean (" << id (name) - << "_value != nullptr);"; - os << "if (" << id (name) << "_value != nullptr)" + << "_value != " + << (this->cppmode_ == CPPMODE::CPP03 ? "0" : "nullptr") + << ");"; + os << "if (" << id (name) << "_value != " + << (this->cppmode_ == CPPMODE::CPP03 ? "0" : "nullptr") + << ")" << std::endl; } // check if the type is a boolean type - if (this->cppmode_ != CPPMODE::CPP03) + if (this->optional_via_if_set ()) { if (type_is_boolean (type)) os << " stream.write_boolean (*" << id (name) diff --git a/XSC/be/CXX/TraversalSource.cpp b/XSC/be/CXX/TraversalSource.cpp index b096075..dd8d28b 100644 --- a/XSC/be/CXX/TraversalSource.cpp +++ b/XSC/be/CXX/TraversalSource.cpp @@ -32,9 +32,9 @@ namespace os << "void " << scope << "::" << id (name) << " (Type& o)" << "{"; - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) os << "dispatch (o." << id (name) << " ());"; - else if (this->cppmode_ == CPPMODE::CPP03 || this->read_only_) + else if (this->cppmode_ == CPPMODE::CPP03) os << type << " const* value = o." << id (name) << "_if_set (); if (value) dispatch (*value);"; else @@ -46,9 +46,9 @@ namespace os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{"; - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) os << "dispatch (o." << id (name) << " ());"; - else if (this->cppmode_ == CPPMODE::CPP03) + else if (this->cppmode_ == CPPMODE::CPP03 || this->read_only_) os << type << " const* value = o." << id (name) << "_if_set (); if (value) dispatch (*value);"; else @@ -317,11 +317,12 @@ namespace { // optional // - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) os << "if (o." << name << "_p ()) " << id (name) << " (o);" << "else " << name << "_none (o);"; else - os << "if (o." << id (name) << "_if_set () != nullptr) " + os << "if (o." << id (name) << "_if_set () != " + << (this->cppmode_ == CPPMODE::CPP03 ? "0" : "nullptr") << ") " << id (name) << " (o);" << "else " << name << "_none (o);"; } @@ -352,11 +353,12 @@ namespace { // optional // - if (this->cppmode_ == CPPMODE::CPP03 && !this->read_only_) + if (!this->optional_via_if_set ()) os << "if (o." << name << "_p ()) " << id (name) << " (o);" << "else " << name << "_none (o);"; else - os << "if (o." << id (name) << "_if_set () != nullptr) " + os << "if (o." << id (name) << "_if_set () != " + << (this->cppmode_ == CPPMODE::CPP03 ? "0" : "nullptr") << ") " << id (name) << " (o);" << "else " << name << "_none (o);"; } diff --git a/XSC/xsc.cpp b/XSC/xsc.cpp index a44d66e..61315d4 100644 --- a/XSC/xsc.cpp +++ b/XSC/xsc.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -384,6 +385,11 @@ int main (int argc, char* argv[]) return 0; } + catch (std::exception const& e) + { + std::cerr << "error: " << e.what () << std::endl; + return 1; + } catch (...) { std::wcerr << "caught unknown exception" << std::endl; From 82e9c72abb0f4a8652471234dc847b8246a44d3a Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 21:11:14 +0200 Subject: [PATCH 18/20] Address PR 84 review feedback --- XSC/be/CXX/Elements.hpp | 20 ++++++++++++++------ XSC/be/CXX/Generator.cpp | 5 ++++- XSC/be/CXX/Header.cpp | 4 ++-- XSC/be/CXX/Source.cpp | 2 +- XSC/be/IDL/Generator.cpp | 5 ++++- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index 2c45abb..72d228c 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -5,6 +5,7 @@ #define CXX_ELEMENTS_HXX #include +#include #include #include #include @@ -565,14 +566,21 @@ inline bool has_constructor_required_members (SemanticGraph::Complex& c) { ConstructorRequiredMembers t; - Traversal::Complex complex; - Traversal::Inherits inherits; + Traversal::Scope scope; Traversal::Names names; - complex.edge_traverser (inherits); - complex.edge_traverser (names); - inherits.node_traverser (t); + scope.edge_traverser (names); names.node_traverser (t); - complex.traverse (c); + + std::function visit = [&] (SemanticGraph::Complex& current) + { + for (auto i (current.inherits_begin ()); i != current.inherits_end (); ++i) + if (auto base = dynamic_cast (std::addressof ((**i).inheritee ()))) + visit (*base); + + scope.traverse (current); + }; + + visit (c); return t.required; } diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index 3f652e5..878b380 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -133,7 +133,10 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con << L"// Arguments: "; std::string const& arguments {options.value ("arguments")}; for (char c : arguments) - output << static_cast (c); + { + unsigned char const u {static_cast (c)}; + output << (u < 0x80 ? static_cast (u) : L'?'); + } output << std::endl; }; diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 97e6d2b..31d4002 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -859,10 +859,10 @@ namespace } } - os << "friend bool " << ex_ + os << "friend bool " << ex_sp_ << "operator== (" << name << " const& a, " << name << " const& b);" << L'\n' - << "friend bool " << ex_ + << "friend bool " << ex_sp_ << "operator!= (" << name << " const& a, " << name << " const& b);" << L'\n'; diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 6ca7179..3478dfb 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -388,7 +388,7 @@ namespace // Convert it to its base type. This will // have an operator << defined to // serialize this type - os << "stream << static_cast < const Base& > (*this);" << std::endl; + os << "stream << static_cast < const " << type << "& > (*this);" << std::endl; } // Helper method implementation diff --git a/XSC/be/IDL/Generator.cpp b/XSC/be/IDL/Generator.cpp index fddc8b4..f51425a 100644 --- a/XSC/be/IDL/Generator.cpp +++ b/XSC/be/IDL/Generator.cpp @@ -60,7 +60,10 @@ namespace IDL << L"// Arguments: "; std::string const& arguments {options.value ("arguments")}; for (char c : arguments) - idl << static_cast (c); + { + unsigned char const u {static_cast (c)}; + idl << (u < 0x80 ? static_cast (u) : L'?'); + } idl << std::endl; // Banner. From e400b15ef9862577690621d06174fa3398d80970 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 21:14:46 +0200 Subject: [PATCH 19/20] Add regression tests for PR 84 fixes --- Tests/Abstract/abstract.mpc | 3 +++ Tests/Abstract/abstract.xsd | 9 ++++++- Tests/Abstract/abstract_api.cpp | 15 +++++++++++ Tests/Validation/run_test.pl | 45 +++++++++++++++++++++++++++++++++ XSC/be/CXX/Elements.hpp | 10 ++++---- 5 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 Tests/Abstract/abstract_api.cpp diff --git a/Tests/Abstract/abstract.mpc b/Tests/Abstract/abstract.mpc index 452cdce..3d206a0 100644 --- a/Tests/Abstract/abstract.mpc +++ b/Tests/Abstract/abstract.mpc @@ -1,6 +1,7 @@ project (xsc_test_abstract): xscdefaults { requires += xsc custom_only = 1 + xscflags += --cxx-generate-cdr-writer-types XSC_Files { abstract.xsd } @@ -10,8 +11,10 @@ project (xsc_test_abstract): xscdefaults { project (xsc_test_abstract_generated): xscrt { after += xsc_test_abstract + includes += $(ACE_ROOT)/ace/XML_Utils Source_Files { abstract.cpp + abstract_api.cpp } } diff --git a/Tests/Abstract/abstract.xsd b/Tests/Abstract/abstract.xsd index 5bfa85b..ba5ba77 100644 --- a/Tests/Abstract/abstract.xsd +++ b/Tests/Abstract/abstract.xsd @@ -14,6 +14,13 @@ + + + + + + + @@ -32,4 +39,4 @@ - \ No newline at end of file + diff --git a/Tests/Abstract/abstract_api.cpp b/Tests/Abstract/abstract_api.cpp new file mode 100644 index 0000000..4747ae0 --- /dev/null +++ b/Tests/Abstract/abstract_api.cpp @@ -0,0 +1,15 @@ +#include "abstract.hpp" + +#include + +using StudentString = ::XMLSchema::string; +using StudentWithoutAdditionalFields = + ::XSC::Tests::StudentWithoutAdditionalFields; + +static_assert (std::is_constructible_v< + StudentWithoutAdditionalFields, + StudentString const&, + StudentString const&, + StudentString const&>); +static_assert (!std::is_default_constructible_v< + StudentWithoutAdditionalFields>); diff --git a/Tests/Validation/run_test.pl b/Tests/Validation/run_test.pl index 57a594b..ac1e463 100644 --- a/Tests/Validation/run_test.pl +++ b/Tests/Validation/run_test.pl @@ -33,4 +33,49 @@ print "XSC rejected test.xsd as expected\n"; } +my $banner = "banner_$$\xFF.txt"; +my $schema = "$ENV{XSC_ROOT}/Tests/Abstract/abstract.xsd"; +open my $banner_file, '>', $banner + or die "ERROR: Cannot create non-ASCII banner file $banner\n"; +close $banner_file; + +for my $backend ( + ['cxx', '--cxx-banner-file', "--cxx-header-suffix .args.$$.hpp --cxx-source-suffix .args.$$.cpp", "abstract.args.$$.hpp"], + ['idl', '--idl-banner-file', "--idl-file-suffix .args.$$.idl", "abstract.args.$$.idl"]) +{ + my ($name, $banner_option, $suffix_options, $output) = @$backend; + my $process = $target->CreateProcess ( + $xsc, "--backend $name $banner_option $banner $suffix_options $schema"); + my $result = $process->SpawnWaitKill ($target->ProcessStartWaitInterval ()); + + if ($result != 0) { + print STDERR "ERROR: XSC $name generation with a non-ASCII argument failed\n"; + $status = 1; + } + elsif (open my $generated, '<', $output) { + binmode $generated; + local $/; + my $text = <$generated>; + close $generated; + my ($arguments) = $text =~ m{^// Arguments: ([^\r\n]*)}m; + if (!defined $arguments || index ($arguments, "\xFF") != -1 || + index ($arguments, '?') == -1) { + print STDERR "ERROR: XSC $name did not safely record non-ASCII arguments\n"; + $status = 1; + } + } + else { + print STDERR "ERROR: XSC did not create $output\n"; + $status = 1; + } + + unlink $output if -e $output; + if ($name eq 'cxx') { + (my $source = $output) =~ s/\.hpp$/.cpp/; + unlink $source if -e $source; + } +} + +unlink $banner; + exit $status; diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index 72d228c..bda299e 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -566,10 +566,6 @@ inline bool has_constructor_required_members (SemanticGraph::Complex& c) { ConstructorRequiredMembers t; - Traversal::Scope scope; - Traversal::Names names; - scope.edge_traverser (names); - names.node_traverser (t); std::function visit = [&] (SemanticGraph::Complex& current) { @@ -577,7 +573,11 @@ has_constructor_required_members (SemanticGraph::Complex& c) if (auto base = dynamic_cast (std::addressof ((**i).inheritee ()))) visit (*base); - scope.traverse (current); + Traversal::Complex complex; + Traversal::Names names; + complex.edge_traverser (names); + names.node_traverser (t); + complex.traverse (current); }; visit (c); From 0a7986843366b2cea90ca7d600eee36b30596b8f Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 22 Oct 2026 21:20:39 +0200 Subject: [PATCH 20/20] Stop tracking recursive example output --- .gitignore | 6 +- Examples/Recursive/recursive.cpp | 128 ------------------------------- Examples/Recursive/recursive.hpp | 81 ------------------- 3 files changed, 5 insertions(+), 210 deletions(-) delete mode 100644 Examples/Recursive/recursive.cpp delete mode 100644 Examples/Recursive/recursive.hpp diff --git a/.gitignore b/.gitignore index 65aaa53..445c521 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,8 @@ Debug/ Release/ *.obj *.lib -*.dll \ No newline at end of file +*.dll + +# Generated example output kept local. +/Examples/Recursive/recursive.cpp +/Examples/Recursive/recursive.hpp diff --git a/Examples/Recursive/recursive.cpp b/Examples/Recursive/recursive.cpp deleted file mode 100644 index 7daf47b..0000000 --- a/Examples/Recursive/recursive.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Generated by XSC version 2.0.0 -// Arguments: '--backend' 'cxx' 'recursive.xsd' -#include "recursive.hpp" -#include - -#include "ace/ace_wchar.h" -namespace Recursive -{ - Element::Element (value_container_type const& value__, - long_container_type const& long___) - : ::XSCRT::Type () - , value_ (value__) - , long__ (long___) - { - } - Element::value_iterator Element::begin_value () - { - return value_.begin (); - } - Element::value_iterator Element::end_value () - { - return value_.end (); - } - Element::value_const_iterator Element::begin_value () const - { - return value_.cbegin (); - } - Element::value_const_iterator Element::end_value () const - { - return value_.cend (); - } - size_t Element::count_value() const - { - return value_.size (); - } - Element::long_iterator Element::begin_long () - { - return long__.begin (); - } - Element::long_iterator Element::end_long () - { - return long__.end (); - } - Element::long_const_iterator Element::begin_long () const - { - return long__.cbegin (); - } - Element::long_const_iterator Element::end_long () const - { - return long__.cend (); - } - size_t Element::count_long() const - { - return long__.size (); - } - Element::el_iterator Element::begin_el () - { - return el_.begin (); - } - Element::el_iterator Element::end_el () - { - return el_.end (); - } - Element::el_const_iterator Element::begin_el () const - { - return el_.cbegin (); - } - Element::el_const_iterator Element::end_el () const - { - return el_.cend (); - } - size_t Element::count_el() const - { - return el_.size (); - } -} -namespace Recursive -{ - Element::Element (::XSCRT::XML::Element const& element) - :Base (element) - { - ::XSCRT::Parser p (element); - - while (p.more_elements ()) - { - ::XSCRT::XML::Element e (p.next_element ()); - std::basic_string const n (::XSCRT::XML::uq_name (e.name ())); - - if (n == ACE_TEXT("value")) - { - value_.emplace_back (e); - } - else if (n == ACE_TEXT("long")) - { - long__.emplace_back (e); - } - else if (n == ACE_TEXT("el")) - { - el_.emplace_back (e); - } - } - } -} -namespace Recursive -{ - namespace reader - { - ::Recursive::Element - el (xercesc::DOMDocument const* d) - { - xercesc::DOMElement* dom_element = d->getDocumentElement (); - if (!dom_element) - { - throw std::runtime_error ("XML document has no root element"); - } - ::XSCRT::XML::Element e (dom_element); - if (e.name () == ACE_TEXT("el")) - { - ::Recursive::Element r (e); - return r; - } - else - { - throw std::runtime_error ("unexpected XML root element; expected "); - } - } - } -} diff --git a/Examples/Recursive/recursive.hpp b/Examples/Recursive/recursive.hpp deleted file mode 100644 index 88e74b7..0000000 --- a/Examples/Recursive/recursive.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// Generated by XSC version 2.0.0 -// Arguments: '--backend' 'cxx' 'recursive.xsd' -#ifndef RECURSIVE_HPP -#define RECURSIVE_HPP - -// Forward declarations. -namespace Recursive -{ - class Element; -} -#include -#include -#include -#include "ace/XML_Utils/XMLSchema/Types.hpp" -#include "ace/XML_Utils/XMLSchema/id_map.hpp" -#include "ace/ace_wchar.h" - -namespace Recursive -{ - class Element : public ::XSCRT::Type - { - using Base = ::XSCRT::Type; - - public: - using value_container_type = std::list<::XMLSchema::string>; - using value_iterator = value_container_type::iterator; - using value_const_iterator = value_container_type::const_iterator; - value_iterator begin_value (); - value_iterator end_value (); - value_const_iterator begin_value () const; - value_const_iterator end_value () const; - size_t count_value () const; - - protected: - value_container_type value_; - - public: - using long_container_type = std::list<::XMLSchema::long_>; - using long_iterator = long_container_type::iterator; - using long_const_iterator = long_container_type::const_iterator; - long_iterator begin_long (); - long_iterator end_long (); - long_const_iterator begin_long () const; - long_const_iterator end_long () const; - size_t count_long () const; - - protected: - long_container_type long__; - - public: - using el_container_type = std::list<::Recursive::Element>; - using el_iterator = el_container_type::iterator; - using el_const_iterator = el_container_type::const_iterator; - el_iterator begin_el (); - el_iterator end_el (); - el_const_iterator begin_el () const; - el_const_iterator end_el () const; - size_t count_el () const; - - protected: - el_container_type el_; - - public: - Element (value_container_type const& value__, - long_container_type const& long___); - - explicit Element (::XSCRT::XML::Element const&); - Element (Element const& s) = default; - Element& operator= (Element const& s) = default; - Element (Element&&) = default; - Element& operator= (Element&&) = default; - }; -} -namespace Recursive -{ - namespace reader - { - ::Recursive::Element el (xercesc::DOMDocument const*); - } -} -#endif // RECURSIVE_HPP