The getopt library has a structure called option (lowercase). We have a structure called Option (uppercase). previously the two structures had exactly the same definitions, and we were doing a C-style cast of an Option* to an option*. C-style casts don't bother to warn you when you cast to unrelated types, but in the original OptionValidator patch I modified the definition of Option. This patch fixes the errors by building an array of option structures and filling it out the correct way before passing it to the getopt library. This also fixes one other source of test failures: an uninitialized read that occurs due to not initializing a field of the OptionDefinition. Reviewed By: Todd Fiala Differential Revision: http://reviews.llvm.org/D4425 llvm-svn: 212628
115 lines
2.5 KiB
C++
115 lines
2.5 KiB
C++
//===-- source/Host/common/OptionParser.cpp ---------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Host/OptionParser.h"
|
|
#include "lldb/Host/HostGetOpt.h"
|
|
#include "lldb/lldb-private-types.h"
|
|
|
|
#include <vector>
|
|
|
|
using namespace lldb_private;
|
|
|
|
void
|
|
OptionParser::Prepare()
|
|
{
|
|
#ifdef __GLIBC__
|
|
optind = 0;
|
|
#else
|
|
optreset = 1;
|
|
optind = 1;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
OptionParser::EnableError(bool error)
|
|
{
|
|
opterr = error ? 1 : 0;
|
|
}
|
|
|
|
int
|
|
OptionParser::Parse (int argc,
|
|
char * const argv [],
|
|
const char *optstring,
|
|
const Option *longopts,
|
|
int *longindex)
|
|
{
|
|
std::vector<option> opts;
|
|
while (longopts->definition != nullptr)
|
|
{
|
|
option opt;
|
|
opt.flag = longopts->flag;
|
|
opt.val = longopts->val;
|
|
opt.name = longopts->definition->long_option;
|
|
opt.has_arg = longopts->definition->option_has_arg;
|
|
opts.push_back(opt);
|
|
++longopts;
|
|
}
|
|
opts.push_back(option());
|
|
return getopt_long_only(argc, argv, optstring, &opts[0], longindex);
|
|
}
|
|
|
|
char*
|
|
OptionParser::GetOptionArgument()
|
|
{
|
|
return optarg;
|
|
}
|
|
|
|
int
|
|
OptionParser::GetOptionIndex()
|
|
{
|
|
return optind;
|
|
}
|
|
|
|
int
|
|
OptionParser::GetOptionErrorCause()
|
|
{
|
|
return optopt;
|
|
}
|
|
|
|
std::string
|
|
OptionParser::GetShortOptionString(struct option *long_options)
|
|
{
|
|
std::string s;
|
|
int i=0;
|
|
bool done = false;
|
|
while (!done)
|
|
{
|
|
if (long_options[i].name == 0 &&
|
|
long_options[i].has_arg == 0 &&
|
|
long_options[i].flag == 0 &&
|
|
long_options[i].val == 0)
|
|
{
|
|
done = true;
|
|
}
|
|
else
|
|
{
|
|
if (long_options[i].flag == NULL &&
|
|
isalpha(long_options[i].val))
|
|
{
|
|
s.append(1, (char)long_options[i].val);
|
|
switch (long_options[i].has_arg)
|
|
{
|
|
default:
|
|
case no_argument:
|
|
break;
|
|
|
|
case optional_argument:
|
|
s.append(2, ':');
|
|
break;
|
|
case required_argument:
|
|
s.append(1, ':');
|
|
break;
|
|
}
|
|
}
|
|
++i;
|
|
}
|
|
}
|
|
return s;
|
|
}
|