* Reduce .o size by decomposing switches (jyrki)
	* Document how to change the default flag value (csilvers)
	* Add a windows-specific README (csilvers)
	* A few comment updates (wojtekm)


git-svn-id: https://gflags.googlecode.com/svn/trunk@39 6586e3c6-dcc4-952a-343f-ff74eb82781d
diff --git a/Makefile.am b/Makefile.am
index 01e3431..16002d9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,7 @@
 ## Add your documentation files (in doc/) in addition to these
 ## top-level boilerplate files.  Also add a TODO file if you have one.
 dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
-	doc/designstyle.css doc/gflags.html
+	README_windows.txt doc/designstyle.css doc/gflags.html
 
 ## The libraries (.so's) you want to install
 lib_LTLIBRARIES =
diff --git a/Makefile.in b/Makefile.in
index b0390d2..3eaf258 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -307,7 +307,7 @@
 googleinclude_HEADERS = src/google/gflags.h src/google/gflags_completions.h
 bin_SCRIPTS = src/gflags_completions.sh
 dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
-	doc/designstyle.css doc/gflags.html
+	README_windows.txt doc/designstyle.css doc/gflags.html
 
 lib_LTLIBRARIES = libgflags.la libgflags_nothreads.la
 WINDOWS_PROJECTS = google-gflags.sln \
diff --git a/README b/README
index b49fac9..7422982 100644
--- a/README
+++ b/README
@@ -6,5 +6,4 @@
 See INSTALL for (generic) installation instructions for C++: basically
    ./configure && make && make install
 
-You can also compile this under Windows, if you want.  The solution
-file (for VC 7.1 and later) is in this directory.
+See README_windows.txt for instructions on using under windows.
diff --git a/README_windows.txt b/README_windows.txt
new file mode 100644
index 0000000..33f839b
--- /dev/null
+++ b/README_windows.txt
@@ -0,0 +1,20 @@
+You can compile this under Windows, if you want.  The solution file
+(for VC 7.1 and later) is in this directory.
+
+I've been told the following steps work to compile this under win64:
+   1) Open the provided solution file
+   2) Click on the Win32 target (on the right of Debug/Release)
+   3) Choose Configuration Manager
+   4) In Active Solution Platforms, choose New...
+   5) In "Type of select the new platform", choose x64.
+      In "Copy settings from:" choose Win32.
+   6) Ok and then Close
+
+I don't know very much about how to install DLLs on Windows, so you'll
+have to figure out that part for yourself.  If you choose to just
+re-use the existing .sln, make sure you set the IncludeDir's
+appropriately!  Look at the properties for libgflags.dll.
+
+You can also link gflags code in statically.  For this to work, you'll
+need to add "/D GFLAGS_DLL_DECL=" to the compile line of every
+gflags .cc file.
diff --git a/doc/gflags.html b/doc/gflags.html
index cf0c4b3..fe202d1 100644
--- a/doc/gflags.html
+++ b/doc/gflags.html
@@ -47,6 +47,7 @@
   <dd> <a href="#together">Putting It Together: How to Set Up Flags</a> </dd>
   <dd> <a href="#commandline">Setting Flags on the Command Line</a> </dd>
   <dd> <a href="#varz">Setting Flags at Runtime</a> </dd>
+  <dd> <a href="#default">Changing the Default Flag Value</a> </dd>
   <dd> <a href="#special">Special Flags</a> </dd>
   <dd> <a href="#api">The API</a> </dd>
   <dd> <br/> </dd>
@@ -348,6 +349,26 @@
 single dash, as in <code>ls -la</code>.</p>
 
 
+
+<h2> <A name=default>Changing the Default Flag Value</A> </h2>
+
+<p>Sometimes a flag is defined in a library, and you want to change
+its default value in one application but not others.  It's simple to
+do this: just assign a new value to the flag in <code>main()</code>,
+before calling <code>ParseCommandLineFlags()</code>:</p>
+<pre>
+   DECLARE_bool(lib_verbose);   // mylib has a lib_verbose flag, default is false
+   int main(int argc, char** argv) {
+     FLAGS_lib_verbose = true;  // in my app, I want a verbose lib by default
+     ParseCommandLineFlags(...);
+   }
+</pre>
+
+<p>For this application, users can still set the flag value on the
+commandline, but if they do not, the flag's value will default to
+true.</p>
+
+
 <h2> <A name="special">Special Flags</code> </h2>
 
 <p>There are a few flags defined by the commandlineflags module
diff --git a/src/gflags.cc b/src/gflags.cc
index d233e50..01067a4 100644
--- a/src/gflags.cc
+++ b/src/gflags.cc
@@ -143,6 +143,8 @@
 # define PRIu64 "llu"
 #endif
 
+typedef unsigned char uint8;
+
 // Special flags, type 1: the 'recursive' flags.  They set another flag's val.
 DEFINE_string(flagfile, "",
               "load flags from file");
@@ -235,8 +237,15 @@
   friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
                              const char*, string*);  // for New(), CopyFrom()
 
-  enum ValueType {FV_BOOL, FV_INT32, FV_INT64, FV_UINT64, FV_DOUBLE, FV_STRING};
-
+  enum ValueType {
+    FV_BOOL = 0,
+    FV_INT32 = 1,
+    FV_INT64 = 2,
+    FV_UINT64 = 3,
+    FV_DOUBLE = 4,
+    FV_STRING = 5,
+    FV_MAX_INDEX = 5,
+  };
   const char* TypeName() const;
   bool Equal(const FlagValue& x) const;
   FlagValue* New() const;   // creates a new one with default value
@@ -249,9 +258,8 @@
   // (*validate_fn)(bool) for a bool flag).
   bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const;
 
-
   void* value_buffer_;          // points to the buffer holding our data
-  ValueType type_;              // how to interpret value_
+  uint32 type_;                  // how to interpret value_
 
   FlagValue(const FlagValue&);   // no copying!
   void operator=(const FlagValue&);
@@ -265,13 +273,12 @@
 #define SET_VALUE_AS(type, value)  VALUE_AS(type) = (value)
 
 FlagValue::FlagValue(void* valbuf, const char* type) : value_buffer_(valbuf) {
-  if      (strcmp(type, "bool") == 0)  type_ = FV_BOOL;
-  else if (strcmp(type, "int32") == 0)  type_ = FV_INT32;
-  else if (strcmp(type, "int64") == 0)  type_ = FV_INT64;
-  else if (strcmp(type, "uint64") == 0)  type_ = FV_UINT64;
-  else if (strcmp(type, "double") == 0)  type_ = FV_DOUBLE;
-  else if (strcmp(type, "string") == 0)  type_ = FV_STRING;
-  else assert(false); // Unknown typename
+  for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) {
+    if (!strcmp(type, TypeName())) {
+      break;
+    }
+  }
+  assert(type_ <= FV_MAX_INDEX);  // Unknown typename
 }
 
 FlagValue::~FlagValue() {
@@ -405,15 +412,20 @@
 }
 
 const char* FlagValue::TypeName() const {
-  switch (type_) {
-    case FV_BOOL:   return "bool";
-    case FV_INT32:  return "int32";
-    case FV_INT64:  return "int64";
-    case FV_UINT64: return "uint64";
-    case FV_DOUBLE: return "double";
-    case FV_STRING: return "string";
-    default: assert(false); return "";  // unknown type
+  static const char types[] =
+      "bool\0xx"
+      "int32\0x"
+      "int64\0x"
+      "uint64\0"
+      "double\0"
+      "string";
+  if (type_ > FV_MAX_INDEX) {
+    assert(false);
+    return "";
   }
+  // Directly indexing the strigns in the 'types' string, each of them
+  // is 7 bytes long.
+  return &types[type_ * 7];
 }
 
 bool FlagValue::Equal(const FlagValue& x) const {
@@ -431,13 +443,14 @@
 }
 
 FlagValue* FlagValue::New() const {
+  const char *type = TypeName();
   switch (type_) {
-    case FV_BOOL:   return new FlagValue(new bool(false), "bool");
-    case FV_INT32:  return new FlagValue(new int32(0), "int32");
-    case FV_INT64:  return new FlagValue(new int64(0), "int64");
-    case FV_UINT64: return new FlagValue(new uint64(0), "uint64");
-    case FV_DOUBLE: return new FlagValue(new double(0.0), "double");
-    case FV_STRING: return new FlagValue(new string, "string");
+    case FV_BOOL:   return new FlagValue(new bool(false), type);
+    case FV_INT32:  return new FlagValue(new int32(0), type);
+    case FV_INT64:  return new FlagValue(new int64(0), type);
+    case FV_UINT64: return new FlagValue(new uint64(0), type);
+    case FV_DOUBLE: return new FlagValue(new double(0.0), type);
+    case FV_STRING: return new FlagValue(new string, type);
     default: assert(false); return NULL;  // unknown type
   }
 }
@@ -456,15 +469,19 @@
 }
 
 int FlagValue::ValueSize() const {
-  switch (type_) {
-    case FV_BOOL:   return sizeof(bool);
-    case FV_INT32:  return sizeof(int32);
-    case FV_INT64:  return sizeof(int64);
-    case FV_UINT64: return sizeof(uint64);
-    case FV_DOUBLE: return sizeof(double);
-    case FV_STRING: return sizeof(string);
-    default: assert(false); return 0; // unknown type
+  if (type_ > FV_MAX_INDEX) {
+    assert(false);  // unknown type
+    return 0;
   }
+  static const uint8 valuesize[] = {
+    sizeof(bool),
+    sizeof(int32),
+    sizeof(int64),
+    sizeof(uint64),
+    sizeof(double),
+    sizeof(string),
+  };
+  return valuesize[type_];
 }
 
 // --------------------------------------------------------------------
diff --git a/src/gflags/gflags.h.in b/src/gflags/gflags.h.in
index 2d38071..889c3fa 100644
--- a/src/gflags/gflags.h.in
+++ b/src/gflags/gflags.h.in
@@ -124,7 +124,8 @@
 // DEFINE_string, etc. at the bottom of this file.  You may also find
 // it useful to register a validator with the flag.  This ensures that
 // when the flag is parsed from the commandline, or is later set via
-// SetCommandLineOption, we call the validation function.
+// SetCommandLineOption, we call the validation function. It is _not_
+// called when you assign the value to the flag directly using the = operator.
 //
 // The validation function should return true if the flag value is valid, and
 // false otherwise. If the function returns false for the new setting of the
@@ -180,7 +181,9 @@
   std::string default_value;  // the default value, as a string
   std::string filename;       // 'cleaned' version of filename holding the flag
   bool has_validator_fn;      // true if RegisterFlagValidator called on flag
-  bool is_default;            // true if the flag has default value
+  bool is_default;            // true if the flag has the default value and
+                              // has not been set explicitly from the cmdline
+                              // or via SetCommandLineOption
 };
 
 // Using this inside of a validator is a recipe for a deadlock.
diff --git a/src/windows/gflags/gflags.h b/src/windows/gflags/gflags.h
index 38bc3c3..191c6e3 100644
--- a/src/windows/gflags/gflags.h
+++ b/src/windows/gflags/gflags.h
@@ -99,12 +99,26 @@
 #endif
 
 // Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef GFLAGS_DLL_DECL
-# ifdef _WIN32
+#if defined(_WIN32)
+# ifndef GFLAGS_DLL_DECL
 #   define GFLAGS_DLL_DECL  __declspec(dllimport)
-# else
+# endif
+# ifndef GFLAGS_DLL_DECLARE_FLAG
+#   define GFLAGS_DLL_DECLARE_FLAG  __declspec(import)
+# endif
+# ifndef GFLAGS_DLL_DEFINE_FLAG
+#   define GFLAGS_DLL_DEFINE_FLAG   __declspec(dllexport)
+# endif
+#else
+# ifndef GFLAGS_DLL_DECL
 #   define GFLAGS_DLL_DECL
 # endif
+# ifndef GFLAGS_DLL_DECLARE_FLAG
+#   define GFLAGS_DLL_DECLARE_FLAG
+# endif
+# ifndef GFLAGS_DLL_DEFINE_FLAG
+#   define GFLAGS_DLL_DEFINE_FLAG
+# endif
 #endif
 
 namespace google {
@@ -133,7 +147,8 @@
 // DEFINE_string, etc. at the bottom of this file.  You may also find
 // it useful to register a validator with the flag.  This ensures that
 // when the flag is parsed from the commandline, or is later set via
-// SetCommandLineOption, we call the validation function.
+// SetCommandLineOption, we call the validation function. It is _not_
+// called when you assign the value to the flag directly using the = operator.
 //
 // The validation function should return true if the flag value is valid, and
 // false otherwise. If the function returns false for the new setting of the
@@ -189,7 +204,9 @@
   std::string default_value;  // the default value, as a string
   std::string filename;       // 'cleaned' version of filename holding the flag
   bool has_validator_fn;      // true if RegisterFlagValidator called on flag
-  bool is_default;            // true if the flag has default value
+  bool is_default;            // true if the flag has the default value and
+                              // has not been set explicitly from the cmdline
+                              // or via SetCommandLineOption
 };
 
 // Using this inside of a validator is a recipe for a deadlock.
@@ -471,7 +488,7 @@
   namespace fL##shorttype {                                     \
     static const type FLAGS_nono##name = value;                 \
     /* We always want to export defined variables, dll or no */ \
-    __declspec(dllexport) type FLAGS_##name = FLAGS_nono##name; \
+    GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
     type FLAGS_no##name = FLAGS_nono##name;                     \
     static ::google::FlagRegisterer o_##name(                   \
       #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__,        \
@@ -482,7 +499,7 @@
 #define DECLARE_VARIABLE(type, shorttype, name) \
   namespace fL##shorttype {                     \
     /* We always want to import declared variables, dll or no */ \
-    extern __declspec(dllimport) type FLAGS_##name; \
+    extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; \
   }                                             \
   using fL##shorttype::FLAGS_##name
 
@@ -528,7 +545,7 @@
 // try to avoid crashes in that case, we use a char buffer to store
 // the string, which we can static-initialize, and then placement-new
 // into it later.  It's not perfect, but the best we can do.
-#define DECLARE_string(name)  namespace fLS { extern __declspec(dllimport) std::string& FLAGS_##name; } \
+#define DECLARE_string(name)  namespace fLS { extern GFLAGS_DLL_DECLARE_FLAG std::string& FLAGS_##name; } \
                               using fLS::FLAGS_##name
 
 // We need to define a var named FLAGS_no##name so people don't define
@@ -545,7 +562,7 @@
     static ::google::FlagRegisterer o_##name(                                 \
       #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__,                    \
       s_##name[0].s, new (s_##name[1].s) std::string(*FLAGS_no##name));       \
-    extern __declspec(dllexport) std::string& FLAGS_##name;                   \
+    extern GFLAGS_DLL_DEFINE_FLAG std::string& FLAGS_##name;                  \
     using fLS::FLAGS_##name;                                                  \
     std::string& FLAGS_##name = *FLAGS_no##name;                              \
   }                                                                           \