From b143a4a1a028d3147b9b603e77866780b34ee828 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 30 Mar 2010 11:05:46 +0200 Subject: Add code generator infrastructure --- odb/generator.cxx | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 odb/generator.cxx (limited to 'odb/generator.cxx') diff --git a/odb/generator.cxx b/odb/generator.cxx new file mode 100644 index 0000000..3548802 --- /dev/null +++ b/odb/generator.cxx @@ -0,0 +1,156 @@ +// file : cli/generator.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include // std::toupper, std::is{alpha,upper,lower} +#include +#include +#include + +#include + +#include +#include + +#include +#include + +using namespace std; +using namespace cutl; + +using semantics::path; + +namespace +{ + static char const cxx_header[] = + "// This code was generated by ODB, an object persistence compiler\n" + "// for C++.\n" + "//\n\n"; + + /* + string + make_guard (string const& file, context& ctx) + { + string g (file); + + // Split words, e.g., "FooBar" to "Foo_Bar" and convert everything + // to upper case. + // + string r; + for (string::size_type i (0), n (g.size ()); i < n - 1; ++i) + { + char c1 (g[i]); + char c2 (g[i + 1]); + + r += toupper (c1); + + if (isalpha (c1) && isalpha (c2) && islower (c1) && isupper (c2)) + r += "_"; + } + r += std::toupper (g[g.size () - 1]); + + return ctx.escape (r); + } + */ + + void + open (ifstream& ifs, string const& path) + { + ifs.open (path.c_str (), ios_base::in | ios_base::binary); + + if (!ifs.is_open ()) + { + cerr << path << ": error: unable to open in read mode" << endl; + throw generator::failed (); + } + } +} + +generator:: +generator () +{ +} + +void generator:: +generate (options const& ops, semantics::unit& unit, path const& p) +{ + try + { + path file (p.leaf ()); + string base (file.base ().string ()); + + fs::auto_removes auto_rm; + + // C++ output. + // + string cxx_name (base + ops.odb_file_suffix () + ops.cxx_suffix ()); + path cxx_path (cxx_name); + + if (!ops.output_dir ().empty ()) + { + path dir (ops.output_dir ()); + cxx_path = dir / cxx_path; + } + + // + // + ofstream cxx (cxx_path.string ().c_str ()); + + if (!cxx.is_open ()) + { + cerr << "error: unable to open '" << cxx_path << "' in write mode" + << endl; + throw failed (); + } + + auto_rm.add (cxx_path); + + // Print headers. + // + cxx << cxx_header; + + typedef compiler::ostream_filter cxx_filter; + + // Include settings. + // + bool br (ops.include_with_brackets ()); + string ip (ops.include_prefix ()); + + if (!ip.empty () && ip[ip.size () - 1] != '/') + ip.append ("/"); + + // CXX + // + { + cxx_filter filt (cxx); + context ctx (cxx, unit, ops); + + cxx << "#include " << (br ? '<' : '"') << ip << file << + (br ? '>' : '"') << endl + << endl; + + // generate_source (ctx); + } + + auto_rm.cancel (); + } + catch (const generation_failed&) + { + // Code generation failed. Diagnostics has already been issued. + // + throw failed (); + } + catch (semantics::invalid_path const& e) + { + cerr << "error: '" << e.path () << "' is not a valid filesystem path" + << endl; + throw failed (); + } + catch (fs::error const&) + { + // Auto-removal of generated files failed. Ignore it. + // + throw failed (); + } +} -- cgit v1.1