Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2010 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include <marsyas/CommandLineOptions.h> 00020 00021 #include <iomanip> 00022 #include <algorithm> 00023 00024 using namespace std; 00025 00026 namespace Marsyas { 00027 00028 CommandLineOptions::CommandLineOptions() 00029 { 00030 } 00031 00032 CommandLineOptions::~CommandLineOptions() 00033 { 00034 std::map<std::string, Option *>::iterator it; 00035 for (it = m_options.begin(); it != m_options.end(); ++it) 00036 { 00037 delete it->second; 00038 } 00039 } 00040 00041 void CommandLineOptions::print() const 00042 { 00043 std::map<std::string, Option *>::const_iterator it; 00044 std::vector<std::string> syntax_strings; 00045 std::string::size_type syntax_field_width = 0; 00046 00047 for (it = m_options.begin(); it != m_options.end(); ++it) 00048 { 00049 const std::string & long_name = it->first; 00050 Option *option = it->second; 00051 ostringstream syntax; 00052 if (!option->short_name.empty()) 00053 syntax << '-' << option->short_name << ", "; 00054 syntax << "--" << long_name; 00055 if (!option->value_name.empty()) 00056 syntax << " " << option->value_name; 00057 syntax_field_width = std::max( syntax_field_width, syntax.str().size() ); 00058 syntax_strings.push_back( syntax.str() ); 00059 } 00060 00061 syntax_field_width += 2; 00062 int idx = 0; 00063 for (it = m_options.begin(); it != m_options.end(); ++it, ++idx) 00064 { 00065 Option *option = it->second; 00066 cout << left << " " << setw(syntax_field_width) << syntax_strings[idx]; 00067 if (!option->description.empty()) 00068 cout << ": " << option->description; 00069 cout << endl; 00070 } 00071 } 00072 00073 bool CommandLineOptions::readOptions(int argc, const char **argv) 00074 { 00075 for (int i=0; i < argc; ++i) 00076 { 00077 m_arguments.push_back(argv[i]); 00078 } 00079 00080 for (int i=1; i < argc; ++i) 00081 { 00082 const string & argument = m_arguments[i]; 00083 string option_name; 00084 00085 if (argument.size() > 1 && argument[0] == '-') 00086 { 00087 if (argument.size() > 2 && argument[1] == '-') 00088 { 00089 option_name = argument.substr(2); 00090 } 00091 else 00092 { 00093 string short_name = argument.substr(1); 00094 std::map<std::string, std::string>::iterator it; 00095 it = m_long_names.find(short_name); 00096 if (it != m_long_names.end()) 00097 { 00098 option_name = it->second; 00099 } 00100 else 00101 { 00102 cerr << "Invalid option: " << argument << endl; 00103 return false; 00104 } 00105 } 00106 } 00107 00108 if (option_name.empty()) 00109 { 00110 m_remaining.push_back(argument); 00111 continue; 00112 } 00113 00114 std::map<std::string, Option*>::iterator option_it; 00115 option_it = m_options.find(option_name); 00116 if (option_it == m_options.end()) 00117 { 00118 cerr << "Invalid option: " << argument << endl; 00119 return false; 00120 } 00121 00122 Option *option = option_it->second; 00123 00124 { 00125 OptionT<bool> *bool_option = option_cast<bool>(option); 00126 if (bool_option) 00127 { 00128 bool_option->is_set = true; 00129 continue; 00130 } 00131 } 00132 00133 if (i == argc-1) 00134 { 00135 std::cerr << "Missing value for option: " << argument << endl; 00136 return false; 00137 } 00138 00139 ++i; 00140 std::istringstream value_stream( m_arguments[i] ); 00141 if (!option->parse_value( value_stream )) 00142 { 00143 std::cerr << "Invalid value for option: " 00144 << argument << ' ' << value_stream.str() << endl; 00145 return false; 00146 } 00147 } 00148 00149 return true; 00150 } 00151 00152 } // namespace Marsyas