// file : cli/cli.cxx // author : Boris Kolpackov // copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file #include #include #include // unique_ptr #include #include #include #include #include #include #include #include using namespace std; using namespace cutl; int main (int argc, char* argv[]) { ostream& e (cerr); const char* file (0); try { cli::argv_file_scanner scan (argc, argv, "--options-file"); options ops (scan); // Handle --version // if (ops.version ()) { ostream& o (cout); o << "CLI (command line interface compiler) " << CLI_VERSION_ID << endl << "Copyright (c) 2009-2019 Code Synthesis Tools CC" << endl; o << "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; } // Handle --help // if (ops.help ()) { ostream& o (cout); o << "Usage: " << argv[0] << " [options] file" << endl << "Options:" << endl; options::print_usage (o); return 0; } if (!scan.more ()) { e << "error: no input file specified" << endl << "info: try '" << argv[0] << " --help' for more information" << endl; return 1; } // Extract include search paths. // parser::paths include_paths; for (vector::const_iterator i (ops.include_path ().begin ()); i != ops.include_path ().end (); ++i) { // Invalid path exception is handled below. // include_paths.push_back (semantics::path (*i)); } // Open the input file. // file = scan.next (); semantics::path path (file); ifstream ifs (path.string ().c_str ()); if (!ifs.is_open ()) { e << path << ": error: unable to open in read mode" << endl; return 1; } ifs.exceptions (ifstream::failbit | ifstream::badbit); // Parse and generate. // parser p (include_paths); unique_ptr unit (p.parse (ifs, path)); // Merge documentation variables from the command line. // for (map::const_iterator i (ops.docvar ().begin ()); i != ops.docvar ().end (); ++i) { using semantics::doc; // Values specified in the .cli file override command line. // if (unit->lookup ("", "var: " + i->first) != 0) continue; doc& d (unit->new_node (semantics::path (""), 0, 0)); unit->new_edge (*unit, d, "var: " + i->first); d.push_back (i->second); } generator g; g.generate (ops, *unit, path); } catch (cli::exception const& ex) { e << ex << endl; return 1; } catch (semantics::invalid_path const& ex) { e << "error: '" << ex.path () << "' is not a valid filesystem path" << endl; return 1; } catch (std::ios_base::failure const&) { e << file << ": error: read failure" << endl; return 1; } catch (parser::invalid_input const&) { // Diagnostics has already been issued by the parser. // return 1; } catch (generator::failed const&) { // Diagnostics has already been issued by the generator. // return 1; } }