aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-03-22 11:11:02 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-04-10 18:46:44 +0200
commit0fc39391cd7b5a5f0b362bed6c21e4c642a0accc (patch)
tree193646c134e9e0fafd96bf20266923800e0a7a51
parent367c524af8ecfe066991bfaa8489b230f6e59446 (diff)
Add --changelog{,-in,-out,-dir} options
-rw-r--r--odb/generator.cxx63
-rw-r--r--odb/options.cli38
-rw-r--r--odb/relational/changelog.cxx21
-rw-r--r--odb/relational/generate.hxx3
-rw-r--r--odb/validator.cxx9
5 files changed, 110 insertions, 24 deletions
diff --git a/odb/generator.cxx b/odb/generator.cxx
index a2254e0..dfc5ba6 100644
--- a/odb/generator.cxx
+++ b/odb/generator.cxx
@@ -129,15 +129,12 @@ generate (options const& ops,
string cxx_name (base + ops.odb_file_suffix ()[db] + ops.cxx_suffix ());
string sch_name (base + ops.schema_file_suffix ()[db] + ops.cxx_suffix ());
string sql_name (base + ops.sql_file_suffix ()[db] + ops.sql_suffix ());
- string log_name (base + ops.changelog_file_suffix ()[db] +
- ops.changelog_suffix ());
path hxx_path (hxx_name);
path ixx_path (ixx_name);
path cxx_path (cxx_name);
path sch_path (sch_name);
path sql_path (sql_name);
- path log_path (p.directory () / path (log_name)); // Input directory.
if (!ops.output_dir ().empty ())
{
@@ -149,6 +146,45 @@ generate (options const& ops,
sql_path = dir / sql_path;
}
+ path in_log_path, out_log_path;
+ path log_dir (ops.changelog_dir ().empty () ? "" : ops.changelog_dir ());
+ if (ops.changelog_in_specified ())
+ {
+ in_log_path = path (ops.changelog_in ());
+ out_log_path = path (ops.changelog_out ());
+
+ if (!log_dir.empty ())
+ {
+ if (!in_log_path.absolute ())
+ in_log_path = log_dir / in_log_path;
+
+ if (!out_log_path.absolute ())
+ out_log_path = log_dir / out_log_path;
+ }
+ }
+ else if (ops.changelog_specified ())
+ {
+ in_log_path = path (ops.changelog ());
+
+ if (!in_log_path.absolute () && !log_dir.empty ())
+ in_log_path = log_dir / in_log_path;
+
+ out_log_path = in_log_path;
+ }
+ else
+ {
+ string log_name (base + ops.changelog_file_suffix ()[db] +
+ ops.changelog_suffix ());
+ in_log_path = path (log_name);
+
+ if (!log_dir.empty ())
+ in_log_path = log_dir / in_log_path;
+ else
+ in_log_path = p.directory () / in_log_path; // Use input directory.
+
+ out_log_path = in_log_path;
+ }
+
// Load the old changelog and generate a new one.
//
bool gen_log (gen_schema && unit.count ("model-version") != 0);
@@ -158,7 +194,7 @@ generate (options const& ops,
if (gen_log)
{
- ifstream log (log_path.string ().c_str (),
+ ifstream log (in_log_path.string ().c_str (),
ios_base::in | ios_base::binary);
if (log.is_open ())
@@ -187,13 +223,13 @@ generate (options const& ops,
istringstream is (old_changelog_xml);
is.exceptions (ios_base::badbit | ios_base::failbit);
- xml::parser p (is, log_path.string ());
+ xml::parser p (is, in_log_path.string ());
old_changelog.reset (
new (shared) semantics::relational::changelog (p));
}
catch (const ios_base::failure& e)
{
- cerr << log_path << ": read failure" << endl;
+ cerr << in_log_path << ": read failure" << endl;
throw failed ();
}
catch (const xml::parsing& e)
@@ -207,7 +243,8 @@ generate (options const& ops,
*model,
unit.get<model_version> ("model-version"),
old_changelog.get (),
- log_path.string ());
+ in_log_path.string (),
+ out_log_path.string ());
}
//
@@ -841,24 +878,24 @@ generate (options const& ops,
{
ostringstream os;
os.exceptions (ifstream::badbit | ifstream::failbit);
- xml::serializer s (os, log_path.string ());
+ xml::serializer s (os, out_log_path.string ());
changelog->serialize (s);
string const& changelog_xml (os.str ());
if (changelog_xml != old_changelog_xml)
{
- ofstream log (log_path.string ().c_str (),
+ ofstream log (out_log_path.string ().c_str (),
ios_base::out | ios_base::binary);
if (!log.is_open ())
{
- cerr << "error: unable to open '" << log_path << "' in write mode"
- << endl;
+ cerr << "error: unable to open '" << out_log_path << "' in " <<
+ "write mode" << endl;
throw failed ();
}
if (old_changelog == 0)
- auto_rm.add (log_path);
+ auto_rm.add (out_log_path);
log.exceptions (ifstream::badbit | ifstream::failbit);
log << changelog_xml;
@@ -866,7 +903,7 @@ generate (options const& ops,
}
catch (const ios_base::failure& e)
{
- cerr << log_path << ": write failure" << endl;
+ cerr << out_log_path << ": write failure" << endl;
throw failed ();
}
catch (const xml::serialization& e)
diff --git a/odb/options.cli b/odb/options.cli
index 45d2305..fcacbd3 100644
--- a/odb/options.cli
+++ b/odb/options.cli
@@ -283,6 +283,44 @@ class options
generated files."
};
+ std::string --changelog
+ {
+ "<file>",
+ "Read/write changelog from/to <file> instead of the default changelog
+ file. The default changelog file name is derived from the input file
+ name and it is placed into the same directory as the input file. Note
+ that the \cb{--output-name} option does not affect the changelog file
+ location. In other words, by default, the changelog file is treated
+ as another input rather than output even though the ODB compiler may
+ modify it. Use the \cb{--changelog-in} and \cb{--changelog-out}
+ options to specify different input and output chaneglog files."
+ };
+
+ std::string --changelog-in
+ {
+ "<file>",
+ "Read changelog from <file> instead of the default changelog file. If
+ this option is specified, then you must also specify the output
+ chanegelog file with \cb{--changelog-out}."
+ };
+
+ std::string --changelog-out
+ {
+ "<file>",
+ "Write changelog to <file> instead of the default changelog file. If
+ this option is specified, then you must also specify the input
+ chanegelog file with \cb{--changelog-in}."
+ };
+
+ std::string --changelog-dir
+ {
+ "<dir>",
+ "Use <dir> instead of the input file directory as the changelog file
+ directory. This directory is also added to changelog files specified
+ with the \cb{--changelog}, \cb{--changelog-in}, and \cb{--changelog-in}
+ options unless they are absolute paths."
+ };
+
database_map<std::string> --odb-file-suffix
{
"<suffix>",
diff --git a/odb/relational/changelog.cxx b/odb/relational/changelog.cxx
index de5e6f7..7435f05 100644
--- a/odb/relational/changelog.cxx
+++ b/odb/relational/changelog.cxx
@@ -142,7 +142,8 @@ namespace relational
generate (model& m,
model_version const& mv,
changelog* old,
- string const& name)
+ std::string const& in_name,
+ std::string const& out_name)
{
cutl::shared_ptr<changelog> cl (new (shared) changelog);
graph& g (*cl);
@@ -151,13 +152,13 @@ namespace relational
{
if (!mv.open)
{
- cerr << name << ": error: unable to initialize changelog because " <<
- "current version is closed" << endl;
+ cerr << out_name << ": error: unable to initialize changelog " <<
+ "because current version is closed" << endl;
throw operation_failed ();
}
- cerr << name << ": info: initializing changelog with base version " <<
- m.version () << endl;
+ cerr << out_name << ": info: initializing changelog with base " <<
+ "version " << m.version () << endl;
g.new_edge<contains_model> (*cl, g.new_node<model> (m, g));
return cl;
@@ -174,7 +175,7 @@ namespace relational
if (mv.current < cver)
{
- cerr << name << ": error: latest changelog version is greater " <<
+ cerr << in_name << ": error: latest changelog version is greater " <<
"than current version" << endl;
throw operation_failed ();
}
@@ -199,8 +200,8 @@ namespace relational
{
qnames& n (*cs.names_begin ());
- cerr << name << ": error: current version is closed" << endl;
- cerr << name << ": info: first new change is " <<
+ cerr << out_name << ": error: current version is closed" << endl;
+ cerr << out_name << ": info: first new change is " <<
n.nameable ().kind () << " '" << n.name () << "'" << endl;
throw operation_failed ();
@@ -242,8 +243,8 @@ namespace relational
{
qnames& n (*cs.names_begin ());
- cerr << name << ": error: current version is closed" << endl;
- cerr << name << ": info: first new change is " <<
+ cerr << out_name << ": error: current version is closed" << endl;
+ cerr << out_name << ": info: first new change is " <<
n.nameable ().kind () << " '" << n.name () << "'" << endl;
throw operation_failed ();
diff --git a/odb/relational/generate.hxx b/odb/relational/generate.hxx
index e5dc376..a50b999 100644
--- a/odb/relational/generate.hxx
+++ b/odb/relational/generate.hxx
@@ -52,7 +52,8 @@ namespace relational
generate (semantics::relational::model&,
model_version const&,
semantics::relational::changelog* old, // Can be NULL.
- std::string const& name);
+ std::string const& in_name,
+ std::string const& out_name);
}
namespace schema
diff --git a/odb/validator.cxx b/odb/validator.cxx
index 77ad874..57cca4a 100644
--- a/odb/validator.cxx
+++ b/odb/validator.cxx
@@ -994,6 +994,15 @@ validate (options const& ops,
valid = false;
}
+ // Changelog options.
+ //
+ if (ops.changelog_in_specified () != ops.changelog_out_specified ())
+ {
+ cerr << "error: both --changelog-in and --changelog-out must be " <<
+ "specified" << endl;
+ valid = false;
+ }
+
if (!valid)
throw failed ();