FCITX_EXPORT_API UT_array* fcitx_utils_string_list_append_no_copy(UT_array *list, char *str) { utarray_extend_back(list); *(char**)utarray_back(list) = str; return list; }
/* Create a new category with name <cat_name>. * The new category is pushed at the back of cat_table. * Aslo, a new hash entry is added for the category in cat_hash. * Return the newly created category. */ static cat_table_entry_t *MPIR_T_cat_create(const char *cat_name) { int cat_idx; cat_table_entry_t *cat; name2index_hash_t *hash_entry; /* New a category */ utarray_extend_back(cat_table); cat =(cat_table_entry_t *)utarray_back(cat_table); cat->name = MPL_strdup(cat_name); cat->desc = NULL; utarray_new(cat->cvar_indices, &ut_int_icd); utarray_new(cat->pvar_indices, &ut_int_icd); utarray_new(cat->subcat_indices, &ut_int_icd); /* Record <cat_name, cat_idx> in cat_hash */ cat_idx = utarray_len(cat_table) - 1; hash_entry = MPL_malloc(sizeof(name2index_hash_t)); MPIU_Assert(hash_entry); /* Need not to Strdup cat_name, since cat_table and cat_hash co-exist */ hash_entry->name = cat_name; hash_entry->idx = cat_idx; HASH_ADD_KEYPTR(hh, cat_hash, hash_entry->name, strlen(hash_entry->name), hash_entry); return cat; }
/* code borrow from kde-workspace/kcontrol/keyboard/xkb_rules.cpp */ void RulesHandlerStartElement(void *ctx, const xmlChar *name, const xmlChar **atts) { FcitxXkbRulesHandler* ruleshandler = (FcitxXkbRulesHandler*) ctx; FcitxXkbRules* rules = ruleshandler->rules; utarray_push_back(ruleshandler->path, &name); char* strPath = fcitx_utils_join_string_list(ruleshandler->path, '/'); if ( StringEndsWith(strPath, "layoutList/layout/configItem") ) { utarray_extend_back(rules->layoutInfos); } else if ( StringEndsWith(strPath, "layoutList/layout/variantList/variant") ) { FcitxXkbLayoutInfo* layoutInfo = (FcitxXkbLayoutInfo*) utarray_back(rules->layoutInfos); utarray_extend_back(layoutInfo->variantInfos); } else if ( StringEndsWith(strPath, "modelList/model") ) { utarray_extend_back(rules->modelInfos); } else if ( StringEndsWith(strPath, "optionList/group") ) { utarray_extend_back(rules->optionGroupInfos); FcitxXkbOptionGroupInfo* optionGroupInfo = (FcitxXkbOptionGroupInfo*) utarray_back(rules->optionGroupInfos); int i = 0; while(atts && atts[i*2] != 0) { if (strcmp(XMLCHAR_CAST atts[i*2], "allowMultipleSelection") == 0) { optionGroupInfo->exclusive = (strcmp(XMLCHAR_CAST atts[i*2 + 1], "true") != 0); } i++; } } else if ( StringEndsWith(strPath, "optionList/group/option") ) { FcitxXkbOptionGroupInfo* optionGroupInfo = (FcitxXkbOptionGroupInfo*) utarray_back(rules->optionGroupInfos); utarray_extend_back(optionGroupInfo->optionInfos); } else if ( strcmp(strPath, "xkbConfigRegistry") == 0 ) { int i = 0; while(atts && atts[i*2] != 0) { if (strcmp(XMLCHAR_CAST atts[i*2], "version") == 0 && strlen(XMLCHAR_CAST atts[i*2 + 1]) != 0) { rules->version = strdup(XMLCHAR_CAST atts[i*2 + 1]); } i++; } } free(strPath); }
/* A low level, generic and internally used interface to register * a pvar to MPIR_T. Other modules should use interfaces defined * for concrete pvar classes. * * IN: varclass, MPI_T_PVAR_CLASS_* * IN: dtype, MPI datatype for this pvar * IN: name, Name of the pvar * IN: addr, Pointer to the pvar if known at registeration, otherwise NULL. * IN: count, # of elements of this pvar if known at registeration, otherwise 0. * IN: etype, MPI_T_enum or MPI_T_ENUM_NULL * IN: verb, MPI_T_PVAR_VERBOSITY_* * IN: binding, MPI_T_BIND_* * IN: flags, Bitwise OR of MPIR_T_R_PVAR_FLAGS_{} * IN: get_value, If not NULL, it is a callback to read the pvar. * IN: get_count, If not NULL, it is a callback to read count of the pvar. * IN: cat, Catogery name of the pvar * IN: desc, Description of the pvar */ void MPIR_T_PVAR_REGISTER_impl( int varclass, MPI_Datatype dtype, const char* name, void *addr, int count, MPIR_T_enum_t *etype, int verb, int binding, int flags, MPIR_T_pvar_get_value_cb get_value, MPIR_T_pvar_get_count_cb get_count, const char * cat, const char * desc) { name2index_hash_t *hash_entry; pvar_table_entry_t *pvar; int pvar_idx; int seq = varclass - MPIR_T_PVAR_CLASS_FIRST; /* Check whether this is a replicated pvar, whose name is unique per class */ HASH_FIND_STR(pvar_hashs[seq], name, hash_entry); if (hash_entry != NULL) { /* Found it, the pvar already exists */ pvar_idx = hash_entry->idx; pvar = (pvar_table_entry_t *)utarray_eltptr(pvar_table, pvar_idx); /* Should never override an existing & active var */ MPIU_Assert(pvar->active != TRUE); pvar->active = TRUE; /* FIXME: Do we need to check consistency between the old and new? */ } else { /* Not found, so push the pvar to back of pvar_table */ utarray_extend_back(pvar_table); pvar = (pvar_table_entry_t *)utarray_back(pvar_table); pvar->active = TRUE; pvar->varclass = varclass; pvar->datatype = dtype; pvar->name = MPL_strdup(name); MPIU_Assert(pvar->name); pvar->addr = addr; pvar->count = count; pvar->enumtype = etype; pvar->verbosity = verb; pvar->bind = binding; pvar->flags = flags; pvar->get_value = get_value; pvar->get_count = get_count; pvar->desc = MPL_strdup(desc); MPIU_Assert(pvar->desc); /* Record <name, index> in hash table */ pvar_idx = utarray_len(pvar_table) - 1; hash_entry = MPL_malloc(sizeof(name2index_hash_t)); MPIU_Assert(hash_entry); /* Need not to Strdup name, since pvar_table and pvar_hashs co-exist */ hash_entry->name = name; hash_entry->idx = pvar_idx; HASH_ADD_KEYPTR(hh, pvar_hashs[seq], hash_entry->name, strlen(hash_entry->name), hash_entry); /* Add the pvar to a category */ MPIR_T_cat_add_pvar(cat, utarray_len(pvar_table)-1); } }
/* Add an item to an exisiting enum. * IN: handle, handle to the enum * IN: item_name, name of the item * IN: item_value, value associated with item_name */ void MPIR_T_enum_add_item(MPI_T_enum handle, const char *item_name, int item_value) { enum_item_t *item; MPIU_Assert(handle); MPIU_Assert(item_name); utarray_extend_back(handle->items); item = (enum_item_t *)utarray_back(handle->items); item->name = MPL_strdup(item_name); MPIU_Assert(item->name); item->value = item_value; }
/* Create an enum. * IN: enum_name, name of the enum * OUT: handle, handle of the enum */ void MPIR_T_enum_create(const char *enum_name, MPI_T_enum *handle) { MPIR_T_enum_t *e; static const UT_icd enum_item_icd = {sizeof(enum_item_t), NULL, NULL, NULL}; MPIU_Assert(enum_name); MPIU_Assert(handle); utarray_extend_back(enum_table); e = (MPIR_T_enum_t *)utarray_back(enum_table); e->name = MPL_strdup(enum_name); MPIU_Assert(e->name); #ifdef HAVE_ERROR_CHECKING e->kind = MPIR_T_ENUM_HANDLE; #endif utarray_new(e->items, &enum_item_icd); (*handle) = e; }
int main() { UT_array *a; int i, *p=NULL; utarray_new(a, &ut_int_icd); for(i=0;i<10;i++) utarray_push_back(a,&i); utarray_pop_back(a); utarray_erase(a,0,1); while ( (p=(int*)utarray_next(a,p)) != NULL ) printf("%d ",*p); printf("\n"); i = 100; utarray_insert(a,&i,3); while ( (p=(int*)utarray_next(a,p)) != NULL ) printf("%d ",*p); printf("\n"); utarray_extend_back(a); p = (int*)utarray_back(a); *p = 1000; p = NULL; while ( (p=(int*)utarray_next(a,p)) != NULL ) printf("%d ",*p); printf("\n"); utarray_clear(a); utarray_free(a); return 0; }
static Value *findOrCreateEntry(ATP_Array *p_array, unsigned int p_index) { Value *l_entry; unsigned int l_length = utarray_len(CAST(p_array)); if (p_index > l_length) { ERR("Index out of bounds\n"); return NULL; } else if (p_index == l_length) { utarray_extend_back(CAST(p_array)); l_entry = (Value *) utarray_back(CAST(p_array)); } else { l_entry = (Value *) utarray_eltptr(CAST(p_array), p_index); } return l_entry; }
/* A low level, generic and internally used interface to register * a cvar to the MPIR_T. * * IN: dtype, MPI datatype for this cvar * IN: name, Name of the cvar * IN: addr, Pointer to the cvar if known at registeration, otherwise NULL. * IN: count, # of elements of this cvar if known at registeration, otherwise 0. * IN: etype, MPI_T_enum or MPI_T_ENUM_NULL * IN: verb, MPI_T_PVAR_VERBOSITY_* * IN: binding, MPI_T_BIND_* * IN: Scope, MPI_T_SCOPE_* * IN: get_addr, If not NULL, it is a callback to get address of the cvar. * IN: get_count, If not NULL, it is a callback to read count of the cvar. * IN: cat, Catogery name of the cvar * IN: desc, Description of the cvar */ void MPIR_T_CVAR_REGISTER_impl( MPI_Datatype dtype, const char* name, const void *addr, int count, MPIR_T_enum_t *etype, MPIR_T_verbosity_t verb, MPIR_T_bind_t binding, MPIR_T_scope_t scope, MPIR_T_cvar_get_addr_cb get_addr, MPIR_T_cvar_get_count_cb get_count, MPIR_T_cvar_value_t defaultval, const char *cat, const char * desc) { name2index_hash_t *hash_entry; cvar_table_entry_t *cvar; int cvar_idx; /* Check whether this is a replicated cvar, whose name is unique. */ HASH_FIND_STR(cvar_hash, name, hash_entry); if (hash_entry != NULL) { /* Found it, the cvar already exists */ cvar_idx = hash_entry->idx; cvar = (cvar_table_entry_t *)utarray_eltptr(cvar_table, cvar_idx); /* Should never override an existing & active var */ MPIU_Assert(cvar->active != TRUE); cvar->active = TRUE; /* FIXME: Do we need to check consistency between the old and new? */ } else { /* Not found, so push the cvar to back of cvar_table */ utarray_extend_back(cvar_table); cvar = (cvar_table_entry_t *)utarray_back(cvar_table); cvar->active = TRUE; cvar->datatype = dtype; cvar->name = MPL_strdup(name); MPIU_Assert(cvar->name); if (dtype != MPI_CHAR) { cvar->addr = (void *)addr; } else { cvar->addr = MPL_malloc(count); MPIU_Assert(cvar->addr); if (defaultval.str == NULL) { ((char *)(cvar->addr))[0] = '\0'; } else { /* Use greater (>), since count includes the terminating '\0', but strlen does not */ MPIU_Assert(count > strlen(defaultval.str)); strcpy(cvar->addr, defaultval.str); } } cvar->count = count; cvar->verbosity = verb; cvar->bind = binding; cvar->scope = scope; cvar->get_addr = get_addr; cvar->get_count = get_count; cvar->defaultval = defaultval; cvar->desc = MPL_strdup(desc); MPIU_Assert(cvar->desc); /* Record <name, index> in hash table */ cvar_idx = utarray_len(cvar_table) - 1; hash_entry = MPL_malloc(sizeof(name2index_hash_t)); MPIU_Assert(hash_entry); /* Need not to Strdup name, since cvar_table and cvar_hash co-exist */ hash_entry->name =name; hash_entry->idx = cvar_idx; HASH_ADD_KEYPTR(hh, cvar_hash, hash_entry->name, strlen(hash_entry->name), hash_entry); /* Add the cvar to a category */ MPIR_T_cat_add_cvar(cat, cvar_idx); } }
FcitxAddon* FcitxAddonsLoadInternal(UT_array* addons, boolean reloadIM) { char **addonPath; size_t len; size_t start; if (!reloadIM) utarray_clear(addons); start = utarray_len(addons); FcitxStringHashSet* sset = FcitxXDGGetFiles("addon", NULL, ".conf"); addonPath = FcitxXDGGetPathWithPrefix(&len, "addon"); char *paths[len]; HASH_FOREACH(string, sset, FcitxStringHashSet) { // FIXME: if it will cause realloc, then it's evil for fcitx 4.2 series if (reloadIM && addons->i == addons->n) { break; } int i; for (i = len - 1; i >= 0; i--) { fcitx_utils_alloc_cat_str(paths[i], addonPath[len - i - 1], "/", string->name); FcitxLog(DEBUG, "Load Addon Config File:%s", paths[i]); } FcitxConfigFile* cfile = FcitxConfigParseMultiConfigFile(paths, len, FcitxAddonGetConfigDesc()); if (cfile) { utarray_extend_back(addons); FcitxAddon *a = (FcitxAddon*) utarray_back(addons); utarray_init(&a->functionList, fcitx_ptr_icd); FcitxAddonConfigBind(a, cfile, FcitxAddonGetConfigDesc()); FcitxConfigBindSync((FcitxGenericConfig*)a); FcitxLog(DEBUG, _("Addon Config %s is %s"), string->name, (a->bEnabled) ? "Enabled" : "Disabled"); boolean error = false; if (reloadIM) { if (a->category != AC_INPUTMETHOD) error = true; } /* if loaded, don't touch the old one */ if (FcitxAddonsGetAddonByNameInternal(addons, a->name, true) != a) error = true; if (error) utarray_pop_back(addons); else FcitxLog(INFO, _("Load Addon Config File:%s"), string->name); } for (i = len - 1;i >= 0;i--) { free(paths[i]); } } FcitxXDGFreePath(addonPath); fcitx_utils_free_string_hash_set(sset); size_t to = utarray_len(addons); utarray_sort_range(addons, AddonPriorityCmp, start, to); return (FcitxAddon*)utarray_eltptr(addons, start); }