Пример #1
0
int
gui_history_hdata_history_update_cb (void *data,
                                     struct t_hdata *hdata,
                                     void *pointer,
                                     struct t_hashtable *hashtable)
{
    struct t_gui_history *ptr_history;
    struct t_gui_buffer *ptr_buffer;
    const char *text, *buffer;
    long unsigned int value;
    int rc;

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

    rc = 0;

    text = hashtable_get (hashtable, "text");
    if (!text)
        return rc;

    if (pointer)
    {
        /* update history */
        ptr_history = (struct t_gui_history *)pointer;
        if (ptr_history->text)
            free (ptr_history->text);
        ptr_history->text = strdup (text);
    }
    else
    {
        /* create new entry in history */
        ptr_buffer = NULL;
        if (hashtable_has_key (hashtable, "buffer"))
        {
            buffer = hashtable_get (hashtable, "buffer");
            if (buffer)
            {
                rc = sscanf (buffer, "%lx", &value);
                if ((rc != EOF) && (rc != 0))
                    ptr_buffer = (struct t_gui_buffer *)value;
            }
        }
        if (ptr_buffer)
            gui_history_add (ptr_buffer, text);
        else
            gui_history_global_add (text);
    }

    return rc;
}
Пример #2
0
int
hdata_update (struct t_hdata *hdata, void *pointer,
              struct t_hashtable *hashtable)
{
    const char *value;
    struct t_hdata_var *var;
    int rc;

    if (!hdata || !hashtable || !hdata->callback_update)
        return 0;

    /* check if create of structure is allowed */
    if (hashtable_has_key (hashtable, "__create_allowed"))
        return (int)hdata->create_allowed;

    /* check if delete of structure is allowed */
    if (hashtable_has_key (hashtable, "__delete_allowed"))
        return (int)hdata->delete_allowed;

    /* check if update of variable is allowed */
    value = hashtable_get (hashtable, "__update_allowed");
    if (value)
    {
        if (!hdata->callback_update)
            return 0;
        var = hashtable_get (hdata->hash_var, value);
        if (!var)
            return 0;
        return (var->update_allowed) ? 1 : 0;
    }

    /* update data */
    hdata->update_pending = 1;
    rc = (hdata->callback_update) (hdata->callback_update_data,
                                   hdata, pointer, hashtable);
    hdata->update_pending = 0;

    return rc;
}
Пример #3
0
TEST(Hashtable, SetGetRemove)
{
    struct t_hashtable *hashtable, *hashtable2;
    struct t_hashtable_item *item, *ptr_item, *ptr_item2;
    const char *str_key = HASHTABLE_TEST_KEY;
    const char *str_value = HASHTABLE_TEST_VALUE;
    const char *ptr_value;
    unsigned long long hash;
    int i;

    hashtable = hashtable_new (32,
                               WEECHAT_HASHTABLE_STRING,
                               WEECHAT_HASHTABLE_STRING,
                               &test_hashtable_hash_key_cb,
                               &test_hashtable_keycmp_cb);
    LONGS_EQUAL(32, hashtable->size);
    LONGS_EQUAL(0, hashtable->items_count);

    /* invalid set of items */
    POINTERS_EQUAL(NULL, hashtable_set_with_size (NULL, NULL, -1, NULL, -1));
    POINTERS_EQUAL(NULL, hashtable_set_with_size (NULL, NULL, -1, NULL, -1));

    /* add an item in hashtable with NULL value */
    item = hashtable_set (hashtable, str_key, NULL);
    CHECK(item);
    LONGS_EQUAL(1, hashtable->items_count);
    STRCMP_EQUAL(str_key, (const char *)item->key);
    LONGS_EQUAL(strlen (str_key) + 1, item->key_size);
    POINTERS_EQUAL(NULL, item->value);
    LONGS_EQUAL(0, item->value_size);
    POINTERS_EQUAL(NULL, item->prev_item);
    POINTERS_EQUAL(NULL, item->next_item);

    /* set a string value for the same key */
    item = hashtable_set (hashtable, str_key, str_value);
    CHECK(item);
    LONGS_EQUAL(1, hashtable->items_count);
    STRCMP_EQUAL(str_key, (const char *)item->key);
    LONGS_EQUAL(strlen (str_key) + 1, item->key_size);
    STRCMP_EQUAL(str_value, (const char *)item->value);
    LONGS_EQUAL(strlen (str_value) + 1, item->value_size);
    POINTERS_EQUAL(NULL, item->prev_item);
    POINTERS_EQUAL(NULL, item->next_item);

    /* get item */
    item = hashtable_get_item (hashtable, str_key, &hash);
    CHECK(item);
    STRCMP_EQUAL(str_key, (const char *)item->key);
    STRCMP_EQUAL(str_value, (const char *)item->value);
    LONGS_EQUAL(2, hash);

    /* get value */
    ptr_value = (const char *)hashtable_get (hashtable, str_key);
    CHECK(ptr_value);
    STRCMP_EQUAL(ptr_value, str_value);

    /* check if key is in hashtable */
    LONGS_EQUAL(0, hashtable_has_key (hashtable, NULL));
    LONGS_EQUAL(0, hashtable_has_key (hashtable, ""));
    LONGS_EQUAL(0, hashtable_has_key (hashtable, "xxx"));
    LONGS_EQUAL(1, hashtable_has_key (hashtable, str_key));

    /* delete an item */
    hashtable_remove (hashtable, str_key);
    LONGS_EQUAL(0, hashtable->items_count);

    /* add an item with size in hashtable */
    item = hashtable_set_with_size (hashtable,
                                    str_key, strlen (str_key) + 1,
                                    str_value, strlen (str_value) + 1);
    CHECK(item);
    LONGS_EQUAL(1, hashtable->items_count);
    STRCMP_EQUAL(str_key, (const char *)item->key);
    LONGS_EQUAL(strlen (str_key) + 1, item->key_size);
    STRCMP_EQUAL(str_value, (const char *)item->value);
    LONGS_EQUAL(strlen (str_value) + 1, item->value_size);

    /* add another item */
    hashtable_set (hashtable, "xxx", "zzz");
    LONGS_EQUAL(2, hashtable->items_count);

    /*
     * test duplication of hashtable and check that duplicated content is
     * exactly the same as initial hashtable
     */
    hashtable2 = hashtable_dup (hashtable);
    CHECK(hashtable2);
    LONGS_EQUAL(hashtable->size, hashtable2->size);
    LONGS_EQUAL(hashtable->items_count, hashtable2->items_count);
    for (i = 0; i < hashtable->size; i++)
    {
        if (hashtable->htable[i])
        {
            ptr_item = hashtable->htable[i];
            ptr_item2 = hashtable2->htable[i];
            while (ptr_item && ptr_item2)
            {
                LONGS_EQUAL(ptr_item->key_size, ptr_item2->key_size);
                LONGS_EQUAL(ptr_item->value_size, ptr_item2->value_size);
                if (ptr_item->key)
                {
                    STRCMP_EQUAL((const char *)ptr_item->key,
                                 (const char *)ptr_item2->key);
                }
                else
                {
                    POINTERS_EQUAL(ptr_item->key, ptr_item2->key);
                }
                if (ptr_item->value)
                {
                    STRCMP_EQUAL((const char *)ptr_item->value,
                                 (const char *)ptr_item2->value);
                }
                else
                {
                    POINTERS_EQUAL(ptr_item->value, ptr_item2->value);
                }
                ptr_item = ptr_item->next_item;
                ptr_item2 = ptr_item2->next_item;
                CHECK((ptr_item && ptr_item2) || (!ptr_item && !ptr_item2));
            }
        }
        else
        {
            POINTERS_EQUAL(hashtable->htable[i], hashtable2->htable[i]);
        }
    }

    /* remove all items */
    hashtable_remove_all (hashtable);
    LONGS_EQUAL(0, hashtable->items_count);

    /* free hashtables */
    hashtable_free (hashtable);
    hashtable_free (hashtable2);

    /*
     * create a hashtable with size 8, and add 6 items,
     * to check if many items with same hashed key work fine,
     * the expected htable inside hashtable is:
     *   +-----+
     *   |   0 |
     *   +-----+
     *   |   1 |
     *   +-----+
     *   |   2 | --> "extensible"
     *   +-----+
     *   |   3 | --> "fast" --> "light"
     *   +-----+
     *   |   4 |
     *   +-----+
     *   |   5 | --> "chat"
     *   +-----+
     *   |   6 | --> "client"
     *   +-----+
     *   |   7 | --> "weechat"
     *   +-----+
     */
    hashtable = hashtable_new (8,
                               WEECHAT_HASHTABLE_STRING,
                               WEECHAT_HASHTABLE_STRING,
                               NULL,
                               NULL);
    LONGS_EQUAL(8, hashtable->size);
    LONGS_EQUAL(0, hashtable->items_count);

    item = hashtable_set (hashtable, "weechat", NULL);
    CHECK(item);
    POINTERS_EQUAL(item, hashtable->htable[7]);

    item = hashtable_set (hashtable, "fast", NULL);
    CHECK(item);
    POINTERS_EQUAL(item, hashtable->htable[3]);

    item = hashtable_set (hashtable, "light", NULL);
    CHECK(item);
    POINTERS_EQUAL(item, hashtable->htable[3]->next_item);

    item = hashtable_set (hashtable, "extensible", NULL);
    CHECK(item);
    POINTERS_EQUAL(item, hashtable->htable[2]);

    item = hashtable_set (hashtable, "chat", NULL);
    CHECK(item);
    POINTERS_EQUAL(item, hashtable->htable[5]);

    item = hashtable_set (hashtable, "client", NULL);
    CHECK(item);
    POINTERS_EQUAL(item, hashtable->htable[6]);

    /* free hashtable */
    hashtable_free (hashtable);
}
Пример #4
0
char *
eval_expression (const char *expr, struct t_hashtable *pointers,
                 struct t_hashtable *extra_vars, struct t_hashtable *options)
{
    int condition, extra_vars_eval, rc, pointers_allocated, regex_allocated;
    char *value;
    const char *prefix, *suffix;
    const char *default_prefix = EVAL_DEFAULT_PREFIX;
    const char *default_suffix = EVAL_DEFAULT_SUFFIX;
    const char *ptr_value, *regex_replace;
    struct t_gui_window *window;
    regex_t *regex;

    if (!expr)
        return NULL;

    condition = 0;
    extra_vars_eval = 0;
    pointers_allocated = 0;
    regex_allocated = 0;
    prefix = default_prefix;
    suffix = default_suffix;
    regex = NULL;
    regex_replace = NULL;

    if (pointers)
    {
        regex = (regex_t *)hashtable_get (pointers, "regex");
    }
    else
    {
        /* create hashtable pointers if it's NULL */
        pointers = hashtable_new (32,
                                  WEECHAT_HASHTABLE_STRING,
                                  WEECHAT_HASHTABLE_POINTER,
                                  NULL,
                                  NULL);
        if (!pointers)
            return NULL;
        pointers_allocated = 1;
    }

    /*
     * set window/buffer with pointer to current window/buffer
     * (if not already defined in the hashtable)
     */
    if (gui_current_window)
    {
        if (!hashtable_has_key (pointers, "window"))
            hashtable_set (pointers, "window", gui_current_window);
        if (!hashtable_has_key (pointers, "buffer"))
        {
            window = (struct t_gui_window *)hashtable_get (pointers, "window");
            if (window)
                hashtable_set (pointers, "buffer", window->buffer);
        }
    }

    /* read options */
    if (options)
    {
        /* check the type of evaluation */
        ptr_value = hashtable_get (options, "type");
        if (ptr_value && (strcmp (ptr_value, "condition") == 0))
            condition = 1;

        /* check if extra vars must be evaluated */
        ptr_value = hashtable_get (options, "extra");
        if (ptr_value && (strcmp (ptr_value, "eval") == 0))
            extra_vars_eval = 1;

        /* check for custom prefix */
        ptr_value = hashtable_get (options, "prefix");
        if (ptr_value && ptr_value[0])
            prefix = ptr_value;

        /* check for custom suffix */
        ptr_value = hashtable_get (options, "suffix");
        if (ptr_value && ptr_value[0])
            suffix = ptr_value;

        /* check for regex */
        ptr_value = hashtable_get (options, "regex");
        if (ptr_value)
        {
            regex = malloc (sizeof (*regex));
            if (string_regcomp (regex, ptr_value,
                                REG_EXTENDED | REG_ICASE) == 0)
            {
                regex_allocated = 1;
            }
            else
            {
                free (regex);
                regex = NULL;
            }
        }

        /* check for regex replacement (evaluated later) */
        ptr_value = hashtable_get (options, "regex_replace");
        if (ptr_value)
        {
            regex_replace = ptr_value;
        }
    }

    /* evaluate expression */
    if (condition)
    {
        /* evaluate as condition (return a boolean: "0" or "1") */
        value = eval_expression_condition (expr, pointers,
                                           extra_vars, extra_vars_eval,
                                           prefix, suffix);
        rc = eval_is_true (value);
        if (value)
            free (value);
        value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
    }
    else
    {
        if (regex && regex_replace)
        {
            /* replace with regex */
            value = eval_replace_regex (expr, regex, regex_replace,
                                        pointers, extra_vars, extra_vars_eval,
                                        prefix, suffix);
        }
        else
        {
            /* only replace variables in expression */
            value = eval_replace_vars (expr, pointers,
                                       extra_vars, extra_vars_eval,
                                       prefix, suffix, NULL);
        }
    }

    if (pointers_allocated)
        hashtable_free (pointers);
    if (regex && regex_allocated)
    {
        regfree (regex);
        free (regex);
    }

    return value;
}
Пример #5
0
int
gui_line_hdata_line_data_update_cb (void *data,
                                    struct t_hdata *hdata,
                                    void *pointer,
                                    struct t_hashtable *hashtable)
{
    const char *value;
    struct t_gui_line_data *line_data;
    struct t_gui_window *ptr_win;
    int rc, update_coords;

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

    line_data = (struct t_gui_line_data *)pointer;

    rc = 0;
    update_coords = 0;

    if (hashtable_has_key (hashtable, "date"))
    {
        value = hashtable_get (hashtable, "date");
        if (value)
        {
            hdata_set (hdata, pointer, "date", value);
            if (line_data->str_time)
                free (line_data->str_time);
            line_data->str_time = gui_chat_get_time_string (line_data->date);
            rc++;
            update_coords = 1;
        }
    }

    if (hashtable_has_key (hashtable, "date_printed"))
    {
        value = hashtable_get (hashtable, "date_printed");
        if (value)
        {
            hdata_set (hdata, pointer, "date_printed", value);
            rc++;
        }
    }

    if (hashtable_has_key (hashtable, "tags_array"))
    {
        value = hashtable_get (hashtable, "tags_array");
        gui_line_tags_free (line_data);
        gui_line_tags_alloc (line_data, value);
        rc++;
    }

    if (hashtable_has_key (hashtable, "prefix"))
    {
        value = hashtable_get (hashtable, "prefix");
        hdata_set (hdata, pointer, "prefix", value);
        line_data->prefix_length = (line_data->prefix) ?
            gui_chat_strlen_screen (line_data->prefix) : 0;
        line_data->buffer->lines->prefix_max_length_refresh = 1;
        rc++;
        update_coords = 1;
    }

    if (hashtable_has_key (hashtable, "message"))
    {
        value = hashtable_get (hashtable, "message");
        hdata_set (hdata, pointer, "message", value);
        rc++;
        update_coords = 1;
    }

    if (rc > 0)
    {
        if (update_coords)
        {
            for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
            {
                gui_window_coords_remove_line_data (ptr_win, line_data);
            }
        }
        gui_filter_buffer (line_data->buffer, line_data);
        gui_buffer_ask_chat_refresh (line_data->buffer, 1);
    }

    return rc;
}
Пример #6
0
char *
eval_expression (const char *expr, struct t_hashtable *pointers,
                 struct t_hashtable *extra_vars, struct t_hashtable *options)
{
    int condition, rc, pointers_allocated;
    char *value;
    const char *prefix, *suffix;
    const char *default_prefix = EVAL_DEFAULT_PREFIX;
    const char *default_suffix = EVAL_DEFAULT_SUFFIX;
    const char *ptr_value;
    struct t_gui_window *window;

    if (!expr)
        return NULL;

    condition = 0;
    pointers_allocated = 0;
    prefix = default_prefix;
    suffix = default_suffix;

    /* create hashtable pointers if it's NULL */
    if (!pointers)
    {
        pointers = hashtable_new (32,
                                  WEECHAT_HASHTABLE_STRING,
                                  WEECHAT_HASHTABLE_POINTER,
                                  NULL,
                                  NULL);
        if (!pointers)
            return NULL;
        pointers_allocated = 1;
    }

    /*
     * set window/buffer with pointer to current window/buffer
     * (if not already defined in the hashtable)
     */
    if (gui_current_window)
    {
        if (!hashtable_has_key (pointers, "window"))
            hashtable_set (pointers, "window", gui_current_window);
        if (!hashtable_has_key (pointers, "buffer"))
        {
            window = (struct t_gui_window *)hashtable_get (pointers, "window");
            if (window)
                hashtable_set (pointers, "buffer", window->buffer);
        }
    }

    /* read options */
    if (options)
    {
        /* check the type of evaluation */
        ptr_value = hashtable_get (options, "type");
        if (ptr_value && (strcmp (ptr_value, "condition") == 0))
            condition = 1;

        /* check for custom prefix */
        ptr_value = hashtable_get (options, "prefix");
        if (ptr_value && ptr_value[0])
            prefix = ptr_value;

        /* check for custom suffix */
        ptr_value = hashtable_get (options, "suffix");
        if (ptr_value && ptr_value[0])
            suffix = ptr_value;
    }

    /* evaluate expression */
    if (condition)
    {
        /* evaluate as condition (return a boolean: "0" or "1") */
        value = eval_expression_condition (expr, pointers, extra_vars,
                                           prefix, suffix);
        rc = eval_is_true (value);
        if (value)
            free (value);
        value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
    }
    else
    {
        /* only replace variables in expression */
        value = eval_replace_vars (expr, pointers, extra_vars, prefix, suffix);
    }

    if (pointers_allocated)
        hashtable_free (pointers);

    return value;
}