summaryrefslogtreecommitdiff
path: root/xsd/xsd/cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsd/xsd/cxx')
-rw-r--r--xsd/xsd/cxx/.gitignore1
-rw-r--r--xsd/xsd/cxx/elements.cxx45
-rw-r--r--xsd/xsd/cxx/option-types.cxx14
-rw-r--r--xsd/xsd/cxx/option-types.hxx8
-rw-r--r--xsd/xsd/cxx/options.cli22
-rw-r--r--xsd/xsd/cxx/parser/generator.cxx200
-rw-r--r--xsd/xsd/cxx/tree/generator.cxx183
-rw-r--r--xsd/xsd/cxx/tree/name-processor.cxx26
-rw-r--r--xsd/xsd/cxx/tree/options.cli6
-rw-r--r--xsd/xsd/cxx/tree/serialization-source.cxx30
-rw-r--r--xsd/xsd/cxx/tree/tree-inline.cxx6
-rw-r--r--xsd/xsd/cxx/tree/tree-source.cxx30
-rw-r--r--xsd/xsd/cxx/tree/validator.cxx2
13 files changed, 392 insertions, 181 deletions
diff --git a/xsd/xsd/cxx/.gitignore b/xsd/xsd/cxx/.gitignore
new file mode 100644
index 0000000..c6e608b
--- /dev/null
+++ b/xsd/xsd/cxx/.gitignore
@@ -0,0 +1 @@
+options.?xx
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 5601f4e..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 () << ':';
@@ -928,19 +958,16 @@ namespace CXX
}
}
- if (inline_)
- {
- hxx << "#ifndef XSD_DONT_INCLUDE_INLINE" << endl
- << "#include " << ctx.process_include_path (ixx_name) << endl
- << "#endif // XSD_DONT_INCLUDE_INLINE" << endl
- << endl;
- }
-
hxx << "#include <xsd/cxx/post.hxx>" << endl
<< endl;
// Copy epilogue.
//
+ // Note that it goes before the inline file in case it defines
+ // something (such as a custom type) which is needed by this file.
+ // And if something in the epilogue needs something from the inline
+ // file, then it should be the inline rather than header epilogue.
+ //
hxx << "// Begin epilogue." << endl
<< "//" << endl;
@@ -951,6 +978,14 @@ namespace CXX
<< "// End epilogue." << endl
<< endl;
+ if (inline_)
+ {
+ hxx << "#ifndef XSD_DONT_INCLUDE_INLINE" << endl
+ << "#include " << ctx.process_include_path (ixx_name) << endl
+ << "#endif // XSD_DONT_INCLUDE_INLINE" << endl
+ << endl;
+ }
+
hxx << "#endif // " << guard << endl;
if (show_sloc)
@@ -999,6 +1034,9 @@ namespace CXX
<< "// End prologue." << endl
<< endl;
+ ixx << "#include <xsd/cxx/pre.hxx>" << endl
+ << endl;
+
// Generate.
//
{
@@ -1006,6 +1044,9 @@ namespace CXX
generate_tree_inline (ctx, 1, 0);
}
+ ixx << "#include <xsd/cxx/post.hxx>" << endl
+ << endl;
+
// Copy epilogue.
//
ixx << "// Begin epilogue." << endl
diff --git a/xsd/xsd/cxx/tree/name-processor.cxx b/xsd/xsd/cxx/tree/name-processor.cxx
index 6ca616e..325870a 100644
--- a/xsd/xsd/cxx/tree/name-processor.cxx
+++ b/xsd/xsd/cxx/tree/name-processor.cxx
@@ -129,6 +129,12 @@ namespace CXX
accessor_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\l$1\\u$2\\u$3/");
accessor_regex.push_back ("/([^,]+)/\\l$1/");
}
+ else if (fn == "ucc")
+ {
+ accessor_regex.push_back ("/([^,]+),([^,]+)/\\u$1\\u$2/");
+ accessor_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\u$1\\u$2\\u$3/");
+ accessor_regex.push_back ("/([^,]+)/\\u$1/");
+ }
else
{
// Java: add get.
@@ -169,6 +175,11 @@ namespace CXX
modifier_regex.push_back ("/([^,]+),([^,]+)/\\l$1\\u$2/");
modifier_regex.push_back ("/([^,]+)/\\l$1/");
}
+ else if (fn == "ucc")
+ {
+ modifier_regex.push_back ("/([^,]+),([^,]+)/\\u$1\\u$2/");
+ modifier_regex.push_back ("/([^,]+)/\\u$1/");
+ }
else
{
// Java: add set.
@@ -202,6 +213,10 @@ namespace CXX
{
parser_regex.push_back ("/(.+)/\\l$1/");
}
+ else if (fn == "ucc")
+ {
+ parser_regex.push_back ("/(.+)/\\u$1/");
+ }
else if (fn == "java")
{
// Java: add parse.
@@ -219,6 +234,10 @@ namespace CXX
{
serializer_regex.push_back ("/(.+)/\\l$1/");
}
+ else if (fn == "ucc")
+ {
+ serializer_regex.push_back ("/(.+)/\\u$1/");
+ }
else if (fn == "java")
{
// Java: add serialize.
@@ -244,6 +263,11 @@ namespace CXX
const_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\l$1_\\u$2_\\u$3/");
const_regex.push_back ("/([^,]+),([^,]+)/\\l$1\\u$2/");
}
+ else if (fn == "ucc")
+ {
+ const_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\u$1_\\u$2_\\u$3/");
+ const_regex.push_back ("/([^,]+),([^,]+)/\\u$1\\u$2/");
+ }
else
{
// Java: all uppercase.
@@ -2173,6 +2197,8 @@ namespace CXX
if (fn == "knr")
n.context ().set ("tree-node-key", String ("tree_node_key"));
+ else if (fn == "ucc")
+ n.context ().set ("tree-node-key", String ("TreeNodeKey"));
else
n.context ().set ("tree-node-key", String ("treeNodeKey"));
diff --git a/xsd/xsd/cxx/tree/options.cli b/xsd/xsd/cxx/tree/options.cli
index 1f0b23f..0230429 100644
--- a/xsd/xsd/cxx/tree/options.cli
+++ b/xsd/xsd/cxx/tree/options.cli
@@ -257,9 +257,9 @@ namespace CXX
{
"<style>",
"Specify the function naming convention that should be used in the
- generated code. Valid styles are \cb{knr} (default), \cb{lcc}, and
- \cb{java}. See the NAMING CONVENTION section below for more
- information."
+ generated code. Valid styles are \cb{knr} (default), \cb{lcc},
+ \cb{ucc}, and \cb{java}. See the NAMING CONVENTION section below
+ for more information."
};
NarrowStrings --type-regex
diff --git a/xsd/xsd/cxx/tree/serialization-source.cxx b/xsd/xsd/cxx/tree/serialization-source.cxx
index 9be7499..08b81d6 100644
--- a/xsd/xsd/cxx/tree/serialization-source.cxx
+++ b/xsd/xsd/cxx/tree/serialization-source.cxx
@@ -999,8 +999,25 @@ namespace CXX
virtual void
traverse (Type& e)
{
+ // Similar to parsing, we cannot just omit this element if it's
+ // abstract because it may serve as a "link" between the root of the
+ // substitution group and a non-abstract element that uses this
+ // element as its root (see
+ // element_serializer_map::find_substitution() for details).
+ //
if (polymorphic && e.substitutes_p ())
{
+ SemanticGraph::Type& t (e.type ());
+
+ // Check if this element is abstract.
+ //
+ bool abst;
+ {
+ SemanticGraph::Complex* tc;
+ abst = (tc = dynamic_cast<SemanticGraph::Complex*> (&t)) != 0 &&
+ tc->abstract_p ();
+ }
+
Type& r (e.substitutes ().root ());
String const& name (ename (e));
@@ -1016,7 +1033,18 @@ namespace CXX
<< strlit (r.name ()) << "," << endl
<< strlit (r.namespace_ ().name ()) << "," << endl
<< strlit (e.name ()) << "," << endl
- << strlit (e.namespace_ ().name ()) << ");"
+ << strlit (e.namespace_ ().name ()) << "," << endl;
+
+ if (abst)
+ os << "0";
+ else
+ {
+ os << "&::xsd::cxx::tree::serializer_impl< ";
+ belongs (e, belongs_);
+ os << " >";
+ }
+
+ os << ");"
<< endl
<< endl;
}
diff --git a/xsd/xsd/cxx/tree/tree-inline.cxx b/xsd/xsd/cxx/tree/tree-inline.cxx
index 318ef66..aa8b726 100644
--- a/xsd/xsd/cxx/tree/tree-inline.cxx
+++ b/xsd/xsd/cxx/tree/tree-inline.cxx
@@ -291,7 +291,7 @@ namespace CXX
}
os << "// " << name << endl
- << "// " << endl
+ << "//" << endl
<< endl;
// default c-tor
@@ -902,7 +902,7 @@ namespace CXX
return;
os << "// " << name << endl
- << "// " << endl
+ << "//" << endl
<< endl;
// Generate accessors and modifiers.
@@ -1037,7 +1037,7 @@ namespace CXX
String const& name (ename (e));
os << "// " << name << endl
- << "// " << endl
+ << "//" << endl
<< endl;
// Accessors/modifiers.
diff --git a/xsd/xsd/cxx/tree/tree-source.cxx b/xsd/xsd/cxx/tree/tree-source.cxx
index 00e895b..89419af 100644
--- a/xsd/xsd/cxx/tree/tree-source.cxx
+++ b/xsd/xsd/cxx/tree/tree-source.cxx
@@ -3562,7 +3562,7 @@ namespace CXX
String const& member (emember (e));
os << "// " << name << endl
- << "// " << endl
+ << "//" << endl
<< endl;
// Virtual accessors.
@@ -3727,24 +3727,36 @@ namespace CXX
}
}
- if (!abst && polymorphic && e.substitutes_p () &&
- !options.suppress_parsing ())
+ // Note that we cannot just omit this element if it's abstract
+ // because it may serve as a "link" between the root of the
+ // substitution group and a non-abstract element that uses this
+ // element as its root (see element_factory_map::find_substitution()
+ // for details).
+ //
+ if (polymorphic && e.substitutes_p () && !options.suppress_parsing ())
{
String const& name (ename (e));
Type& r (e.substitutes ().root ());
os << "static" << endl
<< "const ::xsd::cxx::tree::element_factory_initializer< " <<
- poly_plate << ", " << char_type << ", ";
-
- belongs (e, belongs_);
-
- os << " >" << endl
+ poly_plate << ", " << char_type << " >" << endl
<< "_xsd_" << name << "_element_factory_init (" << endl
<< strlit (r.name ()) << "," << endl
<< strlit (r.namespace_ ().name ()) << "," << endl
<< strlit (e.name ()) << "," << endl
- << strlit (e.namespace_ ().name ()) << ");"
+ << strlit (e.namespace_ ().name ()) << "," << endl;
+
+ if (abst)
+ os << "0";
+ else
+ {
+ os << "&::xsd::cxx::tree::factory_impl< ";
+ belongs (e, belongs_);
+ os << " >";
+ }
+
+ os << ");"
<< endl
<< endl;
}
diff --git a/xsd/xsd/cxx/tree/validator.cxx b/xsd/xsd/cxx/tree/validator.cxx
index 46deb6c..9785560 100644
--- a/xsd/xsd/cxx/tree/validator.cxx
+++ b/xsd/xsd/cxx/tree/validator.cxx
@@ -587,7 +587,7 @@ namespace CXX
NarrowString fn (ops.function_naming ());
- if (fn != "knr" && fn != "lcc" && fn != "java")
+ if (fn != "knr" && fn != "lcc" && fn != "ucc" && fn != "java")
{
wcerr << "error: unknown function naming style specified: '" <<
fn.c_str () << "'" << endl;