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; }
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; }