ConsoleAPI::ConsoleAPI(Framework *fw) : QObject(fw), framework(fw), enabledLogChannels(LogLevelErrorWarnInfo), logFile(0), logFileText(0) { if (!fw->IsHeadless()) consoleWidget = new ConsoleWidget(framework); inputContext = framework->Input()->RegisterInputContext("Console", 100); inputContext->SetTakeKeyboardEventsOverQt(true); connect(inputContext.get(), SIGNAL(KeyEventReceived(KeyEvent *)), SLOT(HandleKeyEvent(KeyEvent *))); RegisterCommand("help", "Lists all registered commands.", this, SLOT(ListCommands())); RegisterCommand("clear", "Clears the console log.", this, SLOT(ClearLog())); RegisterCommand("setLogLevel", "Sets the current log level. Call with one of the parameters \"error\", \"warning\", \"info\", or \"debug\".", this, SLOT(SetLogLevel(const QString &))); #ifdef WIN32 RegisterCommand("createConsole", "Creates the native Windows console if Tundra was started without such.", this, SLOT(CreateNativeConsole())); RegisterCommand("removeConsole", "Removes the native Windows console if applicable.", this, SLOT(RemoveNativeConsole())); #endif /// \todo Visual Leak Detector shows a memory leak originating from this allocation although the shellInputThread is released in the destructor. Perhaps a shared pointer is held elsewhere. shellInputThread = MAKE_SHARED(ShellInputThread); QStringList logLevel = fw->CommandLineParameters("--loglevel"); if (logLevel.size() >= 1) SetLogLevel(logLevel[logLevel.size()-1]); if (logLevel.size() > 1) LogWarning("Ignoring multiple --loglevel command line parameters!"); QStringList logFile = fw->CommandLineParameters("--logfile"); if (logFile.size() >= 1) SetLogFile(logFile[logFile.size()-1]); if (logFile.size() > 1) LogWarning("Ignoring multiple --logfile command line parameters!"); }
/* =============== Cmd_List_f Lists the commands to the console =============== */ void Cmd_List_f(void) { ListCommands (Cmd_Argv(1)); }
void main(int argc, char* argv[]) { #ifdef DEBUG_MODE std::cout << "Press any key to continue..." << std::endl; std::getchar(); #endif auto DoExit = [&](int code) { //erase all tools DeleteTools(); sLogger->WaitUntilEmpty(); exit(code); }; InitTools(); //if no command given, list commands if(argc == 1) { sLogger->Out(Logger::LogLevel::LOG_LEVEL_NORMAL, "AdtTools v%s", ADTTOOLS_VERSION); sLogger->Out(Logger::LogLevel::LOG_LEVEL_NORMAL, "%s", TOOLS_DESCRIPTION); ListCommands(); DoExit(0); } //else if command given std::string executableName = argv[0]; std::string commandName = argv[1]; //check if command exists ConsoleTool* tool = GetToolWithName(commandName); if(!tool) { sLogger->Out(Logger::LogLevel::LOG_LEVEL_ERROR, "%s", "No command found with this name."); ListCommands(); DoExit(1); } if(argc == 2) //if only the command name was given, show extended description { ShowExtendedDescription(executableName, commandName, tool); DoExit(0); } else { //if command argument(s) is/are given unsigned int argCount = argc - 2; if(argCount < tool->GetMinArgumentCount()) { sLogger->Out(Logger::LogLevel::LOG_LEVEL_ERROR, "%s", "Too few arguments."); PrintUsage(executableName, commandName, tool); DoExit(0); } else if (argCount > tool->GetMaxArgumentCount()) { sLogger->Out(Logger::LogLevel::LOG_LEVEL_ERROR, "%s", "Too much arguments."); PrintUsage(executableName, commandName, tool); DoExit(0); } } //all okay let's get to work int error = tool->Work(argc, argv); DoExit(error); }
static void CompleteCommand (void) { char *matches[MAX_MATCHES]; char backup[MAXCMDLINE]; char c, *prefix, *workline; qboolean editing; int count, i; size_t len1, len2; if (key_linepos < 2) return; workline = key_lines[edit_line]; c = workline[key_linepos]; editing = (c != 0); if (editing) { // make a copy of the text starting from the // cursor position (see below) q_strlcpy(backup, workline + key_linepos, sizeof(backup)); } // complete the text only up to the cursor position: // bash style. cut off the rest for now. workline[key_linepos] = 0; prefix = workline + 1; // skip the leading whitespace and command markers while (*prefix) { if (*prefix != '\\' && *prefix != '/' && *prefix > ' ') break; ++prefix; } // if the remainder line has no length or has // spaces in it, don't bother if (!*prefix || strstr(prefix," ")) { workline[key_linepos] = c; return; } // store the length of the relevant partial len1 = len2 = strlen(prefix); // start checking for matches, finally... count = 0; count += ListCommands(prefix, (const char**)matches, count); count += ListCvars (prefix, (const char**)matches, count); count += ListAlias (prefix, (const char**)matches, count); if (count) { // do not do a full auto-complete // unless there is only one match if (count == 1) { workline[1] = '/'; q_strlcpy (workline + 2, matches[0], MAXCMDLINE-2); key_linepos = 2 + strlen(matches[0]); // q_strlcpy (workline + 1, matches[0], MAXCMDLINE-1); // key_linepos = 1 + strlen(matches[0]); workline[key_linepos] = ' '; key_linepos++; } else { // more than one match, sort and list all of them qsort (matches, count, sizeof(char *), COM_StrCompare); Con_Printf("\n"); #if 0 // plain listing for (i = 0; i < count && i < MAX_MATCHES; i++) Con_Printf ("%s\n", matches[i]); Con_Printf("\n%d matches found\n\n", count); #else // S.A.: columnize the listing. Con_Printf("%d possible completions:\n\n", count); Con_ShowList (count, (const char**) matches); Con_Printf("\n"); #endif // cycle throgh all matches and see // if there is a partial completion _search: for (i = 1; i < count && i < MAX_MATCHES; i++) { if (matches[0][len2] != matches[i][len2]) goto _check; } ++len2; goto _search; _check: if (len2 > len1) // found a partial match { workline[1] = '/'; strncpy (workline + 2, matches[0], len2); key_linepos = len2 + 2; // strncpy (workline + 1, matches[0], len2); // key_linepos = len2 + 1; } } workline[key_linepos] = 0; } // put back the remainder of the original text // which was lost after the trimming if (editing) q_strlcpy (workline + key_linepos, backup, MAXCMDLINE-key_linepos); }