diff options
author | Steven Bennetts <steve@lindenlab.com> | 2008-03-15 01:18:27 +0000 |
---|---|---|
committer | Steven Bennetts <steve@lindenlab.com> | 2008-03-15 01:18:27 +0000 |
commit | 672a76d0ea08a0d0fc824e103ee4c4242b7e03ec (patch) | |
tree | b623a9c884383ad75ed755b2c373db2b90643671 /indra/newview/llcommandlineparser.cpp | |
parent | 04611efae8a3291ceba8a29dd920bdae0d404830 (diff) |
reverting premature commit at 82410.
Diffstat (limited to 'indra/newview/llcommandlineparser.cpp')
-rw-r--r-- | indra/newview/llcommandlineparser.cpp | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp deleted file mode 100644 index 2f99ca1247..0000000000 --- a/indra/newview/llcommandlineparser.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/** - * @file llcommandlineparser.cpp - * @brief The LLCommandLineParser class definitions - * - * $LicenseInfo:firstyear=2007&license=viewergpl$ - * - * Copyright (c) 2007, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llcommandlineparser.h" - -// *NOTE: The boost::lexical_cast generates -// the warning C4701(local used with out assignment) in VC7.1. -// Disable the warning for the boost includes. -#if _MSC_VER -# pragma warning(push) -# pragma warning( disable : 4701 ) -#else -// NOTE: For the other platforms? -#endif - -#include <boost/program_options.hpp> -#include <boost/bind.hpp> -#include<boost/tokenizer.hpp> - -#if _MSC_VER -# pragma warning(pop) -#endif - -#include "llsdserialize.h" -#include <iostream> -#include <sstream> - -#include "llcontrol.h" - -namespace po = boost::program_options; - -// *NTOE:MEP - Currently the boost object reside in file scope. -// This has a couple of negatives, they are always around and -// there can be only one instance of each. -// The plus is that the boost-ly-ness of this implementation is -// hidden from the rest of the world. -// Its importatnt to realize that multiple LLCommandLineParser objects -// will all have this single repository of option escs and parsed options. -// This could be good or bad, and probably won't matter for most use cases. -namespace -{ - po::options_description gOptionsDesc; - po::positional_options_description gPositionalOptions; - po::variables_map gVariableMap; - - const LLCommandLineParser::token_vector_t gEmptyValue; - - void read_file_into_string(std::string& str, const std::basic_istream < char >& file) - { - std::ostringstream oss; - oss << file.rdbuf(); - str = oss.str(); - } - - bool gPastLastOption = false; -} - -class LLCLPError : public std::logic_error { -public: - LLCLPError(const std::string& what) : std::logic_error(what) {} -}; - -class LLCLPLastOption : public std::logic_error { -public: - LLCLPLastOption(const std::string& what) : std::logic_error(what) {} -}; - -class LLCLPValue : public po::value_semantic_codecvt_helper<char> -{ - unsigned mMinTokens; - unsigned mMaxTokens; - bool mIsComposing; - typedef boost::function1<void, const LLCommandLineParser::token_vector_t&> notify_callback_t; - notify_callback_t mNotifyCallback; - bool mLastOption; - -public: - LLCLPValue() : - mMinTokens(0), - mMaxTokens(0), - mIsComposing(false), - mLastOption(false) - {} - - virtual ~LLCLPValue() {}; - - void setMinTokens(unsigned c) - { - mMinTokens = c; - } - - void setMaxTokens(unsigned c) - { - mMaxTokens = c; - } - - void setComposing(bool c) - { - mIsComposing = c; - } - - void setLastOption(bool c) - { - mLastOption = c; - } - - void setNotifyCallback(notify_callback_t f) - { - mNotifyCallback = f; - } - - // Overrides to support the value_semantic interface. - virtual std::string name() const - { - const std::string arg("arg"); - const std::string args("args"); - return (max_tokens() > 1) ? args : arg; - } - - virtual unsigned min_tokens() const - { - return mMinTokens; - } - - virtual unsigned max_tokens() const - { - return mMaxTokens; - } - - virtual bool is_composing() const - { - return mIsComposing; - } - - virtual bool apply_default(boost::any& value_store) const - { - return false; // No defaults. - } - - virtual void notify(const boost::any& value_store) const - { - const LLCommandLineParser::token_vector_t* value = - boost::any_cast<const LLCommandLineParser::token_vector_t>(&value_store); - if(mNotifyCallback) - { - mNotifyCallback(*value); - } - - } - -protected: - void xparse(boost::any& value_store, - const std::vector<std::string>& new_tokens) const - { - if(gPastLastOption) - { - throw(LLCLPLastOption("Don't parse no more!")); - } - - // Error checks. Needed? - if (!value_store.empty() && !is_composing()) - { - throw(LLCLPError("Non composing value with multiple occurences.")); - } - if (new_tokens.size() < min_tokens() || new_tokens.size() > max_tokens()) - { - throw(LLCLPError("Illegal number of tokens specified.")); - } - - if(value_store.empty()) - { - value_store = boost::any(LLCommandLineParser::token_vector_t()); - } - LLCommandLineParser::token_vector_t* tv = - boost::any_cast<LLCommandLineParser::token_vector_t>(&value_store); - - for(unsigned i = 0; i < new_tokens.size() && i < mMaxTokens; ++i) - { - tv->push_back(new_tokens[i]); - } - - if(mLastOption) - { - gPastLastOption = true; - } - } -}; - -//---------------------------------------------------------------------------- -// LLCommandLineParser defintions -//---------------------------------------------------------------------------- -void LLCommandLineParser::addOptionDesc(const LLString& option_name, - boost::function1<void, const token_vector_t&> notify_callback, - unsigned int token_count, - const LLString& description, - const LLString& short_name, - bool composing, - bool positional, - bool last_option) -{ - // Compose the name for boost::po. - // It takes the format "long_name, short name" - const LLString comma(","); - LLString boost_option_name = option_name; - if(short_name != LLString::null) - { - boost_option_name += comma; - boost_option_name += short_name; - } - - LLCLPValue* value_desc = new LLCLPValue(); - value_desc->setMinTokens(token_count); - value_desc->setMaxTokens(token_count); - value_desc->setComposing(composing); - value_desc->setLastOption(last_option); - - boost::shared_ptr<po::option_description> d( - new po::option_description(boost_option_name.c_str(), - value_desc, - description.c_str())); - - if(!notify_callback.empty()) - { - value_desc->setNotifyCallback(notify_callback); - } - - gOptionsDesc.add(d); - - if(positional) - { - gPositionalOptions.add(boost_option_name.c_str(), token_count); - } -} - -bool parseAndStoreResults(po::command_line_parser& clp) -{ - try - { - clp.options(gOptionsDesc); - clp.positional(gPositionalOptions); - clp.style(po::command_line_style::default_style - | po::command_line_style::allow_long_disguise); - po::basic_parsed_options<char> opts = clp.run(); - po::store(opts, gVariableMap); - } - catch(po::error& e) - { - llwarns << "Caught Error:" << e.what() << llendl; - return false; - } - catch(LLCLPError& e) - { - llwarns << "Caught Error:" << e.what() << llendl; - return false; - } - catch(LLCLPLastOption&) - { - // Continue without parsing. - llwarns << "Found tokens past last option. Ignoring." << llendl; - - // boost::po will have stored a mal-formed option. - // All such options will be removed below. - for(po::variables_map::iterator i = gVariableMap.begin(); i != gVariableMap.end();) - { - po::variables_map::iterator tempI = i++; - if(tempI->second.empty()) - { - gVariableMap.erase(tempI); - } - } - } - return true; -} - -bool LLCommandLineParser::parseCommandLine(int argc, char **argv) -{ - po::command_line_parser clp(argc, argv); - return parseAndStoreResults(clp); -} - -bool LLCommandLineParser::parseCommandLineString(const std::string& str) -{ - // Split the string content into tokens - boost::escaped_list_separator<char> sep("\\", "\r\n ", "\"'"); - boost::tokenizer< boost::escaped_list_separator<char> > tok(str, sep); - std::vector<std::string> tokens; - // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens)); - for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin(); - i != tok.end(); - ++i) - { - if(0 != i->size()) - { - tokens.push_back(*i); - } - } - - po::command_line_parser clp(tokens); - return parseAndStoreResults(clp); - -} - -bool LLCommandLineParser::parseCommandLineFile(const std::basic_istream < char >& file) -{ - std::string args; - read_file_into_string(args, file); - - return parseCommandLineString(args); -} - -void LLCommandLineParser::notify() -{ - po::notify(gVariableMap); -} - -void LLCommandLineParser::printOptions() const -{ - for(po::variables_map::iterator i = gVariableMap.begin(); i != gVariableMap.end(); ++i) - { - std::string name = i->first; - token_vector_t values = i->second.as<token_vector_t>(); - std::ostringstream oss; - oss << name << ": "; - for(token_vector_t::iterator t_itr = values.begin(); t_itr != values.end(); ++t_itr) - { - oss << t_itr->c_str() << " "; - } - llinfos << oss.str() << llendl; - } -} - -std::ostream& LLCommandLineParser::printOptionsDesc(std::ostream& os) const -{ - return os << gOptionsDesc; -} - -bool LLCommandLineParser::hasOption(const std::string& name) const -{ - return gVariableMap.count(name) > 0; -} - -const LLCommandLineParser::token_vector_t& LLCommandLineParser::getOption(const std::string& name) const -{ - if(hasOption(name)) - { - return gVariableMap[name].as<token_vector_t>(); - } - - return gEmptyValue; -} - -//---------------------------------------------------------------------------- -// LLControlGroupCLP defintions -//---------------------------------------------------------------------------- -void setControlValueCB(const LLCommandLineParser::token_vector_t& value, - const LLString& opt_name, - LLControlGroup* ctrlGroup) -{ - if(value.size() > 1) - { - llwarns << "Ignoring extra tokens mapped to the setting: " << opt_name << "." << llendl; - } - - // *FIX: Do sematic conversion here. - // LLSD (ImplString) Is no good for doing string to type conversion for... - // booleans - // compound types - // ?... - - LLControlVariable* ctrl = ctrlGroup->getControl(opt_name); - if(NULL != ctrl) - { - switch(ctrl->type()) - { - case TYPE_BOOLEAN: - if(value.size() > 1) - { - llwarns << "Ignoring extra tokens." << llendl; - } - - if(value.size() > 0) - { - // There's a token. check the string for true/false/1/0 etc. - BOOL result = false; - BOOL gotSet = LLString::convertToBOOL(value[0], result); - if(gotSet) - { - ctrl->setValue(LLSD(result), false); - } - } - else - { - ctrl->setValue(LLSD(true), false); - } - break; - - default: - { - // For the default types, let llsd do the conversion. - if(value.size() > 1) - { - // Assume its an array... - LLSD llsdArray; - for(unsigned int i = 0; i < value.size(); ++i) - { - LLSD llsdValue; - llsdValue.assign(LLSD::String(value[i])); - llsdArray.set(i, llsdValue); - } - - ctrl->setValue(llsdArray, false); - } - else if(value.size() > 0) - { - LLSD llsdValue; - llsdValue.assign(LLSD::String(value[0])); - ctrl->setValue(llsdValue, false); - } - } - break; - } - } - else - { - llwarns << "Command Line option mapping '" - << opt_name - << "' not found! Ignoring." - << llendl; - } -} - -void LLControlGroupCLP::configure(const LLString& config_filename, LLControlGroup* controlGroup) -{ - // This method reads the llsd based config file, and uses it to set - // members of a control group. - LLSD clpConfigLLSD; - - llifstream input_stream; - input_stream.open(config_filename.c_str(), std::ios::in | std::ios::binary); - - if(input_stream.is_open()) - { - LLSDSerialize::fromXML(clpConfigLLSD, input_stream); - for(LLSD::map_iterator option_itr = clpConfigLLSD.beginMap(); - option_itr != clpConfigLLSD.endMap(); - ++option_itr) - { - LLSD::String long_name = option_itr->first; - LLSD option_params = option_itr->second; - - LLString desc("n/a"); - if(option_params.has("desc")) - { - desc = option_params["desc"].asString(); - } - - LLString short_name = LLString::null; - if(option_params.has("short")) - { - short_name = option_params["short"].asString(); - } - - unsigned int token_count = 0; - if(option_params.has("count")) - { - token_count = option_params["count"].asInteger(); - } - - bool composing = false; - if(option_params.has("compose")) - { - composing = option_params["compose"].asBoolean(); - } - - bool positional = false; - if(option_params.has("positional")) - { - positional = option_params["positional"].asBoolean(); - } - - bool last_option = false; - if(option_params.has("last_option")) - { - last_option = option_params["last_option"].asBoolean(); - } - - boost::function1<void, const token_vector_t&> callback; - if(option_params.has("map-to") && (NULL != controlGroup)) - { - LLString controlName = option_params["map-to"].asString(); - callback = boost::bind(setControlValueCB, _1, - controlName, controlGroup); - } - - this->addOptionDesc( - long_name, - callback, - token_count, - desc, - short_name, - composing, - positional, - last_option); - } - } -} |