113481Sgiacomo.travaglini@arm.com// Copyright 2008, Google Inc.
213481Sgiacomo.travaglini@arm.com// All rights reserved.
313481Sgiacomo.travaglini@arm.com//
413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
613481Sgiacomo.travaglini@arm.com// met:
713481Sgiacomo.travaglini@arm.com//
813481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1013481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1313481Sgiacomo.travaglini@arm.com// distribution.
1413481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1713481Sgiacomo.travaglini@arm.com//
1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913481Sgiacomo.travaglini@arm.com//
3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan)
3113481Sgiacomo.travaglini@arm.com
3213481Sgiacomo.travaglini@arm.com#include "gmock/gmock.h"
3313481Sgiacomo.travaglini@arm.com#include "gmock/internal/gmock-port.h"
3413481Sgiacomo.travaglini@arm.com
3513481Sgiacomo.travaglini@arm.comnamespace testing {
3613481Sgiacomo.travaglini@arm.com
3713481Sgiacomo.travaglini@arm.com// TODO(wan@google.com): support using environment variables to
3813481Sgiacomo.travaglini@arm.com// control the flag values, like what Google Test does.
3913481Sgiacomo.travaglini@arm.com
4013481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_bool_(catch_leaked_mocks, true,
4113481Sgiacomo.travaglini@arm.com                   "true iff Google Mock should report leaked mock objects "
4213481Sgiacomo.travaglini@arm.com                   "as failures.");
4313481Sgiacomo.travaglini@arm.com
4413481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
4513481Sgiacomo.travaglini@arm.com                     "Controls how verbose Google Mock's output is."
4613481Sgiacomo.travaglini@arm.com                     "  Valid values:\n"
4713481Sgiacomo.travaglini@arm.com                     "  info    - prints all messages.\n"
4813481Sgiacomo.travaglini@arm.com                     "  warning - prints warnings and errors.\n"
4913481Sgiacomo.travaglini@arm.com                     "  error   - prints errors only.");
5013481Sgiacomo.travaglini@arm.com
5113481Sgiacomo.travaglini@arm.comnamespace internal {
5213481Sgiacomo.travaglini@arm.com
5313481Sgiacomo.travaglini@arm.com// Parses a string as a command line flag.  The string should have the
5413481Sgiacomo.travaglini@arm.com// format "--gmock_flag=value".  When def_optional is true, the
5513481Sgiacomo.travaglini@arm.com// "=value" part can be omitted.
5613481Sgiacomo.travaglini@arm.com//
5713481Sgiacomo.travaglini@arm.com// Returns the value of the flag, or NULL if the parsing failed.
5813481Sgiacomo.travaglini@arm.comstatic const char* ParseGoogleMockFlagValue(const char* str,
5913481Sgiacomo.travaglini@arm.com                                            const char* flag,
6013481Sgiacomo.travaglini@arm.com                                            bool def_optional) {
6113481Sgiacomo.travaglini@arm.com  // str and flag must not be NULL.
6213481Sgiacomo.travaglini@arm.com  if (str == NULL || flag == NULL) return NULL;
6313481Sgiacomo.travaglini@arm.com
6413481Sgiacomo.travaglini@arm.com  // The flag must start with "--gmock_".
6513481Sgiacomo.travaglini@arm.com  const std::string flag_str = std::string("--gmock_") + flag;
6613481Sgiacomo.travaglini@arm.com  const size_t flag_len = flag_str.length();
6713481Sgiacomo.travaglini@arm.com  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
6813481Sgiacomo.travaglini@arm.com
6913481Sgiacomo.travaglini@arm.com  // Skips the flag name.
7013481Sgiacomo.travaglini@arm.com  const char* flag_end = str + flag_len;
7113481Sgiacomo.travaglini@arm.com
7213481Sgiacomo.travaglini@arm.com  // When def_optional is true, it's OK to not have a "=value" part.
7313481Sgiacomo.travaglini@arm.com  if (def_optional && (flag_end[0] == '\0')) {
7413481Sgiacomo.travaglini@arm.com    return flag_end;
7513481Sgiacomo.travaglini@arm.com  }
7613481Sgiacomo.travaglini@arm.com
7713481Sgiacomo.travaglini@arm.com  // If def_optional is true and there are more characters after the
7813481Sgiacomo.travaglini@arm.com  // flag name, or if def_optional is false, there must be a '=' after
7913481Sgiacomo.travaglini@arm.com  // the flag name.
8013481Sgiacomo.travaglini@arm.com  if (flag_end[0] != '=') return NULL;
8113481Sgiacomo.travaglini@arm.com
8213481Sgiacomo.travaglini@arm.com  // Returns the string after "=".
8313481Sgiacomo.travaglini@arm.com  return flag_end + 1;
8413481Sgiacomo.travaglini@arm.com}
8513481Sgiacomo.travaglini@arm.com
8613481Sgiacomo.travaglini@arm.com// Parses a string for a Google Mock bool flag, in the form of
8713481Sgiacomo.travaglini@arm.com// "--gmock_flag=value".
8813481Sgiacomo.travaglini@arm.com//
8913481Sgiacomo.travaglini@arm.com// On success, stores the value of the flag in *value, and returns
9013481Sgiacomo.travaglini@arm.com// true.  On failure, returns false without changing *value.
9113481Sgiacomo.travaglini@arm.comstatic bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
9213481Sgiacomo.travaglini@arm.com                                    bool* value) {
9313481Sgiacomo.travaglini@arm.com  // Gets the value of the flag as a string.
9413481Sgiacomo.travaglini@arm.com  const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
9513481Sgiacomo.travaglini@arm.com
9613481Sgiacomo.travaglini@arm.com  // Aborts if the parsing failed.
9713481Sgiacomo.travaglini@arm.com  if (value_str == NULL) return false;
9813481Sgiacomo.travaglini@arm.com
9913481Sgiacomo.travaglini@arm.com  // Converts the string value to a bool.
10013481Sgiacomo.travaglini@arm.com  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
10113481Sgiacomo.travaglini@arm.com  return true;
10213481Sgiacomo.travaglini@arm.com}
10313481Sgiacomo.travaglini@arm.com
10413481Sgiacomo.travaglini@arm.com// Parses a string for a Google Mock string flag, in the form of
10513481Sgiacomo.travaglini@arm.com// "--gmock_flag=value".
10613481Sgiacomo.travaglini@arm.com//
10713481Sgiacomo.travaglini@arm.com// On success, stores the value of the flag in *value, and returns
10813481Sgiacomo.travaglini@arm.com// true.  On failure, returns false without changing *value.
10913481Sgiacomo.travaglini@arm.comtemplate <typename String>
11013481Sgiacomo.travaglini@arm.comstatic bool ParseGoogleMockStringFlag(const char* str, const char* flag,
11113481Sgiacomo.travaglini@arm.com                                      String* value) {
11213481Sgiacomo.travaglini@arm.com  // Gets the value of the flag as a string.
11313481Sgiacomo.travaglini@arm.com  const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
11413481Sgiacomo.travaglini@arm.com
11513481Sgiacomo.travaglini@arm.com  // Aborts if the parsing failed.
11613481Sgiacomo.travaglini@arm.com  if (value_str == NULL) return false;
11713481Sgiacomo.travaglini@arm.com
11813481Sgiacomo.travaglini@arm.com  // Sets *value to the value of the flag.
11913481Sgiacomo.travaglini@arm.com  *value = value_str;
12013481Sgiacomo.travaglini@arm.com  return true;
12113481Sgiacomo.travaglini@arm.com}
12213481Sgiacomo.travaglini@arm.com
12313481Sgiacomo.travaglini@arm.com// The internal implementation of InitGoogleMock().
12413481Sgiacomo.travaglini@arm.com//
12513481Sgiacomo.travaglini@arm.com// The type parameter CharType can be instantiated to either char or
12613481Sgiacomo.travaglini@arm.com// wchar_t.
12713481Sgiacomo.travaglini@arm.comtemplate <typename CharType>
12813481Sgiacomo.travaglini@arm.comvoid InitGoogleMockImpl(int* argc, CharType** argv) {
12913481Sgiacomo.travaglini@arm.com  // Makes sure Google Test is initialized.  InitGoogleTest() is
13013481Sgiacomo.travaglini@arm.com  // idempotent, so it's fine if the user has already called it.
13113481Sgiacomo.travaglini@arm.com  InitGoogleTest(argc, argv);
13213481Sgiacomo.travaglini@arm.com  if (*argc <= 0) return;
13313481Sgiacomo.travaglini@arm.com
13413481Sgiacomo.travaglini@arm.com  for (int i = 1; i != *argc; i++) {
13513481Sgiacomo.travaglini@arm.com    const std::string arg_string = StreamableToString(argv[i]);
13613481Sgiacomo.travaglini@arm.com    const char* const arg = arg_string.c_str();
13713481Sgiacomo.travaglini@arm.com
13813481Sgiacomo.travaglini@arm.com    // Do we see a Google Mock flag?
13913481Sgiacomo.travaglini@arm.com    if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
14013481Sgiacomo.travaglini@arm.com                                &GMOCK_FLAG(catch_leaked_mocks)) ||
14113481Sgiacomo.travaglini@arm.com        ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
14213481Sgiacomo.travaglini@arm.com      // Yes.  Shift the remainder of the argv list left by one.  Note
14313481Sgiacomo.travaglini@arm.com      // that argv has (*argc + 1) elements, the last one always being
14413481Sgiacomo.travaglini@arm.com      // NULL.  The following loop moves the trailing NULL element as
14513481Sgiacomo.travaglini@arm.com      // well.
14613481Sgiacomo.travaglini@arm.com      for (int j = i; j != *argc; j++) {
14713481Sgiacomo.travaglini@arm.com        argv[j] = argv[j + 1];
14813481Sgiacomo.travaglini@arm.com      }
14913481Sgiacomo.travaglini@arm.com
15013481Sgiacomo.travaglini@arm.com      // Decrements the argument count.
15113481Sgiacomo.travaglini@arm.com      (*argc)--;
15213481Sgiacomo.travaglini@arm.com
15313481Sgiacomo.travaglini@arm.com      // We also need to decrement the iterator as we just removed
15413481Sgiacomo.travaglini@arm.com      // an element.
15513481Sgiacomo.travaglini@arm.com      i--;
15613481Sgiacomo.travaglini@arm.com    }
15713481Sgiacomo.travaglini@arm.com  }
15813481Sgiacomo.travaglini@arm.com}
15913481Sgiacomo.travaglini@arm.com
16013481Sgiacomo.travaglini@arm.com}  // namespace internal
16113481Sgiacomo.travaglini@arm.com
16213481Sgiacomo.travaglini@arm.com// Initializes Google Mock.  This must be called before running the
16313481Sgiacomo.travaglini@arm.com// tests.  In particular, it parses a command line for the flags that
16413481Sgiacomo.travaglini@arm.com// Google Mock recognizes.  Whenever a Google Mock flag is seen, it is
16513481Sgiacomo.travaglini@arm.com// removed from argv, and *argc is decremented.
16613481Sgiacomo.travaglini@arm.com//
16713481Sgiacomo.travaglini@arm.com// No value is returned.  Instead, the Google Mock flag variables are
16813481Sgiacomo.travaglini@arm.com// updated.
16913481Sgiacomo.travaglini@arm.com//
17013481Sgiacomo.travaglini@arm.com// Since Google Test is needed for Google Mock to work, this function
17113481Sgiacomo.travaglini@arm.com// also initializes Google Test and parses its flags, if that hasn't
17213481Sgiacomo.travaglini@arm.com// been done.
17313481Sgiacomo.travaglini@arm.comGTEST_API_ void InitGoogleMock(int* argc, char** argv) {
17413481Sgiacomo.travaglini@arm.com  internal::InitGoogleMockImpl(argc, argv);
17513481Sgiacomo.travaglini@arm.com}
17613481Sgiacomo.travaglini@arm.com
17713481Sgiacomo.travaglini@arm.com// This overloaded version can be used in Windows programs compiled in
17813481Sgiacomo.travaglini@arm.com// UNICODE mode.
17913481Sgiacomo.travaglini@arm.comGTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
18013481Sgiacomo.travaglini@arm.com  internal::InitGoogleMockImpl(argc, argv);
18113481Sgiacomo.travaglini@arm.com}
18213481Sgiacomo.travaglini@arm.com
18313481Sgiacomo.travaglini@arm.com}  // namespace testing
184