From 7d26ea59564e573b9f8a1f025f7fd5df24ee2e80 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 11 Sep 2023 10:37:45 +0200 Subject: Add --file-list-only option This option allows only writing the list of C++ files that would be generated without actually generating them. --- xsd/doc/pregenerated/xsd.1 | 4 + xsd/doc/pregenerated/xsd.xhtml | 5 + xsd/xsd/cxx/parser/generator.cxx | 173 +++++++++++++++++++++-------------- xsd/xsd/cxx/tree/generator.cxx | 80 +++++++++------- xsd/xsd/options.cli | 7 ++ xsd/xsd/pregenerated/xsd/options.cxx | 6 ++ xsd/xsd/pregenerated/xsd/options.hxx | 4 + xsd/xsd/pregenerated/xsd/options.ixx | 6 ++ xsd/xsd/xsd.cxx | 8 ++ 9 files changed, 192 insertions(+), 101 deletions(-) (limited to 'xsd') diff --git a/xsd/doc/pregenerated/xsd.1 b/xsd/doc/pregenerated/xsd.1 index 5864e0c..52820fb 100644 --- a/xsd/doc/pregenerated/xsd.1 +++ b/xsd/doc/pregenerated/xsd.1 @@ -584,6 +584,10 @@ Write a list of generated C++ files to \fIfile\fR or to \fBstdout\fR if \fIfile\fR is \fB-\fR\. This option is primarily useful in the file-per-type compilation mode (\fB--file-per-type\fR) to create a list of generated C++ files, for example, as a makefile fragment\. +.IP "\fB--file-list-only\fR" +Only write the list of C++ files that would be generated without actually +generating them\. This option only makes sense together with +\fB--file-list\fR\. .IP "\fB--file-list-prologue\fR \fItext\fR" Insert \fItext\fR at the beginning of the file list\. As a convenience, all occurrences of the \fB\en\fR character sequence in \fItext\fR are replaced diff --git a/xsd/doc/pregenerated/xsd.xhtml b/xsd/doc/pregenerated/xsd.xhtml index 95d7264..53b905c 100644 --- a/xsd/doc/pregenerated/xsd.xhtml +++ b/xsd/doc/pregenerated/xsd.xhtml @@ -740,6 +740,11 @@ create a list of generated C++ files, for example, as a makefile fragment. +
--file-list-only
+
Only write the list of C++ files that would be generated without + actually generating them. This option only makes sense together with + --file-list.
+
--file-list-prologue text
Insert text at the beginning of the file list. As a convenience, all occurrences of the \n character diff --git a/xsd/xsd/cxx/parser/generator.cxx b/xsd/xsd/cxx/parser/generator.cxx index 832dbcb..b1acdbb 100644 --- a/xsd/xsd/cxx/parser/generator.cxx +++ b/xsd/xsd/cxx/parser/generator.cxx @@ -231,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); @@ -244,7 +247,7 @@ namespace CXX // Compute state machine info. // - if (validation) + if (gen_cxx && validation) { StateProcessor proc; proc.process (schema, file_path); @@ -253,6 +256,7 @@ namespace CXX // Read-in type maps. // TypeMap::Namespaces type_map; + if (gen_cxx) { using namespace TypeMap; @@ -375,6 +379,7 @@ namespace CXX // Process types. // + if (gen_cxx) { TypeProcessor proc; proc.process (ops, schema, gen_driver, type_map); @@ -558,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 8becfec..d3e4db2 100644 --- a/xsd/xsd/cxx/tree/generator.cxx +++ b/xsd/xsd/cxx/tree/generator.cxx @@ -231,7 +231,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. // @@ -493,72 +493,88 @@ namespace CXX // 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 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 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); } } diff --git a/xsd/xsd/options.cli b/xsd/xsd/options.cli index e81052a..3153be9 100644 --- a/xsd/xsd/options.cli +++ b/xsd/xsd/options.cli @@ -283,6 +283,13 @@ class options = 0 C++ files, for example, as a makefile fragment." }; + bool --file-list-only + { + "Only write the list of C++ files that would be generated without + actually generating them. This option only makes sense together with + \cb{--file-list}." + } + NarrowString --file-list-prologue { "", diff --git a/xsd/xsd/pregenerated/xsd/options.cxx b/xsd/xsd/pregenerated/xsd/options.cxx index d8e59f6..3022ec4 100644 --- a/xsd/xsd/pregenerated/xsd/options.cxx +++ b/xsd/xsd/pregenerated/xsd/options.cxx @@ -1096,6 +1096,7 @@ options () fat_type_file_ (), file_list_ (), file_list_specified_ (false), + file_list_only_ (), file_list_prologue_ (), file_list_prologue_specified_ (false), file_list_epilogue_ (), @@ -1178,6 +1179,9 @@ print_usage (::std::wostream& os, ::cli::usage_para p) os << "--file-list Write a list of generated C++ files to or" << ::std::endl << " to stdout if is -." << ::std::endl; + os << "--file-list-only Only write the list of C++ files that would be" << ::std::endl + << " generated without actually generating them." << ::std::endl; + os << "--file-list-prologue Insert at the beginning of the file list." << ::std::endl; os << "--file-list-epilogue Insert at the end of the file list." << ::std::endl; @@ -1252,6 +1256,8 @@ struct _cli_options_map_init _cli_options_map_["--file-list"] = &::cli::thunk< options, NarrowString, &options::file_list_, &options::file_list_specified_ >; + _cli_options_map_["--file-list-only"] = + &::cli::thunk< options, &options::file_list_only_ >; _cli_options_map_["--file-list-prologue"] = &::cli::thunk< options, NarrowString, &options::file_list_prologue_, &options::file_list_prologue_specified_ >; diff --git a/xsd/xsd/pregenerated/xsd/options.hxx b/xsd/xsd/pregenerated/xsd/options.hxx index 9a1d54c..0f4383c 100644 --- a/xsd/xsd/pregenerated/xsd/options.hxx +++ b/xsd/xsd/pregenerated/xsd/options.hxx @@ -608,6 +608,9 @@ class options bool file_list_specified () const; + const bool& + file_list_only () const; + const NarrowString& file_list_prologue () const; @@ -678,6 +681,7 @@ class options bool fat_type_file_; NarrowString file_list_; bool file_list_specified_; + bool file_list_only_; NarrowString file_list_prologue_; bool file_list_prologue_specified_; NarrowString file_list_epilogue_; diff --git a/xsd/xsd/pregenerated/xsd/options.ixx b/xsd/xsd/pregenerated/xsd/options.ixx index e905544..d87e59c 100644 --- a/xsd/xsd/pregenerated/xsd/options.ixx +++ b/xsd/xsd/pregenerated/xsd/options.ixx @@ -495,6 +495,12 @@ file_list_specified () const return this->file_list_specified_; } +inline const bool& options:: +file_list_only () const +{ + return this->file_list_only_; +} + inline const NarrowString& options:: file_list_prologue () const { diff --git a/xsd/xsd/xsd.cxx b/xsd/xsd/xsd.cxx index 5a239d5..d2b0faf 100644 --- a/xsd/xsd/xsd.cxx +++ b/xsd/xsd/xsd.cxx @@ -298,6 +298,14 @@ main (int argc, char* argv[]) ? static_cast (*tree_ops) : static_cast (*parser_ops)); + // Validate options. + // + if (common_ops.file_list_only () && !common_ops.file_list_specified ()) + { + e << "error: --file-list-only specified without --file-list" << endl; + return 1; + } + // Disabled warnings. // WarningSet disabled_w; -- cgit v1.1