void guac_terminal_parse_color_scheme()

in src/terminal/color-scheme.c [193:271]


void guac_terminal_parse_color_scheme(guac_client* client,
        const char* color_scheme, guac_terminal_color* foreground,
        guac_terminal_color* background,
        guac_terminal_color (*palette)[256]) {

    /* Special cases. */
    if (color_scheme[0] == '\0') {
        /* guac_terminal_parse_color_scheme defaults to gray-black */
    }
    else if (strcmp(color_scheme, GUAC_TERMINAL_SCHEME_GRAY_BLACK) == 0) {
        color_scheme = "foreground:color7;background:color0";
    }
    else if (strcmp(color_scheme, GUAC_TERMINAL_SCHEME_BLACK_WHITE) == 0) {
        color_scheme = "foreground:color0;background:color15";
    }
    else if (strcmp(color_scheme, GUAC_TERMINAL_SCHEME_GREEN_BLACK) == 0) {
        color_scheme = "foreground:color2;background:color0";
    }
    else if (strcmp(color_scheme, GUAC_TERMINAL_SCHEME_WHITE_BLACK) == 0) {
        color_scheme = "foreground:color15;background:color0";
    }

    /* Set default gray-black color scheme and initial palette. */
    *foreground = GUAC_TERMINAL_INITIAL_PALETTE[GUAC_TERMINAL_COLOR_GRAY];
    *background = GUAC_TERMINAL_INITIAL_PALETTE[GUAC_TERMINAL_COLOR_BLACK];
    memcpy(palette, GUAC_TERMINAL_INITIAL_PALETTE,
            sizeof(GUAC_TERMINAL_INITIAL_PALETTE));

    /* Current char being parsed, or NULL if at end of parsing. */
    const char* cursor = color_scheme;

    while (cursor) {
        /* Start of the current "name: value" pair. */
        const char* pair_start = cursor;

        /* End of the current name-value pair. */
        const char* pair_end = strchr(pair_start, ';');
        if (pair_end) {
            cursor = pair_end + 1;
        }
        else {
            pair_end = pair_start + strlen(pair_start);
            cursor = NULL;
        }

        guac_terminal_color_scheme_strip_spaces(&pair_start, &pair_end);
        if (pair_start >= pair_end)
            /* Allow empty pairs, which happens, e.g., when the configuration
             * string ends in a semi-colon. */
            continue;

        /* End of the name part of the pair. */
        const char* name_end = memchr(pair_start, ':', pair_end - pair_start);
        if (name_end == NULL) {
            guac_client_log(client, GUAC_LOG_WARNING,
                            "Expecting colon: \"%.*s\".",
                            pair_end - pair_start, pair_start);
            return;
        }

        /* The color that the name corresponds to. */
        guac_terminal_color* color_target = NULL;

        if (guac_terminal_parse_color_scheme_name(
                client, pair_start, name_end, foreground, background,
                palette, &color_target))
            return; /* Parsing failed. */

        if (guac_terminal_parse_color_scheme_value(
                client, name_end + 1, pair_end,
                (const guac_terminal_color(*)[256]) palette, color_target))
            return; /* Parsing failed. */
    }

    /* Persist pseudo-index for foreground/background colors */
    foreground->palette_index = GUAC_TERMINAL_COLOR_FOREGROUND;
    background->palette_index = GUAC_TERMINAL_COLOR_BACKGROUND;

}