Home | History | Annotate | Download | only in util
      1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      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 
     16 #ifndef TENSORFLOW_CORE_UTIL_COMMAND_LINE_FLAGS_H
     17 #define TENSORFLOW_CORE_UTIL_COMMAND_LINE_FLAGS_H
     18 
     19 #include <functional>
     20 #include <string>
     21 #include <vector>
     22 #include "tensorflow/core/platform/types.h"
     23 
     24 namespace tensorflow {
     25 
     26 // N.B. This library is for INTERNAL use only.
     27 //
     28 // This is a simple command-line argument parsing module to help us handle
     29 // parameters for C++ binaries. The recommended way of using it is with local
     30 // variables and an initializer list of Flag objects, for example:
     31 //
     32 // int some_int = 10;
     33 // bool some_switch = false;
     34 // string some_name = "something";
     35 // std::vector<tensorFlow::Flag> flag_list = {
     36 //   Flag("some_int", &some_int, "an integer that affects X"),
     37 //   Flag("some_switch", &some_switch, "a bool that affects Y"),
     38 //   Flag("some_name", &some_name, "a string that affects Z")
     39 // };
     40 // // Get usage message before ParseFlags() to capture default values.
     41 // string usage = Flag::Usage(argv[0], flag_list);
     42 // bool parsed_values_ok = Flags::Parse(&argc, argv, flag_list);
     43 //
     44 // tensorflow::port::InitMain(usage.c_str(), &argc, &argv);
     45 // if (argc != 1 || !parsed_values_ok) {
     46 //    ...output usage and error message...
     47 // }
     48 //
     49 // The argc and argv values are adjusted by the Parse function so all that
     50 // remains is the program name (at argv[0]) and any unknown arguments fill the
     51 // rest of the array. This means you can check for flags that weren't understood
     52 // by seeing if argv is greater than 1.
     53 // The result indicates if there were any errors parsing the values that were
     54 // passed to the command-line switches. For example, --some_int=foo would return
     55 // false because the argument is expected to be an integer.
     56 //
     57 // NOTE: Unlike gflags-style libraries, this library is intended to be
     58 // used in the `main()` function of your binary. It does not handle
     59 // flag definitions that are scattered around the source code.
     60 
     61 // A description of a single command line flag, holding its name, type, usage
     62 // text, and a pointer to the corresponding variable.
     63 class Flag {
     64  public:
     65   Flag(const char* name, int32* dst, const string& usage_text);
     66   Flag(const char* name, int64* dst, const string& usage_text);
     67   Flag(const char* name, bool* dst, const string& usage_text);
     68   Flag(const char* name, string* dst, const string& usage_text);
     69   Flag(const char* name, float* dst, const string& usage_text);
     70 
     71   // These constructors invoke a hook on a match instead of writing to a
     72   // specific memory location.  The hook may return false to signal a malformed
     73   // or illegal value, which will then fail the command line parse.
     74   //
     75   // "default_value_for_display" is shown as the default value of this flag in
     76   // Flags::Usage().
     77   Flag(const char* name, std::function<bool(int32)> int32_hook,
     78        int32 default_value_for_display, const string& usage_text);
     79   Flag(const char* name, std::function<bool(int64)> int64_hook,
     80        int64 default_value_for_display, const string& usage_text);
     81   Flag(const char* name, std::function<bool(float)> float_hook,
     82        float default_value_for_display, const string& usage_text);
     83   Flag(const char* name, std::function<bool(bool)> bool_hook,
     84        bool default_value_for_display, const string& usage_text);
     85   Flag(const char* name, std::function<bool(string)> string_hook,
     86        string default_value_for_display, const string& usage_text);
     87 
     88  private:
     89   friend class Flags;
     90 
     91   bool Parse(string arg, bool* value_parsing_ok) const;
     92 
     93   string name_;
     94   enum {
     95     TYPE_INT32,
     96     TYPE_INT64,
     97     TYPE_BOOL,
     98     TYPE_STRING,
     99     TYPE_FLOAT,
    100   } type_;
    101 
    102   std::function<bool(int32)> int32_hook_;
    103   int32 int32_default_for_display_;
    104 
    105   std::function<bool(int64)> int64_hook_;
    106   int64 int64_default_for_display_;
    107 
    108   std::function<bool(float)> float_hook_;
    109   float float_default_for_display_;
    110 
    111   std::function<bool(bool)> bool_hook_;
    112   bool bool_default_for_display_;
    113 
    114   std::function<bool(string)> string_hook_;
    115   string string_default_for_display_;
    116 
    117   string usage_text_;
    118 };
    119 
    120 class Flags {
    121  public:
    122   // Parse the command line represented by argv[0, ..., (*argc)-1] to find flag
    123   // instances matching flags in flaglist[].  Update the variables associated
    124   // with matching flags, and remove the matching arguments from (*argc, argv).
    125   // Return true iff all recognized flag values were parsed correctly, and the
    126   // first remaining argument is not "--help".
    127   static bool Parse(int* argc, char** argv, const std::vector<Flag>& flag_list);
    128 
    129   // Return a usage message with command line cmdline, and the
    130   // usage_text strings in flag_list[].
    131   static string Usage(const string& cmdline,
    132                       const std::vector<Flag>& flag_list);
    133 };
    134 
    135 }  // namespace tensorflow
    136 
    137 #endif  // TENSORFLOW_CORE_UTIL_COMMAND_LINE_FLAGS_H
    138