aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-03-30 09:27:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-03-30 09:27:11 +0200
commitfa508bc933b7d45110be3ab64d193653bd876336 (patch)
tree1032cfd2d4fba1449040a46a40332e66921a7998
parent51529c4c62b00ea681f28b591fdcaa0c670da3d1 (diff)
Add support for database-specific profiles
-rw-r--r--odb/odb.cxx86
-rw-r--r--odb/options.cli25
-rw-r--r--odb/plugin.cxx22
-rw-r--r--odb/profile.cxx42
-rw-r--r--odb/profile.hxx13
5 files changed, 127 insertions, 61 deletions
diff --git a/odb/odb.cxx b/odb/odb.cxx
index 87638a6..e70c368 100644
--- a/odb/odb.cxx
+++ b/odb/odb.cxx
@@ -393,7 +393,8 @@ main (int argc, char* argv[])
e << " " << *i << endl;
}
- // Parse plugin options.
+ // Parse plugin options. We have to do it twice to get the target
+ // database which is need while loading profiles.
//
vector<char*> av;
av.push_back (argv[0]);
@@ -406,57 +407,68 @@ main (int argc, char* argv[])
int ac (static_cast<int> (av.size ()));
- profile_data pd (prof_paths, argv[0]);
cli::argv_file_scanner::option_info oi[3];
oi[0].option = "--options-file";
oi[0].search_func = 0;
oi[1].option = "-p";
- oi[1].search_func = &profile_search;
- oi[1].arg = &pd;
oi[2].option = "--profile";
- oi[2].search_func = &profile_search;
- oi[2].arg = &pd;
- cli::argv_file_scanner scan (ac, &av[0], oi, 3);
+ database db;
+ {
+ oi[1].search_func = &profile_search_ignore;
+ oi[2].search_func = &profile_search_ignore;
- options ops (scan);
+ cli::argv_file_scanner scan (ac, &av[0], oi, 3);
+ options ops (scan);
- // Handle --version.
- //
- if (ops.version ())
- {
- e << "ODB object-relational mapping (ORM) compiler for C++ "
- ODB_COMPILER_VERSION_STR << endl
- << "Copyright (c) 2009-2011 Code Synthesis Tools CC" << endl;
+ // Handle --version.
+ //
+ if (ops.version ())
+ {
+ e << "ODB object-relational mapping (ORM) compiler for C++ "
+ ODB_COMPILER_VERSION_STR << endl
+ << "Copyright (c) 2009-2011 Code Synthesis Tools CC" << endl;
- e << "This is free software; see the source for copying conditions. "
- << "There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS "
- << "FOR A PARTICULAR PURPOSE." << endl;
+ e << "This is free software; see the source for copying conditions. "
+ << "There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS "
+ << "FOR A PARTICULAR PURPOSE." << endl;
- return 0;
- }
+ return 0;
+ }
- // Handle --help.
- //
- if (ops.help ())
- {
- e << "Usage: " << argv[0] << " [options] file [file ...]"
- << endl
- << "Options:" << endl;
+ // Handle --help.
+ //
+ if (ops.help ())
+ {
+ e << "Usage: " << argv[0] << " [options] file [file ...]"
+ << endl
+ << "Options:" << endl;
- options::print_usage (e);
- return 0;
- }
+ options::print_usage (e);
+ return 0;
+ }
- // Check that required options were specifed.
- //
- if (!ops.database_specified ())
- {
- e << argv[0] << ": error: no database specified with the --database "
- << "option" << endl;
- return 1;
+ // Check that required options were specifed.
+ //
+ if (!ops.database_specified ())
+ {
+ e << argv[0] << ": error: no database specified with the --database "
+ << "option" << endl;
+ return 1;
+ }
+
+ db = ops.database ();
}
+ profile_data pd (prof_paths, db, argv[0]);
+ oi[1].search_func = &profile_search;
+ oi[2].search_func = &profile_search;
+ oi[1].arg = &pd;
+ oi[2].arg = &pd;
+
+ cli::argv_file_scanner scan (ac, &av[0], oi, 3);
+ options ops (scan);
+
size_t end (scan.end () - 1); // We have one less in plugin_args.
if (end == plugin_args.size ())
diff --git a/odb/options.cli b/odb/options.cli
index b536d21..0b643ec 100644
--- a/odb/options.cli
+++ b/odb/options.cli
@@ -123,14 +123,23 @@ class options
{
"<name>",
"Specify a profile that should be used during compilation. A
- profile is an options file with the name constructed by appending
- the \cb{.options} suffix to <name>. It is searched for in the
- same set of directories as C++ headers included with the
- \cb{#include <...>} directive (built-in paths plus those specified
- with the \cb{-I} options). The options file is first searched for
- in the directory itself and then in its \cb{odb/} subdirectory. For
- the format of the options file refer to the \cb{--options-file} option
- below. You can repeat this option to specify more than one profile."
+ profile is an options file. The ODB compiler first looks for
+ a database-specific version with the name constructed by appending
+ the \cb{-}\ci{database}\cb{.options} suffix to <name>, where
+ \ci{database} is the database name as specified with the
+ \cb{--database} option. If this file is not found, then the
+ ODB compiler looks for a database-independant version with the
+ name constructed by appending just the \cb{.options} suffix.
+
+ The profile options files are searched for in the same set of
+ directories as C++ headers included with the \cb{#include <...>}
+ directive (built-in paths plus those specified with the \cb{-I}
+ options). The options file is first searched for in the directory
+ itself and then in its \cb{odb/} subdirectory.
+
+ For the format of the options file refer to the \cb{--options-file}
+ option below. You can repeat this option to specify more than one
+ profile."
};
std::string --output-dir | -o
diff --git a/odb/plugin.cxx b/odb/plugin.cxx
index ede0235..5364425 100644
--- a/odb/plugin.cxx
+++ b/odb/plugin.cxx
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
#include <cstring> // std::strcpy
+#include <cassert>
#include <iostream>
#include <cutl/fs/path.hxx>
@@ -190,21 +191,34 @@ plugin_init (plugin_name_args* plugin_info, plugin_gcc_version*)
}
}
+ // Two-phase options parsing, similar to the driver.
+ //
int argc (static_cast<int> (argv.size ()));
- profile_data pd (profile_paths_, "odb plugin");
cli::argv_file_scanner::option_info oi[3];
oi[0].option = "--options-file";
oi[0].search_func = 0;
oi[1].option = "-p";
- oi[1].search_func = &profile_search;
- oi[1].arg = &pd;
oi[2].option = "--profile";
+
+ database db;
+ {
+ oi[1].search_func = &profile_search_ignore;
+ oi[2].search_func = &profile_search_ignore;
+
+ cli::argv_file_scanner scan (argc, &argv[0], oi, 3);
+ options ops (scan);
+ assert (ops.database_specified ());
+ db = ops.database ();
+ }
+
+ profile_data pd (profile_paths_, db, "odb plugin");
+ oi[1].search_func = &profile_search;
oi[2].search_func = &profile_search;
+ oi[1].arg = &pd;
oi[2].arg = &pd;
cli::argv_file_scanner scan (argc, &argv[0], oi, 3);
-
auto_ptr<options> ops (
new options (scan, cli::unknown_mode::fail, cli::unknown_mode::fail));
diff --git a/odb/profile.cxx b/odb/profile.cxx
index 393c953..fae2490 100644
--- a/odb/profile.cxx
+++ b/odb/profile.cxx
@@ -13,6 +13,18 @@
using namespace std;
+
+
+static bool
+exist (profile_data::path const& p)
+{
+ struct stat info;
+
+ // Just check that the file exist without checking for permissions, etc.
+ //
+ return stat (p.string ().c_str (), &info) == 0 && S_ISREG (info.st_mode);
+}
+
string
profile_search (char const* prof, void* arg)
{
@@ -24,26 +36,30 @@ profile_search (char const* prof, void* arg)
path p (prof), odb ("odb"), r;
p.normalize (); // Convert '/' to the canonical path separator form.
+ path p_db (p);
+ p_db += "-";
+ p_db += pd->db.string ();
p += ".options";
+ p_db += ".options";
- struct stat info;
paths::const_iterator i (ps.begin ()), end (ps.end ());
-
for (; i != end; ++i)
{
- // First check in the search directory itself and then try the odb/
- // subdirectory.
+ // First check for the database-specific version in the search directory
+ // itself and then try the odb/ subdirectory.
//
- r = *i / p;
+ if (exist (r = *i / p_db))
+ break;
- // Just check that the file exist without checking for permissions, etc.
- //
- if (stat (r.string ().c_str (), &info) == 0 && S_ISREG (info.st_mode))
+ if (exist (r = *i / odb / p_db))
break;
- r = *i / odb / p;
+ // Then try the same with the database-independent version.
+ //
+ if (exist (r = *i / p))
+ break;
- if (stat (r.string ().c_str (), &info) == 0 && S_ISREG (info.st_mode))
+ if (exist (r = *i / odb / p))
break;
}
@@ -60,3 +76,9 @@ profile_search (char const* prof, void* arg)
pd->loaded.insert (r);
return r.string ();
}
+
+string
+profile_search_ignore (char const*, void*)
+{
+ return string ();
+}
diff --git a/odb/profile.hxx b/odb/profile.hxx
index e3c5035..a545ef1 100644
--- a/odb/profile.hxx
+++ b/odb/profile.hxx
@@ -12,16 +12,22 @@
#include <cutl/fs/path.hxx>
+#include <odb/option-types.hxx>
+
struct profile_data
{
typedef cutl::fs::path path;
typedef std::vector<path> paths;
- profile_data (paths const& p, char const* n): search_paths (p), name (n) {}
+ profile_data (paths const& p, database d, char const* n)
+ : search_paths (p), db (d), name (n)
+ {
+ }
paths const& search_paths;
- std::set<path> loaded;
+ database db;
char const* name;
+ std::set<path> loaded;
};
struct profile_failure {};
@@ -29,4 +35,7 @@ struct profile_failure {};
std::string
profile_search (char const* profile, void* arg);
+std::string
+profile_search_ignore (char const* profile, void* arg);
+
#endif // ODB_PROFILE_HXX