LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/base - flags.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 131 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright 2006 The WebRTC Project Authors. All rights reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/base/flags.h"
      12             : 
      13             : #include <stdio.h>
      14             : #include <stdlib.h>
      15             : #include <string.h>
      16             : 
      17             : #include "webrtc/base/checks.h"
      18             : 
      19             : #if defined(WEBRTC_WIN)
      20             : #include "webrtc/base/win32.h"
      21             : #include <shellapi.h>
      22             : #endif
      23             : 
      24             : namespace rtc {
      25             : // -----------------------------------------------------------------------------
      26             : // Implementation of Flag
      27             : 
      28           0 : Flag::Flag(const char* file, const char* name, const char* comment,
      29           0 :            Type type, void* variable, FlagValue default__)
      30             :     : file_(file),
      31             :       name_(name),
      32             :       comment_(comment),
      33             :       type_(type),
      34             :       variable_(reinterpret_cast<FlagValue*>(variable)),
      35           0 :       default_(default__) {
      36           0 :   FlagList::Register(this);
      37           0 : }
      38             : 
      39             : 
      40           0 : void Flag::SetToDefault() {
      41             :   // Note that we cannot simply do '*variable_ = default_;' since
      42             :   // flag variables are not really of type FlagValue and thus may
      43             :   // be smaller! The FlagValue union is simply 'overlayed' on top
      44             :   // of a flag variable for convenient access. Since union members
      45             :   // are guarantee to be aligned at the beginning, this works.
      46           0 :   switch (type_) {
      47             :     case Flag::BOOL:
      48           0 :       variable_->b = default_.b;
      49           0 :       return;
      50             :     case Flag::INT:
      51           0 :       variable_->i = default_.i;
      52           0 :       return;
      53             :     case Flag::FLOAT:
      54           0 :       variable_->f = default_.f;
      55           0 :       return;
      56             :     case Flag::STRING:
      57           0 :       variable_->s = default_.s;
      58           0 :       return;
      59             :   }
      60           0 :   FATAL() << "unreachable code";
      61             : }
      62             : 
      63             : 
      64           0 : static const char* Type2String(Flag::Type type) {
      65           0 :   switch (type) {
      66           0 :     case Flag::BOOL: return "bool";
      67           0 :     case Flag::INT: return "int";
      68           0 :     case Flag::FLOAT: return "float";
      69           0 :     case Flag::STRING: return "string";
      70             :   }
      71           0 :   FATAL() << "unreachable code";
      72             : }
      73             : 
      74             : 
      75           0 : static void PrintFlagValue(Flag::Type type, FlagValue* p) {
      76           0 :   switch (type) {
      77             :     case Flag::BOOL:
      78           0 :       printf("%s", (p->b ? "true" : "false"));
      79           0 :       return;
      80             :     case Flag::INT:
      81           0 :       printf("%d", p->i);
      82           0 :       return;
      83             :     case Flag::FLOAT:
      84           0 :       printf("%f", p->f);
      85           0 :       return;
      86             :     case Flag::STRING:
      87           0 :       printf("%s", p->s);
      88           0 :       return;
      89             :   }
      90           0 :   FATAL() << "unreachable code";
      91             : }
      92             : 
      93             : 
      94           0 : void Flag::Print(bool print_current_value) {
      95           0 :   printf("  --%s (%s)  type: %s  default: ", name_, comment_,
      96           0 :           Type2String(type_));
      97           0 :   PrintFlagValue(type_, &default_);
      98           0 :   if (print_current_value) {
      99           0 :     printf("  current value: ");
     100           0 :     PrintFlagValue(type_, variable_);
     101             :   }
     102           0 :   printf("\n");
     103           0 : }
     104             : 
     105             : 
     106             : // -----------------------------------------------------------------------------
     107             : // Implementation of FlagList
     108             : 
     109             : Flag* FlagList::list_ = NULL;
     110             : 
     111             : 
     112           0 : FlagList::FlagList() {
     113           0 :   list_ = NULL;
     114           0 : }
     115             : 
     116           0 : void FlagList::Print(const char* file, bool print_current_value) {
     117             :   // Since flag registration is likely by file (= C++ file),
     118             :   // we don't need to sort by file and still get grouped output.
     119           0 :   const char* current = NULL;
     120           0 :   for (Flag* f = list_; f != NULL; f = f->next()) {
     121           0 :     if (file == NULL || file == f->file()) {
     122           0 :       if (current != f->file()) {
     123           0 :         printf("Flags from %s:\n", f->file());
     124           0 :         current = f->file();
     125             :       }
     126           0 :       f->Print(print_current_value);
     127             :     }
     128             :   }
     129           0 : }
     130             : 
     131             : 
     132           0 : Flag* FlagList::Lookup(const char* name) {
     133           0 :   Flag* f = list_;
     134           0 :   while (f != NULL && strcmp(name, f->name()) != 0)
     135           0 :     f = f->next();
     136           0 :   return f;
     137             : }
     138             : 
     139             : 
     140           0 : void FlagList::SplitArgument(const char* arg,
     141             :                              char* buffer, int buffer_size,
     142             :                              const char** name, const char** value,
     143             :                              bool* is_bool) {
     144           0 :   *name = NULL;
     145           0 :   *value = NULL;
     146           0 :   *is_bool = false;
     147             : 
     148           0 :   if (*arg == '-') {
     149             :     // find the begin of the flag name
     150           0 :     arg++;  // remove 1st '-'
     151           0 :     if (*arg == '-')
     152           0 :       arg++;  // remove 2nd '-'
     153           0 :     if (arg[0] == 'n' && arg[1] == 'o') {
     154           0 :       arg += 2;  // remove "no"
     155           0 :       *is_bool = true;
     156             :     }
     157           0 :     *name = arg;
     158             : 
     159             :     // find the end of the flag name
     160           0 :     while (*arg != '\0' && *arg != '=')
     161           0 :       arg++;
     162             : 
     163             :     // get the value if any
     164           0 :     if (*arg == '=') {
     165             :       // make a copy so we can NUL-terminate flag name
     166           0 :       int n = static_cast<int>(arg - *name);
     167           0 :       RTC_CHECK_LT(n, buffer_size);
     168           0 :       memcpy(buffer, *name, n * sizeof(char));
     169           0 :       buffer[n] = '\0';
     170           0 :       *name = buffer;
     171             :       // get the value
     172           0 :       *value = arg + 1;
     173             :     }
     174             :   }
     175           0 : }
     176             : 
     177             : 
     178           0 : int FlagList::SetFlagsFromCommandLine(int* argc, const char** argv,
     179             :                                       bool remove_flags) {
     180             :   // parse arguments
     181           0 :   for (int i = 1; i < *argc; /* see below */) {
     182           0 :     int j = i;  // j > 0
     183           0 :     const char* arg = argv[i++];
     184             : 
     185             :     // split arg into flag components
     186             :     char buffer[1024];
     187             :     const char* name;
     188             :     const char* value;
     189             :     bool is_bool;
     190           0 :     SplitArgument(arg, buffer, sizeof buffer, &name, &value, &is_bool);
     191             : 
     192           0 :     if (name != NULL) {
     193             :       // lookup the flag
     194           0 :       Flag* flag = Lookup(name);
     195           0 :       if (flag == NULL) {
     196           0 :         fprintf(stderr, "Error: unrecognized flag %s\n", arg);
     197           0 :         return j;
     198             :       }
     199             : 
     200             :       // if we still need a flag value, use the next argument if available
     201           0 :       if (flag->type() != Flag::BOOL && value == NULL) {
     202           0 :         if (i < *argc) {
     203           0 :           value = argv[i++];
     204             :         } else {
     205           0 :           fprintf(stderr, "Error: missing value for flag %s of type %s\n",
     206           0 :             arg, Type2String(flag->type()));
     207           0 :           return j;
     208             :         }
     209             :       }
     210             : 
     211             :       // set the flag
     212           0 :       char empty[] = { '\0' };
     213           0 :       char* endp = empty;
     214           0 :       switch (flag->type()) {
     215             :         case Flag::BOOL:
     216           0 :           *flag->bool_variable() = !is_bool;
     217           0 :           break;
     218             :         case Flag::INT:
     219           0 :           *flag->int_variable() = strtol(value, &endp, 10);
     220           0 :           break;
     221             :         case Flag::FLOAT:
     222           0 :           *flag->float_variable() = strtod(value, &endp);
     223           0 :           break;
     224             :         case Flag::STRING:
     225           0 :           *flag->string_variable() = value;
     226           0 :           break;
     227             :       }
     228             : 
     229             :       // handle errors
     230           0 :       if ((flag->type() == Flag::BOOL && value != NULL) ||
     231           0 :           (flag->type() != Flag::BOOL && is_bool) ||
     232           0 :           *endp != '\0') {
     233           0 :         fprintf(stderr, "Error: illegal value for flag %s of type %s\n",
     234           0 :           arg, Type2String(flag->type()));
     235           0 :         return j;
     236             :       }
     237             : 
     238             :       // remove the flag & value from the command
     239           0 :       if (remove_flags)
     240           0 :         while (j < i)
     241           0 :           argv[j++] = NULL;
     242             :     }
     243             :   }
     244             : 
     245             :   // shrink the argument list
     246           0 :   if (remove_flags) {
     247           0 :     int j = 1;
     248           0 :     for (int i = 1; i < *argc; i++) {
     249           0 :       if (argv[i] != NULL)
     250           0 :         argv[j++] = argv[i];
     251             :     }
     252           0 :     *argc = j;
     253             :   }
     254             : 
     255             :   // parsed all flags successfully
     256           0 :   return 0;
     257             : }
     258             : 
     259           0 : void FlagList::Register(Flag* flag) {
     260           0 :   RTC_DCHECK(flag);
     261           0 :   RTC_DCHECK_GT(strlen(flag->name()), 0);
     262             :   // NOTE: Don't call Lookup() within Register because it accesses the name_
     263             :   // of other flags in list_, and if the flags are coming from two different
     264             :   // compilation units, the initialization order between them is undefined, and
     265             :   // this will trigger an asan initialization-order-fiasco error.
     266           0 :   flag->next_ = list_;
     267           0 :   list_ = flag;
     268           0 : }
     269             : 
     270             : #if defined(WEBRTC_WIN)
     271             : WindowsCommandLineArguments::WindowsCommandLineArguments() {
     272             :   // start by getting the command line.
     273             :   LPTSTR command_line = ::GetCommandLine();
     274             :    // now, convert it to a list of wide char strings.
     275             :   LPWSTR *wide_argv = ::CommandLineToArgvW(command_line, &argc_);
     276             :   // now allocate an array big enough to hold that many string pointers.
     277             :   argv_ = new char*[argc_];
     278             : 
     279             :   // iterate over the returned wide strings;
     280             :   for(int i = 0; i < argc_; ++i) {
     281             :     std::string s = rtc::ToUtf8(wide_argv[i], wcslen(wide_argv[i]));
     282             :     char *buffer = new char[s.length() + 1];
     283             :     rtc::strcpyn(buffer, s.length() + 1, s.c_str());
     284             : 
     285             :     // make sure the argv array has the right string at this point.
     286             :     argv_[i] = buffer;
     287             :   }
     288             :   LocalFree(wide_argv);
     289             : }
     290             : 
     291             : WindowsCommandLineArguments::~WindowsCommandLineArguments() {
     292             :   // need to free each string in the array, and then the array.
     293             :   for(int i = 0; i < argc_; i++) {
     294             :     delete[] argv_[i];
     295             :   }
     296             : 
     297             :   delete[] argv_;
     298             : }
     299             : #endif  // WEBRTC_WIN
     300             : 
     301             : }  // namespace rtc

Generated by: LCOV version 1.13