NLMISC::CVariablePtr< T > Class Template Reference

#include <variable.h>

Inheritance diagram for NLMISC::CVariablePtr< T >:

NLMISC::IVariable NLMISC::ICommand

template<class T>
class NLMISC::CVariablePtr< T >


Public Types

typedef std::map< std::string,
ICommand * > 
TCommand
enum  TType { Unknown, Command, Variable }

Public Member Functions

 CVariablePtr (const char *commandName, const char *commandHelp, T *valueptr, bool useConfigFile=false, void(*cc)(IVariable &var)=NULL)
virtual bool execute (const std::vector< std::string > &args, NLMISC::CLog &log, bool quiet, bool human)
virtual void fromString (const std::string &val, bool human=false)
const std::string & getName () const
virtual std::string toString (bool human) const

Static Public Member Functions

void execute (const std::string &commandWithArgs, NLMISC::CLog &log, bool quiet=false, bool human=true)
bool exists (std::string &commandName)
 returns true if the command exists

void expand (std::string &commandName, NLMISC::CLog &log=*InfoLog)
void init (CConfigFile &configFile)
bool isCommand (const std::string &str)
 if the string begin with an upper case, it s a variable, otherwise, it s a command

void serialCommands (IStream &f)

Data Fields

std::string CommandArgs
std::string HelpString
TType Type

Static Public Attributes

TCommandCommands
bool CommandsInit

Protected Attributes

std::string _CommandName
void(* ChangeCallback )(IVariable &var)

Private Attributes

T * _ValuePtr

Friends

void cbVarChanged (CConfigFile::CVar &var)

Member Typedef Documentation

typedef std::map<std::string, ICommand *> NLMISC::ICommand::TCommand [inherited]
 

Definition at line 116 of file command.h.

Referenced by NLMISC::ICommand::ICommand().


Member Enumeration Documentation

enum NLMISC::ICommand::TType [inherited]
 

Enumeration values:
Unknown 
Command 
Variable 

Definition at line 111 of file command.h.

00111 { Unknown, Command, Variable };


Constructor & Destructor Documentation

template<class T>
NLMISC::CVariablePtr< T >::CVariablePtr const char *  commandName,
const char *  commandHelp,
T *  valueptr,
bool  useConfigFile = false,
void(*  cc)(IVariable &var) = NULL
[inline]
 

Definition at line 191 of file variable.h.

References NLMISC::CVariablePtr< T >::_ValuePtr, and value.

00191                                                                                                                                                   :
00192                 IVariable (commandName, commandHelp, "[<value>]", useConfigFile, cc), _ValuePtr(valueptr)
00193         {
00194         }


Member Function Documentation

void NLMISC::ICommand::execute const std::string &  commandWithArgs,
NLMISC::CLog log,
bool  quiet = false,
bool  human = true
[static, inherited]
 

Executes the command and display output to the log

Parameters:
quiet true if you don't want to display the "executing the command ..."

Definition at line 103 of file command.cpp.

References NLMISC::CLog::displayNL(), and uint.

00104 {
00105         if (!quiet) log.displayNL ("Executing command : '%s'", commandWithArgs.c_str());
00106 
00107         // convert the buffer into string vector
00108         vector<pair<string, vector<string> > > commands;
00109         
00110         bool firstArg = true;
00111         uint i = 0;
00112         while (true)
00113         {
00114                 // skip whitespace
00115                 while (true)
00116                 {
00117                         if (i == commandWithArgs.size())
00118                         {
00119                                 goto end;
00120                         }
00121                         if (commandWithArgs[i] != ' ' && commandWithArgs[i] != '\t' && commandWithArgs[i] != '\n' && commandWithArgs[i] != '\r')
00122                         {
00123                                 break;
00124                         }
00125                         i++;
00126                 }
00127                 
00128                 // get param
00129                 string arg;
00130                 if (commandWithArgs[i] == '\"')
00131                 {
00132                         // starting with a quote "
00133                         i++;
00134                         while (true)
00135                         {
00136                                 if (i == commandWithArgs.size())
00137                                 {
00138                                         if (!quiet) log.displayNL ("Missing end quote character \"");
00139                                         return;
00140                                 }
00141                                 if (commandWithArgs[i] == '"')
00142                                 {
00143                                         i++;
00144                                         break;
00145                                 }
00146                                 if (commandWithArgs[i] == '\\')
00147                                 {
00148                                         // manage escape char backslash
00149                                         i++;
00150                                         if (i == commandWithArgs.size())
00151                                         {
00152                                                 if (!quiet) log.displayNL ("Missing character after the backslash \\ character");
00153                                                 return;
00154                                         }
00155                                         switch (commandWithArgs[i])
00156                                         {
00157                                                 case '\\':      arg += '\\'; break; // double backslash
00158                                                 case 'n':       arg += '\n'; break; // new line
00159                                                 case '"':       arg += '"'; break; // "
00160                                                 default:
00161                                                         if (!quiet) log.displayNL ("Unknown escape code '\\%c'", commandWithArgs[i]);
00162                                                         return;
00163                                         }
00164                                         i++;
00165                                 }
00166                                 else
00167                                 {
00168                                         arg += commandWithArgs[i++];
00169                                 }
00170                         }
00171                 }
00172                 else
00173                 {
00174                         // normal word
00175                         while (true)
00176                         {
00177                                 if (commandWithArgs[i] == '\\')
00178                                 {
00179                                         // manage escape char backslash
00180                                         i++;
00181                                         if (i == commandWithArgs.size())
00182                                         {
00183                                                 if (!quiet) log.displayNL ("Missing character after the backslash \\ character");
00184                                                 return;
00185                                         }
00186                                         switch (commandWithArgs[i])
00187                                         {
00188                                                 case '\\':      arg += '\\'; break; // double backslash
00189                                                 case 'n':       arg += '\n'; break; // new line
00190                                                 case '"':       arg += '"'; break; // "
00191                                                 case ';':       arg += ';'; break; // ;
00192                                                 default:
00193                                                         if (!quiet) log.displayNL ("Unknown escape code '\\%c'", commandWithArgs[i]);
00194                                                         return;
00195                                         }
00196                                 }
00197                                 else if (commandWithArgs[i] == ';')
00198                                 {
00199                                         // command separator
00200                                         break;
00201                                 }
00202                                 else
00203                                 {
00204                                         arg += commandWithArgs[i];
00205                                 }
00206 
00207                                 i++;
00208 
00209                                 if (i == commandWithArgs.size() || commandWithArgs[i] == ' ' || commandWithArgs[i] == '\t' || commandWithArgs[i] == '\n' || commandWithArgs[i] == '\r')
00210                                 {
00211                                         break;
00212                                 }
00213                         }
00214                 }
00215 
00216                 if (!arg.empty())
00217                 {
00218                         if (firstArg)
00219                         {
00220                                 commands.push_back (make_pair(arg, vector<string> () ));
00221                                 firstArg = false;
00222                         }
00223                         else
00224                         {
00225                                 commands[commands.size()-1].second.push_back (arg);
00226                         }
00227                 }
00228 
00229                 // separator
00230                 if (i < commandWithArgs.size() && commandWithArgs[i] == ';')
00231                 {
00232                         firstArg = true;
00233                         i++;
00234                 }
00235         }
00236 end:
00237 
00238 // displays args for debug purpose
00239 /*      for (uint u = 0; u < commands.size (); u++)
00240         {
00241                 nlinfo ("c '%s'", commands[u].first.c_str());
00242                 for (uint t = 0; t < commands[u].second.size (); t++)
00243                 {
00244                         nlinfo ("p%d '%s'", t, commands[u].second[t].c_str());
00245                 }
00246         }
00247 */
00248 
00249         for (uint u = 0; u < commands.size (); u++)
00250         {
00251                 // find the command     
00252                 TCommand::iterator comm = (*Commands).find(commands[u].first);
00253                 if (comm == (*Commands).end ())
00254                 {
00255                         // the command doesn't exist
00256                         if (!quiet) log.displayNL("Command '%s' not found, try 'help'", commands[u].first.c_str());
00257                 }
00258                 else
00259                 {
00260                         //nlinfo("execute command '%s'", commands[u].first.c_str());
00261                         if (!(*comm).second->execute (commands[u].second, log, quiet, human))
00262                         {
00263                                 if (!quiet) log.displayNL("Bad command usage, try 'help %s'", commands[u].first.c_str());
00264                         }
00265                 }
00266         }
00267 }

virtual bool NLMISC::IVariable::execute const std::vector< std::string > &  args,
NLMISC::CLog log,
bool  quiet,
bool  human
[inline, virtual, inherited]
 

Implements NLMISC::ICommand.

Reimplemented in NLMISC::CVariable< T >, NLMISC::CVariable< uint16 >, and NLMISC::CVariable< std::string >.

Definition at line 148 of file variable.h.

References NLMISC::CLog::displayNL(), NLMISC::IVariable::fromString(), and NLMISC::IVariable::toString().

00149         {
00150                 if (args.size() > 1)
00151                         return false;
00152                 
00153                 if (args.size() == 1)
00154                 {
00155                         // set the value
00156                         fromString (args[0], human);
00157                 }
00158                 
00159                 // display the value
00160                 if (quiet)
00161                 {
00162                         log.displayNL(toString(human).c_str());
00163                 }
00164                 else
00165                 {
00166                         log.displayNL("Variable %s = %s", _CommandName.c_str(), toString(human).c_str());
00167                 }
00168                 return true;
00169         }

bool NLMISC::ICommand::exists std::string &  commandName  )  [static, inherited]
 

returns true if the command exists

Definition at line 384 of file command.cpp.

00385 {
00386         return ((*Commands).find(commandName) != (*Commands).end ());
00387 }

void NLMISC::ICommand::expand std::string &  commandName,
NLMISC::CLog log = *InfoLog
[static, inherited]
 

Command name completion. Case-sensitive. Displays the list after two calls with the same non-unique completion. Completes commands used with prefixes (such as "help " for example) as well.

Definition at line 275 of file command.cpp.

References NLMISC::CLog::displayNL(), NLMISC::strlwr(), uint, and uint32.

00276 {
00277         // Take out the string before the last separator and remember it as a prefix
00278         uint32 lastseppos = commandName.find_last_of( " " );
00279         string prefix;
00280         bool useprefix;
00281         if ( lastseppos != string::npos )
00282         {
00283                 prefix = commandName.substr( 0, lastseppos+1 );
00284                 commandName.erase( 0, lastseppos+1 );
00285                 useprefix = true;
00286         }
00287         else
00288         {
00289                 useprefix = false;
00290         }
00291 
00292         string lowerCommandName = strlwr(const_cast<const string &>(commandName));
00293         // Build the list of matching command names
00294         vector<string> matchingnames;
00295         for (TCommand::iterator comm = (*Commands).begin(); comm != (*Commands).end(); comm++)
00296         {
00297                 string first = strlwr(const_cast<const string &>((*comm).first));
00298                 if (first.find( lowerCommandName ) == 0)
00299                 {
00300                         matchingnames.push_back( (*comm).first );
00301                 }
00302         }
00303 
00304         // Do not complete if there is no result
00305         if ( matchingnames.empty() )
00306         {
00307                 log.displayNL( "No matching command" );
00308                 goto returnFromExpand;
00309         }
00310 
00311         // Complete if there is a single result
00312         if ( matchingnames.size() == 1 )
00313         {
00314                 commandName = matchingnames.front() + " ";
00315                 goto returnFromExpand;
00316         }
00317 
00318         // Try to complete to the common part if there are several results
00319         {
00320                 // Stop loop when a name size is i or names[i] are different
00321                 string commonstr = commandName;
00322                 uint i = commandName.size();
00323                 while ( true )
00324                 {
00325                         char letter = 0;
00326                         vector<string>::iterator imn;
00327                         for ( imn=matchingnames.begin(); imn!=matchingnames.end(); ++imn )
00328                         {
00329                                 // Return common string if the next letter is not the same in all matching names
00330                                 if ( ((*imn).size() == i) || ( (letter!=0) && ((*imn)[i] != letter) ) )
00331                                 {
00332                                         log.displayNL( "(Matching command not unique)" );
00333                                         static string lastCommandName;
00334                                         commandName = commonstr;
00335                                         if ( lastCommandName == commandName )
00336                                         {
00337                                                 // Display all the matching names 
00338                                                 vector<string>::iterator imn2;
00339                                                 //stringstream ss;
00340                                                 string str;
00341                                                 //ss << "Matching commands:" << endl;
00342                                                 str += "Matching commands:\n";
00343                                                 for ( imn2=matchingnames.begin(); imn2!=matchingnames.end(); ++imn2 )
00344                                                 {
00345                                                         //ss << " " << (*imn2);
00346                                                         str += " " + (*imn2);
00347                                                 }
00348                                                 log.displayNL( "%s", str.c_str() );
00349                                         }
00350                                         lastCommandName = commandName;
00351                                         goto returnFromExpand;
00352                                 }
00353                                 // Add the next letter to the common string if it is the same in all matching names
00354                                 else if ( letter == 0 )
00355                                 {
00356                                         letter = (*imn)[i];
00357                                 }
00358                         }
00359                         commonstr += letter;
00360                         ++i;
00361                 }
00362         }
00363 
00364 returnFromExpand:
00365 
00366         // Put back the prefix
00367         if ( useprefix )
00368         {
00369                 commandName = prefix + commandName;
00370         }
00371 }

template<class T>
virtual void NLMISC::CVariablePtr< T >::fromString const std::string &  val,
bool  human = false
[inline, virtual]
 

Implements NLMISC::IVariable.

Definition at line 196 of file variable.h.

References NLMISC::CVariablePtr< T >::_ValuePtr, NLMISC::IVariable::ChangeCallback, and NLMISC::fromString().

00197         {
00198                 //std::stringstream ss (val);
00199                 //ss >> *_ValuePtr;
00200                 NLMISC::fromString(val, *_ValuePtr);
00201                 if (ChangeCallback) ChangeCallback (*this);
00202         }

const std::string& NLMISC::ICommand::getName void   )  const [inline, inherited]
 

Definition at line 145 of file command.h.

References NLMISC::ICommand::_CommandName.

Referenced by NLNET::cbDirectoryChanged().

00145 { return _CommandName; }

void NLMISC::IVariable::init CConfigFile configFile  )  [static, inherited]
 

Definition at line 50 of file variable.cpp.

References NLMISC::ICommand::_CommandName, NLMISC::IVariable::_UseConfigFile, NLMISC::CConfigFile::CVar::asString(), NLMISC::cbVarChanged(), NLMISC::IVariable::fromString(), NLMISC::CConfigFile::getFilename(), NLMISC::CConfigFile::getVarPtr(), nlinfo, nlwarning, and NLMISC::CConfigFile::setCallback().

Referenced by NLNET::IService::main().

00051 {
00052         for (TCommand::iterator comm = (*Commands).begin(); comm != (*Commands).end(); comm++)
00053         {
00054                 if ((*comm).second->Type == ICommand::Variable)
00055                 {
00056                         IVariable *var = (IVariable *)((*comm).second);
00057                         if (var->_UseConfigFile)
00058                         {
00059                                 configFile.setCallback(var->_CommandName, cbVarChanged);
00060                                 CConfigFile::CVar *cvar = configFile.getVarPtr(var->_CommandName);
00061                                 if (cvar != 0)
00062                                 {
00063                                         string val = cvar->asString();
00064                                         nlinfo ("VAR: Setting variable '%s' with value '%s' from config file '%s'", var->_CommandName.c_str(), val.c_str(), configFile.getFilename().c_str());
00065                                         var->fromString(val, true);
00066                                 }
00067                                 else
00068                                 {
00069                                         nlwarning ("VAR: No variable '%s' in config file '%s'", var->_CommandName.c_str(), configFile.getFilename().c_str());
00070                                 }
00071                         }
00072                 }
00073         }
00074 }

bool NLMISC::ICommand::isCommand const std::string &  str  )  [inline, static, inherited]
 

if the string begin with an upper case, it s a variable, otherwise, it s a command

Definition at line 137 of file command.h.

00138         {
00139                 if (str.empty())
00140                         return false;
00141                 
00142                 return isupper(str[0]) == 0;
00143         }

void NLMISC::ICommand::serialCommands IStream f  )  [static, inherited]
 

Definition at line 374 of file command.cpp.

References NLMISC::IStream::serialCont().

00375 {
00376         vector<CSerialCommand> cmd;
00377         for (TCommand::iterator comm = (*Commands).begin(); comm != (*Commands).end(); comm++)
00378         {
00379                 cmd.push_back (CSerialCommand ((*comm).first, (*comm).second->Type));
00380         }
00381         f.serialCont (cmd);
00382 }

template<class T>
virtual std::string NLMISC::CVariablePtr< T >::toString bool  human  )  const [inline, virtual]
 

Implements NLMISC::IVariable.

Definition at line 204 of file variable.h.

References NLMISC::CVariablePtr< T >::_ValuePtr, and NLMISC::toString().

00205         {
00206                 //std::stringstream ss;
00207                 //ss << *_ValuePtr;
00208                 //return ss.str();
00209                 return NLMISC::toString(*_ValuePtr);
00210         }


Friends And Related Function Documentation

void cbVarChanged CConfigFile::CVar var  )  [friend, inherited]
 

Definition at line 36 of file variable.cpp.

00037 {
00038         for (ICommand::TCommand::iterator comm = (*ICommand::Commands).begin(); comm != (*ICommand::Commands).end(); comm++)
00039         {
00040                 if ((*comm).second->Type == ICommand::Variable && (*comm).second->_CommandName == cvar.Name)
00041                 {
00042                         IVariable *var = (IVariable *)((*comm).second);
00043                         string val = cvar.asString();
00044                         nlinfo ("VAR: Setting variable '%s' with value '%s' from config file", cvar.Name.c_str(), val.c_str());
00045                         var->fromString(val, true);
00046                 }
00047         }
00048 }


Field Documentation

std::string NLMISC::ICommand::_CommandName [protected, inherited]
 

Definition at line 149 of file command.h.

Referenced by NLMISC::ICommand::getName(), NLMISC::ICommand::ICommand(), and NLMISC::IVariable::init().

template<class T>
T* NLMISC::CVariablePtr< T >::_ValuePtr [private]
 

Definition at line 214 of file variable.h.

Referenced by NLMISC::CVariablePtr< T >::CVariablePtr(), NLMISC::CVariablePtr< T >::fromString(), and NLMISC::CVariablePtr< T >::toString().

void(* NLMISC::IVariable::ChangeCallback)(IVariable &var) [protected, inherited]
 

Referenced by NLMISC::CVariablePtr< T >::fromString(), NLMISC::IVariable::IVariable(), and NLMISC::CVariable< std::string >::set().

std::string NLMISC::ICommand::CommandArgs [inherited]
 

Definition at line 108 of file command.h.

Referenced by NLMISC::ICommand::ICommand().

ICommand::TCommand * NLMISC::ICommand::Commands [static, inherited]
 

Definition at line 35 of file command.cpp.

Referenced by NLMISC::ICommand::ICommand(), and NLMISC::ICommand::~ICommand().

bool NLMISC::ICommand::CommandsInit [static, inherited]
 

Definition at line 36 of file command.cpp.

Referenced by NLMISC::ICommand::ICommand(), and NLMISC::ICommand::~ICommand().

std::string NLMISC::ICommand::HelpString [inherited]
 

Definition at line 107 of file command.h.

Referenced by NLMISC::ICommand::ICommand().

TType NLMISC::ICommand::Type [inherited]
 

Definition at line 112 of file command.h.


The documentation for this class was generated from the following file:
Generated on Tue Mar 16 13:41:04 2004 for NeL by doxygen 1.3.6