23 #include "shared/shared.h" 
   24 #include "common/common.h" 
   25 #include "common/cvar.h" 
   26 #include "common/field.h" 
   27 #include "common/files.h" 
   28 #include "common/prompt.h" 
   36     int count = end - start;
 
   37     int numCols = 7, numLines;
 
   39     size_t maxlen, len, total;
 
   46         numLines = ceil((
float)count / numCols);
 
   48         for (i = 0; i < numCols; i++) {
 
   49             k = start + numLines * i;
 
   54             for (j = k; j < k + numLines && j < end; j++) {
 
   55                 len = strlen(matches[j]);
 
   61             if (maxlen > prompt->widthInChars) {
 
   62                 maxlen = prompt->widthInChars;
 
   64             colwidths[i] = maxlen;
 
   67         if (total < prompt->widthInChars) {
 
   70     } 
while (numCols > 1);
 
   72     for (i = 0; i < numLines; i++) {
 
   73         for (j = 0; j < numCols; j++) {
 
   74             k = start + j * numLines + i;
 
   79             prompt->printf(
"%s", match);
 
   81             if (len < colwidths[j]) {
 
   83                 for (k = 0; k < colwidths[j] - len; k++) {
 
   93     commandPrompt_t *prompt,
 
  102         qsort(matches + offset, numCommands, 
sizeof(matches[0]), 
SortStrcmp);
 
  104         prompt->printf(
"\n%i possible command%s:\n",
 
  105                        numCommands, numCommands != 1 ? 
"s" : 
"");
 
  108         offset += numCommands;
 
  112         qsort(matches + offset, numCvars, 
sizeof(matches[0]), 
SortStrcmp);
 
  114         prompt->printf(
"\n%i possible variable%s:\n",
 
  115                        numCvars, numCvars != 1 ? 
"s" : 
"");
 
  122         qsort(matches + offset, numAliases, 
sizeof(matches[0]), 
SortStrcmp);
 
  124         prompt->printf(
"\n%i possible alias%s:\n",
 
  125                        numAliases, numAliases != 1 ? 
"es" : 
"");
 
  128         offset += numAliases;
 
  132 static qboolean 
find_dup(genctx_t *ctx, 
const char *s)
 
  136     for (i = 0; i < ctx->count; i++) {
 
  140             r = strcmp(ctx->matches[i], s);
 
  153     if (ctx->count >= ctx->size)
 
  159         r = strncmp(ctx->partial, s, ctx->length);
 
  164     if (ctx->ignoredups && 
find_dup(ctx, s))
 
  167     ctx->matches[ctx->count++] = Z_CopyString(s);
 
  177         if (
c == 
'$' || 
c == 
';' || !Q_isgraph(
c)) {
 
  192     inputField_t *inputLine = &prompt->inputLine;
 
  193     char *text, *partial, *s;
 
  194     int i, argc, currentArg, argnum;
 
  195     size_t size, len, pos;
 
  198     char *matches[MAX_MATCHES], *sortedMatches[MAX_MATCHES];
 
  199     int numCommands, numCvars, numAliases;
 
  201     text = inputLine->text;
 
  202     size = inputLine->maxChars + 1;
 
  203     pos = inputLine->cursorPos;
 
  207         if (inputLine->text[0] != 
'\\' && inputLine->text[0] != 
'/') {
 
  208             memmove(inputLine->text + 1, inputLine->text, size - 1);
 
  209             inputLine->text[0] = 
'\\';
 
  230     for (i = 0; i < currentArg; i++) {
 
  241     if (*partial == 
';') {
 
  249     memset(&ctx, 0, 
sizeof(ctx));
 
  250     ctx.partial = partial;
 
  251     ctx.length = strlen(partial);
 
  252     ctx.argnum = currentArg;
 
  253     ctx.matches = matches;
 
  254     ctx.size = MAX_MATCHES;
 
  259         numCommands = numCvars = numAliases = 0;
 
  263         numCommands = ctx.count;
 
  266         numCvars = ctx.count - numCommands;
 
  269         numAliases = ctx.count - numCvars - numCommands;
 
  273         pos = strlen(inputLine->text);
 
  274         prompt->tooMany = qfalse;
 
  289     if (ctx.count == 1) {
 
  293             pos += 
Q_concat(text, size, 
"\"", matches[0], 
"\" ", s, NULL);
 
  295             pos += 
Q_concat(text, size, matches[0], 
" ", s, NULL);
 
  298         prompt->tooMany = qfalse;
 
  303         prompt->printf(
"Press TAB again to display all %d possibilities.\n", ctx.count);
 
  304         pos = strlen(inputLine->text);
 
  305         prompt->tooMany = qtrue;
 
  309     prompt->tooMany = qfalse;
 
  312     for (i = 0; i < ctx.count; i++) {
 
  313         sortedMatches[i] = matches[i];
 
  315     qsort(sortedMatches, ctx.count, 
sizeof(sortedMatches[0]),
 
  319     first = sortedMatches[0];
 
  320     last = sortedMatches[ctx.count - 1];
 
  323         if (*first != *last) {
 
  324             if (!ctx.ignorecase || Q_tolower(*first) != Q_tolower(*last)) {
 
  328         text[len++] = *first;
 
  329         if (len == size - 1) {
 
  342     if (currentArg + 1 < argc) {
 
  344         pos += 
Q_concat(text + len, size, 
" ", s, NULL);
 
  357         for (i = 0; i < ctx.count; i++) {
 
  358             prompt->printf(
"%s\n", sortedMatches[i]);
 
  375     for (i = 0; i < ctx.count; i++) {
 
  381     if (pos >= inputLine->maxChars) {
 
  382         pos = inputLine->maxChars - 1;
 
  384     inputLine->cursorPos = pos;
 
  392     if (!prompt->search) {
 
  393         s = prompt->inputLine.text;
 
  394         if (*s == 
'/' || *s == 
'\\') {
 
  400         prompt->search = Z_CopyString(s);
 
  404         for (i = prompt->historyLineNum + 1; i < prompt->inputLineNum; i++) {
 
  405             s = prompt->history[i & HISTORY_MASK];
 
  406             if (s && strstr(s, prompt->search)) {
 
  407                 if (strcmp(s, prompt->inputLine.text)) {
 
  414         j = prompt->inputLineNum - HISTORY_SIZE;
 
  418         for (i = prompt->historyLineNum - 1; i >= j; i--) {
 
  419             s = prompt->history[i & HISTORY_MASK];
 
  420             if (s && strstr(s, prompt->search)) {
 
  421                 if (strcmp(s, prompt->inputLine.text)) {
 
  433     prompt->historyLineNum = i;
 
  434     IF_Replace(&prompt->inputLine, prompt->history[i & HISTORY_MASK]);
 
  439     prompt->tooMany = qfalse;
 
  440     if (prompt->search) {
 
  442         prompt->search = NULL;
 
  455     char *s = prompt->inputLine.text;
 
  459     if (s[0] == 0 || ((s[0] == 
'/' || s[0] == 
'\\') && s[1] == 0)) {
 
  465     i = prompt->inputLineNum & HISTORY_MASK;
 
  466     j = (prompt->inputLineNum - 1) & HISTORY_MASK;
 
  467     if (!prompt->history[j] || strcmp(prompt->history[j], s)) {
 
  468         if (prompt->history[i]) {
 
  469             Z_Free(prompt->history[i]);
 
  471         prompt->history[i] = Z_CopyString(s);
 
  472         prompt->inputLineNum++;
 
  478     prompt->historyLineNum = prompt->inputLineNum;
 
  482     return prompt->history[i];
 
  496     if (prompt->historyLineNum == prompt->inputLineNum) {
 
  498         i = prompt->inputLineNum & HISTORY_MASK;
 
  499         if (prompt->history[i]) {
 
  500             Z_Free(prompt->history[i]);
 
  502         prompt->history[i] = Z_CopyString(prompt->inputLine.text);
 
  505     if (prompt->inputLineNum - prompt->historyLineNum < HISTORY_SIZE &&
 
  506         prompt->historyLineNum > 0) {
 
  507         prompt->historyLineNum--;
 
  510     i = prompt->historyLineNum & HISTORY_MASK;
 
  511     IF_Replace(&prompt->inputLine, prompt->history[i]);
 
  525     if (prompt->historyLineNum == prompt->inputLineNum) {
 
  529     prompt->historyLineNum++;
 
  531     i = prompt->historyLineNum & HISTORY_MASK;
 
  532     IF_Replace(&prompt->inputLine, prompt->history[i]);
 
  546     for (i = 0; i < HISTORY_SIZE; i++) {
 
  547         if (prompt->history[i]) {
 
  548             Z_Free(prompt->history[i]);
 
  549             prompt->history[i] = NULL;
 
  553     prompt->historyLineNum = 0;
 
  554     prompt->inputLineNum = 0;
 
  565     FS_FOpenFile(filename, &f, FS_MODE_WRITE | FS_PATH_BASE);
 
  570     if (lines > HISTORY_SIZE) {
 
  571         lines = HISTORY_SIZE;
 
  574     i = prompt->inputLineNum - lines;
 
  578     for (; i < prompt->inputLineNum; i++) {
 
  579         s = prompt->history[i & HISTORY_MASK];
 
  590     char buffer[MAX_FIELD_TEXT];
 
  595     FS_FOpenFile(filename, &f, FS_MODE_READ | FS_TYPE_REAL | FS_PATH_BASE);
 
  600     for (i = 0; i < HISTORY_SIZE; i++) {
 
  601         if ((len = 
FS_ReadLine(f, buffer, 
sizeof(buffer))) < 1) {
 
  604         if (prompt->history[i]) {
 
  605             Z_Free(prompt->history[i]);
 
  607         prompt->history[i] = memcpy(Z_Malloc(len + 1), buffer, len + 1);
 
  612     prompt->historyLineNum = i;
 
  613     prompt->inputLineNum = i;