diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | odb/include.cxx | 49 | ||||
-rw-r--r-- | odb/odb.cxx | 57 | ||||
-rw-r--r-- | odb/options.cli | 16 |
4 files changed, 116 insertions, 9 deletions
@@ -6,6 +6,9 @@ Version 1.4.0 type differently depending on whether it is used in an ordinary member or an object id. + * New options, --odb-prologue-file and --odb-epilogue-file, allow the + inclusion of file contents into the ODB compilation. + Version 1.3.0 * Support for the SQLite database. Provided connection factories include diff --git a/odb/include.cxx b/odb/include.cxx index ccdc8bc..de3be4a 100644 --- a/odb/include.cxx +++ b/odb/include.cxx @@ -121,8 +121,9 @@ namespace } void - parse_file (string const& f, include_lines& lines) + parse_file (string const& file, include_lines& lines) { + string f (file); size_t n (f.size ()); // Check if we have a synthesized prologue/epilogue fragment. @@ -144,24 +145,42 @@ namespace istr >> n; } + n--; // Prologues/epilogues are counted from 1. + stringstream ss; + f.clear (); // We don't need the #line part. // if (name == "odb-prologue") - ss << options_.odb_prologue ()[n - 1]; + { + size_t size (options_.odb_prologue ().size ()); + + if (n < size) + ss << options_.odb_prologue ()[n]; + else + f = options_.odb_prologue_file ()[n - size]; + } else - ss << options_.odb_epilogue ()[n - 1]; + { + size_t size (options_.odb_epilogue ().size ()); - ss << endl; + if (n < size) + ss << options_.odb_epilogue ()[n]; + else + f = options_.odb_epilogue_file ()[n - size]; + } - parse_stream (ss, f, lines); - return; + if (f.empty ()) + { + parse_stream (ss, file, lines); + return; + } + // Otherwise use the code below to parse the file. } } } - ifstream is (f.c_str ()); if (!is.is_open ()) @@ -183,9 +202,23 @@ namespace string line; bool bslash (false); size_t lb (1), le (1); + bool eof (false); - for (int_type c (is.get ()); is.good (); c = is.get ()) + for (int_type c (is.get ()); !eof; c = is.get ()) { + if (is.fail ()) + { + if (is.eof ()) + { + // If we are still in the range, treat this as the last newline. + // + c = '\n'; + eof = true; + } + else + break; // Some other failure -- bail out. + } + if (c == '\n') { le++; diff --git a/odb/odb.cxx b/odb/odb.cxx index 4511115..b7c31da 100644 --- a/odb/odb.cxx +++ b/odb/odb.cxx @@ -578,7 +578,7 @@ main (int argc, char* argv[]) if (!ifs.is_open ()) { - cerr << input << ": error: unable to open in read mode" << endl; + e << input << ": error: unable to open in read mode" << endl; return 1; } @@ -626,6 +626,33 @@ main (int argc, char* argv[]) << endl; } + strings const& prof (ops.odb_prologue_file ()); + for (size_t i (0); i < prof.size (); ++i) + { + os << "#line 1 \"<odb-prologue-" << pro.size () + i + 1 << ">\"" + << endl; + + ifstream ifs (prof[i].c_str (), ios_base::in | ios_base::binary); + + if (!ifs.is_open ()) + { + e << prof[i] << ": error: unable to open in read mode" << endl; + fb.close (); + wait_process (pi, argv[0]); + return 1; + } + + if (!(os << ifs.rdbuf ())) + { + e << prof[i] << ": error: io failure" << endl; + fb.close (); + wait_process (pi, argv[0]); + return 1; + } + + os << endl; + } + // Write the synthesized translation unit to stdout. // os << "#line 1 \"" << escape_path (input) << "\"" << endl; @@ -633,6 +660,7 @@ main (int argc, char* argv[]) if (!(os << ifs.rdbuf ())) { e << input << ": error: io failure" << endl; + fb.close (); wait_process (pi, argv[0]); return 1; } @@ -654,6 +682,33 @@ main (int argc, char* argv[]) << endl; } + strings const& epif (ops.odb_epilogue_file ()); + for (size_t i (0); i < epif.size (); ++i) + { + os << "#line 1 \"<odb-epilogue-" << epi.size () + i + 1 << ">\"" + << endl; + + ifstream ifs (epif[i].c_str (), ios_base::in | ios_base::binary); + + if (!ifs.is_open ()) + { + e << epif[i] << ": error: unable to open in read mode" << endl; + fb.close (); + wait_process (pi, argv[0]); + return 1; + } + + if (!(os << ifs.rdbuf ())) + { + e << epif[i] << ": error: io failure" << endl; + fb.close (); + wait_process (pi, argv[0]); + return 1; + } + + os << endl; + } + // Add the standard epilogue at the end so that we see all // the declarations. // diff --git a/odb/options.cli b/odb/options.cli index 0b643ec..d61d60f 100644 --- a/odb/options.cli +++ b/odb/options.cli @@ -305,6 +305,14 @@ class options to the ODB compilation process." }; + std::vector<std::string> --odb-prologue-file + { + "<file>", + "Compile <file> contents before the input header file. Prologue files + are compiled after all the prologue text fragments (\cb{--odb-prologue} + option)." + }; + std::vector<std::string> --odb-epilogue { "<text>", @@ -313,6 +321,14 @@ class options to the ODB compilation process." }; + std::vector<std::string> --odb-epilogue-file + { + "<file>", + "Compile <file> contents after the input header file. Epilogue files + are compiled after all the epilogue text fragments (\cb{--odb-epilogue} + option)." + }; + // Include options. // bool --include-with-brackets |