Files
clang-p2996/lldb/source/Host/common/OptionParser.cpp
Zachary Turner df734cdd39 Fix tests broken by the OptionValidator changes.
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
2014-07-09 16:32:07 +00:00

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;
}