public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/libbash:master commit in: src/, /, utils/
@ 2011-05-08 13:07 Petteri Räty
  0 siblings, 0 replies; only message in thread
From: Petteri Räty @ 2011-05-08 13:07 UTC (permalink / raw
  To: gentoo-commits

commit:     7f6c20a9ef87ec5377f0d7758f7cdce20da11831
Author:     Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
AuthorDate: Thu May  5 06:53:14 2011 +0000
Commit:     Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
CommitDate: Sun May  8 12:55:51 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=7f6c20a9

Utils: reimplement instruo with libbash

With the help of instruo from Paludis, we can setup variables to
bash env needed for metadata generation. In the meanwhile, we can
compare the original instruo utility with our implementation.

---
 .gitignore                                     |    2 +
 Makefile.am                                    |   15 ++-
 configure.ac                                   |    2 +
 src/libbash.cpp                                |    5 +
 src/libbash.h                                  |    3 +-
 utils/command_line.cpp                         |   88 +++++++++
 utils/command_line.h                           |   62 ++++++
 utils/instruo.cpp                              |  251 ++++++++++++++++++++++++
 utils/{metadata_generator.cpp => metadata.cpp} |   35 +---
 src/libbash.h => utils/metadata.h              |   31 +---
 utils/metadata_generator.cpp                   |   84 +--------
 11 files changed, 445 insertions(+), 133 deletions(-)

diff --git a/.gitignore b/.gitignore
index 10b4131..79e3a80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 *.swo
 *.o
 *.la
+*.a
 *.lo
 *.log
 *.class
@@ -21,6 +22,7 @@ cppunittests
 variable_printer
 metadata_generator
 ast_printer
+instruo
 long.sh
 massif.out
 libbash.g

diff --git a/Makefile.am b/Makefile.am
index a3890bb..95beba6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -113,13 +113,24 @@ cppunittests_LDFLAGS = -static
 
 endif
 
-noinst_PROGRAMS = variable_printer metadata_generator ast_printer
+noinst_LIBRARIES = libmetadata.a
+
+libmetadata_a_SOURCES = utils/metadata.h utils/metadata.cpp
+libmetadata_a_CPPFLAGS = $(AM_CPPFLAGS) -Iutils
+
+noinst_PROGRAMS = variable_printer metadata_generator ast_printer instruo
 
 variable_printer_SOURCES = utils/variable_printer.cpp
 variable_printer_LDADD = libcppbash.la
 
 metadata_generator_SOURCES = utils/metadata_generator.cpp
-metadata_generator_LDADD = libcppbash.la
+metadata_generator_LDADD = libcppbash.la libmetadata.a
+metadata_generator_CPPFLAGS = $(AM_CPPFLAGS) -Iutils
+
+instruo_SOURCES = utils/instruo.cpp utils/command_line.cpp utils/command_line.h
+instruo_LDADD = libcppbash.la @PALUDIS_LIBS@ libmetadata.a
+instruo_CPPFLAGS = $(AM_CPPFLAGS) @PALUDIS_CFLAGS@ -Iutils
+instruo_CXXFLAGS = $(AM_CXXFLAGS) -Wno-extra
 
 ast_printer_SOURCES = utils/ast_printer.cpp
 ast_printer_LDADD = libcppbash.la $(BOOST_PROGRAM_OPTIONS_LIB)

diff --git a/configure.ac b/configure.ac
index b710a97..3563013 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,8 @@ AC_ARG_ENABLE([developer],
 			  [AS_HELP_STRING([--enable-developer],[enables various QA checks])])
 AM_CONDITIONAL([DEVELOPER_MODE],[test "x$enable_developer" = xyes])
 
+PKG_CHECK_MODULES([PALUDIS], [paludis])
+
 AS_IF([test "x$enable_developer" = xyes],[boost_version="1.46.1"],[boost_version="1.43.0"])
 AX_BOOST_BASE([$boost_version],[:],
 			  [AC_MSG_ERROR([Needed boost not found])])

diff --git a/src/libbash.cpp b/src/libbash.cpp
index 4fb4102..f04064d 100644
--- a/src/libbash.cpp
+++ b/src/libbash.cpp
@@ -39,6 +39,11 @@ namespace libbash
     if(!input)
       throw interpreter_exception("Unable to create fstream for script: " + path);
     interpreter walker;
+
+    // Initialize bash environment
+    for(auto iter = variables.begin(); iter != variables.end(); ++iter)
+      walker.set_value(iter->first, (iter->second)[0]);
+
     bash_ast ast(input);
     ast.interpret_with(walker);
 

diff --git a/src/libbash.h b/src/libbash.h
index ca8cdaa..3f903e9 100644
--- a/src/libbash.h
+++ b/src/libbash.h
@@ -39,7 +39,8 @@ namespace libbash
   /// \brief interpret a script specifid by path, return a map filled with
   ///        variables defined in the script
   /// \param the path of target script
-  /// \param the map to store variables
+  /// \param[in, out] we use the map to initialize bash environment and store the result
+  /// \param[out] store the names of the functions defined in the script
   void LIBBASH_API interpret(const std::string& path,
                              std::unordered_map<std::string, std::vector<std::string>>& variables,
                              std::vector<std::string>& functions);

diff --git a/utils/command_line.cpp b/utils/command_line.cpp
new file mode 100644
index 0000000..8d238b4
--- /dev/null
+++ b/utils/command_line.cpp
@@ -0,0 +1,88 @@
+/* This file was copied from Paludis src/clients/instruo/command_line.cc that is licensed as follows: */
+
+/*
+ * Copyright (c) 2007, 2008, 2009, 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "command_line.h"
+#include <paludis/util/singleton-impl.hh>
+
+using namespace paludis;
+
+template class paludis::Singleton<CommandLine>;
+
+CommandLine::CommandLine() :
+    ArgsHandler(),
+
+    action_args(main_options_section(), "Actions",
+            "Selects which basic action to perform. Exactly one action should "
+            "be specified."),
+    a_generate_cache(&action_args, "generate-cache", 'g', "Generate cache", false),
+    a_version(&action_args,        "version",        'V', "Display program version", false),
+    a_help(&action_args,           "help",           'h', "Display program help", false),
+
+    general_args(main_options_section(), "General options",
+            "Options which are relevant for most or all actions."),
+    a_log_level(&general_args, "log-level",  '\0'),
+    a_no_colour(&general_args, "no-colour", '\0', "Do not use colour", false),
+    a_no_color(&a_no_colour, "no-color"),
+    a_force_colour(&general_args, "force-colour", '\0', "Force the use of colour", false),
+    a_force_color(&a_force_colour, "force-color"),
+    a_repository_directory(&general_args, "repository-dir", 'D',
+            "Where to find the repository (default: current directory)"),
+    a_output_directory(&general_args, "output-dir", 'o',
+            "Where to place generated metadata (default: current directory)"),
+    a_master_repository_name(&general_args, "master-repository-name", '\0',
+            "Use the specified name for the master repository. Specify the location using --extra-repository-dir. "
+            "Only for repositories with no metadata/layout.conf."),
+    a_extra_repository_dir(&general_args, "extra-repository-dir", '\0',
+            "Also include the repository at this location. May be specified multiple times, in creation order."),
+    a_report_file(&general_args, "report-file", 'r',
+            "Write report to the specified file, rather than stdout")
+{
+    add_usage_line("--generate-cache [ at least one of --repository-dir /dir or --output-dir /dir ]");
+
+    add_description_line("instruo is configured purely from the command line. It does not use any user "
+            "configuration files.");
+
+    add_environment_variable("INSTRUO_OPTIONS", "Default command-line options.");
+    add_environment_variable("INSTRUO_THREADS", "Number of threads to use. Default: 5");
+}
+
+std::string
+CommandLine::app_name() const
+{
+    return "instruo";
+}
+
+std::string
+CommandLine::app_synopsis() const
+{
+    return "Metadata generation client for Paludis";
+}
+
+std::string
+CommandLine::app_description() const
+{
+    return
+        "instruo is a metadata generation client for Paludis. It generates metadata cache for every ID in a "
+        "given repository and produces a report of any failures.";
+}
+
+CommandLine::~CommandLine()
+{
+}
+

diff --git a/utils/command_line.h b/utils/command_line.h
new file mode 100644
index 0000000..2fdb10b
--- /dev/null
+++ b/utils/command_line.h
@@ -0,0 +1,62 @@
+/* This file was copied from Paludis src/clients/instruo/command_line.hh that is licensed as follows: */
+
+/*
+ * Copyright (c) 2007, 2008, 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef PALUDIS_GUARD_SRC_CLIENTS_INSTRUO_COMMAND_LINE_HH
+#define PALUDIS_GUARD_SRC_CLIENTS_INSTRUO_COMMAND_LINE_HH 1
+
+#include <paludis/args/args.hh>
+#include <paludis/util/singleton.hh>
+#include <paludis/args/log_level_arg.hh>
+
+class CommandLine :
+    public paludis::args::ArgsHandler,
+    public paludis::Singleton<CommandLine>
+{
+    friend class paludis::Singleton<CommandLine>;
+
+    private:
+        CommandLine();
+        ~CommandLine();
+
+    public:
+        virtual std::string app_name() const;
+        virtual std::string app_synopsis() const;
+        virtual std::string app_description() const;
+
+        paludis::args::ArgsGroup action_args;
+
+        paludis::args::SwitchArg a_generate_cache;
+        paludis::args::SwitchArg a_version;
+        paludis::args::SwitchArg a_help;
+
+        paludis::args::ArgsGroup general_args;
+
+        paludis::args::LogLevelArg a_log_level;
+        paludis::args::SwitchArg a_no_colour;
+        paludis::args::AliasArg a_no_color;
+        paludis::args::SwitchArg a_force_colour;
+        paludis::args::AliasArg a_force_color;
+        paludis::args::StringArg a_repository_directory;
+        paludis::args::StringArg a_output_directory;
+        paludis::args::StringArg a_master_repository_name;
+        paludis::args::StringSequenceArg a_extra_repository_dir;
+        paludis::args::StringArg a_report_file;
+};
+
+#endif

diff --git a/utils/instruo.cpp b/utils/instruo.cpp
new file mode 100644
index 0000000..bd1c981
--- /dev/null
+++ b/utils/instruo.cpp
@@ -0,0 +1,251 @@
+/* This file was partly copied from Paludis src/clients/instruo/instruo.cc.
+ * The metadata generation logic is reimplemented with libbash. This file is
+ * licensed as follows: */
+
+/*
+ * Copyright (c) 2007, 2008, 2009, 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <algorithm>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <map>
+
+#include <paludis/args/do_help.hh>
+#include <paludis/about.hh>
+#include <paludis/action.hh>
+#include <paludis/package_id.hh>
+#include <paludis/generator.hh>
+#include <paludis/filter.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/selection.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/join.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/visitor_cast.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/mutex.hh>
+#include <paludis/util/thread_pool.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/safe_ofstream.hh>
+#include <paludis/util/pretty_print.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/timestamp.hh>
+#include <paludis/util/accept_visitor.hh>
+#include <paludis/environments/no_config/no_config_environment.hh>
+#include <paludis/package_database.hh>
+#include <paludis/metadata_key.hh>
+
+#include "command_line.h"
+#include "libbash.h"
+#include "utils/metadata.h"
+
+using namespace paludis;
+using std::cout;
+using std::cerr;
+using std::endl;
+
+void worker(const std::shared_ptr<PackageIDSequence> &ids)
+{
+  std::unordered_map<std::string, std::vector<std::string>> variables;
+
+  std::shared_ptr<const PackageID> id;
+  unsigned total(0);
+  CategoryNamePart old_cat("OLDCAT");
+  while(!ids->empty())
+  {
+    id = *ids->begin();
+    ids->pop_front();
+    if (id->name().category() != old_cat)
+    {
+      std::cout << "Processing " << stringify(id->name().category()) << "..." << std::endl;
+      old_cat = id->name().category();
+      FSPath(CommandLine::get_instance()->a_output_directory.argument() + "/" +
+          stringify(id->name().category())).mkdir(0755,  {fspmkdo_ok_if_exists});
+      ++total;
+    }
+
+    Context i_context("When generating metadata for ID '" + stringify(*id) + "':");
+
+    variables.clear();
+    variables["PN"].push_back(stringify(id->name().package()));
+    variables["PV"].push_back(stringify(id->version().remove_revision()));
+    variables["P"].push_back(stringify(id->name().package()) + "-" +
+                             stringify(id->version().remove_revision()));
+    variables["PR"].push_back(id->version().revision_only());
+    variables["PVR"].push_back(stringify(id->version()));
+    variables["PF"].push_back(stringify(id->name().package()) + "-" + stringify(id->version()));
+    variables["CATEGORY"].push_back(stringify(id->name().category()));
+    std::vector<std::string> functions;
+
+    std::string ebuild_path(CommandLine::get_instance()->a_repository_directory.argument() +
+                            variables["CATEGORY"][0] + "/" +
+                            variables["PN"][0] + "/" +
+                            variables["PN"][0] + "-" +
+                            variables["PVR"][0] + ".ebuild");
+    try
+    {
+      libbash::interpret(ebuild_path, variables, functions);
+    }
+    catch(const interpreter_exception& e)
+    {
+      cerr << "Exception occurred while interpreting " << ebuild_path << ". The error message is:\n"
+        << e.what() << endl;
+      continue;
+    }
+
+    std::string output_path(CommandLine::get_instance()->a_output_directory.argument() + "/" +
+                            variables["CATEGORY"][0] + "/" +
+                            variables["PN"][0] + "-" +
+                            variables["PVR"][0]);
+    FSPath(output_path).dirname().mkdir(0755, {fspmkdo_ok_if_exists});
+    std::ofstream output(output_path, std::ofstream::out | std::ofstream::trunc);
+    write_metadata(output, variables, functions);
+  }
+}
+
+int main(int argc, char** argv)
+{
+  try
+  {
+    std::string options(paludis::getenv_with_default("INSTRUO_OPTIONS", ""));
+    if (! options.empty())
+        options = "(" + options + ") ";
+    options += join(argv + 1, argv + argc, " ");
+
+    Context context(std::string("In program ") + argv[0] + " " + options + ":");
+
+    CommandLine::get_instance()->run(argc, argv, "instruo", "INSTRUO_OPTIONS", "INSTRUO_CMDLINE");
+
+    if (CommandLine::get_instance()->a_help.specified())
+        throw args::DoHelp();
+
+    if (CommandLine::get_instance()->a_log_level.specified())
+        Log::get_instance()->set_log_level(CommandLine::get_instance()->a_log_level.option());
+    else
+        Log::get_instance()->set_log_level(ll_qa);
+
+    if (1 < (
+                CommandLine::get_instance()->a_generate_cache.specified() +
+                CommandLine::get_instance()->a_version.specified()
+            ))
+        throw args::DoHelp("you should specify exactly one action");
+
+    if (! CommandLine::get_instance()->a_repository_directory.specified())
+        CommandLine::get_instance()->a_repository_directory.set_argument(stringify(FSPath::cwd()));
+
+    if (CommandLine::get_instance()->a_version.specified())
+    {
+        cout << "instruo, part of " << PALUDIS_PACKAGE << " " << PALUDIS_VERSION_MAJOR << "."
+            << PALUDIS_VERSION_MINOR << "." << PALUDIS_VERSION_MICRO << PALUDIS_VERSION_SUFFIX;
+        if (! std::string(PALUDIS_GIT_HEAD).empty())
+            cout << " git " << PALUDIS_GIT_HEAD;
+        cout << endl << endl;
+        cout << "Paludis comes with ABSOLUTELY NO WARRANTY. Paludis is free software, and you" << endl;
+        cout << "are welcome to redistribute it under the terms of the GNU General Public" << endl;
+        cout << "License, version 2." << endl;
+
+        return EXIT_SUCCESS;
+    }
+
+    if ((
+                CommandLine::get_instance()->a_repository_directory.specified() +
+                CommandLine::get_instance()->a_output_directory.specified()
+        ) < 1)
+        throw args::DoHelp("at least one of '--" + CommandLine::get_instance()->a_repository_directory.long_name() + "' or '--"
+                + CommandLine::get_instance()->a_output_directory.long_name() + "' must be specified");
+
+    if (! CommandLine::get_instance()->a_output_directory.specified())
+        CommandLine::get_instance()->a_output_directory.set_argument(stringify(FSPath::cwd()));
+
+    std::shared_ptr<FSPathSequence> extra_repository_dirs(std::make_shared<FSPathSequence>());
+    for (args::StringSequenceArg::ConstIterator d(CommandLine::get_instance()->a_extra_repository_dir.begin_args()),
+            d_end(CommandLine::get_instance()->a_extra_repository_dir.end_args()) ;
+            d != d_end ; ++d)
+        extra_repository_dirs->push_back(FSPath(*d));
+
+    std::shared_ptr<Map<std::string, std::string> > keys(std::make_shared<Map<std::string, std::string>>());
+    keys->insert("append_repository_name_to_write_cache", "false");
+    NoConfigEnvironment env(make_named_values<no_config_environment::Params>(
+                n::accept_unstable() = true,
+                n::disable_metadata_cache() = true,
+                n::extra_accept_keywords() = "",
+                n::extra_params() = keys,
+                n::extra_repository_dirs() = extra_repository_dirs,
+                n::master_repository_name() = CommandLine::get_instance()->a_master_repository_name.argument(),
+                n::profiles_if_not_auto() = "",
+                n::repository_dir() = CommandLine::get_instance()->a_repository_directory.argument(),
+                n::repository_type() = no_config_environment::ncer_ebuild,
+                n::write_cache() = CommandLine::get_instance()->a_output_directory.argument()
+            ));
+
+    FSPath(CommandLine::get_instance()->a_output_directory.argument()).mkdir(0755,  {fspmkdo_ok_if_exists});
+
+    std::shared_ptr<PackageIDSequence> ids(env[selection::AllVersionsSorted(
+                generator::InRepository(env.main_repository()->name()))]);
+    worker(ids);
+  }
+  catch (const paludis::args::ArgsError & e)
+  {
+      cerr << "Usage error: " << e.message() << endl;
+      cerr << "Try " << argv[0] << " --help" << endl;
+      return EXIT_FAILURE;
+  }
+  catch (const args::DoHelp & h)
+  {
+      if (h.message.empty())
+      {
+          cout << "Usage: " << argv[0] << " [options]" << endl;
+          cout << endl;
+          cout << *CommandLine::get_instance();
+          return EXIT_SUCCESS;
+      }
+      else
+      {
+          cerr << "Usage error: " << h.message << endl;
+          cerr << "Try " << argv[0] << " --help" << endl;
+          return EXIT_FAILURE;
+      }
+  }
+  catch (const Exception & e)
+  {
+      cout << endl;
+      cerr << "Unhandled exception:" << endl
+          << "  * " << e.backtrace("\n  * ")
+          << e.message() << " (" << e.what() << ")" << endl;
+      return EXIT_FAILURE;
+  }
+  catch (const std::exception & e)
+  {
+      cout << endl;
+      cerr << "Unhandled exception:" << endl
+          << "  * " << e.what() << endl;
+      return EXIT_FAILURE;
+  }
+  catch (...)
+  {
+      cout << endl;
+      cerr << "Unhandled exception:" << endl
+          << "  * Unknown exception type. Ouch..." << endl;
+      return EXIT_FAILURE;
+  }
+
+  return EXIT_SUCCESS;
+}

diff --git a/utils/metadata_generator.cpp b/utils/metadata.cpp
similarity index 83%
copy from utils/metadata_generator.cpp
copy to utils/metadata.cpp
index 52b4590..600f9e4 100644
--- a/utils/metadata_generator.cpp
+++ b/utils/metadata.cpp
@@ -17,21 +17,18 @@
    along with libbash.  If not, see <http://www.gnu.org/licenses/>.
    */
 ///
-/// \file metadata_generator.cpp
+/// \file metadata.cpp
 /// \author Mu Qiao
-/// \brief a simple utility for generating metadata
+/// \brief a helper for printing metadata content
 ///
-#include <iostream>
 #include <set>
-#include <string>
-#include <vector>
 
 #include <boost/spirit/include/karma.hpp>
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/trim.hpp>
 
-#include "libbash.h"
+#include "utils/metadata.h"
 
 static const std::vector<std::string> metadata_names = {"DEPEND", "RDEPEND", "SLOT", "SRC_URI",
                                                         "RESTRICT",  "HOMEPAGE",  "LICENSE", "DESCRIPTION",
@@ -56,20 +53,10 @@ static const std::unordered_map<std::string, std::string> phases = {
   {"pkg_nofetch", "nofetch"}
 };
 
-int main(int argc, char** argv)
+void write_metadata(std::ostream& output,
+                    std::unordered_map<std::string, std::vector<std::string>>& variables,
+                    std::vector<std::string>& functions)
 {
-  using namespace boost::spirit::karma;
-
-  if(argc != 2)
-  {
-    std::cerr<<"Please provide your script as an argument"<<std::endl;
-    exit(EXIT_FAILURE);
-  }
-
-  std::unordered_map<std::string, std::vector<std::string>> variables;
-  std::vector<std::string> functions;
-  libbash::interpret(argv[1], variables, functions);
-
   for(auto iter_name = metadata_names.begin(); iter_name != metadata_names.end(); ++iter_name)
   {
     auto iter_value = variables.find(*iter_name);
@@ -106,7 +93,8 @@ int main(int argc, char** argv)
                  value,
                  boost::is_any_of(" \t\n"),
                  boost::token_compress_on);
-    std::cout << format(string % ' ', splitted_value) << std::endl;
+    using namespace boost::spirit::karma;
+    output << format(string % ' ', splitted_value) << std::endl;
   }
 
   // Print defined phases
@@ -117,10 +105,9 @@ int main(int argc, char** argv)
     if(iter_phase != phases.end())
       sorted_phases.insert(iter_phase->second);
   }
-  std::cout << format(string % ' ', sorted_phases) << std::endl;
+  using namespace boost::spirit::karma;
+  output << format(string % ' ', sorted_phases) << std::endl;
 
   // Print empty lines
-  std::cout << std::endl << std::endl << std::endl << std::endl << std::endl;
-
-  return EXIT_SUCCESS;
+  output << std::endl << std::endl << std::endl << std::endl << std::endl;
 }

diff --git a/src/libbash.h b/utils/metadata.h
similarity index 55%
copy from src/libbash.h
copy to utils/metadata.h
index ca8cdaa..cb7f559 100644
--- a/src/libbash.h
+++ b/utils/metadata.h
@@ -15,34 +15,17 @@
 
    You should have received a copy of the GNU General Public License
    along with libbash.  If not, see <http://www.gnu.org/licenses/>.
-*/
+   */
 ///
-/// \file libbash.h
+/// \file metadata.h
 /// \author Mu Qiao
-/// \brief public interface for libbash
+/// \brief a helper for printing metadata content
 ///
-
-#ifndef LIBBASH_LIBBASH_H_
-#define LIBBASH_LIBBASH_H_
-
-#include <memory>
+#include <iostream>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
-#include "common.h"
-#include "core/interpreter_exception.h"
-
-namespace libbash
-{
-  ///
-  /// \brief interpret a script specifid by path, return a map filled with
-  ///        variables defined in the script
-  /// \param the path of target script
-  /// \param the map to store variables
-  void LIBBASH_API interpret(const std::string& path,
-                             std::unordered_map<std::string, std::vector<std::string>>& variables,
-                             std::vector<std::string>& functions);
-}
-
-#endif
+void write_metadata(std::ostream& output,
+                    std::unordered_map<std::string, std::vector<std::string>>& variables,
+                    std::vector<std::string>& functions);

diff --git a/utils/metadata_generator.cpp b/utils/metadata_generator.cpp
index 52b4590..14602f2 100644
--- a/utils/metadata_generator.cpp
+++ b/utils/metadata_generator.cpp
@@ -22,44 +22,14 @@
 /// \brief a simple utility for generating metadata
 ///
 #include <iostream>
-#include <set>
 #include <string>
 #include <vector>
 
-#include <boost/spirit/include/karma.hpp>
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/algorithm/string/trim.hpp>
-
 #include "libbash.h"
-
-static const std::vector<std::string> metadata_names = {"DEPEND", "RDEPEND", "SLOT", "SRC_URI",
-                                                        "RESTRICT",  "HOMEPAGE",  "LICENSE", "DESCRIPTION",
-                                                        "KEYWORDS",  "INHERITED", "IUSE", "REQUIRED_USE",
-                                                        "PDEPEND",   "PROVIDE", "EAPI", "PROPERTIES"};
-
-static const std::unordered_map<std::string, std::string> phases = {
-  {"pkg_pretend", "ppretend"},
-  {"pkg_setup", "setup"},
-  {"src_unpack", "unpack"},
-  {"src_prepare", "prepare"},
-  {"src_configure", "configure"},
-  {"src_compile", "compile"},
-  {"src_test", "test"},
-  {"src_install", "install"},
-  {"pkg_preinst", "preinst"},
-  {"pkg_postinst", "postinst"},
-  {"pkg_prerm", "prerm"},
-  {"pkg_postrm", "postrm"},
-  {"pkg_config", "config"},
-  {"pkg_info", "info"},
-  {"pkg_nofetch", "nofetch"}
-};
+#include "utils/metadata.h"
 
 int main(int argc, char** argv)
 {
-  using namespace boost::spirit::karma;
-
   if(argc != 2)
   {
     std::cerr<<"Please provide your script as an argument"<<std::endl;
@@ -70,57 +40,7 @@ int main(int argc, char** argv)
   std::vector<std::string> functions;
   libbash::interpret(argv[1], variables, functions);
 
-  for(auto iter_name = metadata_names.begin(); iter_name != metadata_names.end(); ++iter_name)
-  {
-    auto iter_value = variables.find(*iter_name);
-    std::string value;
-
-    if(iter_value != variables.end())
-      value = iter_value->second[0];
-
-    // Check if global is defined
-    auto iter_global = variables.find("E_" + *iter_name);
-    if(iter_global != variables.end())
-    {
-      boost::trim_if(iter_global->second[0], boost::is_any_of(" \t\n"));
-      std::vector<std::string> splitted_global;
-      boost::split(splitted_global,
-                   iter_global->second[0],
-                   boost::is_any_of(" \t\n"),
-                   boost::token_compress_on);
-
-      // Append the global value to 'value' if it doesn't cause duplication
-      for(auto iter_splitted_global = splitted_global.begin();
-          iter_splitted_global != splitted_global.end();
-          ++iter_splitted_global)
-      {
-        if(value.find(*iter_splitted_global) == std::string::npos)
-          value += " " + *iter_splitted_global;
-      }
-    }
-
-    boost::trim_if(value, boost::is_any_of(" \t\n"));
-
-    std::vector<std::string> splitted_value;
-    boost::split(splitted_value,
-                 value,
-                 boost::is_any_of(" \t\n"),
-                 boost::token_compress_on);
-    std::cout << format(string % ' ', splitted_value) << std::endl;
-  }
-
-  // Print defined phases
-  std::set<std::string> sorted_phases;
-  for(auto iter = functions.begin(); iter != functions.end(); ++iter)
-  {
-    auto iter_phase = phases.find(*iter);
-    if(iter_phase != phases.end())
-      sorted_phases.insert(iter_phase->second);
-  }
-  std::cout << format(string % ' ', sorted_phases) << std::endl;
-
-  // Print empty lines
-  std::cout << std::endl << std::endl << std::endl << std::endl << std::endl;
+  write_metadata(std::cout, variables, functions);
 
   return EXIT_SUCCESS;
 }



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2011-05-08 13:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-08 13:07 [gentoo-commits] proj/libbash:master commit in: src/, /, utils/ Petteri Räty

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox