From 0e56fe29a9afeee00e02e722496678df89d37d50 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 17 Nov 2009 13:59:39 +0200 Subject: Complete the implementation of the option documentation Add the man page generator. Port CLI usage, HTML documentation and the man page to the auto-generated version. Update examples and documentation. --- cli/generator.cxx | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 8 deletions(-) (limited to 'cli/generator.cxx') diff --git a/cli/generator.cxx b/cli/generator.cxx index 6043825..7531ffe 100644 --- a/cli/generator.cxx +++ b/cli/generator.cxx @@ -21,6 +21,7 @@ #include "runtime-inline.hxx" #include "runtime-source.hxx" +#include "man.hxx" #include "html.hxx" #include "context.hxx" @@ -35,10 +36,23 @@ using semantics::path; namespace { - static char const header[] = - "// This code was generated by CLI, a command line interface\n" - "// compiler for C++.\n" - "//\n\n"; + static char const cxx_header[] = + "// This code was generated by CLI, a command line interface\n" + "// compiler for C++.\n" + "//\n\n"; + + static char const man_header[] = + ".\\\"\n" + ".\\\" The following documentation was generated by CLI, a command\n" + ".\\\" line interface compiler for C++.\n" + ".\\\"\n"; + + static char const html_header[] = + "\n" + "\n\n"; string make_guard (string const& file, context& ctx) @@ -63,6 +77,18 @@ namespace 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:: @@ -103,6 +129,8 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) fs::auto_removes auto_rm; + // C++ output. + // if (gen_cxx) { bool inl (!ops.suppress_inline ()); @@ -177,10 +205,10 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) // Print headers. // - hxx << header; + hxx << cxx_header; if (inl) - ixx << header; - cxx << header; + ixx << cxx_header; + cxx << cxx_header; typedef compiler::ostream_filter @@ -255,8 +283,83 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) } } + // man output + // + if (gen_man) + { + // Prologue & epilogue. + // + ifstream prologue, epilogue; + { + string file (ops.man_prologue ()); + + if (!file.empty ()) + open (prologue, file); + } + + { + string file (ops.man_epilogue ()); + + if (!file.empty ()) + open (epilogue, file); + } + + ofstream man; + + if (!ops.stdout ()) + { + path man_path (base + ops.man_suffix ()); + + if (!ops.output_dir ().empty ()) + man_path = path (ops.output_dir ()) / man_path; + + man.open (man_path.string ().c_str ()); + + if (!man.is_open ()) + { + cerr << "error: unable to open '" << man_path << "' in write mode" + << endl; + throw failed (); + } + + auto_rm.add (man_path); + } + + ostream& os (ops.stdout () ? cout : man); + + if (prologue.is_open ()) + os << prologue.rdbuf (); + + os << man_header; + + context ctx (os, unit, ops); + generate_man (ctx); + + if (epilogue.is_open ()) + os << epilogue.rdbuf (); + } + + // HTML output + // if (gen_html) { + // Prologue & epilogue. + // + ifstream prologue, epilogue; + { + string file (ops.html_prologue ()); + + if (!file.empty ()) + open (prologue, file); + } + + { + string file (ops.html_epilogue ()); + + if (!file.empty ()) + open (epilogue, file); + } + ofstream html; if (!ops.stdout ()) @@ -278,8 +381,18 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p) auto_rm.add (html_path); } - context ctx (ops.stdout () ? cout : html, unit, ops); + ostream& os (ops.stdout () ? cout : html); + + if (prologue.is_open ()) + os << prologue.rdbuf (); + + os << html_header; + + context ctx (os, unit, ops); generate_html (ctx); + + if (epilogue.is_open ()) + os << epilogue.rdbuf (); } auto_rm.cancel (); -- cgit v1.1