예제 #1
0
파일: cfg.c 프로젝트: jwgcarlson/OPSEC
int cfg_write(Config cfg, FILE* f) {
    ConfigEntry entry;
    if(f == NULL) {
        fprintf(stderr, "Config: file pointer is NULL\n");
        return CFG_STREAM_ERROR;
    }
    entry = cfg->first;
    while(entry != NULL) {
        if(needs_quotes(entry->value))
            fprintf(f, "%s = \"%s\"\n", entry->key, entry->value);
        else
            fprintf(f, "%s = %s\n", entry->key, entry->value);
        entry = entry->next;
    }
    return CFG_OKAY;
}
예제 #2
0
파일: prompt.c 프로젝트: Jenco420/q2pro
/*
====================
Prompt_CompleteCommand
====================
*/
void Prompt_CompleteCommand(commandPrompt_t *prompt, qboolean backslash)
{
    inputField_t *inputLine = &prompt->inputLine;
    char *text, *partial, *s;
    int i, argc, currentArg, argnum;
    size_t size, len, pos;
    char *first, *last;
    genctx_t ctx;
    char *matches[MAX_MATCHES], *sortedMatches[MAX_MATCHES];
    int numCommands, numCvars, numAliases;

    text = inputLine->text;
    size = inputLine->maxChars + 1;
    pos = inputLine->cursorPos;

    // prepend backslash if missing
    if (backslash) {
        if (inputLine->text[0] != '\\' && inputLine->text[0] != '/') {
            memmove(inputLine->text + 1, inputLine->text, size - 1);
            inputLine->text[0] = '\\';
        }
        text++;
        size--;
        pos--;
    }

    // parse the input line into tokens
    Cmd_TokenizeString(text, qfalse);

    argc = Cmd_Argc();

    // determine absolute argument number to be completed
    currentArg = Cmd_FindArgForOffset(pos);
    if (currentArg == argc - 1 && Cmd_WhiteSpaceTail()) {
        // start completing new argument if command line has trailing whitespace
        currentArg++;
    }

    // determine relative argument number to be completed
    argnum = 0;
    for (i = 0; i < currentArg; i++) {
        s = Cmd_Argv(i);
        argnum++;
        if (*s == ';') {
            // semicolon starts a new command
            argnum = 0;
        }
    }

    // get the partial argument string to be completed
    partial = Cmd_Argv(currentArg);
    if (*partial == ';') {
        // semicolon starts a new command
        currentArg++;
        partial = Cmd_Argv(currentArg);
        argnum = 0;
    }

    // generate matches
    memset(&ctx, 0, sizeof(ctx));
    ctx.partial = partial;
    ctx.length = strlen(partial);
    ctx.argnum = currentArg;
    ctx.matches = matches;
    ctx.size = MAX_MATCHES;

    if (argnum) {
        // complete a command/cvar argument
        Com_Generic_c(&ctx, argnum);
        numCommands = numCvars = numAliases = 0;
    } else {
        // complete a command/cvar/alias name
        Cmd_Command_g(&ctx);
        numCommands = ctx.count;

        Cvar_Variable_g(&ctx);
        numCvars = ctx.count - numCommands;

        Cmd_Alias_g(&ctx);
        numAliases = ctx.count - numCvars - numCommands;
    }

    if (!ctx.count) {
        pos = strlen(inputLine->text);
        prompt->tooMany = qfalse;
        goto finish2; // nothing found
    }

    pos = Cmd_ArgOffset(currentArg);
    text += pos;
    size -= pos;

    // append whitespace since Cmd_TokenizeString eats it
    if (currentArg == argc && Cmd_WhiteSpaceTail()) {
        *text++ = ' ';
        pos++;
        size--;
    }

    if (ctx.count == 1) {
        // we have finished completion!
        s = Cmd_RawArgsFrom(currentArg + 1);
        if (needs_quotes(matches[0])) {
            pos += Q_concat(text, size, "\"", matches[0], "\" ", s, NULL);
        } else {
            pos += Q_concat(text, size, matches[0], " ", s, NULL);
        }
        pos++;
        prompt->tooMany = qfalse;
        goto finish1;
    }

    if (ctx.count > com_completion_treshold->integer && !prompt->tooMany) {
        prompt->printf("Press TAB again to display all %d possibilities.\n", ctx.count);
        pos = strlen(inputLine->text);
        prompt->tooMany = qtrue;
        goto finish1;
    }

    prompt->tooMany = qfalse;

    // sort matches alphabethically
    for (i = 0; i < ctx.count; i++) {
        sortedMatches[i] = matches[i];
    }
    qsort(sortedMatches, ctx.count, sizeof(sortedMatches[0]),
          ctx.ignorecase ? SortStricmp : SortStrcmp);

    // copy matching part
    first = sortedMatches[0];
    last = sortedMatches[ctx.count - 1];
    len = 0;
    do {
        if (*first != *last) {
            if (!ctx.ignorecase || Q_tolower(*first) != Q_tolower(*last)) {
                break;
            }
        }
        text[len++] = *first;
        if (len == size - 1) {
            break;
        }

        first++;
        last++;
    } while (*first);

    text[len] = 0;
    pos += len;
    size -= len;

    // copy trailing arguments
    if (currentArg + 1 < argc) {
        s = Cmd_RawArgsFrom(currentArg + 1);
        pos += Q_concat(text + len, size, " ", s, NULL);
    }

    pos++;

    prompt->printf("]\\%s\n", Cmd_ArgsFrom(0));
    if (argnum) {
        goto multi;
    }

    switch (com_completion_mode->integer) {
    case 0:
        // print in solid list
        for (i = 0; i < ctx.count; i++) {
            prompt->printf("%s\n", sortedMatches[i]);
        }
        break;
    case 1:
multi:
        // print in multiple columns
        Prompt_ShowMatches(prompt, sortedMatches, 0, ctx.count);
        break;
    case 2:
    default:
        // resort matches by type and print in multiple columns
        Prompt_ShowIndividualMatches(prompt, matches, numCommands, numAliases, numCvars);
        break;
    }

finish1:
    // free matches
    for (i = 0; i < ctx.count; i++) {
        Z_Free(matches[i]);
    }

finish2:
    // move cursor
    if (pos >= inputLine->maxChars) {
        pos = inputLine->maxChars - 1;
    }
    inputLine->cursorPos = pos;
}