예제 #1
0
TEST(String, Duplicate)
{
    const char *str_test = "test";
    char *str;

    str = string_strndup (NULL, 0);

    str = string_strndup (str_test, 0);
    CHECK(str);
    CHECK(str != str_test);
    STRCMP_EQUAL(str, "");
    free (str);

    str = string_strndup (str_test, 2);
    CHECK(str);
    CHECK(str != str_test);
    STRCMP_EQUAL(str, "te");
    free (str);

    str = string_strndup (str_test, 500);
    CHECK(str);
    CHECK(str != str_test);
    STRCMP_EQUAL(str, str_test);
    free (str);
}
예제 #2
0
void
hdata_get_index_and_name (const char *name, int *index, const char **ptr_name)
{
    char *pos, *str_index, *error;
    long number;

    if (index)
        *index = -1;
    if (ptr_name)
        *ptr_name = name;

    if (!name)
        return;

    pos = strchr (name, '|');
    if (pos)
    {
        str_index = string_strndup (name, pos - name);
        if (str_index)
        {
            error = NULL;
            number = strtol (str_index, &error, 10);
            if (error && !error[0])
            {
                if (index)
                    *index = number;
                if (ptr_name)
                    *ptr_name = pos + 1;
            }
            free (str_index);
        }
    }
}
예제 #3
0
struct t_proxy *
proxy_search_with_option_name (const char *option_name)
{
    char *proxy_name, *pos_option;
    struct t_proxy *ptr_proxy;

    ptr_proxy = NULL;

    pos_option = strchr (option_name, '.');
    if (pos_option)
    {
        proxy_name = string_strndup (option_name, pos_option - option_name);
        if (proxy_name)
        {
            for (ptr_proxy = weechat_proxies; ptr_proxy;
                 ptr_proxy = ptr_proxy->next_proxy)
            {
                if (strcmp (ptr_proxy->name, proxy_name) == 0)
                    break;
            }
            free (proxy_name);
        }
    }

    return ptr_proxy;
}
예제 #4
0
int
completion_list_add_plugins_commands_cb (void *data,
                                         const char *completion_item,
                                         struct t_gui_buffer *buffer,
                                         struct t_gui_completion *completion)
{
    char *pos_space, *plugin_name;
    struct t_weechat_plugin *ptr_plugin;
    struct t_hook *ptr_hook;

    /* make C compiler happy */
    (void) data;
    (void) completion_item;
    (void) buffer;

    if (completion->args)
    {
        pos_space = strchr (completion->args, ' ');
        if (pos_space)
            plugin_name = string_strndup (completion->args,
                                          pos_space - completion->args);
        else
            plugin_name = strdup (completion->args);

        if (plugin_name)
        {
            ptr_plugin = NULL;
            if (string_strcasecmp (plugin_name, PLUGIN_CORE) != 0)
            {
                /*
                 * plugin name is different from "core", then search it in
                 * plugin list
                 */
                ptr_plugin = plugin_search (plugin_name);
                if (!ptr_plugin)
                    return WEECHAT_RC_OK;
            }
            for (ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; ptr_hook;
                 ptr_hook = ptr_hook->next_hook)
            {
                if (!ptr_hook->deleted
                    && (ptr_hook->plugin == ptr_plugin)
                    && HOOK_COMMAND(ptr_hook, command)
                    && HOOK_COMMAND(ptr_hook, command)[0])
                {
                    gui_completion_list_add (completion,
                                             HOOK_COMMAND(ptr_hook, command),
                                             0, WEECHAT_LIST_POS_SORT);
                }
            }
            free (plugin_name);
        }
    }

    return WEECHAT_RC_OK;
}
예제 #5
0
파일: wee-utf8.c 프로젝트: Ratler/weechat
char *
utf8_strndup (const char *string, int length)
{
    const char *end;

    if (!string || (length < 0))
        return NULL;

    if (length == 0)
        return strdup ("");

    end = utf8_add_offset (string, length);
    if (!end || (end == string))
        return strdup (string);

    return string_strndup (string, end - string);
}
예제 #6
0
파일: wee-eval.c 프로젝트: Evalle/weechat
char *
eval_expression_condition (const char *expr,
                           struct t_hashtable *pointers,
                           struct t_hashtable *extra_vars,
                           int extra_vars_eval,
                           const char *prefix,
                           const char *suffix)
{
    int logic, comp, length, level, rc;
    const char *pos, *pos_end;
    char *expr2, *sub_expr, *value, *tmp_value, *tmp_value2;

    value = NULL;

    if (!expr)
        return NULL;

    if (!expr[0])
        return strdup (expr);

    /* skip spaces at beginning of string */
    while (expr[0] == ' ')
    {
        expr++;
    }
    if (!expr[0])
        return strdup (expr);

    /* skip spaces at end of string */
    pos_end = expr + strlen (expr) - 1;
    while ((pos_end > expr) && (pos_end[0] == ' '))
    {
        pos_end--;
    }

    expr2 = string_strndup (expr, pos_end + 1 - expr);
    if (!expr2)
        return NULL;

    /*
     * search for a logical operator, and if one is found:
     * - split expression into two sub-expressions
     * - evaluate first sub-expression
     * - if needed, evaluate second sub-expression
     * - return result
     */
    for (logic = 0; logic < EVAL_NUM_LOGICAL_OPS; logic++)
    {
        pos = eval_strstr_level (expr2, logical_ops[logic]);
        if (pos > expr2)
        {
            pos_end = pos - 1;
            while ((pos_end > expr2) && (pos_end[0] == ' '))
            {
                pos_end--;
            }
            sub_expr = string_strndup (expr2, pos_end + 1 - expr2);
            if (!sub_expr)
                goto end;
            tmp_value = eval_expression_condition (sub_expr, pointers,
                                                   extra_vars, extra_vars_eval,
                                                   prefix, suffix);
            free (sub_expr);
            rc = eval_is_true (tmp_value);
            if (tmp_value)
                free (tmp_value);
            /*
             * if rc == 0 with "&&" or rc == 1 with "||", no need to
             * evaluate second sub-expression, just return the rc
             */
            if ((!rc && (logic == EVAL_LOGICAL_OP_AND))
                || (rc && (logic == EVAL_LOGICAL_OP_OR)))
            {
                value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
                goto end;
            }
            pos += strlen (logical_ops[logic]);
            while (pos[0] == ' ')
            {
                pos++;
            }
            tmp_value = eval_expression_condition (pos, pointers,
                                                   extra_vars, extra_vars_eval,
                                                   prefix, suffix);
            rc = eval_is_true (tmp_value);
            if (tmp_value)
                free (tmp_value);
            value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
            goto end;
        }
    }

    /*
     * search for a comparison, and if one is found:
     * - split expression into two sub-expressions
     * - evaluate the two sub-expressions
     * - compare sub-expressions
     * - return result
     */
    for (comp = 0; comp < EVAL_NUM_COMPARISONS; comp++)
    {
        pos = eval_strstr_level (expr2, comparisons[comp]);
        if (pos > expr2)
        {
            pos_end = pos - 1;
            while ((pos_end > expr2) && (pos_end[0] == ' '))
            {
                pos_end--;
            }
            sub_expr = string_strndup (expr2, pos_end + 1 - expr2);
            if (!sub_expr)
                goto end;
            pos += strlen (comparisons[comp]);
            while (pos[0] == ' ')
            {
                pos++;
            }
            if ((comp == EVAL_COMPARE_REGEX_MATCHING)
                || (comp == EVAL_COMPARE_REGEX_NOT_MATCHING))
            {
                /* for regex: just replace vars in both expressions */
                tmp_value = eval_replace_vars (sub_expr, pointers,
                                               extra_vars, extra_vars_eval,
                                               prefix, suffix,
                                               NULL);
                tmp_value2 = eval_replace_vars (pos, pointers,
                                                extra_vars, extra_vars_eval,
                                                prefix, suffix,
                                                NULL);
            }
            else
            {
                /* other comparison: fully evaluate both expressions */
                tmp_value = eval_expression_condition (sub_expr, pointers,
                                                       extra_vars,
                                                       extra_vars_eval,
                                                       prefix, suffix);
                tmp_value2 = eval_expression_condition (pos, pointers,
                                                        extra_vars,
                                                        extra_vars_eval,
                                                        prefix, suffix);
            }
            free (sub_expr);
            value = eval_compare (tmp_value, comp, tmp_value2);
            if (tmp_value)
                free (tmp_value);
            if (tmp_value2)
                free (tmp_value2);
            goto end;
        }
    }

    /*
     * evaluate sub-expressions between parentheses and replace them with their
     * value
     */
    while (expr2[0] == '(')
    {
        level = 0;
        pos = expr2 + 1;
        while (pos[0])
        {
            if (pos[0] == '(')
                level++;
            else if (pos[0] == ')')
            {
                if (level == 0)
                    break;
                level--;
            }
            pos++;
        }
        /* closing parenthesis not found */
        if (pos[0] != ')')
            goto end;
        sub_expr = string_strndup (expr2 + 1, pos - expr2 - 1);
        if (!sub_expr)
            goto end;
        tmp_value = eval_expression_condition (sub_expr, pointers,
                                               extra_vars, extra_vars_eval,
                                               prefix, suffix);
        free (sub_expr);
        if (!pos[1])
        {
            /*
             * nothing around parentheses, then return value of
             * sub-expression as-is
             */
            value = tmp_value;
            goto end;
        }
        length = ((tmp_value) ? strlen (tmp_value) : 0) + 1 +
            strlen (pos + 1) + 1;
        tmp_value2 = malloc (length);
        if (!tmp_value2)
        {
            if (tmp_value)
                free (tmp_value);
            goto end;
        }
        tmp_value2[0] = '\0';
        if (tmp_value)
            strcat (tmp_value2, tmp_value);
        strcat (tmp_value2, " ");
        strcat (tmp_value2, pos + 1);
        free (expr2);
        expr2 = tmp_value2;
        if (tmp_value)
            free (tmp_value);
    }

    /*
     * at this point, there is no more logical operator neither comparison,
     * so we just replace variables in string and return the result
     */
    value = eval_replace_vars (expr2, pointers, extra_vars, extra_vars_eval,
                               prefix, suffix, NULL);

end:
    if (expr2)
        free (expr2);

    return value;
}
예제 #7
0
파일: wee-eval.c 프로젝트: Evalle/weechat
char *
eval_replace_vars_cb (void *data, const char *text)
{
    struct t_hashtable *pointers, *extra_vars;
    struct t_eval_regex *eval_regex;
    struct t_config_option *ptr_option;
    struct t_gui_buffer *ptr_buffer;
    char str_value[512], *value, *pos, *pos1, *pos2, *hdata_name, *list_name;
    char *tmp, *info_name, *hide_char, *hidden_string, *error;
    const char *prefix, *suffix, *ptr_value, *ptr_arguments, *ptr_string;
    struct t_hdata *hdata;
    void *pointer;
    int i, length_hide_char, length, index, rc, extra_vars_eval;
    long number;
    long unsigned int ptr;
    time_t date;
    struct tm *date_tmp;

    pointers = (struct t_hashtable *)(((void **)data)[0]);
    extra_vars = (struct t_hashtable *)(((void **)data)[1]);
    extra_vars_eval = *(int *)(((void **)data)[2]);
    prefix = (const char *)(((void **)data)[3]);
    suffix = (const char *)(((void **)data)[4]);
    eval_regex = (struct t_eval_regex *)(((void **)data)[5]);

    /* 1. variable in hashtable "extra_vars" */
    if (extra_vars)
    {
        ptr_value = hashtable_get (extra_vars, text);
        if (ptr_value)
        {
            if (extra_vars_eval)
            {
                return eval_replace_vars (ptr_value, pointers,
                                          extra_vars, extra_vars_eval,
                                          prefix, suffix,
                                          eval_regex);
            }
            else
            {
                return strdup (ptr_value);
            }
        }
    }

    /*
     * 2. force evaluation of string (recursive call)
     *    --> use with caution: the text must be safe!
     */
    if (strncmp (text, "eval:", 5) == 0)
    {
        return eval_replace_vars (text + 5, pointers,
                                  extra_vars, extra_vars_eval,
                                  prefix, suffix,
                                  eval_regex);
    }

    /* 3. convert escaped chars */
    if (strncmp (text, "esc:", 4) == 0)
        return string_convert_escaped_chars (text + 4);
    if ((text[0] == '\\') && text[1] && (text[1] != '\\'))
        return string_convert_escaped_chars (text);

    /* 4. hide chars: replace all chars by a given char/string */
    if (strncmp (text, "hide:", 5) == 0)
    {
        hidden_string = NULL;
        ptr_string = strchr (text + 5,
                             (text[5] == ',') ? ';' : ',');
        if (!ptr_string)
            return strdup ("");
        hide_char = string_strndup (text + 5, ptr_string - text - 5);
        if (hide_char)
        {
            length_hide_char = strlen (hide_char);
            length = utf8_strlen (ptr_string + 1);
            hidden_string = malloc ((length * length_hide_char) + 1);
            if (hidden_string)
            {
                index = 0;
                for (i = 0; i < length; i++)
                {
                    memcpy (hidden_string + index, hide_char,
                            length_hide_char);
                    index += length_hide_char;
                }
                hidden_string[length * length_hide_char] = '\0';
            }
            free (hide_char);
        }
        return (hidden_string) ? hidden_string : strdup ("");
    }

    /* 5. regex group captured */
    if (strncmp (text, "re:", 3) == 0)
    {
        if (eval_regex && eval_regex->result)
        {
            if (strcmp (text + 3, "+") == 0)
                number = eval_regex->last_match;
            else
            {
                number = strtol (text + 3, &error, 10);
                if (!error || error[0])
                    number = -1;
            }
            if ((number >= 0) && (number <= eval_regex->last_match))
            {
                return string_strndup (
                    eval_regex->result + eval_regex->match[number].rm_so,
                    eval_regex->match[number].rm_eo - eval_regex->match[number].rm_so);
            }
        }
        return strdup ("");
    }

    /* 6. color code */
    if (strncmp (text, "color:", 6) == 0)
    {
        ptr_value = gui_color_search_config (text + 6);
        if (ptr_value)
            return strdup (ptr_value);
        ptr_value = gui_color_get_custom (text + 6);
        return strdup ((ptr_value) ? ptr_value : "");
    }

    /* 7. info */
    if (strncmp (text, "info:", 5) == 0)
    {
        ptr_value = NULL;
        ptr_arguments = strchr (text + 5, ',');
        if (ptr_arguments)
        {
            info_name = string_strndup (text + 5, ptr_arguments - text - 5);
            ptr_arguments++;
        }
        else
            info_name = strdup (text + 5);
        if (info_name)
        {
            ptr_value = hook_info_get (NULL, info_name, ptr_arguments);
            free (info_name);
        }
        return strdup ((ptr_value) ? ptr_value : "");
    }

    /* 8. current date/time */
    if ((strncmp (text, "date", 4) == 0) && (!text[4] || (text[4] == ':')))
    {
        date = time (NULL);
        date_tmp = localtime (&date);
        if (!date_tmp)
            return strdup ("");
        rc = (int) strftime (str_value, sizeof (str_value),
                             (text[4] == ':') ? text + 5 : "%F %T",
                             date_tmp);
        return strdup ((rc > 0) ? str_value : "");
    }

    /* 9. environment variable */
    if (strncmp (text, "env:", 4) == 0)
    {
        ptr_value = getenv (text + 4);
        if (ptr_value)
            return strdup (ptr_value);
    }

    /* 10. option: if found, return this value */
    if (strncmp (text, "sec.data.", 9) == 0)
    {
        ptr_value = hashtable_get (secure_hashtable_data, text + 9);
        return strdup ((ptr_value) ? ptr_value : "");
    }
    else
    {
        config_file_search_with_string (text, NULL, NULL, &ptr_option, NULL);
        if (ptr_option)
        {
            if (!ptr_option->value)
                return strdup ("");
            switch (ptr_option->type)
            {
                case CONFIG_OPTION_TYPE_BOOLEAN:
                    return strdup (CONFIG_BOOLEAN(ptr_option) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
                case CONFIG_OPTION_TYPE_INTEGER:
                    if (ptr_option->string_values)
                        return strdup (ptr_option->string_values[CONFIG_INTEGER(ptr_option)]);
                    snprintf (str_value, sizeof (str_value),
                              "%d", CONFIG_INTEGER(ptr_option));
                    return strdup (str_value);
                case CONFIG_OPTION_TYPE_STRING:
                    return strdup (CONFIG_STRING(ptr_option));
                case CONFIG_OPTION_TYPE_COLOR:
                    return strdup (gui_color_get_name (CONFIG_COLOR(ptr_option)));
                case CONFIG_NUM_OPTION_TYPES:
                    return strdup ("");
            }
        }
    }

    /* 11. local variable in buffer */
    ptr_buffer = hashtable_get (pointers, "buffer");
    if (ptr_buffer)
    {
        ptr_value = hashtable_get (ptr_buffer->local_variables, text);
        if (ptr_value)
            return strdup (ptr_value);
    }

    /* 12. hdata */
    value = NULL;
    hdata_name = NULL;
    list_name = NULL;
    pointer = NULL;

    pos = strchr (text, '.');
    if (pos > text)
        hdata_name = string_strndup (text, pos - text);
    else
        hdata_name = strdup (text);

    if (!hdata_name)
        goto end;

    pos1 = strchr (hdata_name, '[');
    if (pos1 > hdata_name)
    {
        pos2 = strchr (pos1 + 1, ']');
        if (pos2 > pos1 + 1)
        {
            list_name = string_strndup (pos1 + 1, pos2 - pos1 - 1);
        }
        tmp = string_strndup (hdata_name, pos1 - hdata_name);
        if (tmp)
        {
            free (hdata_name);
            hdata_name = tmp;
        }
    }

    hdata = hook_hdata_get (NULL, hdata_name);
    if (!hdata)
        goto end;

    if (list_name)
    {
        if (strncmp (list_name, "0x", 2) == 0)
        {
            rc = sscanf (list_name, "%lx", &ptr);
            if ((rc != EOF) && (rc != 0))
            {
                pointer = (void *)ptr;
                if (!hdata_check_pointer (hdata, NULL, pointer))
                    goto end;
            }
            else
                goto end;
        }
        else
            pointer = hdata_get_list (hdata, list_name);
    }

    if (!pointer)
    {
        pointer = hashtable_get (pointers, hdata_name);
        if (!pointer)
            goto end;
    }

    value = eval_hdata_get_value (hdata, pointer, (pos) ? pos + 1 : NULL);

end:
    if (hdata_name)
        free (hdata_name);
    if (list_name)
        free (list_name);

    return (value) ? value : strdup ("");
}
예제 #8
0
int
input_exec_command (struct t_gui_buffer *buffer,
                    int any_plugin,
                    struct t_weechat_plugin *plugin,
                    const char *string)
{
    char *command, *command_name, *pos;
    int rc;

    if ((!string) || (!string[0]))
        return WEECHAT_RC_ERROR;

    command = strdup (string);
    if (!command)
        return WEECHAT_RC_ERROR;

    /* ignore spaces at the end of command */
    pos = &command[strlen (command) - 1];
    if (pos[0] == ' ')
    {
        while ((pos > command) && (pos[0] == ' '))
            pos--;
        pos[1] = '\0';
    }

    /* extract command name */
    pos = strchr (command, ' ');
    command_name = (pos) ?
        string_strndup (command, pos - command) : strdup (command);
    if (!command_name)
    {
        free (command);
        return WEECHAT_RC_ERROR;
    }

    /* execute command */
    rc = WEECHAT_RC_OK;
    switch (hook_command_exec (buffer, any_plugin, plugin, command))
    {
        case HOOK_COMMAND_EXEC_OK:
            /* command hooked, OK (executed) */
            break;
        case HOOK_COMMAND_EXEC_ERROR:
            /* command hooked, error */
            rc = WEECHAT_RC_ERROR;
            break;
        case HOOK_COMMAND_EXEC_NOT_FOUND:
            /*
             * command not found: if unknown commands are accepted by this
             * buffer, just send input text as data to buffer,
             * otherwise display error
             */
            if (buffer->input_get_unknown_commands)
            {
                input_exec_data (buffer, string);
            }
            else
            {
                gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER,
                                           _("%sError: unknown command \"%s\" "
                                             "(type /help for help)"),
                                           gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
                                           command_name);
                rc = WEECHAT_RC_ERROR;
            }
            break;
        case HOOK_COMMAND_EXEC_AMBIGUOUS_PLUGINS:
            /* command is ambiguous (exists for other plugins) */
            gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER,
                                       _("%sError: ambiguous command \"%s\": "
                                         "it exists in many plugins and not in "
                                         "\"%s\" plugin"),
                                       gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
                                       command_name,
                                       plugin_get_name (plugin));
            rc = WEECHAT_RC_ERROR;
            break;
        case HOOK_COMMAND_EXEC_AMBIGUOUS_INCOMPLETE:
            /*
             * command is ambiguous (incomplete command and multiple commands
             * start with this name)
             */
            gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER,
                                       _("%sError: incomplete command \"%s\" "
                                         "and multiple commands start with "
                                         "this name"),
                                       gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
                                       command_name);
            rc = WEECHAT_RC_ERROR;
            break;
        case HOOK_COMMAND_EXEC_RUNNING:
            /* command is running */
            gui_chat_printf_date_tags (NULL, 0, GUI_FILTER_TAG_NO_FILTER,
                                       _("%sError: too many calls to command "
                                         "\"%s\" (looping)"),
                                       gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
                                       command_name);
            rc = WEECHAT_RC_ERROR;
            break;
        default:
            break;
    }

    free (command);
    free (command_name);

    return rc;
}
예제 #9
0
struct t_gui_filter *
gui_filter_new (int enabled, const char *name, const char *buffer_name,
                const char *tags, const char *regex)
{
    struct t_gui_filter *new_filter;
    regex_t *regex1, *regex2;
    char *pos_tab, *regex_prefix;
    const char *ptr_start_regex, *pos_regex_message;

    if (!name || !buffer_name || !tags || !regex)
        return NULL;

    if (gui_filter_search_by_name (name))
        return NULL;

    ptr_start_regex = regex;
    if ((ptr_start_regex[0] == '!')
        || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!')))
    {
        ptr_start_regex++;
    }

    regex1 = NULL;
    regex2 = NULL;
    if (strcmp (ptr_start_regex, "*") != 0)
    {
        pos_tab = strstr (ptr_start_regex, "\\t");
        if (pos_tab)
        {
            regex_prefix = string_strndup (ptr_start_regex,
                                           pos_tab - ptr_start_regex);
            pos_regex_message = pos_tab + 2;
        }
        else
        {
            regex_prefix = NULL;
            pos_regex_message = ptr_start_regex;
        }

        if (regex_prefix)
        {
            regex1 = malloc (sizeof (*regex1));
            if (regex1)
            {
                if (string_regcomp (regex1, regex_prefix,
                                    REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
                {
                    free (regex_prefix);
                    free (regex1);
                    return NULL;
                }
            }
        }

        regex2 = malloc (sizeof (*regex2));
        if (regex2)
        {
            if (string_regcomp (regex2, pos_regex_message,
                                REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
            {
                if (regex_prefix)
                    free (regex_prefix);
                if (regex1)
                    free (regex1);
                free (regex2);
                return NULL;
            }
        }

        if (regex_prefix)
            free (regex_prefix);
    }

    /* create new filter */
    new_filter = malloc (sizeof (*new_filter));
    if (new_filter)
    {
        /* init filter */
        new_filter->enabled = enabled;
        new_filter->name = strdup (name);
        new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*");
        new_filter->buffers = string_split (new_filter->buffer_name,
                                            ",", 0, 0,
                                            &new_filter->num_buffers);
        if (tags)
        {
            new_filter->tags = (tags) ? strdup (tags) : NULL;
            new_filter->tags_array = string_split (tags, ",", 0, 0,
                                                   &new_filter->tags_count);
        }
        else
        {
            new_filter->tags = NULL;
            new_filter->tags_count = 0;
            new_filter->tags_array = NULL;
        }
        new_filter->regex = strdup (regex);
        new_filter->regex_prefix = regex1;
        new_filter->regex_message = regex2;

        /* add filter to filters list */
        new_filter->prev_filter = last_gui_filter;
        if (gui_filters)
            last_gui_filter->next_filter = new_filter;
        else
            gui_filters = new_filter;
        last_gui_filter = new_filter;
        new_filter->next_filter = NULL;

        hook_signal_send ("filter_added",
                          WEECHAT_HOOK_SIGNAL_POINTER, new_filter);
    }

    return new_filter;
}
예제 #10
0
파일: plugin-api.c 프로젝트: haasn/weechat
const char *
plugin_api_info_get_internal (void *data, const char *info_name,
                              const char *arguments)
{
    time_t inactivity;
    static char value[32], version_number[32] = { '\0' };
    static char weechat_dir_absolute_path[PATH_MAX] = { '\0' };
    int rgb, limit;
    char *pos, *color;

    /* make C compiler happy */
    (void) data;

    if (!info_name)
        return NULL;

    if (string_strcasecmp (info_name, "version") == 0)
    {
        return version_get_version ();
    }
    else if (string_strcasecmp (info_name, "version_number") == 0)
    {
        if (!version_number[0])
        {
            snprintf (version_number, sizeof (version_number), "%d",
                      util_version_number (version_get_version ()));
        }
        return version_number;
    }
    else if (string_strcasecmp (info_name, "version_git") == 0)
    {
        return version_get_git ();
    }
    else if (string_strcasecmp (info_name, "date") == 0)
    {
        return version_get_compilation_date ();
    }
    else if (string_strcasecmp (info_name, "dir_separator") == 0)
    {
        return DIR_SEPARATOR;
    }
    else if (string_strcasecmp (info_name, "weechat_dir") == 0)
    {
        if (!weechat_dir_absolute_path[0])
        {
            if (!realpath (weechat_home, weechat_dir_absolute_path))
                return NULL;
        }
        return (weechat_dir_absolute_path[0]) ?
            weechat_dir_absolute_path : weechat_home;
    }
    else if (string_strcasecmp (info_name, "weechat_libdir") == 0)
    {
        return WEECHAT_LIBDIR;
    }
    else if (string_strcasecmp (info_name, "weechat_sharedir") == 0)
    {
        return WEECHAT_SHAREDIR;
    }
    else if (string_strcasecmp (info_name, "weechat_localedir") == 0)
    {
        return LOCALEDIR;
    }
    else if (string_strcasecmp (info_name, "weechat_site") == 0)
    {
        return WEECHAT_WEBSITE;
    }
    else if (string_strcasecmp (info_name, "weechat_site_download") == 0)
    {
        return WEECHAT_WEBSITE_DOWNLOAD;
    }
    else if (string_strcasecmp (info_name, "weechat_upgrading") == 0)
    {
        snprintf (value, sizeof (value), "%d", weechat_upgrading);
        return value;
    }
    else if (string_strcasecmp (info_name, "charset_terminal") == 0)
    {
        return weechat_local_charset;
    }
    else if (string_strcasecmp (info_name, "charset_internal") == 0)
    {
        return WEECHAT_INTERNAL_CHARSET;
    }
    else if (string_strcasecmp (info_name, "locale") == 0)
    {
        return setlocale (LC_MESSAGES, NULL);
    }
    else if (string_strcasecmp (info_name, "inactivity") == 0)
    {
        if (gui_key_last_activity_time == 0)
            inactivity = 0;
        else
            inactivity = time (NULL) - gui_key_last_activity_time;
        snprintf (value, sizeof (value), "%ld", (long int)inactivity);
        return value;
    }
    else if (string_strcasecmp (info_name, "filters_enabled") == 0)
    {
        snprintf (value, sizeof (value), "%d", gui_filters_enabled);
        return value;
    }
    else if (string_strcasecmp (info_name, "cursor_mode") == 0)
    {
        snprintf (value, sizeof (value), "%d", gui_cursor_mode);
        return value;
    }
    else if (string_strcasecmp (info_name, "term_width") == 0)
    {
        snprintf (value, sizeof (value), "%d", gui_window_get_width ());
        return value;
    }
    else if (string_strcasecmp (info_name, "term_height") == 0)
    {
        snprintf (value, sizeof (value), "%d", gui_window_get_height ());
        return value;
    }
    else if (string_strcasecmp (info_name, "color_ansi_regex") == 0)
    {
        return GUI_COLOR_REGEX_ANSI_DECODE;
    }
    else if (string_strcasecmp (info_name, "color_term2rgb") == 0)
    {
        if (arguments && arguments[0])
        {
            snprintf (value, sizeof (value),
                      "%d",
                      gui_color_convert_term_to_rgb (atoi (arguments)));
            return value;
        }
    }
    else if (string_strcasecmp (info_name, "color_rgb2term") == 0)
    {
        if (arguments && arguments[0])
        {
            limit = 256;
            pos = strchr (arguments, ',');
            if (pos)
            {
                color = string_strndup (arguments, pos - arguments);
                if (!color)
                    return NULL;
                rgb = atoi (color);
                limit = atoi (pos + 1);
                free (color);
            }
            else
                rgb = atoi (arguments);
            snprintf (value, sizeof (value),
                      "%d",
                      gui_color_convert_rgb_to_term (rgb, limit));
            return value;
        }
    }

    /* info not found */
    return NULL;
}
예제 #11
0
파일: gui-color.c 프로젝트: matsuu/weechat
const char *
gui_color_get_custom (const char *color_name)
{
    int fg, bg;
    static char color[20][16];
    static int index_color = 0;
    char *pos_comma, *str_fg, *pos_bg;
    
    /* attribute or other color name (GUI dependent) */
    index_color = (index_color + 1) % 20;
    color[index_color][0] = '\0';
    
    if (!color_name || !color_name[0])
        return color[index_color];
    
    if (string_strcasecmp (color_name, "reset") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s",
                  GUI_COLOR_RESET_STR);
    }
    else if (string_strcasecmp (color_name, "bold") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_SET_WEECHAT_STR,
                  GUI_COLOR_ATTR_BOLD_STR);
    }
    else if (string_strcasecmp (color_name, "-bold") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_REMOVE_WEECHAT_STR,
                  GUI_COLOR_ATTR_BOLD_STR);
    }
    else if (string_strcasecmp (color_name, "reverse") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_SET_WEECHAT_STR,
                  GUI_COLOR_ATTR_REVERSE_STR);
    }
    else if (string_strcasecmp (color_name, "-reverse") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_REMOVE_WEECHAT_STR,
                  GUI_COLOR_ATTR_REVERSE_STR);
    }
    else if (string_strcasecmp (color_name, "italic") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_SET_WEECHAT_STR,
                  GUI_COLOR_ATTR_ITALIC_STR);
    }
    else if (string_strcasecmp (color_name, "-italic") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_REMOVE_WEECHAT_STR,
                  GUI_COLOR_ATTR_ITALIC_STR);
    }
    else if (string_strcasecmp (color_name, "underline") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_SET_WEECHAT_STR,
                  GUI_COLOR_ATTR_UNDERLINE_STR);
    }
    else if (string_strcasecmp (color_name, "-underline") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%s%s",
                  GUI_COLOR_REMOVE_WEECHAT_STR,
                  GUI_COLOR_ATTR_UNDERLINE_STR);
    }
    else if (string_strcasecmp (color_name, "bar_fg") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_FG_CHAR);
    }
    else if (string_strcasecmp (color_name, "bar_delim") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_DELIM_CHAR);
    }
    else if (string_strcasecmp (color_name, "bar_bg") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_BG_CHAR);
    }
    else
    {
        /* custom color name (GUI dependent) */
        pos_comma = strchr (color_name, ',');
        if (pos_comma)
        {
            if (pos_comma == color_name)
                str_fg = NULL;
            else
                str_fg = string_strndup (color_name, pos_comma - color_name);
            pos_bg = pos_comma + 1;
        }
        else
        {
            str_fg = strdup (color_name);
            pos_bg = NULL;
        }
        
        if (str_fg && pos_bg)
        {
            fg = gui_color_search (str_fg);
            bg = gui_color_search (pos_bg);
            snprintf (color[index_color], sizeof (color[index_color]),
                      "%s*%02d,%02d",
                      GUI_COLOR_COLOR_STR, fg, bg);
        }
        else if (str_fg && !pos_bg)
        {
            fg = gui_color_search (str_fg);
            snprintf (color[index_color], sizeof (color[index_color]),
                      "%sF%02d",
                      GUI_COLOR_COLOR_STR, fg);
        }
        else if (!str_fg && pos_bg)
        {
            bg = gui_color_search (pos_bg);
            snprintf (color[index_color], sizeof (color[index_color]),
                      "%sB%02d",
                      GUI_COLOR_COLOR_STR, bg);
        }
        
        if (str_fg)
            free (str_fg);
    }
    
    return color[index_color];
}
예제 #12
0
char *
eval_replace_vars_cb (void *data, const char *text)
{
    struct t_hashtable *pointers, *extra_vars;
    struct t_config_option *ptr_option;
    struct t_gui_buffer *ptr_buffer;
    char str_value[64], *value, *pos, *pos1, *pos2, *hdata_name, *list_name;
    char *tmp, *info_name, *hide_char, *hidden_string;
    const char *ptr_value, *ptr_arguments, *ptr_string;
    struct t_hdata *hdata;
    void *pointer;
    int i, length_hide_char, length, index;

    pointers = (struct t_hashtable *)(((void **)data)[0]);
    extra_vars = (struct t_hashtable *)(((void **)data)[1]);

    /* 1. look for var in hashtable "extra_vars" */
    if (extra_vars)
    {
        ptr_value = hashtable_get (extra_vars, text);
        if (ptr_value)
            return strdup (ptr_value);
    }

    /* 2. convert escaped chars */
    if (strncmp (text, "esc:", 4) == 0)
        return string_convert_escaped_chars (text + 4);
    if ((text[0] == '\\') && text[1] && (text[1] != '\\'))
        return string_convert_escaped_chars (text);

    /* 3. hide chars: replace all chars by a given char */
    if (strncmp (text, "hide:", 5) == 0)
    {
        hidden_string = NULL;
        ptr_string = strchr (text + 5,
                             (text[5] == ',') ? ';' : ',');
        if (!ptr_string)
            return strdup ("");
        hide_char = string_strndup (text + 5, ptr_string - text - 5);
        if (hide_char)
        {
            length_hide_char = strlen (hide_char);
            length = utf8_strlen (ptr_string + 1);
            hidden_string = malloc ((length * length_hide_char) + 1);
            if (hidden_string)
            {
                index = 0;
                for (i = 0; i < length; i++)
                {
                    memcpy (hidden_string + index, hide_char,
                            length_hide_char);
                    index += length_hide_char;
                }
                hidden_string[length * length_hide_char] = '\0';
            }
            free (hide_char);
        }
        return (hidden_string) ? hidden_string : strdup ("");
    }

    /* 4. look for a color */
    if (strncmp (text, "color:", 6) == 0)
    {
        ptr_value = gui_color_get_custom (text + 6);
        return strdup ((ptr_value) ? ptr_value : "");
    }

    /* 5. look for an info */
    if (strncmp (text, "info:", 5) == 0)
    {
        ptr_value = NULL;
        ptr_arguments = strchr (text + 5, ',');
        if (ptr_arguments)
        {
            info_name = string_strndup (text + 5, ptr_arguments - text - 5);
            ptr_arguments++;
        }
        else
            info_name = strdup (text + 5);
        if (info_name)
        {
            ptr_value = hook_info_get (NULL, info_name, ptr_arguments);
            free (info_name);
        }
        return strdup ((ptr_value) ? ptr_value : "");
    }

    /* 6. look for name of option: if found, return this value */
    if (strncmp (text, "sec.data.", 9) == 0)
    {
        ptr_value = hashtable_get (secure_hashtable_data, text + 9);
        return strdup ((ptr_value) ? ptr_value : "");
    }
    else
    {
        config_file_search_with_string (text, NULL, NULL, &ptr_option, NULL);
        if (ptr_option)
        {
            if (!ptr_option->value)
                return strdup ("");
            switch (ptr_option->type)
            {
                case CONFIG_OPTION_TYPE_BOOLEAN:
                    return strdup (CONFIG_BOOLEAN(ptr_option) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
                case CONFIG_OPTION_TYPE_INTEGER:
                    if (ptr_option->string_values)
                        return strdup (ptr_option->string_values[CONFIG_INTEGER(ptr_option)]);
                    snprintf (str_value, sizeof (str_value),
                              "%d", CONFIG_INTEGER(ptr_option));
                    return strdup (str_value);
                case CONFIG_OPTION_TYPE_STRING:
                    return strdup (CONFIG_STRING(ptr_option));
                case CONFIG_OPTION_TYPE_COLOR:
                    return strdup (gui_color_get_name (CONFIG_COLOR(ptr_option)));
                case CONFIG_NUM_OPTION_TYPES:
                    return strdup ("");
            }
        }
    }

    /* 7. look for local variable in buffer */
    ptr_buffer = hashtable_get (pointers, "buffer");
    if (ptr_buffer)
    {
        ptr_value = hashtable_get (ptr_buffer->local_variables, text);
        if (ptr_value)
            return strdup (ptr_value);
    }

    /* 8. look for hdata */
    value = NULL;
    hdata_name = NULL;
    list_name = NULL;
    pointer = NULL;

    pos = strchr (text, '.');
    if (pos > text)
        hdata_name = string_strndup (text, pos - text);
    else
        hdata_name = strdup (text);

    if (!hdata_name)
        goto end;

    pos1 = strchr (hdata_name, '[');
    if (pos1 > hdata_name)
    {
        pos2 = strchr (pos1 + 1, ']');
        if (pos2 > pos1 + 1)
        {
            list_name = string_strndup (pos1 + 1, pos2 - pos1 - 1);
        }
        tmp = string_strndup (hdata_name, pos1 - hdata_name);
        if (tmp)
        {
            free (hdata_name);
            hdata_name = tmp;
        }
    }

    hdata = hook_hdata_get (NULL, hdata_name);
    if (!hdata)
        goto end;

    if (list_name)
        pointer = hdata_get_list (hdata, list_name);
    if (!pointer)
    {
        pointer = hashtable_get (pointers, hdata_name);
        if (!pointer)
            goto end;
    }

    value = eval_hdata_get_value (hdata, pointer, (pos) ? pos + 1 : NULL);

end:
    if (hdata_name)
        free (hdata_name);
    if (list_name)
        free (list_name);

    return (value) ? value : strdup ("");
}
예제 #13
0
int
completion_list_add_config_option_values_cb (void *data,
                                             const char *completion_item,
                                             struct t_gui_buffer *buffer,
                                             struct t_gui_completion *completion)
{
    char *pos_space, *option_full_name, *pos_section, *pos_option;
    char *file, *section, *value_string, str_number[64];
    const char *color_name;
    int length, i, num_colors;
    struct t_config_file *ptr_config;
    struct t_config_section *ptr_section, *section_found;
    struct t_config_option *option_found;
    struct t_gui_color_palette *color_palette;

    /* make C compiler happy */
    (void) data;
    (void) completion_item;
    (void) buffer;

    if (completion->args)
    {
        pos_space = strchr (completion->args, ' ');
        if (pos_space)
            option_full_name = string_strndup (completion->args,
                                               pos_space - completion->args);
        else
            option_full_name = strdup (completion->args);

        if (option_full_name)
        {
            file = NULL;
            section = NULL;
            pos_option = NULL;

            pos_section = strchr (option_full_name, '.');
            pos_option = (pos_section) ? strchr (pos_section + 1, '.') : NULL;

            if (pos_section && pos_option)
            {
                file = string_strndup (option_full_name,
                                       pos_section - option_full_name);
                section = string_strndup (pos_section + 1,
                                          pos_option - pos_section - 1);
                pos_option++;
            }
            if (file && section && pos_option)
            {
                ptr_config = config_file_search (file);
                if (ptr_config)
                {
                    ptr_section = config_file_search_section (ptr_config,
                                                              section);
                    if (ptr_section)
                    {
                        config_file_search_section_option (ptr_config,
                                                           ptr_section,
                                                           pos_option,
                                                           &section_found,
                                                           &option_found);
                        if (option_found)
                        {
                            switch (option_found->type)
                            {
                                case CONFIG_OPTION_TYPE_BOOLEAN:
                                    gui_completion_list_add (completion, "on",
                                                             0, WEECHAT_LIST_POS_SORT);
                                    gui_completion_list_add (completion, "off",
                                                             0, WEECHAT_LIST_POS_SORT);
                                    gui_completion_list_add (completion, "toggle",
                                                             0, WEECHAT_LIST_POS_END);
                                    if (option_found->value)
                                    {
                                        if (CONFIG_BOOLEAN(option_found) == CONFIG_BOOLEAN_TRUE)
                                            gui_completion_list_add (completion, "on",
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                        else
                                            gui_completion_list_add (completion, "off",
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                    }
                                    else
                                    {
                                        gui_completion_list_add (completion,
                                                                 WEECHAT_CONFIG_OPTION_NULL,
                                                                 0, WEECHAT_LIST_POS_BEGINNING);
                                    }
                                    break;
                                case CONFIG_OPTION_TYPE_INTEGER:
                                    if (option_found->string_values)
                                    {
                                        for (i = 0; option_found->string_values[i]; i++)
                                        {
                                            gui_completion_list_add (completion,
                                                                     option_found->string_values[i],
                                                                     0, WEECHAT_LIST_POS_SORT);
                                        }
                                        gui_completion_list_add (completion, "++1",
                                                                 0, WEECHAT_LIST_POS_END);
                                        gui_completion_list_add (completion, "--1",
                                                                 0, WEECHAT_LIST_POS_END);
                                        if (option_found->value)
                                        {
                                            gui_completion_list_add (completion,
                                                                     option_found->string_values[CONFIG_INTEGER(option_found)],
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                        }
                                        else
                                        {
                                            gui_completion_list_add (completion,
                                                                     WEECHAT_CONFIG_OPTION_NULL,
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                        }
                                    }
                                    else
                                    {
                                        if (option_found->value && CONFIG_INTEGER(option_found) > option_found->min)
                                            gui_completion_list_add (completion, "--1",
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                        if (option_found->value && CONFIG_INTEGER(option_found) < option_found->max)
                                            gui_completion_list_add (completion, "++1",
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                        if (option_found->value)
                                        {
                                            length = 64;
                                            value_string = malloc (length);
                                            if (value_string)
                                            {
                                                snprintf (value_string, length,
                                                          "%d", CONFIG_INTEGER(option_found));
                                                gui_completion_list_add (completion,
                                                                         value_string,
                                                                         0, WEECHAT_LIST_POS_BEGINNING);
                                                free (value_string);
                                            }
                                        }
                                        else
                                        {
                                            gui_completion_list_add (completion,
                                                                     WEECHAT_CONFIG_OPTION_NULL,
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                        }
                                    }
                                    break;
                                case CONFIG_OPTION_TYPE_STRING:
                                    gui_completion_list_add (completion,
                                                             "\"\"",
                                                             0, WEECHAT_LIST_POS_BEGINNING);
                                    if (option_found->value)
                                    {
                                        length = strlen (CONFIG_STRING(option_found)) + 2 + 1;
                                        value_string = malloc (length);
                                        if (value_string)
                                        {
                                            snprintf (value_string, length,
                                                      "\"%s\"",
                                                      CONFIG_STRING(option_found));
                                            gui_completion_list_add (completion,
                                                                     value_string,
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                            free (value_string);
                                        }
                                    }
                                    else
                                    {
                                        gui_completion_list_add (completion,
                                                                 WEECHAT_CONFIG_OPTION_NULL,
                                                                 0, WEECHAT_LIST_POS_BEGINNING);
                                    }
                                    break;
                                case CONFIG_OPTION_TYPE_COLOR:
                                    num_colors = gui_color_get_weechat_colors_number ();
                                    for (i = 0; i < num_colors; i++)
                                    {
                                        color_name = gui_color_get_name (i);
                                        if (color_name)
                                        {
                                            gui_completion_list_add (completion,
                                                                     color_name,
                                                                     0, WEECHAT_LIST_POS_SORT);
                                        }
                                    }
                                    num_colors = gui_color_get_term_colors ();
                                    for (i = 0; i <= num_colors; i++)
                                    {
                                        color_palette = gui_color_palette_get (i);
                                        if (color_palette)
                                        {
                                            gui_completion_list_add (completion,
                                                                     color_palette->alias,
                                                                     0, WEECHAT_LIST_POS_END);
                                        }
                                        else
                                        {
                                            snprintf (str_number,
                                                      sizeof (str_number),
                                                      "%d",
                                                      i);
                                            gui_completion_list_add (completion,
                                                                     str_number,
                                                                     0, WEECHAT_LIST_POS_END);
                                        }
                                    }
                                    gui_completion_list_add (completion, "++1",
                                                             0, WEECHAT_LIST_POS_END);
                                    gui_completion_list_add (completion, "--1",
                                                             0, WEECHAT_LIST_POS_END);
                                    if (option_found->value)
                                    {
                                        color_name = gui_color_get_name (CONFIG_INTEGER(option_found));
                                        if (color_name)
                                        {
                                            gui_completion_list_add (completion,
                                                                     color_name,
                                                                     0, WEECHAT_LIST_POS_BEGINNING);
                                        }
                                    }
                                    else
                                    {
                                        gui_completion_list_add (completion,
                                                                 WEECHAT_CONFIG_OPTION_NULL,
                                                                 0, WEECHAT_LIST_POS_BEGINNING);
                                    }
                                    break;
                                case CONFIG_NUM_OPTION_TYPES:
                                    break;
                            }
                            if (option_found->value
                                && option_found->null_value_allowed)
                            {
                                gui_completion_list_add (completion,
                                                         WEECHAT_CONFIG_OPTION_NULL,
                                                         0,
                                                         WEECHAT_LIST_POS_END);
                            }
                        }
                    }
                }
            }
            if (file)
                free (file);
            if (section)
                free (section);
        }
    }

    return WEECHAT_RC_OK;
}
예제 #14
0
파일: wee-eval.c 프로젝트: Evalle/weechat
char *
eval_hdata_get_value (struct t_hdata *hdata, void *pointer, const char *path)
{
    char *value, *old_value, *var_name, str_value[128], *pos;
    const char *ptr_value, *hdata_name;
    int type;
    struct t_hashtable *hashtable;

    value = NULL;
    var_name = NULL;

    /* NULL pointer? return empty string */
    if (!pointer)
        return strdup ("");

    /* no path? just return current pointer as string */
    if (!path || !path[0])
    {
        snprintf (str_value, sizeof (str_value),
                  "0x%lx", (long unsigned int)pointer);
        return strdup (str_value);
    }

    /*
     * look for name of hdata, for example in "window.buffer.full_name", the
     * hdata name is "window"
     */
    pos = strchr (path, '.');
    if (pos > path)
        var_name = string_strndup (path, pos - path);
    else
        var_name = strdup (path);

    if (!var_name)
        goto end;

    /* search type of variable in hdata */
    type = hdata_get_var_type (hdata, var_name);
    if (type < 0)
        goto end;

    /* build a string with the value or variable */
    switch (type)
    {
        case WEECHAT_HDATA_CHAR:
            snprintf (str_value, sizeof (str_value),
                      "%c", hdata_char (hdata, pointer, var_name));
            value = strdup (str_value);
            break;
        case WEECHAT_HDATA_INTEGER:
            snprintf (str_value, sizeof (str_value),
                      "%d", hdata_integer (hdata, pointer, var_name));
            value = strdup (str_value);
            break;
        case WEECHAT_HDATA_LONG:
            snprintf (str_value, sizeof (str_value),
                      "%ld", hdata_long (hdata, pointer, var_name));
            value = strdup (str_value);
            break;
        case WEECHAT_HDATA_STRING:
        case WEECHAT_HDATA_SHARED_STRING:
            ptr_value = hdata_string (hdata, pointer, var_name);
            value = (ptr_value) ? strdup (ptr_value) : NULL;
            break;
        case WEECHAT_HDATA_POINTER:
            pointer = hdata_pointer (hdata, pointer, var_name);
            snprintf (str_value, sizeof (str_value),
                      "0x%lx", (long unsigned int)pointer);
            value = strdup (str_value);
            break;
        case WEECHAT_HDATA_TIME:
            snprintf (str_value, sizeof (str_value),
                      "%ld", (long)hdata_time (hdata, pointer, var_name));
            value = strdup (str_value);
            break;
        case WEECHAT_HDATA_HASHTABLE:
            pointer = hdata_hashtable (hdata, pointer, var_name);
            if (pos)
            {
                /*
                 * for a hashtable, if there is a "." after name of hdata,
                 * get the value for this key in hashtable
                 */
                hashtable = pointer;
                ptr_value = hashtable_get (hashtable, pos + 1);
                if (ptr_value)
                {
                    switch (hashtable->type_values)
                    {
                        case HASHTABLE_INTEGER:
                            snprintf (str_value, sizeof (str_value),
                                      "%d", *((int *)ptr_value));
                            value = strdup (str_value);
                            break;
                        case HASHTABLE_STRING:
                            value = strdup (ptr_value);
                            break;
                        case HASHTABLE_POINTER:
                        case HASHTABLE_BUFFER:
                            snprintf (str_value, sizeof (str_value),
                                      "0x%lx", (long unsigned int)ptr_value);
                            value = strdup (str_value);
                            break;
                        case HASHTABLE_TIME:
                            snprintf (str_value, sizeof (str_value),
                                      "%ld", (long)(*((time_t *)ptr_value)));
                            value = strdup (str_value);
                            break;
                        case HASHTABLE_NUM_TYPES:
                            break;
                    }
                }
            }
            else
            {
                snprintf (str_value, sizeof (str_value),
                          "0x%lx", (long unsigned int)pointer);
                value = strdup (str_value);
            }
            break;
    }

    /*
     * if we are on a pointer and that something else is in path (after "."),
     * go on with this pointer and remaining path
     */
    if ((type == WEECHAT_HDATA_POINTER) && pos)
    {
        hdata_name = hdata_get_var_hdata (hdata, var_name);
        if (!hdata_name)
            goto end;

        hdata = hook_hdata_get (NULL, hdata_name);
        old_value = value;
        value = eval_hdata_get_value (hdata, pointer, (pos) ? pos + 1 : NULL);
        if (old_value)
            free (old_value);
    }

end:
    if (var_name)
        free (var_name);

    return value;
}
예제 #15
0
파일: gui-filter.c 프로젝트: Petzku/weechat
struct t_gui_filter *
gui_filter_new (int enabled, const char *name, const char *buffer_name,
                const char *tags, const char *regex)
{
    struct t_gui_filter *new_filter;
    regex_t *regex1, *regex2;
    char *pos_tab, *regex_prefix, **tags_array, buf[512], str_error[512];
    const char *ptr_start_regex, *pos_regex_message;
    int i, rc;

    if (!name || !buffer_name || !tags || !regex)
    {
        gui_filter_new_error (name, _("not enough arguments"));
        return NULL;
    }

    if (gui_filter_search_by_name (name))
    {
        gui_filter_new_error (name,
                              _("a filter with same name already exists"));
        return NULL;
    }

    ptr_start_regex = regex;
    if ((ptr_start_regex[0] == '!')
        || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!')))
    {
        ptr_start_regex++;
    }

    regex1 = NULL;
    regex2 = NULL;

    if (strcmp (ptr_start_regex, "*") != 0)
    {
        pos_tab = strstr (ptr_start_regex, "\\t");
        if (pos_tab)
        {
            regex_prefix = string_strndup (ptr_start_regex,
                                           pos_tab - ptr_start_regex);
            pos_regex_message = pos_tab + 2;
        }
        else
        {
            regex_prefix = NULL;
            pos_regex_message = ptr_start_regex;
        }

        if (regex_prefix && regex_prefix[0])
        {
            regex1 = malloc (sizeof (*regex1));
            if (regex1)
            {
                rc = string_regcomp (regex1, regex_prefix,
                                     REG_EXTENDED | REG_ICASE | REG_NOSUB);
                if (rc != 0)
                {
                    regerror (rc, regex1, buf, sizeof (buf));
                    snprintf (str_error, sizeof (str_error),
                              /* TRANSLATORS: %s is the error returned by regerror */
                              _("invalid regular expression (%s)"),
                              buf);
                    gui_filter_new_error (name, str_error);
                    free (regex_prefix);
                    free (regex1);
                    return NULL;
                }
            }
        }

        if (pos_regex_message && pos_regex_message[0])
        {
            regex2 = malloc (sizeof (*regex2));
            if (regex2)
            {
                rc = string_regcomp (regex2, pos_regex_message,
                                     REG_EXTENDED | REG_ICASE | REG_NOSUB);
                if (rc != 0)
                {
                    regerror (rc, regex2, buf, sizeof (buf));
                    snprintf (str_error, sizeof (str_error),
                              /* TRANSLATORS: %s is the error returned by regerror */
                              _("invalid regular expression (%s)"),
                              buf);
                    gui_filter_new_error (name, str_error);
                    if (regex_prefix)
                        free (regex_prefix);
                    if (regex1)
                    {
                        regfree (regex1);
                        free (regex1);
                    }
                    free (regex2);
                    return NULL;
                }
            }
        }

        if (regex_prefix)
            free (regex_prefix);
    }

    /* create new filter */
    new_filter = malloc (sizeof (*new_filter));
    if (new_filter)
    {
        /* init filter */
        new_filter->enabled = enabled;
        new_filter->name = strdup (name);
        new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*");
        new_filter->buffers = string_split (new_filter->buffer_name,
                                            ",", 0, 0,
                                            &new_filter->num_buffers);
        new_filter->tags = (tags) ? strdup (tags) : NULL;
        new_filter->tags_count = 0;
        new_filter->tags_array = NULL;
        if (new_filter->tags)
        {
            tags_array = string_split (new_filter->tags, ",", 0, 0,
                                       &new_filter->tags_count);
            if (tags_array)
            {
                new_filter->tags_array = malloc (new_filter->tags_count *
                                                 sizeof (*new_filter->tags_array));
                if (new_filter->tags_array)
                {
                    for (i = 0; i < new_filter->tags_count; i++)
                    {
                        new_filter->tags_array[i] = string_split (tags_array[i],
                                                                  "+", 0, 0,
                                                                  NULL);
                    }
                }
                string_free_split (tags_array);
            }
        }
        new_filter->regex = strdup (regex);
        new_filter->regex_prefix = regex1;
        new_filter->regex_message = regex2;

        /* add filter to filters list */
        new_filter->prev_filter = last_gui_filter;
        if (gui_filters)
            last_gui_filter->next_filter = new_filter;
        else
            gui_filters = new_filter;
        last_gui_filter = new_filter;
        new_filter->next_filter = NULL;

        (void) hook_signal_send ("filter_added",
                                 WEECHAT_HOOK_SIGNAL_POINTER, new_filter);
    }
    else
    {
        gui_filter_new_error (name, _("not enough memory"));
    }

    return new_filter;
}
예제 #16
0
파일: gui-color.c 프로젝트: Ratler/weechat
const char *
gui_color_get_custom (const char *color_name)
{
    int fg, bg, fg_term, bg_term, term_color;
    static char color[32][32];
    static int index_color = 0;
    char color_fg[32], color_bg[32];
    char *pos_delim, *str_fg, *pos_bg, *error, *color_attr;
    const char *ptr_color_name;

    /* attribute or other color name (GUI dependent) */
    index_color = (index_color + 1) % 32;
    color[index_color][0] = '\0';

    if (!color_name || !color_name[0])
        return color[index_color];

    if (string_strcasecmp (color_name, "reset") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c",
                  GUI_COLOR_RESET_CHAR);
    }
    else if (string_strcasecmp (color_name, "resetcolor") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_RESET_CHAR);
    }
    else if (string_strcasecmp (color_name, "bold") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_SET_ATTR_CHAR,
                  GUI_COLOR_ATTR_BOLD_CHAR);
    }
    else if (string_strcasecmp (color_name, "-bold") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_REMOVE_ATTR_CHAR,
                  GUI_COLOR_ATTR_BOLD_CHAR);
    }
    else if (string_strcasecmp (color_name, "reverse") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_SET_ATTR_CHAR,
                  GUI_COLOR_ATTR_REVERSE_CHAR);
    }
    else if (string_strcasecmp (color_name, "-reverse") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_REMOVE_ATTR_CHAR,
                  GUI_COLOR_ATTR_REVERSE_CHAR);
    }
    else if (string_strcasecmp (color_name, "italic") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_SET_ATTR_CHAR,
                  GUI_COLOR_ATTR_ITALIC_CHAR);
    }
    else if (string_strcasecmp (color_name, "-italic") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_REMOVE_ATTR_CHAR,
                  GUI_COLOR_ATTR_ITALIC_CHAR);
    }
    else if (string_strcasecmp (color_name, "underline") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_SET_ATTR_CHAR,
                  GUI_COLOR_ATTR_UNDERLINE_CHAR);
    }
    else if (string_strcasecmp (color_name, "-underline") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c",
                  GUI_COLOR_REMOVE_ATTR_CHAR,
                  GUI_COLOR_ATTR_UNDERLINE_CHAR);
    }
    else if (string_strcasecmp (color_name, "bar_fg") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_FG_CHAR);
    }
    else if (string_strcasecmp (color_name, "bar_delim") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_DELIM_CHAR);
    }
    else if (string_strcasecmp (color_name, "bar_bg") == 0)
    {
        snprintf (color[index_color], sizeof (color[index_color]),
                  "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_BG_CHAR);
    }
    else
    {
        /* custom color name (GUI dependent) */
        fg_term = -1;
        bg_term = -1;
        fg = -1;
        bg = -1;
        color_attr = NULL;
        color_fg[0] = '\0';
        color_bg[0] = '\0';

        /* read extra attributes (bold, ..) */
        ptr_color_name = color_name;
        while (gui_color_attr_get_flag (ptr_color_name[0]) > 0)
        {
            ptr_color_name++;
        }
        if (ptr_color_name != color_name)
        {
            color_attr = string_strndup (color_name,
                                         ptr_color_name - color_name);
        }

        pos_delim = strchr (ptr_color_name, ',');
        if (!pos_delim)
            pos_delim = strchr (ptr_color_name, ':');
        if (pos_delim)
        {
            if (pos_delim == ptr_color_name)
                str_fg = NULL;
            else
                str_fg = string_strndup (ptr_color_name,
                                         pos_delim - ptr_color_name);
            pos_bg = pos_delim + 1;
        }
        else
        {
            str_fg = strdup (ptr_color_name);
            pos_bg = NULL;
        }

        if (str_fg)
        {
            fg_term = gui_color_palette_get_alias (str_fg);
            if (fg_term < 0)
            {
                error = NULL;
                term_color = (int)strtol (str_fg, &error, 10);
                if (error && !error[0])
                {
                    fg_term = term_color;
                    if (fg_term < 0)
                        fg_term = 0;
                    else if (fg_term > GUI_COLOR_EXTENDED_MAX)
                        fg_term = GUI_COLOR_EXTENDED_MAX;
                }
                else
                    fg = gui_color_search (str_fg);
            }
        }
        if (pos_bg)
        {
            bg_term = gui_color_palette_get_alias (pos_bg);
            if (bg_term < 0)
            {
                error = NULL;
                term_color = (int)strtol (pos_bg, &error, 10);
                if (error && !error[0])
                {
                    bg_term = term_color;
                    if (bg_term < 0)
                        bg_term = 0;
                    else if (bg_term > GUI_COLOR_EXTENDED_MAX)
                        bg_term = GUI_COLOR_EXTENDED_MAX;
                }
                else
                    bg = gui_color_search (pos_bg);
            }
        }

        if (fg_term >= 0)
        {
            snprintf (color_fg, sizeof (color_fg), "%c%s%05d",
                      GUI_COLOR_EXTENDED_CHAR,
                      (color_attr) ? color_attr : "",
                      fg_term);
        }
        else if (fg >= 0)
        {
            snprintf (color_fg, sizeof (color_fg), "%s%02d",
                      (color_attr) ? color_attr : "",
                      fg);
        }

        if (bg_term >= 0)
        {
            snprintf (color_bg, sizeof (color_bg), "%c%05d",
                      GUI_COLOR_EXTENDED_CHAR,
                      bg_term);
        }
        else if (bg >= 0)
        {
            snprintf (color_bg, sizeof (color_bg), "%02d",
                      bg);
        }

        if (color_fg[0] && color_bg[0])
        {
            snprintf (color[index_color], sizeof (color[index_color]),
                      "%c%c%s,%s",
                      GUI_COLOR_COLOR_CHAR,
                      GUI_COLOR_FG_BG_CHAR,
                      color_fg,
                      color_bg);
        }
        else if (color_fg[0])
        {
            snprintf (color[index_color], sizeof (color[index_color]),
                      "%c%c%s",
                      GUI_COLOR_COLOR_CHAR,
                      GUI_COLOR_FG_CHAR,
                      color_fg);
        }
        else if (color_bg[0])
        {
            snprintf (color[index_color], sizeof (color[index_color]),
                      "%c%c%s",
                      GUI_COLOR_COLOR_CHAR,
                      GUI_COLOR_BG_CHAR,
                      color_bg);
        }

        if (color_attr)
            free (color_attr);
        if (str_fg)
            free (str_fg);
    }

    return color[index_color];
}
예제 #17
0
void
gui_bar_window_draw (struct t_gui_bar_window *bar_window,
                     struct t_gui_window *window)
{
    int x, y, items_count, num_lines, line;
    enum t_gui_bar_filling filling;
    char *content, **items;
    static char str_start_input[16] = { '\0' };
    static char str_start_input_hidden[16] = { '\0' };
    static char str_cursor[16] = { '\0' };
    char *pos_start_input, *pos_after_start_input, *pos_cursor, *buf;
    char *new_start_input, *ptr_string;
    static int length_start_input, length_start_input_hidden;
    int length_on_screen;
    int chars_available, index, size;
    int length_screen_before_cursor, length_screen_after_cursor;
    int diff, max_length, optimal_number_of_lines;
    int some_data_not_displayed;
    int index_item, index_subitem, index_line;

    if (!gui_init_ok)
        return;

    if (gui_window_bare_display)
        return;

    if ((bar_window->x < 0) || (bar_window->y < 0))
        return;

    if (!str_start_input[0])
    {
        snprintf (str_start_input, sizeof (str_start_input), "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_START_INPUT_CHAR);
        length_start_input = strlen (str_start_input);

        snprintf (str_start_input_hidden, sizeof (str_start_input_hidden), "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_START_INPUT_HIDDEN_CHAR);
        length_start_input_hidden = strlen (str_start_input_hidden);

        snprintf (str_cursor, sizeof (str_cursor), "%c%c%c",
                  GUI_COLOR_COLOR_CHAR,
                  GUI_COLOR_BAR_CHAR,
                  GUI_COLOR_BAR_MOVE_CURSOR_CHAR);
    }

    /*
     * these values will be overwritten later (by gui_bar_window_print_string)
     * if cursor has to move somewhere in bar window
     */
    bar_window->cursor_x = -1;
    bar_window->cursor_y = -1;

    /* remove coords */
    gui_bar_window_coords_free (bar_window);
    index_item = -1;
    index_subitem = -1;
    index_line = 0;

    gui_window_current_emphasis = 0;

    filling = gui_bar_get_filling (bar_window->bar);

    content = gui_bar_window_content_get_with_filling (bar_window, window);
    if (content)
    {
        if ((filling == GUI_BAR_FILLING_HORIZONTAL)
            && (bar_window->scroll_x > 0))
        {
            length_on_screen = gui_chat_strlen_screen (content);
            if (bar_window->scroll_x > length_on_screen - bar_window->width)
            {
                bar_window->scroll_x = length_on_screen - bar_window->width;
                if (bar_window->scroll_x < 0)
                    bar_window->scroll_x = 0;
            }
        }

        items = string_split (content, "\n", 0, 0, &items_count);
        if (items_count == 0)
        {
            if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]) == 0)
                gui_bar_window_set_current_size (bar_window, window, 1);
            gui_window_clear (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                              CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]),
                              CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
        }
        else
        {
            /* bar with auto size ? then compute new size, according to content */
            if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]) == 0)
            {
                /* search longer line and optimal number of lines */
                max_length = 0;
                optimal_number_of_lines = 0;
                for (line = 0; line < items_count; line++)
                {
                    length_on_screen = gui_chat_strlen_screen (items[line]);

                    pos_cursor = strstr (items[line], str_cursor);
                    if (pos_cursor && (gui_chat_strlen_screen (pos_cursor) == 0))
                        length_on_screen++;

                    if (length_on_screen > max_length)
                        max_length = length_on_screen;

                    if (length_on_screen % bar_window->width == 0)
                        num_lines = length_on_screen / bar_window->width;
                    else
                        num_lines = (length_on_screen / bar_window->width) + 1;
                    if (num_lines == 0)
                        num_lines = 1;
                    optimal_number_of_lines += num_lines;
                }
                if (max_length == 0)
                    max_length = 1;

                switch (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_POSITION]))
                {
                    case GUI_BAR_POSITION_BOTTOM:
                    case GUI_BAR_POSITION_TOP:
                        if (filling == GUI_BAR_FILLING_HORIZONTAL)
                            num_lines = optimal_number_of_lines;
                        else
                            num_lines = items_count;
                        gui_bar_window_set_current_size (bar_window, window,
                                                         num_lines);
                        break;
                    case GUI_BAR_POSITION_LEFT:
                    case GUI_BAR_POSITION_RIGHT:
                        gui_bar_window_set_current_size (bar_window, window,
                                                         max_length);
                        break;
                    case GUI_BAR_NUM_POSITIONS:
                        break;
                }
            }

            gui_window_clear (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                              CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]),
                              CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
            x = 0;
            y = 0;
            some_data_not_displayed = 0;
            if ((bar_window->scroll_y > 0)
                && (bar_window->scroll_y > items_count - bar_window->height))
            {
                bar_window->scroll_y = items_count - bar_window->height;
                if (bar_window->scroll_y < 0)
                    bar_window->scroll_y = 0;
            }
            for (line = 0;
                 (line < items_count) && (y < bar_window->height);
                 line++)
            {
                pos_start_input = strstr (items[line], str_start_input);
                if (pos_start_input)
                {
                    pos_after_start_input = pos_start_input + strlen (str_start_input);
                    pos_cursor = strstr (pos_after_start_input, str_cursor);
                    if (pos_cursor)
                    {
                        chars_available =
                            ((bar_window->height - y - 1) * bar_window->width) + /* next lines */
                            (bar_window->width - x - 1); /* chars on current line */

                        length_screen_before_cursor = -1;
                        length_screen_after_cursor = -1;

                        buf = string_strndup (items[line], pos_cursor - items[line]);
                        if (buf)
                        {
                            length_screen_before_cursor = gui_chat_strlen_screen (buf);
                            length_screen_after_cursor = gui_chat_strlen_screen (pos_cursor);
                            free (buf);
                        }

                        if ((length_screen_before_cursor < 0) || (length_screen_after_cursor < 0))
                            length_screen_before_cursor = gui_chat_strlen_screen (items[line]);

                        diff = length_screen_before_cursor - chars_available;
                        if (diff > 0)
                        {
                            if (CONFIG_INTEGER(config_look_input_cursor_scroll) > 0)
                            {
                                diff += (CONFIG_INTEGER(config_look_input_cursor_scroll)
                                         - 1
                                         - (diff % CONFIG_INTEGER(config_look_input_cursor_scroll)));
                            }

                            /* compute new start for displaying input */
                            new_start_input = pos_after_start_input +
                                gui_chat_string_real_pos (pos_after_start_input,
                                                          diff, 1);
                            if (new_start_input > pos_cursor)
                                new_start_input = pos_cursor;

                            buf = malloc (strlen (items[line]) + length_start_input_hidden + 1);
                            if (buf)
                            {
                                /* add string before start of input */
                                index = 0;
                                if (pos_start_input > items[line])
                                {
                                    size = pos_start_input - items[line];
                                    memmove (buf, items[line], size);
                                    index += size;
                                }
                                /* add tag "start_input_hidden" */
                                memmove (buf + index, str_start_input_hidden, length_start_input_hidden);
                                index += length_start_input_hidden;
                                /* add hidden part of input */
                                size = new_start_input - pos_after_start_input;
                                memmove (buf + index, pos_after_start_input, size);
                                index += size;
                                /* add tag "start_input" */
                                memmove (buf + index, str_start_input, length_start_input);
                                index += length_start_input;
                                /* add input (will be displayed) */
                                size = strlen (new_start_input) + 1;
                                memmove (buf + index, new_start_input, size);

                                free (items[line]);
                                items[line] = buf;
                            }
                        }

                    }
                }

                if ((bar_window->scroll_y == 0)
                    || (line >= bar_window->scroll_y))
                {
                    if (!gui_bar_window_print_string (bar_window, filling,
                                                      &x, &y,
                                                      items[line], 1, 1,
                                                      &index_item,
                                                      &index_subitem,
                                                      &index_line))
                    {
                        some_data_not_displayed = 1;
                    }

                    if (x < bar_window->width)
                    {
                        if (filling == GUI_BAR_FILLING_HORIZONTAL)
                        {
                            gui_window_set_custom_color_fg_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                                                               CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]),
                                                               CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
                            gui_window_remove_color_style (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                                                           A_ALL_ATTR);
                            wclrtobot (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar);
                        }
                        else
                        {
                            gui_window_remove_color_style (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                                                           A_ALL_ATTR);
                        }
                        while (x < bar_window->width)
                        {
                            gui_bar_window_print_string (bar_window, filling,
                                                         &x, &y, " ", 0, 0,
                                                         &index_item,
                                                         &index_subitem,
                                                         &index_line);
                        }
                    }

                    x = 0;
                    y++;
                }
            }
            if ((bar_window->cursor_x < 0) && (bar_window->cursor_y < 0)
                && ((bar_window->scroll_x > 0) || (bar_window->scroll_y > 0)))
            {
                if (filling == GUI_BAR_FILLING_HORIZONTAL)
                {
                    ptr_string = CONFIG_STRING(config_look_bar_more_left);
                    x = 0;
                }
                else
                {
                    ptr_string = CONFIG_STRING(config_look_bar_more_up);
                    x = bar_window->width - utf8_strlen_screen (ptr_string);
                    if (x < 0)
                        x = 0;
                }
                y = 0;
                if (ptr_string && ptr_string[0])
                {
                    gui_window_set_custom_color_fg_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                                                       CONFIG_COLOR(config_color_bar_more),
                                                       CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
                    mvwaddstr (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                               y, x, ptr_string);
                }
            }
            if ((bar_window->cursor_x < 0) && (bar_window->cursor_y < 0)
                && (some_data_not_displayed || (line < items_count)))
            {
                ptr_string = (filling == GUI_BAR_FILLING_HORIZONTAL) ?
                    CONFIG_STRING(config_look_bar_more_right) :
                    CONFIG_STRING(config_look_bar_more_down);
                x = bar_window->width - utf8_strlen_screen (ptr_string);
                if (x < 0)
                    x = 0;
                y = (bar_window->height > 1) ? bar_window->height - 1 : 0;
                if (ptr_string && ptr_string[0])
                {
                    gui_window_set_custom_color_fg_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                                                       CONFIG_COLOR(config_color_bar_more),
                                                       CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
                    mvwaddstr (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                               y, x, ptr_string);
                }
            }
        }
        if (items)
            string_free_split (items);
        free (content);
    }
    else
    {
        if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE]) == 0)
            gui_bar_window_set_current_size (bar_window, window, 1);
        gui_window_clear (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
                          CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]),
                          CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
    }

    /*
     * move cursor if it was asked in an item content (input_text does that
     * to move cursor in user input text)
     */
    if ((!window || (gui_current_window == window))
        && (bar_window->cursor_x >= 0) && (bar_window->cursor_y >= 0))
    {
        y = bar_window->cursor_y - bar_window->y;
        x = bar_window->cursor_x - bar_window->x;
        if (x > bar_window->width - 2)
            x = bar_window->width - 2;
        wmove (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar, y, x);
        wrefresh (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar);
        if (!gui_cursor_mode)
        {
            gui_window_cursor_x = bar_window->cursor_x;
            gui_window_cursor_y = bar_window->cursor_y;
            move (bar_window->cursor_y, bar_window->cursor_x);
        }
    }
    else
        wnoutrefresh (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar);

    if (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SEPARATOR]))
    {
        switch (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_POSITION]))
        {
            case GUI_BAR_POSITION_BOTTOM:
                gui_window_set_weechat_color (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                              GUI_COLOR_SEPARATOR);
                gui_window_hline (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                  0, 0, bar_window->width,
                                  CONFIG_STRING(config_look_separator_horizontal));
                break;
            case GUI_BAR_POSITION_TOP:
                gui_window_set_weechat_color (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                              GUI_COLOR_SEPARATOR);
                gui_window_hline (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                  0, 0, bar_window->width,
                                  CONFIG_STRING(config_look_separator_horizontal));
                break;
            case GUI_BAR_POSITION_LEFT:
                gui_window_set_weechat_color (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                              GUI_COLOR_SEPARATOR);
                gui_window_vline (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                  0, 0, bar_window->height,
                                  CONFIG_STRING(config_look_separator_vertical));
                break;
            case GUI_BAR_POSITION_RIGHT:
                gui_window_set_weechat_color (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                              GUI_COLOR_SEPARATOR);
                gui_window_vline (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator,
                                  0, 0, bar_window->height,
                                  CONFIG_STRING(config_look_separator_vertical));
                break;
            case GUI_BAR_NUM_POSITIONS:
                break;
        }
        wnoutrefresh (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_separator);
    }

    refresh ();
}