Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/CommandLineOptions.cpp
Go to the documentation of this file.
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