From fa508bc933b7d45110be3ab64d193653bd876336 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 30 Mar 2011 09:27:11 +0200 Subject: Add support for database-specific profiles --- odb/odb.cxx | 86 ++++++++++++++++++++++++++++++++------------------------- odb/options.cli | 25 +++++++++++------ odb/plugin.cxx | 22 ++++++++++++--- odb/profile.cxx | 42 +++++++++++++++++++++------- odb/profile.hxx | 13 +++++++-- 5 files changed, 127 insertions(+), 61 deletions(-) (limited to 'odb') 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 av; av.push_back (argv[0]); @@ -406,57 +407,68 @@ main (int argc, char* argv[]) int ac (static_cast (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 { "", "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 . 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 , 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 #include #include // std::strcpy +#include #include #include @@ -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 (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 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 +#include + struct profile_data { typedef cutl::fs::path path; typedef std::vector 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 loaded; + database db; char const* name; + std::set 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 -- cgit v1.1