Example #1
0
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;
}
Example #2
0
int
hdata_get_var_array_size (struct t_hdata *hdata, void *pointer,
                          const char *name)
{
    struct t_hdata_var *var;
    const char *ptr_size;
    char *error;
    long value;
    int i, offset;
    void *ptr_value;

    if (!hdata || !name)
        return -1;

    var = hashtable_get (hdata->hash_var, name);
    if (!var)
        return -1;

    ptr_size = var->array_size;
    if (!ptr_size)
        return -1;

    if (strcmp (ptr_size, "*") == 0)
    {
        /*
         * automatic size: look for NULL in array
         * (this automatic size is possible only with pointers, so with
         * types: string, pointer, hashtable)
         */
        if ((var->type == DOGECHAT_HDATA_STRING)
            || (var->type == DOGECHAT_HDATA_SHARED_STRING)
            || (var->type == DOGECHAT_HDATA_POINTER)
            || (var->type == DOGECHAT_HDATA_HASHTABLE))
        {
            if (!(*((void **)(pointer + var->offset))))
                return 0;
            i = 0;
            while (1)
            {
                ptr_value = NULL;
                switch (var->type)
                {
                    case DOGECHAT_HDATA_STRING:
                    case DOGECHAT_HDATA_SHARED_STRING:
                        ptr_value = (*((char ***)(pointer + var->offset)))[i];
                        break;
                    case DOGECHAT_HDATA_POINTER:
                        ptr_value = (*((void ***)(pointer + var->offset)))[i];
                        break;
                    case DOGECHAT_HDATA_HASHTABLE:
                        ptr_value = (*((struct t_hashtable ***)(pointer + var->offset)))[i];
                        break;
                }
                if (!ptr_value)
                    break;
                i++;
            }
            return i;
        }
    }
    else
    {
        /* fixed size: the size can be a name of variable or integer */
        offset = hdata_get_var_offset (hdata, ptr_size);
        if (offset >= 0)
        {
            /* size is the name of a variable in hdata, read it */
            switch (hdata_get_var_type (hdata, ptr_size))
            {
                case DOGECHAT_HDATA_CHAR:
                    return (int)(*((char *)(pointer + offset)));
                case DOGECHAT_HDATA_INTEGER:
                    return *((int *)(pointer + offset));
                case DOGECHAT_HDATA_LONG:
                    return (int)(*((long *)(pointer + offset)));
                default:
                    break;
            }
        }
        else
        {
            /* check if the size is a valid integer */
            error = NULL;
            value = strtol (ptr_size, &error, 10);
            if (error && !error[0])
                return (int)value;
        }
    }

    return -1;
}