From 6beedac106f5949496234349b754e8d48fccdda4 Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Sat, 21 Jul 2001 12:43:07 +0000 Subject: [PATCH] Program options class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Makefile | 12 ++ support/lib/Support/Makefile | 12 ++ support/lib/Support/ProgramOption.cpp | 138 ++++++++++++++ support/lib/Support/ProgramOptions.cpp | 249 +++++++++++++++++++++++++ 4 files changed, 411 insertions(+) create mode 100644 lib/Support/Makefile create mode 100644 support/lib/Support/Makefile create mode 100644 support/lib/Support/ProgramOption.cpp create mode 100644 support/lib/Support/ProgramOptions.cpp diff --git a/lib/Support/Makefile b/lib/Support/Makefile new file mode 100644 index 00000000000..7a41c62b04e --- /dev/null +++ b/lib/Support/Makefile @@ -0,0 +1,12 @@ +LEVEL = ../.. + +DIRS = + +LIBRARYNAME = support + +## List source files in link order +Source = \ + ProgramOption.o \ + ProgramOptions.o + +include $(LEVEL)/Makefile.common diff --git a/support/lib/Support/Makefile b/support/lib/Support/Makefile new file mode 100644 index 00000000000..7a41c62b04e --- /dev/null +++ b/support/lib/Support/Makefile @@ -0,0 +1,12 @@ +LEVEL = ../.. + +DIRS = + +LIBRARYNAME = support + +## List source files in link order +Source = \ + ProgramOption.o \ + ProgramOptions.o + +include $(LEVEL)/Makefile.common diff --git a/support/lib/Support/ProgramOption.cpp b/support/lib/Support/ProgramOption.cpp new file mode 100644 index 00000000000..2fa987941be --- /dev/null +++ b/support/lib/Support/ProgramOption.cpp @@ -0,0 +1,138 @@ +// $Id$ +//*************************************************************************** +// +// File: +// ProgramOption.C +// +// Purpose: +// General representations for a program option. +// +// History: +// 08/08/95 - adve - created in the dHPF compiler +// 11/26/96 - adve - EvalOpt now returns #args consumed, or -1 for error +// 07/15/01 - vadve - Copied to LLVM system and modified +// +//**************************************************************************/ + +//************************** System Include Files **************************/ + +#include +#include +#include +#include + +//*************************** User Include Files ***************************/ + +#include "llvm/Support/ProgramOption.h" + +//********************** Local Variable Definitions ************************/ + +//************************ Class Implementations ***************************/ + + +//**************************************************************************/ + +StringOption::StringOption(const char* _argString, + const char* _helpMesg, + const char* _initValue, + bool _append) + : ProgramOption(_argString, _helpMesg), + value(_initValue), + append(_append) +{} + +int +StringOption::EvalOpt(const char* optarg) +{ + if (optarg == (char*) NULL) + return -1; // flag the error + + if (this->append) + value += optarg; + else + value = optarg; + + optionSpecified = true; + return 1; // one additional argument consumed +} + + +//**************************************************************************/ + +FlagOption::FlagOption(const char* _argString, + const char* _helpMesg, + bool _initValue) + : ProgramOption(_argString, _helpMesg, 0), + value(_initValue) +{} + +int +FlagOption::EvalOpt(const char* optarg) +{ + if (strcmp(optarg, "0") == 0) { + value = false; + return 1; // one additional argument consumed + } + else { + value = true; + return 0; // zero ... consumed + } +} + +//**************************************************************************/ + +RealValuedOption::RealValuedOption(const char* _argString, + const char* _helpMesg, + double _initValue) + : ProgramOption(_argString, _helpMesg), + value(_initValue) +{} + +int +RealValuedOption::EvalOpt(const char* optarg) +{ + if (optarg == (char*) NULL) + return -1; + + char* lastCharScanned = NULL; + value = strtod(optarg, &lastCharScanned); + if (! (*lastCharScanned == '\0')) // look for incorrect or partially + return -1; // correct numerical argument + + optionSpecified = true; + return 1; +} + +char* +RealValuedOption::GetTextValue() const +{ + char buffer[40]; + sprintf(buffer, "%f", value); + return strdup(buffer); +} + +//**************************************************************************/ + +IntegerValuedOption::IntegerValuedOption(const char* _argString, + const char* _helpMesg, + int _initValue) + : RealValuedOption(_argString, _helpMesg, (double) _initValue) +{} + +int +IntegerValuedOption::Value() const +{ + double realValue = RealValuedOption::Value(); + assert(realValue == (int) realValue); + return (int) realValue; +} + +char* +IntegerValuedOption::GetTextValue() const +{ + char buffer[40]; + sprintf(buffer, "%d", Value()); + return strdup(buffer); +} + +//**************************************************************************/ diff --git a/support/lib/Support/ProgramOptions.cpp b/support/lib/Support/ProgramOptions.cpp new file mode 100644 index 00000000000..40fa5ac10af --- /dev/null +++ b/support/lib/Support/ProgramOptions.cpp @@ -0,0 +1,249 @@ +// $Id$ +//*************************************************************************** +// +// File: +// ProgramOptions.C +// +// Purpose: +// General options processing for any program. +// +// History: +// 08/08/95 - adve - created in the dHPF compiler +// 10/10/96 - mpal, dbaker - converted to const member functions. +// 11/26/96 - adve - fixed to handle options that consume 0+ arguments +// 07/15/01 - vadve - Copied to LLVM system and modified +// +//**************************************************************************/ + +//************************** System Include Files **************************/ + +#include +#include +#include +#include +#include +#include +#ifndef MAXINT +#define MAXINT ((1 << sizeof(int)-1) - 1) +#endif + +//*************************** User Include Files ***************************/ + +#include "llvm/Support/ProgramOptions.h" +#include "llvm/Support/ProgramOption.h" +#include "llvm/Support/StringUtils.h" + + +//************************** Method Definitions ****************************/ + +ProgramOptions::ProgramOptions(int _argc, + const char* _argv[], + const char* _envp[]) + : optionRegistry(), + argc(_argc), + argv(_argv), + envp(_envp), + argsConsumed(0) +{} + +const char* +ProgramOptions::StringOptionValue(const char* optString) const +{ + const StringOption* handler = (const StringOption*) OptionHandler(optString); + return (handler == NULL) ? NULL : handler->Value(); +} + +bool +ProgramOptions::FlagOptionValue(const char* optString) const +{ + const FlagOption* handler = (const FlagOption*) OptionHandler(optString); + return (handler == NULL) ? false : handler->Value(); +} + +double +ProgramOptions::RealOptionValue(const char* optString) const +{ + const RealValuedOption* handler = + (const RealValuedOption*) OptionHandler(optString); + return (handler == NULL) ? MAXFLOAT : handler->Value(); +} + +int +ProgramOptions::IntOptionValue(const char* optString) const +{ + const IntegerValuedOption* handler = + (const IntegerValuedOption*) OptionHandler(optString); + return (handler == NULL) ? MAXINT : handler->Value(); +} + +bool +ProgramOptions::OptionSpecified(const char* optString) const +{ + const ProgramOption* handler = OptionHandler(optString); + return handler->OptionSpecified(); +} + +const char* +ProgramOptions::ProgramName() const +{ + return argv[0]; +} + +int +ProgramOptions::NumberOfOtherOptions() const +{ + return argc - argsConsumed; +} + +const char* +ProgramOptions::OtherOption(int i) const +{ + i += argsConsumed; + assert(i >= 0 && i < argc); + return argv[i]; +} + +const char** +ProgramOptions::GetOriginalArgs() const +{ + return argv; +} + +vector +ProgramOptions::GetDescription() const +{ + vector optDesc; + + if (optDesc.size() < (unsigned) argc) + { + for (StringMap::const_iterator iter=optionRegistry.begin(); + ! (iter == optionRegistry.end()); + ++iter) + { + const ProgramOption* handler = (*iter).second; + optDesc.push_back(strdup(handler->ArgString())); // 1st + optDesc.push_back(strdup(handler->HelpMesg())); // 2nd + optDesc.push_back(handler->GetTextValue()); // 3rd + } + } + + return optDesc; +} + +void +ProgramOptions::Register(ProgramOption* option) +{ + optionRegistry[option->ArgString()] = option; +} + +//---------------------------------------------------------------------- +// function ProgramOptions::ParseArgs +// +// Parse command-line options until you run out of options or see +// an unrecognized option. `getopt' is a standard package to do this, +// but incredibly, it limited to single-letter options. +// +// -- Each option can consume zero or one additional arguments of argv +// -- "--" can be used to mark the end of options +// so that a program argument can also start with "-". +//---------------------------------------------------------------------/ + +void +ProgramOptions::ParseArgs(int argc, + const char* argv[], + const char* envp[]) +{ + if (argc == 0) { + Usage(); + } + // consume the program name + argsConsumed = 1; + + while (argsConsumed < argc) + { + const char* arg = argv[argsConsumed]; + if (arg[0] == '-') + { + if (strcmp(arg, "--") == 0) { // "--" marks end of options + argsConsumed++; // consume and + break; // discontinue the for loop + } + ProgramOption* handler = OptionHandler(arg+1); + if (handler == NULL) { + cerr << "Unrecognized option: " << arg+1 << endl; + Usage(); + } + + if (argc - argsConsumed < handler->MinExpectedArgs()) { + cerr << "Option " << (char*) arg+1 << " needs " + << handler->MinExpectedArgs() << " arguments" << endl; + Usage(); + } + + argsConsumed++; // consumed the option + + const char* nextArg = (argsConsumed < argc)? argv[argsConsumed] + : ""; + int numAdditionalArgsConsumed = handler->EvalOpt(nextArg); + if (numAdditionalArgsConsumed < 0) + Usage(); + argsConsumed += numAdditionalArgsConsumed; + } + else + { + break; // quit the while loop + } + } + + ParseExtraArgs(); +} + +void +ProgramOptions::PrintArgs(ostream& stream) const +{ + for (int i = 0; i < argc; i++) { + stream << argv[i] << " "; + } + stream << endl; +} + + +void +ProgramOptions::PrintOptions(ostream& stream) const +{ + stream << "OPTIONS:" << endl; + stream << "\tUse argument 0 to turn OFF a flag option: " + << "- 0" << endl << endl; + + for (StringMap::const_iterator iter=optionRegistry.begin(); + ! (iter == optionRegistry.end()); + ++iter) + { + const ProgramOption* handler = (*iter).second; + + stream << "\t-" << handler->ArgString(); + + const char* const showarg = " "; + int i = 1; + for (i=1; i <= handler->MinExpectedArgs(); i++) + stream << showarg; + + int numCharsPrinted = 1 + strlen(handler->ArgString()) + + strlen(showarg) * handler->MinExpectedArgs(); + for (i=1; i > numCharsPrinted / 8; i--) + stream << "\t"; + + stream << "\t" << handler->HelpMesg() + << endl; + } +} + +void +ProgramOptions::Usage() const +{ + PrintUsage(cerr); + exit(1); +} + + +//**************************************************************************/