
Index: ChangeLog from BenoƮt Perrot <benoit@lrde.epita.fr> Handle options waiting for an integer. * src/task/task.hh, src/task/task.cc: Add a "needs a value" flag. * src/task/task_register.cc: Handle values from command line. * src/task/int_task.hh, src/task/int_task.cc: New files. * src/task/Makefile.am, src/task/libtask.hh: Distribute new files. New files. Index: src/task/task.hh --- src/task/task.hh (revision 122) +++ src/task/task.hh (revision 123) @@ -32,7 +32,8 @@ public: Task (const std::string& option, const std::string& module_name, - const std::string& desc, const std::string& deps = ""); + const std::string& desc, const std::string& deps = "", + bool needs_value = false); virtual ~Task() {} public: @@ -64,12 +65,20 @@ return dependencies_; } + bool needs_value() const + { + return needs_value_; + } + virtual bool set_value(const std::string &value) const; + protected: std::string long_opt_; std::string short_opt_; std::string module_; std::string description_; deps_type dependencies_; + + bool needs_value_; }; } // namespace task Index: src/task/int_task.cc --- src/task/int_task.cc (revision 0) +++ src/task/int_task.cc (revision 123) @@ -0,0 +1,61 @@ +// +// This file is part of Nolimips, a MIPS simulator with unlimited registers +// Copyright (C) 2004 Akim Demaille <akim@epita.fr> and +// Benoit Perrot <benoit@lrde.epita.fr> +// +// Nolimips is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// Nolimips is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +#include <iostream> +#include <sstream> + +#include "task/int_task.hh" + +namespace task +{ + + IntTask::IntTask(int &var, int min, int max, + const std::string& option, + const std::string& module_name, + const std::string& desc, + const std::string& deps): + Task(option, module_name, desc, deps, true), + var_(var), min_(min), max_(max) + {} + + bool + IntTask::set_value(const std::string &value) const + { + std::istringstream iss(value); + iss >> value_; + + // FIXME: print program_name! + if (iss.fail()) + std::cerr << ": expected an integer: " << value << std::endl; + else if (value_ < min_ || max_ < value_) + std::cerr << ": invalid integer: " << value_ << std::endl; + else + return true; + + return false; + } + + void + IntTask::execute(void) const + { + var_ = value_; + } + +} //namespace task Index: src/task/task.cc --- src/task/task.cc (revision 122) +++ src/task/task.cc (revision 123) @@ -24,8 +24,10 @@ { Task::Task (const std::string& option, const std::string& module_name, - const std::string& desc, const std::string& deps): - module_ (module_name), description_ (desc) + const std::string &desc, const std::string &deps, + bool needs_value): + module_(module_name), description_(desc), + needs_value_(needs_value) { // Compute dependencies std::string::size_type start = 0, end = 0; @@ -60,6 +62,12 @@ TaskRegister::instance ().register_task (*this); } + bool + Task::set_value(const std::string &value) const + { + // Default: fail + return false; + } // /** \brief Display dependencies of this task . */ // void Index: src/task/libtask.hh --- src/task/libtask.hh (revision 122) +++ src/task/libtask.hh (revision 123) @@ -23,6 +23,7 @@ # include "task/function_task.hh" # include "task/boolean_task.hh" +# include "task/int_task.hh" # ifdef NOLIMIPS_CC_ @@ -36,11 +37,18 @@ Desc, Deps) # define BOOLEAN_TASK_DECLARE(Option, Desc, Flag, Deps) \ - bool Flag; \ + bool Flag = false; \ static task::BooleanTask task_##Flag(Flag, \ Option, module_name, \ Desc, Deps) +# define INT_TASK_DECLARE(Option, Desc, Var, Default, Min, Max, Deps) \ + int Var = Default; \ + static task::IntTask task_##Var(Var, Min, Max, \ + Option, module_name, \ + Desc, Deps) + + # else // !NOLIMIPS_CC_ # define TASK_MODULE(Name) @@ -48,6 +56,8 @@ extern void (Routine) (void) # define BOOLEAN_TASK_DECLARE(Name, Help, Flag, Dependencies)\ extern bool Flag +# define INT_TASK_DECLARE(Option, Desc, Var, Default, Min, Max, Deps) \ + extern int Var # endif // NOLIMIPS_CC_ Index: src/task/Makefile.am --- src/task/Makefile.am (revision 122) +++ src/task/Makefile.am (revision 123) @@ -5,6 +5,7 @@ task.hh task.cc \ function_task.hh function_task.cc \ boolean_task.hh boolean_task.cc \ + int_task.hh int_task.cc \ task_register.hh task_register.cc \ libtask.hh \ task-tasks.hh task-tasks.cc Index: src/task/task_register.cc --- src/task/task_register.cc (revision 122) +++ src/task/task_register.cc (revision 123) @@ -137,58 +137,62 @@ TaskRegister::parse_args (int argc, char *argv[]) { char* res = 0; -// const Task *task = 0; for (int i = 1; i < argc; ++i) { - std::string arg = argv[i]; - -// if (task != 0) -// { -// enable_task(*task, arg); -// task = 0; -// continue; -// } + std::string arg(argv[i]); if ((1 < arg.size ()) && (arg[0] == '-')) { -// FIXME: split on '=' for =ARG forms + std::string value; + unsigned eq = arg.find('='); + if (eq < arg.size()) + { + value = std::string(arg, eq +1); + arg.resize(eq); + } + // Identify option TaskRegister::const_task_iterator it(tasks_.end()); - if (arg[1] == '-') - // Long option - { + if (arg[1] == '-') // Long option it = find_task(arg); - if (it != tasks_.end()) - { -// task = (*it).second; -// if (task->has_arg()) -// continue; - enable_task(*(it->second)); -// task = 0; - } - } - else - // Short option + else // Short option for (unsigned l = 1; l < arg.size(); ++l) { std::string short_option("-"); short_option += arg[l]; it = find_task(short_option); - if (it != tasks_.end()) + if (it != tasks_.end() && (l < arg.size() -1)) enable_task(*(it->second)); } + + // Consider value + if (it != tasks_.end()) + { + const Task *task = it->second; + if (!task->needs_value() && !value.empty()) + std::cerr + << program_name + << ": option `" << task->long_opt() + << "' does not take a value" << std::endl; + else if (task->needs_value() && value.empty()) + std::cerr + << program_name + << ": option `" << task->long_opt() + << "' takes a value" << std::endl; + else if (value.empty() || task->set_value(value)) + enable_task(*task); + } + else if (!value.empty()) + std::cerr + << program_name + << ": `"<< value << "': unexpected value" << std::endl; } else res = argv[i]; } -// if (task != 0) -// std::cerr << program_name -// << ": option `" << task->long_opt() << "' takes an argument" -// << std::endl; - return res; } @@ -270,8 +274,8 @@ else ostr << " "; ostr << "--" << (*jt)->long_opt(); -// if ((*jt)->has_arg()) -// ostr << " ARG"; + if ((*jt)->needs_value()) + ostr << "=ARG"; if ((*jt)->long_opt().size () <= 8) ostr << '\t'; ostr << '\t' << (*jt)->description() << std::endl; Index: src/task/int_task.hh --- src/task/int_task.hh (revision 0) +++ src/task/int_task.hh (revision 123) @@ -0,0 +1,50 @@ +// +// This file is part of Nolimips, a MIPS simulator with unlimited registers +// Copyright (C) 2004 Akim Demaille <akim@epita.fr> and +// Benoit Perrot <benoit@lrde.epita.fr> +// +// Nolimips is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// Nolimips is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +#ifndef TASK_INT_TASK_HH +# define TASK_INT_TASK_HH + +#include "task/task.hh" + +namespace task +{ + + class IntTask: public Task + { + public: + IntTask(int &var, int min, int max, + const std::string& option, const std::string& module_name, + const std::string& desc, const std::string& deps = ""); + + public: + virtual bool set_value(const std::string &value) const; + + public: + virtual void execute() const; + + private: + mutable int value_; + mutable int &var_; + int min_; + int max_; + }; + +} // namespace task + +#endif // !TASK_INT_TASK_HH