- 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 <sstream>
using namespace std;
//using namespace sgpem;
using Glib::ustring;
namespace sgpem
{
/**
\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;
}
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
*/
@ -112,3 +142,49 @@ string_to_float(const Glib::ustring& str, float& f)
ss << str;
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 <sstream>
#include <iostream>
#include <vector>
#include <stdexcept>
#include <glibmm/ustring.h>
// FIXME : mark this file as deprecated.
#warning "This file is obsolete and deprecated."
#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).
\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);
/**\brief This function converts an integer value into a string.
There is no return value because this function always succeeds.
*/
void SG_DLLEXPORT int_to_string(const int&, Glib::ustring&);
*/
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.
*/
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 value 0 is assigned.
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

View File

@ -21,10 +21,14 @@
#include "backend/string_utils.hh"
#include "backend/policies_gatekeeper.hh"
#include "backend/policy_manager.hh"
#include "backend/policy_parameters.hh"
#include "backend/history.hh"
#include "text_simulation.hh"
#include <sstream>
using namespace std;
using namespace sgpem;
using namespace memory;
@ -50,9 +54,320 @@ TextSimulation::add_io_device(smart_ptr<IOManager> io)
// 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
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;
// 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."));
// return;
// }
}
//}
void
@ -530,3 +845,4 @@ TextSimulation::_io_loop(pair<TextSimulation* , int > pun)
pun.first->parse_command(p);
}
}

View File

@ -27,7 +27,8 @@
#include "simulation.hh"
#include "io_manager.hh"
#include "templates/smartp.hh"
#include "backend/policy_parameters.hh"
//#include "backend/policy_parameters.hh"
#include "backend/string_utils.hh"
#include "smartp.hh"
@ -120,6 +121,25 @@ namespace sgpem
void update();
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;
static void _io_loop(std::pair<TextSimulation*, int>);
};