retcode Terminal::ProcessLine(const string& arLine) { stringstream ss(arLine); // Insert the string into a stream vector<string> tokens; // Create vector to hold our words string buf; while (ss >> buf) tokens.push_back(buf); retcode result = SUCCESS; if(tokens.size() > 0) { ERROR_BLOCK(LEV_INFO, "Executing: " << arLine, TERMINAL_CODE); TokenNode<CommandNode>* pNode = mCmdRoot.FindNode(tokens); CommandNode* pCmd = pNode->GetValue(); if(pCmd->mHandler) { result = pCmd->mHandler(tokens); if(result == BAD_ARGUMENTS) { //print the usage for this command this->QueueSend("usage: " + pCmd->mUsage + "\r\n", false); } } else { //the end node isn't a command, so print it it's subcommands vector<string> subcommands; pNode->GetSubNodeNames(subcommands); this->PrintSubCommands(pCmd->mName, subcommands); } } return result; }
// does recursive lookup on the FullCommand name and popluates the command // hierarchy void Terminal::BindCommand(const CommandNode& arNode, const std::string& arFullCommand) { //tokenize the full command name typedef boost::tokenizer<boost::char_separator<char> > Tok; boost::char_separator<char> sep; // default constructed Tok tok(arFullCommand, sep); std::vector<std::string> tokens; for(Tok::iterator iter = tok.begin(); iter != tok.end(); ++iter) { tokens.push_back(*iter); } // find the deepest tree node TokenNode<CommandNode>* pNode = this->mCmdRoot.FindNode(tokens); // create interior nodes while(tokens.size() > 0) { CommandNode node; node.mName = tokens[0]; node.mUsage = node.mDesc = ""; pNode = pNode->AddToken(tokens[0], node); tokens.erase(tokens.begin()); } //when all the nodes are consume CommandNode* pCmdNode = pNode->GetValue(); if(pCmdNode->mHandler) { // if a handler is already set throw Exception(LOCATION, "Command already has a bound handler: " + arFullCommand); } pNode->SetValue(arNode); }
retcode Terminal::HandleHelp(std::vector<std::string>& arTokens) { if(arTokens.size() > 0) { //help topics were provided //figure out what help the user has requested TokenNode<CommandNode>* pNode = mCmdRoot.FindNode(arTokens); CommandNode* pCmd = pNode->GetValue(); if(arTokens.size() > 0) { //didn't consume all the tokens, didn't find the topic ostringstream oss; oss << "No topic found for: " << arTokens[0] << ITerminal::EOL; this->QueueSend(oss.str()); } else { if(pCmd->mHandler) { // the node is not a command, so print it's subcommands this->QueueSend("usage: " + pCmd->mUsage + "\r\n"); this->QueueSend(pCmd->mDesc + "\r\n"); } else { //the node is a function vector<string> subcmds; pNode->GetSubNodeNames(subcmds); this->PrintSubCommands(pCmd->mName, subcmds); } } } else { //dump out all the commands at the root vector<string> names; deque<string> path; mCmdRoot.GetSubNodesWithOptions(names); this->QueueSend("usage: help [topic] [subtopic 1] ... [subtopic N]\r\n\r\n"); for(size_t i = 0; i < names.size(); i++) this->QueueSend(names[i] + "\r\n"); } return SUCCESS; }
int TokenNode::findChildPos(const QChar &c) const { int low = 0; int high = m_children.count() - 1; while (low <= high) { const int mid = low + (high-low+1)/2; TokenNode* midVal = m_children[mid]; if (midVal->ch() < c) { low = mid + 1; } else if (midVal->ch() > c) { high = mid - 1; } else { return mid; // key found } } return -(low + 1); // key not found }
QDebug operator<<(QDebug& dbg, const TokenNode& node) { return dbg << QString::fromLatin1("TokenNode(%1)").arg(node.ch()); }