diff --git a/src/backend/string_utils.cc b/src/backend/string_utils.cc index ae8ffd3..37206c2 100644 --- a/src/backend/string_utils.cc +++ b/src/backend/string_utils.cc @@ -19,7 +19,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "string_utils.hh" - +#include "gettext.h" #include using namespace std; @@ -77,7 +77,7 @@ T string_to(const ustring& str) throw(domain_error) { if(tokenize(str).size() != 1) - throw domain_error("too few or too many tokens"); + throw domain_error(_("too few or too many tokens")); istringstream iss(str); @@ -99,7 +99,39 @@ string_to(const ustring& str) throw(domain_error) iss.exceptions(ios_base::goodbit); if(iss.peek() != istringstream::traits_type::eof()) - throw domain_error("incorrect number format"); + throw domain_error(_("incorrect number format")); + + return value; +} + +template <> +bool +string_to(const Glib::ustring& str) throw(domain_error) +{ + if(tokenize(str).size() != 1) + throw domain_error(_("too few or too many tokens")); + + istringstream iss(str); + + iss.exceptions(ios_base::failbit | ios_base::badbit); + + bool value; + + try + { + iss >> boolalpha >> value; + } + catch(ios_base::failure e) + { + throw domain_error(e.what()); + } + + // disable exceptions, otherwise peek() will throw them! + // how useless!!! + iss.exceptions(ios_base::goodbit); + + if(iss.peek() != istringstream::traits_type::eof()) + throw domain_error(_("incorrect boolean")); return value; } @@ -197,5 +229,5 @@ tokenize(const ustring& str) template int string_to(const Glib::ustring&); template float string_to(const Glib::ustring&); - +template bool string_to(const Glib::ustring&); } diff --git a/src/text_simulation.cc b/src/text_simulation.cc index 0be6680..9fae42a 100644 --- a/src/text_simulation.cc +++ b/src/text_simulation.cc @@ -28,6 +28,7 @@ #include "backend/dynamic_thread.hh" #include "backend/dynamic_request.hh" #include "backend/dynamic_sub_request.hh" +#include "backend/concrete_history.hh" #include "text_simulation.hh" @@ -44,6 +45,7 @@ using Glib::ustring; namespace sgpem { + //TODO move this class to another file... template class CommandParameter { @@ -182,7 +184,7 @@ TextSimulation::get_parameter(CommandParameter& parameter) buf << "*"; buf << parameter.description << " (range: [" << parameter.low_bound << ", " << - parameter.up_bound << "] current: " << parameter.value << ") = "; + parameter.up_bound << "] current: " << parameter.value << ") : "; p_stdout(buf.str()); @@ -244,7 +246,7 @@ namespace sgpem buf += "*"; p_stdout(buf + parameter.description + - " (current: \"" + parameter.value + "\") = "); + " (current: \"" + parameter.value + "\") : "); buf = readline(); @@ -264,6 +266,51 @@ namespace sgpem } } } + + template <> + void + TextSimulation::get_parameter(CommandParameter& parameter) + { + bool loop = true; + + while(loop) + { + ostringstream buf; + + buf << "\n"; + + if(parameter.required) + buf << "*"; + + buf << parameter.description << + " (current: " << boolalpha << parameter.value << ") : "; + + p_stdout(buf.str()); + + ustring str = readline(); + + // FIXME semi-hack, it's a bit overkill to tokenize the string + // to find if it's only composed of white spaces... + // Indedeed there's a pro: by using extensively tokenize() we are more sure + // it's correct ;-) + Tokens tokens = tokenize(str); + + if(tokens.size() == 0 && parameter.required) + p_stderr(_("\nERROR: This is a mandatory atribute; you MUST provide a valid value!")); + else + { + try + { + parameter.value = string_to(str); + loop = false; + } + catch(domain_error e) + { + p_stderr(_("\nERROR: Please provide a valid boolean value ('true' or 'false')")); + } + } + } + } } void @@ -640,8 +687,12 @@ TextSimulation::on_set(const Tokens& arguments) void TextSimulation::on_show(const Tokens& arguments) { - if(!check_arguments_num(arguments, 1)) + if(arguments.size() < 1) + { + //print error + check_arguments_num(arguments, 1); return; + } //make a local copy which we'll probably modify Tokens args = arguments; @@ -833,6 +884,97 @@ TextSimulation::on_show_resource_policies(const Tokens& arguments) void TextSimulation::on_add(const Tokens& arguments) +{ + if(arguments.size() < 1) + { + //print error + check_arguments_num(arguments, 1); + return; + } + + //make a local copy which we'll probably modify + Tokens args = arguments; + + ustring entity = args[0].uppercase(); + args.erase(args.begin()); + + typedef void (TextSimulation::*f_ptr)(const Tokens&); + map entity_handlers; + + entity_handlers["PROCESS"] = &TextSimulation::on_add_process; + entity_handlers["RESOURCE"] = &TextSimulation::on_add_resource; + entity_handlers["THREAD"] = &TextSimulation::on_add_thread; + entity_handlers["REQUEST"] = &TextSimulation::on_add_request; + entity_handlers["SUBREQUEST"] = &TextSimulation::on_add_subrequest; + + if(entity_handlers.find(entity) == entity_handlers.end()) + p_stderr(_("\nERROR: invalid argument\n")); + else + (this->*(entity_handlers[entity]))(args); +} + +void +TextSimulation::on_add_process(const Tokens& arguments) +{ + check_arguments_num(arguments, 0); + + CommandParameter name(_("name"), "", "", false, ""); + CommandParameter arrival_time(_("arrival time"), 0, INT_MAX, false, 0); + CommandParameter base_priority(_("priority"), 0, INT_MAX, false, 0); + + get_parameter(name); + get_parameter(arrival_time); + get_parameter(base_priority); + + // FIXME: need to use the true history, not this stub + ConcreteHistory h; + + h.add_process(name.value, arrival_time.value, base_priority.value); +} + +// CommandParameter(const ustring& _description, +// const T& _low_bound, +// const T& _up_bound, +// bool _required, +// const T& _preset); +// + +void +TextSimulation::on_add_resource(const Tokens& arguments) +{ + check_arguments_num(arguments, 0); + + CommandParameter name(_("name"), "", "", false, ""); + // FIXME need to further specialize string_to and get_parameter for bool + CommandParameter preemptable(_("pre-emptable?"), false, false, false, false); + CommandParameter places(_("places"), 0, INT_MAX, false, 1); + CommandParameter availability(_("availability"), 0, INT_MAX, false, 0); + + get_parameter(name); + get_parameter(preemptable); + get_parameter(places); + get_parameter(availability); + + // FIXME: need to use the true history, not this stub + ConcreteHistory h; + + h.add_resource(name.value, preemptable.value, places.value, availability.value); +} + +void +TextSimulation::on_add_thread(const Tokens& arguments) +{ + p_stderr(_("\nFIXME: Not implemented\n")); +} + +void +TextSimulation::on_add_request(const Tokens& arguments) +{ + p_stderr(_("\nFIXME: Not implemented\n")); +} + +void +TextSimulation::on_add_subrequest(const Tokens& arguments) { p_stderr(_("\nFIXME: Not implemented\n")); } diff --git a/src/text_simulation.hh b/src/text_simulation.hh index 80629ad..346d2f6 100644 --- a/src/text_simulation.hh +++ b/src/text_simulation.hh @@ -149,6 +149,11 @@ namespace sgpem void on_show_cpu_policies(const Tokens& arguments); void on_show_resource_policies(const Tokens& arguments); void on_add(const Tokens& arguments); + void on_add_process(const Tokens& arguments); + void on_add_resource(const Tokens& arguments); + void on_add_thread(const Tokens& arguments); + void on_add_request(const Tokens& arguments); + void on_add_subrequest(const Tokens& arguments); void on_remove(const Tokens& arguments); // FIXME This is a temporary replacement for the