Coverage for /Syzygy/common/application.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%37370.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // Declares a generic command-line application framework.
  16    :  //
  17    :  // An application can be declared as follows in a library:
  18    :  //
  19    :  //     class MyApp : public common::AppImplBase {
  20    :  //      public:
  21    :  //       bool ParseCommandLine(const CommandLine* command_line);
  22    :  //       int Run();
  23    :  //      protected:
  24    :  //       bool InternalFunc();
  25    :  //     };
  26    :  //
  27    :  // The application class can then be unit-tested as appropriate. See the
  28    :  // declaration of common::AppImplBase for the entire interface expected
  29    :  // by the application framework. Note that derivation from AppImplBase
  30    :  // is optional, as the integration with the application framework is
  31    :  // by template expansion, not virtual function invocation; AppImplBase
  32    :  // is purely a convenience base class to allow you to elide defining
  33    :  // parts of the interface you don't need to specialize.
  34    :  //
  35    :  // The main() function for the executable can be reduced to:
  36    :  //
  37    :  //     int main(int argc, const char* const* argv) {
  38    :  //       base::AtExitManager at_exit_manager;
  39    :  //       CommandLine::Init(argc, argv);
  40    :  //       return common::Application<MyApp>().Run();
  41    :  //     }
  42    :  //
  43    :  // To test how your application implementation interacts with the
  44    :  // application framework. You can run the application directly from
  45    :  // a unittest as follows:
  46    :  //
  47    :  //     TEST(FixtureName, TestName) {
  48    :  //       using common::Application;
  49    :  //
  50    :  //       file_util::ScopedFILE in(file_util::OpenFile("NUL", "r"));
  51    :  //       file_util::ScopedFILE out(file_util::OpenFile("NUL", "w"));
  52    :  //       file_util::ScopedFILE err(file_util::OpenFile("NUL", "w"));
  53    :  //       ASSERT_TRUE(in.get() != NULL);
  54    :  //       ASSERT_TRUE(out.get() != NULL);
  55    :  //       ASSERT_TRUE(err.get() != NULL);
  56    :  //
  57    :  //       CommandLine cmd_line(FilePath(L"program"));
  58    :  //       Application<MyTestApp, LOG_INIT_NO> test_app(&cmd_line,
  59    :  //                                                    in.get(),
  60    :  //                                                    out.get(),
  61    :  //                                                    err.get());
  62    :  //
  63    :  //       ASSERT_TRUE(test_app.implementation().SomeFunc());
  64    :  //       ASSERT_EQ(0, test_app.Run());
  65    :  //     }
  66    :  //
  67    :  
  68    :  #ifndef SYZYGY_COMMON_APPLICATION_H_
  69    :  #define SYZYGY_COMMON_APPLICATION_H_
  70    :  
  71    :  #include <objbase.h>
  72    :  
  73    :  #include "base/at_exit.h"
  74    :  #include "base/command_line.h"
  75    :  #include "base/logging.h"
  76    :  #include "base/string_number_conversions.h"
  77    :  #include "base/string_util.h"
  78    :  #include "sawbuck/common/com_utils.h"
  79    :  
  80    :  namespace common {
  81    :  
  82    :  // A convenience base class that describes the interface an application
  83    :  // implementation is expected to expose. This class provides empty default
  84    :  // method implementations.
  85    :  //
  86    :  // @note Each method is responsible for logging its own errors as it deems
  87    :  //     appropriate. No log messages are otherwise generated if one of the
  88    :  //     AppImplBase methods returns an error.
  89    :  class AppImplBase {
  90    :   public:
  91    :    // Initializes an application implementation with the standard IO streams.
  92    :    // Use the stream IO accessors to customize the IO streams.
  93    :    // @param name the name of the application.
  94    :    explicit AppImplBase(const base::StringPiece& name);
  95    :  
  96    :    // Parse the given command line in preparation for execution.
  97    :    bool ParseCommandLine(const CommandLine* command_line);
  98    :  
  99    :    // A hook called just before Run().
 100    :    bool SetUp();
 101    :  
 102    :    // The main logic for the application implementation.
 103    :    // @returns the exit status for the application.
 104    :    int Run();
 105    :  
 106    :    // A hook called just after Run().
 107    :    void TearDown();
 108    :  
 109    :    // Get the application name.
 110  E :    const std::string& name() const { return name_; }
 111    :  
 112    :    // @name IO Stream Accessors
 113    :    // @{
 114  E :    FILE* in() const { return in_; }
 115  E :    FILE* out() const { return out_; }
 116  E :    FILE* err() const { return err_; }
 117    :  
 118  E :    void set_in(FILE* f) {
 119  E :      DCHECK(f != NULL);
 120  E :      in_ = f;
 121  E :    }
 122    :  
 123  E :    void set_out(FILE* f) {
 124  E :      DCHECK(f != NULL);
 125  E :      out_ = f;
 126  E :    }
 127    :  
 128  E :    void set_err(FILE* f) {
 129  E :      DCHECK(f != NULL);
 130  E :      err_ = f;
 131  E :    }
 132    :    // @}
 133    :  
 134    :    // A helper function to return an absolute path (if possible) for the given
 135    :    // path. If the conversion to an absolute path fails, the original path is
 136    :    // returned.
 137    :    static FilePath AbsolutePath(const FilePath& path);
 138    :  
 139    :   protected:
 140    :    // The name of this application.
 141    :    std::string name_;
 142    :  
 143    :    // @name Standard file streams.
 144    :    // @{
 145    :    FILE* in_;
 146    :    FILE* out_;
 147    :    FILE* err_;
 148    :    // @}
 149    :  };
 150    :  
 151    :  // Flags controlling the initialization of the logging subsystem.
 152    :  enum AppLoggingFlag { INIT_LOGGING_NO, INIT_LOGGING_YES };
 153    :  
 154    :  // The Application template class.
 155    :  //
 156    :  // @tparam Implementation The class which implements the application logic.
 157    :  // @tparam kInitLogging Tracks whether or not the application should
 158    :  //     (re-)initialize the logging subsystem on startup. Under testing,
 159    :  //     for example, one might want to skip initializing the logging
 160    :  //     subsystem.
 161    :  template <typename Impl, AppLoggingFlag kInitLogging = INIT_LOGGING_YES>
 162    :  class Application {
 163    :   public:
 164    :    // The application implementation class.
 165    :    typedef typename Impl Implementation;
 166    :  
 167    :    // Initializes the application with the current processes command line and
 168    :    // the standard IO streams.
 169    :    //
 170    :    // @pre CommandLine::Init() has been called prior to the creation of the
 171    :    //     application object.
 172    :    Application();
 173    :  
 174    :    // Accessor for the underlying implementation.
 175  E :    Implementation& implementation() { return implementation_; }
 176    :  
 177    :    // @name Accessors for the command line.
 178    :    // @{
 179  E :    const CommandLine* command_line() const { return command_line_; }
 180    :  
 181  E :    void set_command_line(const CommandLine* command_line) {
 182  E :      DCHECK(command_line != NULL);
 183  E :      command_line_ = command_line;
 184  E :    }
 185    :    // @}
 186    :  
 187    :    // Get the application name.
 188  E :    const std::string& name() const { return implementation_.name(); }
 189    :  
 190    :    // The main skeleton for actually running an application.
 191    :    // @returns the exit status for the application.
 192    :    int Run();
 193    :  
 194    :    // @name IO Stream Accessors
 195    :    // @{
 196  E :    FILE* in() const { return implementation_.in(); }
 197  E :    FILE* out() const { return implementation_.out(); }
 198  E :    FILE* err() const { return implementation_.err(); }
 199    :  
 200  E :    void set_in(FILE* f) { implementation_.set_in(f); }
 201  E :    void set_out(FILE* f) { implementation_.set_out(f); }
 202  E :    void set_err(FILE* f) { implementation_.set_err(f); }
 203    :    // @}
 204    :  
 205    :   protected:
 206    :    // Initializes the logging subsystem for this application. This includes
 207    :    // checking the command line for the --verbose[=level] flag and handling
 208    :    // it appropriately.
 209    :    bool InitializeLogging();
 210    :  
 211    :    // The command line for this application. The referred instance must outlive
 212    :    // the application instance.
 213    :    const CommandLine* command_line_;
 214    :  
 215    :    // The implementation instance for this application. Execution will be
 216    :    // delegated to this object.
 217    :    Implementation implementation_;
 218    :  
 219    :   private:
 220    :    DISALLOW_COPY_AND_ASSIGN(Application);
 221    :  };
 222    :  
 223    :  // A helper class for timing an activity within a scope.
 224    :  class ScopedTimeLogger {
 225    :   public:
 226  E :    explicit ScopedTimeLogger(const char* label)
 227    :        : label_(label), start_(base::Time::Now()) {
 228  E :      DCHECK(label != NULL);
 229  E :      LOG(INFO) << label_ << ".";
 230  E :    }
 231    :  
 232  E :    ~ScopedTimeLogger() {
 233  E :      base::TimeDelta duration = base::Time::Now() - start_;
 234  E :      LOG(INFO) << label_ << " took " << duration.InSecondsF() << " seconds.";
 235  E :    }
 236    :  
 237    :   private:
 238    :    // A labeling phrase for the activity being timed.
 239    :    const char* const label_;
 240    :  
 241    :    // The time at which the activity began.
 242    :    const base::Time start_;
 243    :  };
 244    :  
 245    :  }  // namespace common
 246    :  
 247    :  #include "syzygy/common/application_impl.h"
 248    :  
 249    :  #endif  // SYZYGY_COMMON_APPLICATION_H_

Coverage information generated Thu Sep 06 11:30:46 2012.