void CCommand::execute (CEntity *entity, const std::string &commandWithArgs, CLog &log, bool quiet, bool human) { if (!quiet) { ucstring temp; temp.fromUtf8(commandWithArgs); string disp = temp.toString(); log.displayNL ("Executing command : '%s'", disp.c_str()); } // convert the buffer into string vector vector<pair<string, vector<string> > > commands; bool firstArg = true; uint i = 0; while (true) { // skip whitespace while (true) { if (i == commandWithArgs.size()) { goto end; } if (commandWithArgs[i] != ' ' && commandWithArgs[i] != '\t' && commandWithArgs[i] != '\n' && commandWithArgs[i] != '\r') { break; } i++; } // get param string arg; if (commandWithArgs[i] == '\"') { // starting with a quote " i++; while (true) { if (i == commandWithArgs.size()) { if (!quiet) log.displayNL ("Missing end quote character \""); return; } if (commandWithArgs[i] == '"') { i++; break; } if (commandWithArgs[i] == '\\') { // manage escape char backslash i++; if (i == commandWithArgs.size()) { if (!quiet) log.displayNL ("Missing character after the backslash \\ character"); return; } switch (commandWithArgs[i]) { case '\\': arg += '\\'; break; // double backslash case 'n': arg += '\n'; break; // new line case '"': arg += '"'; break; // " default: if (!quiet) log.displayNL ("Unknown escape code '\\%c'", commandWithArgs[i]); return; } i++; } else { arg += commandWithArgs[i++]; } } } else { // normal word while (true) { if (commandWithArgs[i] == '\\') { // manage escape char backslash i++; if (i == commandWithArgs.size()) { if (!quiet) log.displayNL ("Missing character after the backslash \\ character"); return; } switch (commandWithArgs[i]) { case '\\': arg += '\\'; break; // double backslash case 'n': arg += '\n'; break; // new line case '"': arg += '"'; break; // " case ';': arg += ';'; break; // ; default: if (!quiet) log.displayNL ("Unknown escape code '\\%c'", commandWithArgs[i]); return; } } else if (commandWithArgs[i] == ';') { // command separator break; } else { arg += commandWithArgs[i]; } i++; if (i == commandWithArgs.size() || commandWithArgs[i] == ' ' || commandWithArgs[i] == '\t' || commandWithArgs[i] == '\n' || commandWithArgs[i] == '\r') { break; } } } if (!arg.empty()) { if (firstArg) { commands.push_back (make_pair(arg, vector<string> () )); firstArg = false; } else { commands[commands.size()-1].second.push_back (arg); } } // separator if (i < commandWithArgs.size() && commandWithArgs[i] == ';') { firstArg = true; i++; } } end: // displays args for debug purpose /* for (uint u = 0; u < commands.size (); u++) { nlinfo ("c '%s'", commands[u].first.c_str()); for (uint t = 0; t < commands[u].second.size (); t++) { nlinfo ("p%d '%s'", t, commands[u].second[t].c_str()); } } */ for (uint u = 0; u < commands.size (); u++) { if(!CCommandRegistry::getInstance().isCommand(commands[u].first)) { // the command doesn't exist if (!quiet) log.displayNL("Command '%s' not found, try 'help'", commands[u].first.c_str()); } else { ICommand *icom = CCommandRegistry::getInstance().getCommand(commands[u].first); //ICommand *icom = (*comm).second; if(icom->CategoryName=="mtpt_commands")//TODO find a better way, bad macro usage can result in bad cast :((( { CCommand *ccom = (CCommand *)icom; if (!ccom->execute (entity,commands[u].second, log, quiet, human)) { if (!quiet) log.displayNL("Bad ccommand usage, try 'help %s'", commands[u].first.c_str()); } } else { if (!icom->execute(NULL, commands[u].second, log, quiet, human)) { if (!quiet) log.displayNL("Bad icommand usage, try 'help %s'", commands[u].first.c_str()); } } } } }