From 836be384fafd503bfb4a08b4d4c41f930e555065 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Tue, 23 Sep 2025 18:11:46 +0600 Subject: [PATCH] New locale functions, hash table fixes --- source/libublsettings-hash.c | 25 +++++++--- source/libublsettings-locale.c | 83 ++++++++++++++++++++++++++++++++-- source/libublsettings.h | 15 +++++- 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/source/libublsettings-hash.c b/source/libublsettings-hash.c index 68c2b5a..5c60980 100644 --- a/source/libublsettings-hash.c +++ b/source/libublsettings-hash.c @@ -1,26 +1,39 @@ #include "libublsettings.h" +unsigned int yon_str_hash(const char *str) { + unsigned int hash = 5381; + for (; *str != '\0'; str++) { + hash = (hash << 5) + hash + (unsigned char)(*str); + } + return hash; +} + +//\ +===================================================================== + yon_hash *yon_hash_new(int size, unsigned int(*hash_func)(const char *)){ yon_hash *hash = malloc(sizeof(yon_hash)); memset(hash,0,sizeof(yon_hash)); hash->data = malloc(sizeof(yon_hash_element)*size); + memset(hash->data,0,sizeof(yon_hash_element)*size); hash->size = size; hash->hash_func = hash_func; return hash; } -yon_hash_element *yon_hash_element_new(const char *key, const char *data){ +yon_hash_element *yon_hash_element_new(const char *key, void *data){ yon_hash_element *element = malloc(sizeof(yon_hash_element)); memset(element,0,sizeof(yon_hash_element)); element->key = yon_char_new(key); - element->data = yon_char_new(data); + element->data = data; + element->first = (struct yon_hash_element*)element; return element; } int yon_hash_insert(yon_hash *target, const char *key, void *data){ if (target&&target->hash_func&&!yon_char_is_empty(key)&&data){ unsigned int hash = target->hash_func(key)%target->size; - if (target->data[hash]){ + if (target->data&&target->data[hash]){ yon_hash_element *element = yon_hash_element_new(key,data); yon_hash_element *last = (yon_hash_element *)yon_dictionary_get_last((dictionary*)target->data[hash]); last->next=(struct yon_hash_element*)element; @@ -28,8 +41,8 @@ int yon_hash_insert(yon_hash *target, const char *key, void *data){ element->first=(struct yon_hash_element*)last->first; return 1; } else { - target->data = malloc(sizeof(yon_hash_element*)); - target->data[0] = yon_hash_element_new(key,data); + // target->data[hash] = malloc(sizeof(yon_hash_element*)); + target->data[hash] = yon_hash_element_new(key,data); return 1; } } @@ -62,7 +75,7 @@ int yon_hash_contains(yon_hash *target, const char *key){ if (target&&!yon_char_is_empty(key)){ unsigned int hash = target->hash_func(key)%target->size; if (target->data[hash]){ - if (yon_dictionary_get((dictionary**)&target->data[hash],key)) return 1; + if (yon_dictionary_get((dictionary**)&target->data[hash],(char*)key)) return 1; } } return 0; diff --git a/source/libublsettings-locale.c b/source/libublsettings-locale.c index edd5f93..22404a8 100644 --- a/source/libublsettings-locale.c +++ b/source/libublsettings-locale.c @@ -2,6 +2,8 @@ #define locales_path "/usr/share/i18n/locales/" +yon_hash *locales_hash_table = NULL; + struct yon_locale { char *code; char *lang_ab; @@ -17,26 +19,99 @@ struct yon_locale *yon_lang_new(){ return cur_locale; } +char *yon_locale_unwrap(char *parameter){ + char *final = yon_char_new(parameter); + free(yon_char_divide_search(final,"\"",-1)); + char *temp = yon_char_divide_search(final,"\"",-1); + free(final); + final = yon_char_return_if_exist(temp,NULL); + return final; +} + void yon_locale_set(struct yon_locale *target,char *locale_name){ int size; char *path = yon_char_unite(locales_path,locale_name,NULL); - config_str *locale_string = yon_file_open(path,&size); + config_str locale_string = yon_file_open(path,&size); target->code = yon_char_new(locale_name); - target->lang_ab = yon_char_parsed_check_exist_begins_with(locale_string,size,"lang_ab"); + target->lang_ab = yon_char_new(locale_name); target->territory = yon_char_parsed_check_exist_begins_with(locale_string,size,"territory"); target->language = yon_char_parsed_check_exist_begins_with(locale_string,size,"language"); target->lang_name = yon_char_parsed_check_exist_begins_with(locale_string,size,"lang_name"); target->title = yon_char_parsed_check_exist_begins_with(locale_string,size,"title"); + if (!yon_char_is_empty(target->lang_ab)){ + yon_char_divide_search_self(target->code,"_",-1); + } + if (!yon_char_is_empty(target->territory)){ + char *temp = yon_locale_unwrap(target->territory); + free(target->territory); + target->territory = yon_char_new(temp); + } + if (!yon_char_is_empty(target->language)){ + char *temp = yon_locale_unwrap(target->language); + free(target->language); + target->language = yon_char_new(temp); + } + if (!yon_char_is_empty(target->lang_name)){ + char *temp = yon_locale_unwrap(target->lang_name); + free(target->lang_name); + target->lang_name = yon_char_new(temp); + } + if (!yon_char_is_empty(target->title)){ + char *temp = yon_locale_unwrap(target->title); + free(target->title); + target->title = yon_char_new(temp); + } yon_char_parsed_free(locale_string,size); free(path); } void yon_locale_init(){ int size; - config_str *locales_list = yon_dir_get_contents(locales_path,&size); + config_str locales_list = yon_dir_get_contents(locales_path,&size); + locales_hash_table = yon_hash_new(size*2,yon_str_hash); for (int i=0;isize;i++){ + if (locales_hash_table->data[i]){ + yon_hash_element *dict = NULL; + for_dictionaries(dict,locales_hash_table->data[i]){ + yon_char_parsed_add_or_create_if_exists(final,size,dict->key); + } + } + } + return final; +} + +char *yon_locale_get_parameter(char *code,enum YON_LOCALE_PARAMETER type){ + unsigned int hash = locales_hash_table->hash_func(code)%locales_hash_table->size; + yon_hash_element *data = (yon_hash_element*)yon_dictionary_get((dictionary**)&locales_hash_table->data[hash],code); + struct yon_locale *cur_locale = yon_dictionary_get_data(data,struct yon_locale*); + switch(type){ + case YON_LOCALE_LANGUAGE:{ + return cur_locale->language; + }break; + case YON_LOCALE_LANG_NAME:{ + return cur_locale->lang_name; + }break; + case YON_LOCALE_TERRITORY:{ + return cur_locale->territory; + }break; + case YON_LOCALE_LANG_AB:{ + return cur_locale->lang_ab; + }break; + case YON_LOCALE_TITLE:{ + return cur_locale->title; + }break; + } } \ No newline at end of file diff --git a/source/libublsettings.h b/source/libublsettings.h index 8bb88cd..b5205be 100644 --- a/source/libublsettings.h +++ b/source/libublsettings.h @@ -1098,7 +1098,15 @@ void yon_launch(char *command); // void *yon_malloc(int size, char *group_key); -typedef struct { +enum YON_LOCALE_PARAMETER{ + YON_LOCALE_LANGUAGE, + YON_LOCALE_LANG_NAME, + YON_LOCALE_TERRITORY, + YON_LOCALE_LANG_AB, + YON_LOCALE_TITLE +}; + +typedef struct yon_hash_element{ dictionary_fields(yon_hash_element); } yon_hash_element; @@ -1108,11 +1116,16 @@ typedef struct { unsigned int(*hash_func)(const char *); } yon_hash; +unsigned int yon_str_hash(const char *str); + yon_hash *yon_hash_new(int size, unsigned int(*hash_func)(const char *)); int yon_hash_insert(yon_hash *target, const char *key, void *data); int yon_hash_remove(yon_hash *target, const char *key); void *yon_hash_lookup(yon_hash *target, const char *key); int yon_hash_add(yon_hash *target,const char *key); int yon_hash_contains(yon_hash *target, const char *key); +void yon_locale_init(); +config_str yon_locale_get_all_codes(int *size); +char *yon_locale_get_parameter(char *code,enum YON_LOCALE_PARAMETER type); #endif \ No newline at end of file