#include <variable.h>
Inheritance diagram for NLMISC::IVariable:

Public Types | |
| typedef std::map< std::string, ICommand * > | TCommand |
| enum | TType { Unknown, Command, Variable } |
Public Member Functions | |
| 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)=0 |
| const std::string & | getName () const |
| IVariable (const char *commandName, const char *commandHelp, const char *commandArgs="[< value >]", bool useConfigFile=false, void(*cc)(IVariable &var)=NULL) | |
| virtual std::string | toString (bool human=false) const=0 |
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 | |
| TCommand * | Commands |
| bool | CommandsInit |
Protected Attributes | |
| std::string | _CommandName |
| void(* | ChangeCallback )(IVariable &var) |
Private Attributes | |
| bool | _UseConfigFile |
Friends | |
| void | cbVarChanged (CConfigFile::CVar &var) |
|
|
Definition at line 116 of file command.h. Referenced by NLMISC::ICommand::ICommand(). |
|
|
Definition at line 111 of file command.h.
|
|
||||||||||||||||||||||||
|
Definition at line 138 of file variable.h. References _UseConfigFile, and ChangeCallback.
00138 : 00139 ICommand(commandName, commandHelp, commandArgs), _UseConfigFile(useConfigFile), ChangeCallback(cc) 00140 { 00141 Type = Variable; 00142 } |
|
||||||||||||||||||||
|
Executes the command and display output to the log
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 }
|
|
||||||||||||||||||||
|
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(), fromString(), and 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 }
|
|
|
returns true if the command exists
Definition at line 384 of file command.cpp.
00385 {
00386 return ((*Commands).find(commandName) != (*Commands).end ());
00387 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
Implemented in NLMISC::CVariablePtr< T >, NLMISC::CVariable< T >, NLMISC::CVariable< uint16 >, and NLMISC::CVariable< std::string >. Referenced by NLNET::cbDirectoryChanged(), NLMISC::cbVarChanged(), execute(), and init(). |
|
|
Definition at line 145 of file command.h. References NLMISC::ICommand::_CommandName. Referenced by NLNET::cbDirectoryChanged().
00145 { return _CommandName; }
|
|
|
Definition at line 50 of file variable.cpp. References NLMISC::ICommand::_CommandName, _UseConfigFile, NLMISC::CConfigFile::CVar::asString(), NLMISC::cbVarChanged(), 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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Implemented in NLMISC::CVariablePtr< T >, NLMISC::CVariable< T >, NLMISC::CVariable< uint16 >, and NLMISC::CVariable< std::string >. Referenced by NLNET::cbDirectoryChanged(), execute(), and NLNET::UpdateAssertionThreadTimeoutCB(). |
|
|
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 }
|
|
|
Definition at line 149 of file command.h. Referenced by NLMISC::ICommand::getName(), NLMISC::ICommand::ICommand(), and init(). |
|
|
Definition at line 175 of file variable.h. Referenced by init(), and IVariable(). |
|
|
Referenced by NLMISC::CVariablePtr< T >::fromString(), IVariable(), and NLMISC::CVariable< std::string >::set(). |
|
|
Definition at line 108 of file command.h. Referenced by NLMISC::ICommand::ICommand(). |
|
|
Definition at line 35 of file command.cpp. Referenced by NLMISC::ICommand::ICommand(), and NLMISC::ICommand::~ICommand(). |
|
|
Definition at line 36 of file command.cpp. Referenced by NLMISC::ICommand::ICommand(), and NLMISC::ICommand::~ICommand(). |
|
|
Definition at line 107 of file command.h. Referenced by NLMISC::ICommand::ICommand(). |
|
|
|
1.3.6