$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r84305 - branches/release/tools/inspect
From: dnljms_at_[hidden]
Date: 2013-05-16 18:21:45
Author: danieljames
Date: 2013-05-16 18:21:45 EDT (Thu, 16 May 2013)
New Revision: 84305
URL: http://svn.boost.org/trac/boost/changeset/84305
Log:
Merge inspect to release.
Changes to get it to work better with new versions of program execution
monitor, outside of subversion.
Properties modified: 
   branches/release/tools/inspect/   (props changed)
   branches/release/tools/inspect/inspect.cpp   (contents, props changed)
Text files modified: 
   branches/release/tools/inspect/inspect.cpp |   100 +++++++++++++++++++++++++++++++-------- 
   1 files changed, 79 insertions(+), 21 deletions(-)
Modified: branches/release/tools/inspect/inspect.cpp
==============================================================================
--- branches/release/tools/inspect/inspect.cpp	(original)
+++ branches/release/tools/inspect/inspect.cpp	2013-05-16 18:21:45 EDT (Thu, 16 May 2013)
@@ -31,6 +31,15 @@
 #include "boost/filesystem/operations.hpp"
 #include "boost/filesystem/fstream.hpp"
 
+#include <stdio.h>  // for popen, pclose
+#if defined(_MSC_VER)
+# define POPEN _popen
+# define PCLOSE _pclose
+#else
+# define POPEN popen
+# define PCLOSE pclose
+#endif
+
 #include "time_string.hpp"
 
 #include "inspector.hpp"
@@ -115,33 +124,82 @@
   typedef std::vector< lib_error_count > lib_error_count_vector;
   lib_error_count_vector libs;
 
-//  get info (as a string) if inspect_root is svn working copy  --------------//
+//  run subversion to get revisions info  ------------------------------------//
+//
+// implemented as function object that can be passed to boost::execution_monitor
+// in order to swallow any errors from 'svn info'.
+
+  struct svn_check
+  {
+    explicit svn_check(const fs::path & inspect_root) :
+      inspect_root(inspect_root), fp(0) {}
+
+    int operator()() {
+      string rev("unknown");
+      string repos("unknown");
+      string command("cd ");
+      command += inspect_root.string() + " && svn info";
 
-  void extract_info( fs::ifstream & entries_file, string & rev, string & repos )
-    {
-      std::getline( entries_file, rev );
-      std::getline( entries_file, rev );
-      std::getline( entries_file, rev );
-      std::getline( entries_file, rev );    // revision number as a string
-      std::getline( entries_file, repos );  // repository as a string
+      fp = (POPEN(command.c_str(), "r"));
+      if (fp)
+      {
+        static const int line_max = 128;
+        char line[line_max];
+        while (fgets(line, line_max, fp) != NULL)
+        {
+          string ln(line);
+          string::size_type pos;
+          if ((pos = ln.find("Revision: ")) != string::npos)
+            rev = ln.substr(pos + 10);
+          else if ((pos = ln.find("URL: ")) != string::npos)
+            repos = ln.substr(pos + 5);
+        }
+      }
+
+      result = repos + " at revision " + rev;
+      return 0;
     }
 
+    ~svn_check() { if (fp) PCLOSE(fp); }
+
+    const fs::path & inspect_root;
+    std::string result;
+    FILE* fp;
+  private:
+    svn_check(svn_check const&);
+    svn_check const& operator=(svn_check const&);
+  };
+
+  // Small helper class because svn_check can't be passed by copy.
+  template <typename F, typename R>
+  struct nullary_function_ref
+  {
+    explicit nullary_function_ref(F& f) : f(f) {}
+    R operator()() const { return f(); }
+    F& f;
+  };
+
+//  get info (as a string) if inspect_root is svn working copy  --------------//
+
   string info( const fs::path & inspect_root )
   {
-    string rev( "?" );
-    string repos( "unknown" );
-    fs::path entries( inspect_root / ".svn" / "entries" );
-    fs::ifstream entries_file( entries );
-    if ( entries_file )
-      extract_info( entries_file, rev, repos );
-    else
-    {
-      entries = inspect_root / ".." / "svn_info" / ".svn" / "entries";
-      fs::ifstream entries_file( entries );
-      if ( entries_file )
-        extract_info( entries_file, rev, repos );
+    try {
+      boost::execution_monitor e;
+      svn_check check(inspect_root);
+
+      e.execute(nullary_function_ref<svn_check, int>(check));
+      return check.result;
+    }
+    catch(boost::execution_exception const& e) {
+      if (e.code() == boost::execution_exception::system_error) {
+        // There was an error running 'svn info' - it probably
+        // wasn't run in a subversion repo.
+        return string("unknown");
+      }
+      else {
+        throw;
+      }
     }
-    return repos + " at revision " + rev;
   }
 
 //  visit_predicate (determines which directories are visited)  --------------//