#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(). |
|
|