- Written some code for command processing. Still not tested it. Feedback is very much appreciated!

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@746 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
elvez 2006-07-09 16:27:16 +00:00
parent 0e79b163f3
commit 2ede92d6d1
4 changed files with 444 additions and 23 deletions

View File

@ -20,9 +20,15 @@
#include "string_utils.hh" #include "string_utils.hh"
#include <sstream>
using namespace std; using namespace std;
//using namespace sgpem;
using Glib::ustring; using Glib::ustring;
namespace sgpem
{
/** /**
\brief A function that converts a Unicode string to an integer value \brief A function that converts a Unicode string to an integer value
@ -66,6 +72,30 @@ string_to_int(const ustring& str, int& num)
return true; return true;
} }
int
string_to_int(const 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);
int value;
try
{
iss >> value;
}
catch(ios_base::failure& e)
{
throw domain_error(e.what());
}
return value;
}
/** /**
\brief A function that converts an integer value to an Unicode string \brief A function that converts an integer value to an Unicode string
*/ */
@ -112,3 +142,49 @@ string_to_float(const Glib::ustring& str, float& f)
ss << str; ss << str;
ss >> f; ss >> f;
} }
// helper function for tokenize()
static void
add_token(Tokens& tokens, const ustring& token)
{
if(token.size() > 0)
tokens.push_back(token);
}
Tokens
tokenize(const ustring& str)
{
istringstream iss(str);
Tokens tokens;
while(iss)
{
ustring token;
iss >> token;
ustring::size_type index;
// for the SET command, parse the assigment symbol as
// a separate token
do
{
index = token.find('=');
if(index != ustring::npos)
{
add_token(tokens, token.substr(0, index));
add_token(tokens, "=");
// the second argument can safely be out of range
token = token.substr(index + 1, token.size());
}
}
while(index != ustring::npos);
add_token(tokens, token);
}
return tokens;
}
}

View File

@ -24,45 +24,54 @@
#include "config.h" #include "config.h"
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <vector>
#include <stdexcept>
#include <glibmm/ustring.h> #include <glibmm/ustring.h>
// FIXME : mark this file as deprecated. // FIXME : mark this file as deprecated.
#warning "This file is obsolete and deprecated." #warning "This file is obsolete and deprecated."
#warning "It will be removed soon. Please update your code!" #warning "It will be removed soon. Please update your code!"
namespace sgpem
{
typedef std::vector<Glib::ustring> Tokens;
/**\brief This function tries to convert a string into an integer value.
/**\brief This function tries to convert a string into an integer value. The string can contain only digits and the minus character (for negative numbers).
The string can contain only digits and the minus character (for negative numbers). \returns TRUE if ths string represent a valid integer number
\returns FALSE otherwise
\returns TRUE if ths string represent a valid integer number */
\returns FALSE otherwise bool SG_DLLEXPORT string_to_int(const Glib::ustring&, int&);
*/
bool SG_DLLEXPORT string_to_int(const Glib::ustring&, int&);
/**\brief This function converts an integer value into a string. int SG_DLLEXPORT string_to_int(const Glib::ustring&) throw(std::domain_error);
There is no return value because this function always succeeds. /**\brief This function converts an integer value into a string.
*/
void SG_DLLEXPORT int_to_string(const int&, Glib::ustring&); There is no return value because this function always succeeds.
*/
void SG_DLLEXPORT int_to_string(const int&, Glib::ustring&);
/**\brief This function converts a float value into a string. /**\brief This function converts a float value into a string.
There is no return value because this function always succeeds. There is no return value because this function always succeeds.
*/ */
void SG_DLLEXPORT float_to_string(const float&, Glib::ustring&); void SG_DLLEXPORT float_to_string(const float&, Glib::ustring&);
/**\brief This function tries to convert a string into a float value. /**\brief This function tries to convert a string into a float value.
The string can contain only digits, the minus, plus and dot (-+.) characters. If not, The string can contain only digits, the minus, plus and dot (-+.) characters. If not,
the value 0 is assigned. the value 0 is assigned.
There is no return value because this function always succeeds, even if the string is badly formed. There is no return value because this function always succeeds, even if the string is badly formed.
*/ */
void SG_DLLEXPORT string_to_float(const Glib::ustring&, float&); void SG_DLLEXPORT string_to_float(const Glib::ustring&, float&);
Tokens tokenize(const Glib::ustring& str);
}
#endif #endif

View File

@ -21,10 +21,14 @@
#include "backend/string_utils.hh" #include "backend/string_utils.hh"
#include "backend/policies_gatekeeper.hh" #include "backend/policies_gatekeeper.hh"
#include "backend/policy_manager.hh" #include "backend/policy_manager.hh"
#include "backend/policy_parameters.hh"
#include "backend/history.hh" #include "backend/history.hh"
#include "text_simulation.hh" #include "text_simulation.hh"
#include <sstream>
using namespace std; using namespace std;
using namespace sgpem; using namespace sgpem;
using namespace memory; using namespace memory;
@ -50,9 +54,320 @@ TextSimulation::add_io_device(smart_ptr<IOManager> io)
// Thread::create( sigc::bind(&TextSimulation::_io_loop, p), true); // Thread::create( sigc::bind(&TextSimulation::_io_loop, p), true);
} }
void
TextSimulation::arguments_ignored(const Tokens& arguments)
{
if(arguments.size() != 0)
p_stderr(_("\nWARNING: some arguments will be ignored"));
}
void
TextSimulation::on_run(const Tokens& arguments)
{
arguments_ignored(arguments);
try
{
run();
}
catch(UserInterruptException e)
{
p_stderr(_("\nERROR: "));
p_stderr(e.what());
p_stderr(_("\nSimulation is now stopped"));
}
}
void
TextSimulation::on_pause(const Tokens& arguments)
{
arguments_ignored(arguments);
pause();
}
void
TextSimulation::on_stop(const Tokens& arguments)
{
arguments_ignored(arguments);
stop();
}
void
TextSimulation::on_configure_cpu_policy(const Tokens& arguments)
{
arguments_ignored(arguments);
PolicyParameters& parameters = get_policy()->get_parameters();
p_stdout(_("\nPlease provide a value for each attribute"));
p_stdout(_("\nMandatory arguments are marked with an asterisk (*)"));
typedef map<ustring, PolicyParameters::Parameter<int> > IntParams;
typedef map<ustring, PolicyParameters::Parameter<float> > FloatParams;
typedef map<ustring, PolicyParameters::Parameter<ustring> > StringParams;
// TODO for int and double this code is easily replaced with a call to a
// template function. for strings we'll need to specialize it...
IntParams int_params = parameters.get_registered_int_parameters();
for(IntParams::iterator it = int_params.begin(); it != int_params.end();)
{
PolicyParameters::Parameter<int> &p = it->second;
ostringstream buf;
buf << "\n";
if(p.is_required())
buf << "*";
buf << p.get_name() << " (range: [" << p.get_lower_bound() << ", " <<
p.get_upper_bound() << "] default: " << p.get_default() << ") = ";
p_stdout(buf.str());
bool arg_provided = false;
bool correct = true;
ustring input = readline();
int value;
// 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 ;-)
if(tokenize(input).size() > 0)
{
try
{
value = string_to_int(input);
}
catch(domain_error e)
{
p_stderr(_("\nERROR: Please provide a valid integer value"));
correct = false;
}
if(value > p.get_upper_bound() || value < p.get_lower_bound())
{
p_stderr(_("\nERROR: Provided value is out of range"));
correct = false;
}
if(correct)
p.set_value(value);
}
else if(p.is_required())
{
p_stderr(_("\nERROR: This is a mandatory attribute; you MUST provide a valid value!"));
correct = false;
}
if(correct)
++it;
}
//FIXME code for float arguments
// StringParams string_params = parameters->get_registered_string_parameters();
//
// for(StringParams::iterator it = int_params.begin(); it != int_params.end();)
// {
// Parameter<ustring> &p = *it;
// ustring buf;
//
// buf = "\n";
//
// if(p.is_required())
// buf += "*";
//
// p_stdout(buf + p.get_name() + " = ");
//
// buf = read();
//
// // 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(input);
//
// if(tokens.size() == 0 && p.is_required())
// p_stderr(_("\nERROR: This is a mandatory atribute; you MUST provide a valid value!"));
// else
// {
// p.set_value(tokens[0]);
// ++it;
// }
//
// }
}
void
TextSimulation::on_help(const Tokens& arguments)
{
ustring command;
//make a local copy which we'll probably modify
Tokens args = arguments;
if(args.size() > 1)
{
command = args[0].uppercase();
args.erase(args.begin());
}
arguments_ignored(args);
if(command.size() == 0)
p_stdout(_("\nAvaiable commands:\nRUN\nPAUSE\nSTOP\nQUIT\nHELP"
"\nGET\nSET\nSHOW\nADD\nREMOVE"
"\n\nHELP followed by a command shows help about it."
"\n ex. HELP RUN shows help about the command RUN"));
else if(command == "RUN")
p_stdout(_("\n-- RUN COMMAND --\nStarts the simulation. It can be "
"continuous or step-by-step depending on the mode configured with "
"SET MODE (default=CONTINUOUS).\n\n"
"The output of RUN is one or more rows each of which represents the "
"state of the schedulable entities. It can be RUNNING, READY, BLOCKED, "
"FUTURE or TERMINATED."
"\nThe row begins with the number of the instant described by the "
"following lists of states. The instant 0 represents the INITIAL STATE "
"during which no process is running. The scheduler "
"activity begins at instant 1. Each schedulable entity is represented by "
"its name followed "
"by its priority enclosed between round parenthesis."));
else if(command == "STOP")
p_stdout(_("\n-- STOP COMMAND --\nStops the simulation. The next call to RUN will "
"bring the simulation to the FIRST instant and start it."));
else if(command == "PAUSE")
p_stdout(_("\n-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will restart it."));
else if(command == "CONFIGURE-CPU-POLICY")
p_stdout(_("\nFIXME"));
else if(command == "HELP")
p_stdout(_("\n-- Do you really want me to explain what HELP means? --"
"\n ************** YOU ARE JOKING ME !!! ************\n\n"));
else if(command == "GET")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "SET")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "SHOW")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "ADD")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "REMOVE")
p_stderr(_("\nFIXME: Not implemented"));
else if(command == "QUIT")
p_stderr(_("\nFIXME: Not implemented"));
else
p_stderr(_("\nERROR: Sorry, no help available for this command."));
}
void
TextSimulation::on_quit(const Tokens& arguments)
{
arguments_ignored(arguments);
p_stdout(_("\n\n*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n\n"));
// Is this ok? Really? Oh, sure, if it we always did it in this way, it is surely a Good Thing!
exit(1);
}
void
TextSimulation::on_get(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_set(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_show(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_add(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::on_remove(const Tokens& arguments)
{
p_stderr(_("\nFIXME: Not implemented"));
}
void
TextSimulation::p_stdout(const ustring& str)
{
cout << str;
}
void
TextSimulation::p_stderr(const ustring& str)
{
cerr << str;
}
ustring
TextSimulation::readline()
{
string str;
getline(cin, str);
return str;
}
void void
TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const ustring > p) TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const ustring > p)
{ {
typedef void (TextSimulation::*f_ptr)(const Tokens&);
map<ustring, f_ptr> command_handlers;
command_handlers["RUN"] = &TextSimulation::on_run;
command_handlers["STOP"] = &TextSimulation::on_stop;
command_handlers["PAUSE"] = &TextSimulation::on_pause;
command_handlers["CONFIGURE-CPU-POLICY"] = &TextSimulation::on_configure_cpu_policy;
command_handlers["HELP"] = &TextSimulation::on_help;
command_handlers["GET"] = &TextSimulation::on_get;
command_handlers["SET"] = &TextSimulation::on_set;
command_handlers["SHOW"] = &TextSimulation::on_show;
command_handlers["ADD"] = &TextSimulation::on_add;
command_handlers["REMOVE"] = &TextSimulation::on_remove;
command_handlers["QUIT"] = &TextSimulation::on_quit;
ustring str = p.second;
Tokens arguments = tokenize(str);
if(arguments.size() == 0)
return;
if(command_handlers.find(arguments[0]) == command_handlers.end())
{
p_stderr(_("\nERROR: command not supported"));
return;
}
ustring key = arguments[0].uppercase();
arguments.erase(arguments.begin());
TextSimulation* obj = p.first.first;
(obj->*(command_handlers[key]))(arguments);
}
// ** Please do NOT delete this code, I still use it as a reference **
//void
//TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const ustring > p)
//{
// //
// TextSimulation* obj = p.first.first; // TextSimulation* obj = p.first.first;
// ustring str = p.second; // ustring str = p.second;
@ -431,7 +746,7 @@ TextSimulation::parse_command(pair< pair<TextSimulation*, IOManager*>, const us
// obj->_devices[quale]->write_buffer(_("\nTyper HELP for a list of avaiable commands.")); // obj->_devices[quale]->write_buffer(_("\nTyper HELP for a list of avaiable commands."));
// return; // return;
// } // }
} //}
void void
@ -530,3 +845,4 @@ TextSimulation::_io_loop(pair<TextSimulation* , int > pun)
pun.first->parse_command(p); pun.first->parse_command(p);
} }
} }

View File

@ -27,7 +27,8 @@
#include "simulation.hh" #include "simulation.hh"
#include "io_manager.hh" #include "io_manager.hh"
#include "templates/smartp.hh" #include "templates/smartp.hh"
#include "backend/policy_parameters.hh" //#include "backend/policy_parameters.hh"
#include "backend/string_utils.hh"
#include "smartp.hh" #include "smartp.hh"
@ -120,6 +121,25 @@ namespace sgpem
void update(); void update();
private: private:
void arguments_ignored(const Tokens& arguments);
void on_run(const Tokens& arguments);
void on_pause(const Tokens& arguments);
void on_stop(const Tokens& arguments);
void on_configure_cpu_policy(const Tokens& arguments);
void on_help(const Tokens& arguments);
void on_quit(const Tokens& arguments);
void on_get(const Tokens& arguments);
void on_set(const Tokens& arguments);
void on_show(const Tokens& arguments);
void on_add(const Tokens& arguments);
void on_remove(const Tokens& arguments);
// FIXME This is a temporary replacement for the
// to-be written I/O layer
static void p_stdout(const Glib::ustring& str);
static void p_stderr(const Glib::ustring& str);
static Glib::ustring readline();
std::vector<memory::smart_ptr<IOManager> > _devices; std::vector<memory::smart_ptr<IOManager> > _devices;
static void _io_loop(std::pair<TextSimulation*, int>); static void _io_loop(std::pair<TextSimulation*, int>);
}; };