diff options
Diffstat (limited to 'xsd/xsd/cxx')
-rw-r--r-- | xsd/xsd/cxx/elements.cxx | 45 | ||||
-rw-r--r-- | xsd/xsd/cxx/option-types.cxx | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/option-types.hxx | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/options.cli | 22 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/generator.cxx | 200 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/generator.cxx | 156 |
6 files changed, 289 insertions, 156 deletions
diff --git a/xsd/xsd/cxx/elements.cxx b/xsd/xsd/cxx/elements.cxx index e914f9d..02a768e 100644 --- a/xsd/xsd/cxx/elements.cxx +++ b/xsd/xsd/cxx/elements.cxx @@ -102,6 +102,36 @@ namespace CXX L"xor", L"xor_eq" }; + + // Note: excluding "identifiers with special meaning" in certain contexts + // ("final", "override") since they shouldn't cause any issues. + // + wchar_t const* keywords_cxx11[] = { + L"alignas", + L"alignof", + L"char16_t", + L"char32_t", + L"constexpr", + L"decltype", + L"noexcept", + L"nullptr", + L"static_assert", + L"thread_local" + }; + + // Note: excluding "identifiers with special meaning" in certain contexts + // ("import", "module") since they shouldn't cause any issues. + // + wchar_t const* keywords_cxx20[] = { + L"char8_t", + L"concept", + L"consteval", + L"constinit", + L"co_await", + L"co_return", + L"co_yield", + L"requires" + }; } // Context @@ -268,8 +298,21 @@ namespace CXX // Populate the keyword set. // - for (size_t i (0); i < sizeof (keywords) / sizeof (char*); ++i) + for (size_t i (0); i < sizeof (keywords) / sizeof (wchar_t*); ++i) keyword_set_.insert (keywords[i]); + + if (std >= cxx_version::cxx11) + { + for (size_t i (0); i < sizeof (keywords_cxx11) / sizeof (wchar_t*); ++i) + keyword_set_.insert (keywords_cxx11[i]); + } + + if (std >= cxx_version::cxx20) + { + for (size_t i (0); i < sizeof (keywords_cxx20) / sizeof (wchar_t*); ++i) + keyword_set_.insert (keywords_cxx20[i]); + } + } String Context:: diff --git a/xsd/xsd/cxx/option-types.cxx b/xsd/xsd/cxx/option-types.cxx index ad8a3c9..8744d7f 100644 --- a/xsd/xsd/cxx/option-types.cxx +++ b/xsd/xsd/cxx/option-types.cxx @@ -17,7 +17,11 @@ namespace CXX static const char* cxx_version_[] = { "c++98", - "c++11" + "c++11", + "c++14", + "c++17", + "c++20", + "c++23", }; string cxx_version:: @@ -38,6 +42,14 @@ namespace CXX v = cxx_version::cxx98; else if (s == "c++11") v = cxx_version::cxx11; + else if (s == "c++14") + v = cxx_version::cxx14; + else if (s == "c++17") + v = cxx_version::cxx17; + else if (s == "c++20") + v = cxx_version::cxx20; + else if (s == "c++23") + v = cxx_version::cxx23; else is.setstate (istream::failbit); } diff --git a/xsd/xsd/cxx/option-types.hxx b/xsd/xsd/cxx/option-types.hxx index bbb15b3..98a493a 100644 --- a/xsd/xsd/cxx/option-types.hxx +++ b/xsd/xsd/cxx/option-types.hxx @@ -14,10 +14,14 @@ namespace CXX enum value { cxx98, - cxx11 + cxx11, + cxx14, + cxx17, + cxx20, + cxx23 }; - cxx_version (value v = value (0)) : v_ (v) {} + cxx_version (value v) : v_ (v) {} operator value () const {return v_;} std::string diff --git a/xsd/xsd/cxx/options.cli b/xsd/xsd/cxx/options.cli index 2c50f19..1be7607 100644 --- a/xsd/xsd/cxx/options.cli +++ b/xsd/xsd/cxx/options.cli @@ -15,17 +15,19 @@ namespace CXX { // Language. // - cxx_version --std = cxx_version::cxx98 + cxx_version --std = cxx_version::cxx11 { "<version>", "Specify the C++ standard that the generated code should conform to. - Valid values are \cb{c++98} (default) and \cb{c++11}. + Valid values are \cb{c++98}, \cb{c++11} (default), \cb{c++14}, + \cb{c++17}, \cb{c++20}, and \cb{c++23}. The C++ standard affects various aspects of the generated code that are discussed in more detail in various mapping-specific documentation. Overall, when C++11 is selected, the generated code relies on the move semantics and uses \cb{std::unique_ptr} - instead of deprecated \cb{std::auto_ptr}. + instead of deprecated \cb{std::auto_ptr}. Currently, there is no + difference between the C++11 and the later standards modes. When the C++11 mode is selected, you normally don't need to perform any extra steps other than enable C++11 in your C++ @@ -498,7 +500,7 @@ namespace CXX generated files on the main schema file as well as all the schema files that it includes/imports, transitively. This dependency file is then normally included into the main \cb{makefile} to implement - automatic dependency tracking. + automatic dependency tracking. See also the \cb{--dep-*} options. Note also that automatic dependency generation is not supported in the file-per-type mode (\cb{--file-per-type}). In this case, all @@ -534,8 +536,16 @@ namespace CXX NarrowString --dep-suffix = ".d" { "<suffix>", - "Use the provided <suffix> instead of the default \cb{.d} to - construct the name of the dependency file." + "Use <suffix> instead of the default \cb{.d} to construct the name of + the dependency file. See also \cb{--dep-file}." + }; + + NarrowString --dep-file + { + "<path>", + "Use <path> as the generated dependency file path instead of deriving + it from the input file name. Write the dependency information to + \cb{stdout} if <path> is \cb{-}. See also \cb{--dep-regex}." }; NarrowString --dep-regex diff --git a/xsd/xsd/cxx/parser/generator.cxx b/xsd/xsd/cxx/parser/generator.cxx index 91af898..b1acdbb 100644 --- a/xsd/xsd/cxx/parser/generator.cxx +++ b/xsd/xsd/cxx/parser/generator.cxx @@ -77,19 +77,19 @@ namespace CXX "// along with this program; if not, write to the Free Software\n" "// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" "//\n" - "// In addition, as a special exception, Code Synthesis Tools CC gives\n" - "// permission to link this program with the Xerces-C++ library (or with\n" - "// modified versions of Xerces-C++ that use the same license as Xerces-C++),\n" - "// and distribute linked combinations including the two. You must obey\n" - "// the GNU General Public License version 2 in all respects for all of\n" - "// the code used other than Xerces-C++. If you modify this copy of the\n" - "// program, you may extend this exception to your version of the program,\n" - "// but you are not obligated to do so. If you do not wish to do so, delete\n" - "// this exception statement from your version.\n" + "// In addition, as a special exception, Code Synthesis gives permission\n" + "// to link this program with the Xerces-C++ library (or with modified\n" + "// versions of Xerces-C++ that use the same license as Xerces-C++), and\n" + "// distribute linked combinations including the two. You must obey the GNU\n" + "// General Public License version 2 in all respects for all of the code\n" + "// used other than Xerces-C++. If you modify this copy of the program, you\n" + "// may extend this exception to your version of the program, but you are\n" + "// not obligated to do so. If you do not wish to do so, delete this\n" + "// exception statement from your version.\n" "//\n" - "// Furthermore, Code Synthesis Tools CC makes a special exception for\n" - "// the Free/Libre and Open Source Software (FLOSS) which is described\n" - "// in the accompanying FLOSSE file.\n" + "// Furthermore, Code Synthesis makes a special exception for the Free/Libre\n" + "// and Open Source Software (FLOSS) which is described in the accompanying\n" + "// FLOSSE file.\n" "//\n\n"; char const copyright_proprietary[] = @@ -98,8 +98,7 @@ namespace CXX "// This program was generated by CodeSynthesis XSD, an XML Schema\n" "// to C++ data binding compiler, in the Proprietary License mode.\n" "// You should have received a proprietary license from Code Synthesis\n" - "// Tools CC prior to generating this code. See the license text for\n" - "// conditions.\n" + "// prior to generating this code. See the license text for conditions.\n" "//\n\n"; char const copyright_impl[] = @@ -232,8 +231,11 @@ namespace CXX throw Failed (); } + bool gen_cxx (!ops.file_list_only ()); + // Process names. // + if (gen_cxx) { NameProcessor proc; proc.process (ops, schema, file_path, string_literal_map); @@ -245,7 +247,7 @@ namespace CXX // Compute state machine info. // - if (validation) + if (gen_cxx && validation) { StateProcessor proc; proc.process (schema, file_path); @@ -254,6 +256,7 @@ namespace CXX // Read-in type maps. // TypeMap::Namespaces type_map; + if (gen_cxx) { using namespace TypeMap; @@ -376,6 +379,7 @@ namespace CXX // Process types. // + if (gen_cxx) { TypeProcessor proc; proc.process (ops, schema, gen_driver, type_map); @@ -559,135 +563,165 @@ namespace CXX if (impl) { - if (!ops.force_overwrite ()) + if (gen_cxx) { - WideInputFileStream tmp ( - hxx_impl_path.string ().c_str (), ios_base::in); + if (!ops.force_overwrite ()) + { + WideInputFileStream tmp ( + hxx_impl_path.string ().c_str (), ios_base::in); - if (tmp.is_open ()) + if (tmp.is_open ()) + { + wcerr << hxx_impl_path << ": error: cowardly refusing to " << + "overwrite an existing file" << endl; + throw Failed (); + } + + tmp.close (); + } + + hxx_impl.open (hxx_impl_path.string ().c_str (), ios_base::out); + + if (!hxx_impl.is_open ()) { - wcerr << hxx_impl_path << ": error: cowardly refusing to " << - "overwrite an existing file" << endl; + wcerr << hxx_impl_path << ": error: unable to open in write mode" + << endl; throw Failed (); } - tmp.close (); + unlinks.add (hxx_impl_path); } - hxx_impl.open (hxx_impl_path.string ().c_str (), ios_base::out); + file_list.push_back (hxx_impl_path.string ()); - if (!hxx_impl.is_open ()) + if (gen_cxx) { - wcerr << hxx_impl_path << ": error: unable to open in write mode" - << endl; - throw Failed (); - } + if (!ops.force_overwrite ()) + { + WideInputFileStream tmp ( + cxx_impl_path.string ().c_str (), ios_base::in); - unlinks.add (hxx_impl_path); - file_list.push_back (hxx_impl_path.string ()); + if (tmp.is_open ()) + { + wcerr << cxx_impl_path << ": error: cowardly refusing to " << + "overwrite an existing file" << endl; + throw Failed (); + } - if (!ops.force_overwrite ()) - { - WideInputFileStream tmp ( - cxx_impl_path.string ().c_str (), ios_base::in); + tmp.close (); + } - if (tmp.is_open ()) + cxx_impl.open (cxx_impl_path.string ().c_str (), ios_base::out); + + if (!cxx_impl.is_open ()) { - wcerr << cxx_impl_path << ": error: cowardly refusing to " << - "overwrite an existing file" << endl; + wcerr << cxx_impl_path << ": error: unable to open in write mode" + << endl; throw Failed (); } - tmp.close (); - } - - cxx_impl.open (cxx_impl_path.string ().c_str (), ios_base::out); - - if (!cxx_impl.is_open ()) - { - wcerr << cxx_impl_path << ": error: unable to open in write mode" - << endl; - throw Failed (); + unlinks.add (cxx_impl_path); } - unlinks.add (cxx_impl_path); file_list.push_back (cxx_impl_path.string ()); } if (driver) { - if (!ops.force_overwrite ()) + if (gen_cxx) { - WideInputFileStream tmp ( - cxx_driver_path.string ().c_str (), ios_base::in); - - if (tmp.is_open ()) + if (!ops.force_overwrite ()) { - wcerr << cxx_driver_path << ": error: cowardly refusing to " << - "overwrite an existing file" << endl; - throw Failed (); + WideInputFileStream tmp ( + cxx_driver_path.string ().c_str (), ios_base::in); + + if (tmp.is_open ()) + { + wcerr << cxx_driver_path << ": error: cowardly refusing to " << + "overwrite an existing file" << endl; + throw Failed (); + } + + tmp.close (); } - tmp.close (); - } + cxx_driver.open (cxx_driver_path.string ().c_str (), ios_base::out); - cxx_driver.open (cxx_driver_path.string ().c_str (), ios_base::out); + if (!cxx_driver.is_open ()) + { + wcerr << cxx_driver_path << ": error: unable to open in write " << + "mode" << endl; + throw Failed (); + } - if (!cxx_driver.is_open ()) - { - wcerr << cxx_driver_path << ": error: unable to open in write " << - "mode" << endl; - throw Failed (); + unlinks.add (cxx_driver_path); } - unlinks.add (cxx_driver_path); file_list.push_back (cxx_driver_path.string ()); } // Open the skel files. // - WideOutputFileStream hxx (hxx_path.string ().c_str (), ios_base::out); + WideOutputFileStream hxx; WideOutputFileStream ixx; WideOutputFileStream cxx; - if (!hxx.is_open ()) + if (gen_cxx) { - wcerr << hxx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + hxx.open (hxx_path.string ().c_str (), ios_base::out); + + if (!hxx.is_open ()) + { + wcerr << hxx_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (hxx_path); } - unlinks.add (hxx_path); file_list.push_back (hxx_path.string ()); if (inline_) { - ixx.open (ixx_path.string ().c_str (), ios_base::out); - - if (!ixx.is_open ()) + if (gen_cxx) { - wcerr << ixx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + ixx.open (ixx_path.string ().c_str (), ios_base::out); + + if (!ixx.is_open ()) + { + wcerr << ixx_path << ": error: unable to open in write mode" + << endl; + throw Failed (); + } + + unlinks.add (ixx_path); } - unlinks.add (ixx_path); file_list.push_back (ixx_path.string ()); } - if (source) { - cxx.open (cxx_path.string ().c_str (), ios_base::out); - - if (!cxx.is_open ()) + if (gen_cxx) { - wcerr << cxx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + cxx.open (cxx_path.string ().c_str (), ios_base::out); + + if (!cxx.is_open ()) + { + wcerr << cxx_path << ": error: unable to open in write mode" + << endl; + throw Failed (); + } + + unlinks.add (cxx_path); } - unlinks.add (cxx_path); file_list.push_back (cxx_path.string ()); } + if (!gen_cxx) + return 0; + // Print copyright and license. // char const* copyright ( diff --git a/xsd/xsd/cxx/tree/generator.cxx b/xsd/xsd/cxx/tree/generator.cxx index 3233248..9782b4d 100644 --- a/xsd/xsd/cxx/tree/generator.cxx +++ b/xsd/xsd/cxx/tree/generator.cxx @@ -54,6 +54,8 @@ using namespace XSDFrontend::SemanticGraph; // // +typedef std::wostream WideOutputStream; + typedef std::wifstream WideInputFileStream; typedef std::wofstream WideOutputFileStream; @@ -80,19 +82,19 @@ namespace CXX "// along with this program; if not, write to the Free Software\n" "// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" "//\n" - "// In addition, as a special exception, Code Synthesis Tools CC gives\n" - "// permission to link this program with the Xerces-C++ library (or with\n" - "// modified versions of Xerces-C++ that use the same license as Xerces-C++),\n" - "// and distribute linked combinations including the two. You must obey\n" - "// the GNU General Public License version 2 in all respects for all of\n" - "// the code used other than Xerces-C++. If you modify this copy of the\n" - "// program, you may extend this exception to your version of the program,\n" - "// but you are not obligated to do so. If you do not wish to do so, delete\n" - "// this exception statement from your version.\n" + "// In addition, as a special exception, Code Synthesis gives permission\n" + "// to link this program with the Xerces-C++ library (or with modified\n" + "// versions of Xerces-C++ that use the same license as Xerces-C++), and\n" + "// distribute linked combinations including the two. You must obey the GNU\n" + "// General Public License version 2 in all respects for all of the code\n" + "// used other than Xerces-C++. If you modify this copy of the program, you\n" + "// may extend this exception to your version of the program, but you are\n" + "// not obligated to do so. If you do not wish to do so, delete this\n" + "// exception statement from your version.\n" "//\n" - "// Furthermore, Code Synthesis Tools CC makes a special exception for\n" - "// the Free/Libre and Open Source Software (FLOSS) which is described\n" - "// in the accompanying FLOSSE file.\n" + "// Furthermore, Code Synthesis makes a special exception for the Free/Libre\n" + "// and Open Source Software (FLOSS) which is described in the accompanying\n" + "// FLOSSE file.\n" "//\n\n"; char const copyright_proprietary[] = @@ -101,8 +103,7 @@ namespace CXX "// This program was generated by CodeSynthesis XSD, an XML Schema\n" "// to C++ data binding compiler, in the Proprietary License mode.\n" "// You should have received a proprietary license from Code Synthesis\n" - "// Tools CC prior to generating this code. See the license text for\n" - "// conditions.\n" + "// prior to generating this code. See the license text for conditions.\n" "//\n\n"; } @@ -232,7 +233,7 @@ namespace CXX throw Failed (); } - bool gen_cxx (!ops.generate_dep_only ()); + bool gen_cxx (!ops.generate_dep_only () && !ops.file_list_only ()); // Process ordered types. // @@ -345,9 +346,13 @@ namespace CXX ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + fwd_suffix + "#" : ops.fwd_regex ()); - Regex dep_expr (ops.dep_regex ().empty () - ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + dep_suffix + "#" - : ops.dep_regex ()); + // @@ This will blow up if --dep-file value contains backslashes (e.g., + // it's a Windows path). + // + Regex dep_expr ( + ops.dep_regex_specified () ? ops.dep_regex () : + ops.dep_file_specified () ? "#.+#" + ops.dep_file () + "#" : + "#^(.+?)(\\.[^./\\\\]+)?$#$1" + dep_suffix + "#"); if (header && !hxx_expr.match (name)) { @@ -397,7 +402,7 @@ namespace CXX Path hxx_path (hxx_name); Path ixx_path (ixx_name); Path fwd_path (fwd_name); - Path dep_path (dep_name); + Path dep_path (dep_name != "-" ? dep_name : NarrowString ()); Paths cxx_paths; if (source) @@ -458,10 +463,11 @@ namespace CXX if (!out_dir.empty ()) { - hxx_path = out_dir / hxx_path; - ixx_path = out_dir / ixx_path; - fwd_path = out_dir / fwd_path; - dep_path = out_dir / dep_path; + if (!hxx_path.empty ()) hxx_path = out_dir / hxx_path; + if (!ixx_path.empty ()) ixx_path = out_dir / ixx_path; + if (!fwd_path.empty ()) fwd_path = out_dir / fwd_path; + if (!dep_path.empty () && + !dep_path.absolute ()) dep_path = out_dir / dep_path; for (Paths::iterator i (cxx_paths.begin ()); i != cxx_paths.end (); ++i) @@ -473,93 +479,116 @@ namespace CXX WideOutputFileStream hxx; WideOutputFileStream ixx; WideOutputFileStream fwd; - WideOutputFileStream dep; + WideOutputFileStream depf; // See dep below. WideOutputFileStreams cxx; // DEP // if (gen_dep) { - dep.open (dep_path.string ().c_str (), ios_base::out); - - if (!dep.is_open ()) + if (!dep_path.empty ()) { - wcerr << dep_path << ": error: unable to open in write mode" << endl; - throw Failed (); + depf.open (dep_path.string ().c_str (), ios_base::out); + + if (!depf.is_open ()) + { + wcerr << dep_path << ": error: unable to open in write mode" + << endl; + throw Failed (); + } + + unlinks.add (dep_path); } - unlinks.add (dep_path); - file_list.push_back (dep_path.string ()); + // Note: not adding to file_list. } + WideOutputStream& dep (gen_dep && !dep_path.empty () ? depf : wcout); + // FWD // - if (gen_cxx && forward) + if (forward) { - fwd.open (fwd_path.string ().c_str (), ios_base::out); - - if (!fwd.is_open ()) + if (gen_cxx) { - wcerr << fwd_path << ": error: unable to open in write mode" << endl; - throw Failed (); + fwd.open (fwd_path.string ().c_str (), ios_base::out); + + if (!fwd.is_open ()) + { + wcerr << fwd_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (fwd_path); } - unlinks.add (fwd_path); file_list.push_back (fwd_path.string ()); } // HXX // - if (gen_cxx && header) + if (header) { - hxx.open (hxx_path.string ().c_str (), ios_base::out); - - if (!hxx.is_open ()) + if (gen_cxx) { - wcerr << hxx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + hxx.open (hxx_path.string ().c_str (), ios_base::out); + + if (!hxx.is_open ()) + { + wcerr << hxx_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (hxx_path); } - unlinks.add (hxx_path); file_list.push_back (hxx_path.string ()); } // IXX // - if (gen_cxx && inline_) + if (inline_) { - ixx.open (ixx_path.string ().c_str (), ios_base::out); - - if (!ixx.is_open ()) + if (gen_cxx) { - wcerr << ixx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + ixx.open (ixx_path.string ().c_str (), ios_base::out); + + if (!ixx.is_open ()) + { + wcerr << ixx_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (ixx_path); } - unlinks.add (ixx_path); file_list.push_back (ixx_path.string ()); } // CXX // - if (gen_cxx && source) + if (source) { for (Paths::iterator i (cxx_paths.begin ()); i != cxx_paths.end (); ++i) { - shared_ptr<WideOutputFileStream> s ( - new (shared) WideOutputFileStream ( - i->string ().c_str (), ios_base::out)); - - if (!s->is_open ()) + if (gen_cxx) { - wcerr << *i << ": error: unable to open in write mode" << endl; - throw Failed (); + shared_ptr<WideOutputFileStream> s ( + new (shared) WideOutputFileStream ( + i->string ().c_str (), ios_base::out)); + + if (!s->is_open ()) + { + wcerr << *i << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + cxx.push_back (s); + unlinks.add (*i); } - unlinks.add (*i); file_list.push_back (i->string ()); - cxx.push_back (s); } } @@ -668,7 +697,8 @@ namespace CXX i != cxx_paths.end (); ++i) target += " \\\n" + i->string (); - target += " \\\n" + dep_path.string (); + if (!dep_path.empty ()) + target += " \\\n" + dep_path.string (); } dep << target.c_str () << ':'; |