From c80b900151886cdf6c56bd7535d41b550c7e5f6a Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Thu, 7 Mar 2024 10:36:06 +0600 Subject: [PATCH 1/4] Saving API and functions rework --- source/libublsettings.c | 417 ++++++++++++++++++++++++++++++++++++++-- source/libublsettings.h | 51 ++++- 2 files changed, 453 insertions(+), 15 deletions(-) diff --git a/source/libublsettings.c b/source/libublsettings.c index 68ff6ba..c70cffa 100644 --- a/source/libublsettings.c +++ b/source/libublsettings.c @@ -518,7 +518,7 @@ char **yon_char_parse(char *parameters, int *size, char *divider){ } char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete){ - if (char_string&&(*size)>0&&(*size)>item_to_delete&&item_to_delete>0){ + if (char_string&&(*size)>0&&(*size)>item_to_delete&&item_to_delete>=0){ char **new_char_parsed=NULL; new_char_parsed=malloc(sizeof(char*)*((*size)-1)); int flag = 0; @@ -745,6 +745,18 @@ char *yon_char_parsed_to_string(config_str parsed, int size, char *divider_repla } else if (size==0&&!parsed) return ""; } +int yon_char_parsed_find_element(config_str parsed, int size, char *target){ + if (parsed&&size){ + for (int i=0;iprev=NULL; param->section=NULL; param->ignore=0; + param->save_command=NULL; + param->load_command=NULL; return param; } @@ -900,7 +916,7 @@ dictionary *__yon_config_ignored = NULL; #define check_config if(__yon__config__strings&&__yon__config__strings->data_type==DICTIONARY_CHAR_TYPE) #define check_default_config if(__yon__config__default__strings) -#define for_config dictionary *temp = NULL; for_dictionaries(temp,(dictionary*)__yon__config__strings) +#define for_config yon_config_parameter *temp = NULL; for_dictionaries(temp,__yon__config__strings) #define for_default_config dictionary *temp = NULL; for_dictionaries(temp,(dictionary*)__yon__config__default__strings) #define yon_config_parameter_add_or_create_if_exists_with_data(dict,key,value) {if (dict){\ yon_config_parameter *dct = (yon_config_parameter *)yon_dictionary_get((dictionary**)&dict,key);\ @@ -914,6 +930,53 @@ dictionary *__yon_config_ignored = NULL; }\ else dict=yon_config_parameter_new_with_data(key,value);} +char *yon_config_get_type_path(YON_CONFIG_TYPE type){ + switch (type){ + case YON_CONFIG_DEFAULT: + return "default"; + break; + case YON_CONFIG_BOTH: + return ""; + break; + case YON_CONFIG_GLOBAL: + return "global"; + break; + case YON_CONFIG_LOCAL: + return "system"; + break; + } + return NULL; +} + +void yon_config_parameter_set_load_command(char *key, char *command){ + dictionary *found = yon_dictionary_get((dictionary**)&__yon__config__strings,key); + if (found){ + ((yon_config_parameter*)found)->load_command=yon_char_new(command); + } +} + +void yon_config_parameter_set_save_command(char *key, char *command){ + dictionary *found = yon_dictionary_get((dictionary**)&__yon__config__strings,key); + if (found){ + ((yon_config_parameter*)found)->save_command=yon_char_new(command); + } +} + +char *yon_config_parameter_get_load_command(char *key){ + dictionary *found = yon_dictionary_get((dictionary**)&__yon__config__strings,key); + if (found){ + return ((yon_config_parameter*)found)->load_command; + } + return NULL; +} + +char *yon_config_parameter_get_save_command(char *key){ + dictionary *found = yon_dictionary_get((dictionary**)&__yon__config__strings,key); + if (found){ + return ((yon_config_parameter*)found)->save_command; + } + return NULL; +} int yon_config_set_ignore(char *key){ if (!yon_dictionary_get(&__yon_config_ignored,key)){ @@ -958,7 +1021,7 @@ int yon_config_load_register_no_cleaning(YON_CONFIG_TYPE config_type,char *secti char *command=NULL; dictionary *dict; for_dictionaries(dict,sections){ - command = yon_char_unite(ubconfig_load_command,config_type==YON_CONFIG_GLOBAL ? " global get " : config_type==YON_CONFIG_LOCAL ? " system get " : " default get", dict->key," ", yon_dictionary_get_data(dict,char*),NULL); + command = yon_char_unite(ubconfig_load_command_old,config_type==YON_CONFIG_GLOBAL ? " global get " : config_type==YON_CONFIG_LOCAL ? " system get " : " default get", dict->key," ", yon_dictionary_get_data(dict,char*),NULL); FILE *output = popen(command, "r"); int i = 0; char str[4096]; @@ -1023,6 +1086,79 @@ int yon_config_parse_parameter(char *parameter,char **key, char **value){ return 0; } +int yon_char_remove_brackets(char *string){ + int done=0; + if (string[0]=='\''||string[0]=='\"'){done=1; free(yon_char_divide(string,0));} + if (string[strlen(string)-1]=='\''||string[strlen(string)-1]=='\"') {done=1; string[strlen(string)-1] = '\0';} + return done; +} + +char *yon_config_replace_parameter(char *command, char *parameter, int place){ + if (!yon_char_is_empty(command)); + int size=0; + config_str parsed = yon_char_parse(command,&size," "); + if (place5){ + for (int j=5;j0){ + for (int j=0;jkey," ", yon_dictionary_get_data(dict,char*),NULL); + command = yon_char_unite(ubconfig_load_command_old,config_type==YON_CONFIG_GLOBAL ? " global get " : config_type==YON_CONFIG_LOCAL ? " system get " : " default get ", dict->key," ", yon_dictionary_get_data(dict,char*),NULL); FILE *output = popen(command, "r"); int i = 0; char str[4096]; @@ -1283,7 +1419,9 @@ int yon_config_clean(){ else return 0; } -void yon_config_register(char *key, char *config_section, void *data){ +void yon_config_register(char *key, char *config_load, void *data){ + key=yon_char_new(key); + config_load=yon_char_new(config_load); if (!__yon__config__strings||!yon_dictionary_get((dictionary**)&__yon__config__strings,key)){ { if (__yon__config__strings){ @@ -1305,17 +1443,25 @@ void yon_config_register(char *key, char *config_section, void *data){ __yon__config__strings = (yon_config_parameter*)yon_dictionary_get_last((dictionary*)__yon__config__strings); __yon__config__strings->flag1=1; __yon__config__strings->data_type=DICTIONARY_CHAR_TYPE; - __yon__config__strings->section=yon_char_new(config_section); + __yon__config__strings->load_command=config_load; + int size=0; + config_str section = yon_char_parse(config_load,&size," "); + __yon__config__strings->section=yon_char_new(section[4]); + yon_char_parsed_free(section,size); } else if (yon_dictionary_get((dictionary**)&__yon__config__strings,key)){ if (data!=__yon__config__strings->data&&strcmp(__yon__config__strings->data,data)){ __yon__config__strings->data=yon_char_new(data); __yon__config__strings->flag1=1; __yon__config__strings->data_type=DICTIONARY_CHAR_TYPE; - __yon__config__strings->section=yon_char_new(config_section); - if (yon_dictionary_get(&__yon_config_ignored, __yon__config__strings->key)){ - yon_dictionary_rip(__yon_config_ignored); - } + __yon__config__strings->load_command=config_load; + if (yon_dictionary_get(&__yon_config_ignored, __yon__config__strings->key)){ + yon_dictionary_rip(__yon_config_ignored); + } + int size=0; + config_str section = yon_char_parse(config_load,&size," "); + __yon__config__strings->section=yon_char_new(section[4]); + yon_char_parsed_free(section,size); } } } @@ -1347,6 +1493,255 @@ config_str yon_config_load(char *command, int *str_len){ } } +config_str yon_config_load_file(FILE *file, int *str_len){ + FILE *output = file; + char **output_strings = NULL; + output_strings = malloc(sizeof(char)); + int i = 0; + char str[4096]; + memset(str, 0, 4096); + while (fgets(str, 4096, output)) + { + if (strcmp(str, "") != 0) + { + output_strings = realloc(output_strings, sizeof(char *) * (i + 1)); + output_strings[i] = NULL; + output_strings[i] = yon_char_new(str); + memset(str, 0, 4096); + i++; + } + } + if (i>0){ + *str_len = i; + return output_strings; + } else{ + *str_len=-1; + return NULL; + } +} + +char *yon_config_parameter_to_string(yon_config_parameter *parameter, int insert_section){ + if (parameter){ + char *param_string = NULL; + param_string = yon_char_unite(insert_section?parameter->section:"",insert_section?" ":"", parameter->key,parameter->flag1==-1?NULL:"","=\'",parameter->data,"\'",NULL); + return param_string; + } + return NULL; +} + +config_str yon_config_get_load_parameters_by_list(int *size, config_str parameters, int params_size){ + va_list list; + (*size)=0; + config_str updated = NULL; + int final_size; + config_str final = NULL; + char *current_str = NULL; + for (int i=0;ikey,current_str)){ + int position = yon_char_parsed_find_element(final,*size,((yon_config_parameter*)temp)->section); + if (position>=0){ + char *string = yon_char_unite((final)[position]," ",current_str,NULL); + free((final)[position]); + (final)[position]=string; + + } else { + char *string = yon_char_unite(temp->section," ",current_str,NULL); + yon_char_parsed_add_or_create_if_exists(final,size,string); + } + } + } + } + return final; +} + +config_str yon_config_get_save_parameters_by_list(int *size, config_str parameters, int params_size){ + va_list list; + (*size)=0; + int removed_size; + config_str removed = NULL; + int updated_size; + config_str updated = NULL; + config_str final = NULL; + char *current_str = NULL; + for (int i=0;ikey,current_str)){ + if (((yon_config_parameter*)temp)->flag1!=-2){ + char *action = NULL; + config_str *current=NULL; + int *current_size=NULL; + switch (((yon_config_parameter*)temp)->flag1){ + case -1: + action = "remove"; + current = &removed; + current_size = &removed_size; + break; + case 1: + action = "set"; + current = &updated; + current_size = &updated_size; + break; + } + int position = yon_char_parsed_find_element(*current,*current_size,((yon_config_parameter*)temp)->section); + if (position>=0){ + char *string = yon_char_unite((*current)[position]," ",yon_config_parameter_to_string((yon_config_parameter*)temp,0),NULL); + free((*current)[position]); + (*current)[position]=string; + + } else { + char *string = yon_char_unite(action," ",yon_config_parameter_to_string((yon_config_parameter*)temp,1),NULL); + yon_char_parsed_add_or_create_if_exists(*current,current_size,string); + } + } + } + } + } + final = yon_char_parsed_merge(updated,updated_size,removed,removed_size,size); + return final; +} + +config_str yon_config_get_save_parameters_by_key(int *size, char *parameter,...){ + va_list list; + (*size)=0; + va_start(list,parameter); + int removed_size; + config_str removed = NULL; + int updated_size; + config_str updated = NULL; + config_str final = NULL; + char *current_str = NULL; + + yon_va_while(list,char*,current_str){ + for_config{ + if (!strcmp(temp->key,current_str)){ + if (((yon_config_parameter*)temp)->flag1!=-2){ + char *action = NULL; + config_str *current=NULL; + int *current_size=NULL; + switch (((yon_config_parameter*)temp)->flag1){ + case -1: + action = "remove"; + current = &removed; + current_size = &removed_size; + break; + case 1: + action = "set"; + current = &updated; + current_size = &updated_size; + break; + } + int position = yon_char_parsed_find_element(*current,*current_size,((yon_config_parameter*)temp)->section); + if (position>=0){ + char *string = yon_char_unite((*current)[position]," ",yon_config_parameter_to_string((yon_config_parameter*)temp,0),NULL); + free((*current)[position]); + (*current)[position]=string; + + } else { + char *string = yon_char_unite(action," ",yon_config_parameter_to_string((yon_config_parameter*)temp,1),NULL); + yon_char_parsed_add_or_create_if_exists(*current,current_size,string); + } + } + } + } + } + final = yon_char_parsed_merge(updated,updated_size,removed,removed_size,size); + return final; +} + +config_str yon_config_get_save_parameters(int *size){ + + (*size)=0; + int removed_size; + config_str removed = NULL; + int updated_size; + config_str updated = NULL; + config_str final = NULL; + for_config{ + if (((yon_config_parameter*)temp)->flag1!=0&&((yon_config_parameter*)temp)->flag1!=-2){ + char *action = NULL; + config_str *current=NULL; + int *current_size=NULL; + switch (((yon_config_parameter*)temp)->flag1){ + case -1: + action = "remove"; + current = &removed; + current_size = &removed_size; + break; + case 1: + action = "set"; + current = &updated; + current_size = &updated_size; + break; + } + int position = yon_char_parsed_find_element(*current,*current_size,((yon_config_parameter*)temp)->section); + if (position>=0){ + char *string = yon_char_unite((*current)[position]," ",yon_config_parameter_to_string((yon_config_parameter*)temp,0),NULL); + free((*current)[position]); + (*current)[position]=string; + + } else { + char *string = yon_char_unite(action," ",yon_config_parameter_to_string((yon_config_parameter*)temp,1),NULL); + yon_char_parsed_add_or_create_if_exists(*current,current_size,string); + } + } + } + final = yon_char_parsed_merge(updated,updated_size,removed,removed_size,size); + return final; +} + +char *yon_config_save_simple(YON_CONFIG_TYPE target, char *path){ + int parameters_size=0; + config_str parameters=yon_config_get_save_parameters(¶meters_size); + if (parameters){ + yon_char_parsed_prepend_strings(parameters,parameters_size,ubconfig_set_command(path)); + char *final_command = yon_char_parsed_to_string(parameters,parameters_size,";"); + printf("%s\n",final_command); + FILE *file = popen(final_command,"r"); + if (file){ + int file_size=0; + config_str file_output = yon_config_load_file(file,&file_size); + if (file_output){ + char *final_string = yon_char_parsed_to_string(file_output,file_size,""); + if (!yon_char_is_empty(final_string)){ + return final_string; + } + } + } + } + return NULL; +} + +char *yon_config_parameter_prepare_command(char *command, char *path, char *section, char *parameter){ + if (path||parameter){ + int size=0; + config_str parsed = yon_char_parse(command,&size," "); + if (path){ + if (size>4&&!strcmp(parsed[1],"--source")){ + free(parsed[2]); + parsed[2]=yon_char_new(path); + } + } + if (section){ + if (size>4){ + free(parsed[4]); + parsed[4]=yon_char_new(section); + } + } + if (parameter){ + if (size>5){ + free(parsed[5]); + parsed[5] = yon_char_new(parameter); + } + } + char *final = yon_char_parsed_to_string(parsed,size," "); + yon_char_parsed_free(parsed,size); + return final; + } +} + int yon_config_save_registered(char *path){ check_config{ dictionary *dct; @@ -1372,7 +1767,6 @@ int yon_config_save_registered(char *path){ for_dictionaries(dct,sections_add){ char *command = yon_dictionary_get_data(dct,char*); yon_launch(command); - if (debug_output) printf("%s\n",command); } yon_dictionary_free_all(sections_add,free); @@ -1380,7 +1774,6 @@ int yon_config_save_registered(char *path){ for_dictionaries(dct,sections_remove){ char *command = yon_dictionary_get_data(dct,char*); yon_launch(command); - if (debug_output) printf("%s\n",command); } yon_dictionary_free_all(sections_remove,free); diff --git a/source/libublsettings.h b/source/libublsettings.h index 3549096..24ceda4 100644 --- a/source/libublsettings.h +++ b/source/libublsettings.h @@ -30,6 +30,8 @@ #define get_home_dir_command yon_char_unite("getent passwd \"",yon_ubl_root_user_get(),"\" | cut -d: -f6",NULL) +#define yon_va_while(list,type,target) while ((target=va_arg(list,type))) + typedef enum { DICTIONARY_GTK_WIDGETS_TYPE, @@ -40,6 +42,12 @@ typedef enum } DICT_TYPE; +#define dictionary_fields(type_name) char *key;\ + void *data;\ + struct type_name *next;\ + struct type_name *prev;\ + struct type_name *first;\ + DICT_TYPE data_type; /** * Структура именованого списка. * [key] - ключ элемента @@ -595,7 +603,13 @@ config_str yon_dir_get_contents(char *dir_path, int *size); //config functions #define ubconfig_save_command "ubconfig " -#define ubconfig_load_command "ubconfig --source" + +#define ubconfig_load_command_old "ubconfig --source" + +#define ubconfig_dull_command "ubconfig " +#define ubconfig_set_command(target) yon_char_unite("ubconfig --target ",target," ",NULL) +#define ubconfig_load_command(target) yon_char_unite("ubconfig --source ",target," get ",NULL) +#define ubconfig_load_command_full(target, data) yon_char_unite("ubconfig --source ",target," get ",data,NULL) /** * Типы конфигураций ubconfig-а @@ -604,10 +618,19 @@ typedef enum { YON_CONFIG_LOCAL=0, YON_CONFIG_GLOBAL, YON_CONFIG_BOTH, - YON_CONFIG_DEFAULT + YON_CONFIG_DEFAULT, + YON_CONFIG_CUSTOM } YON_CONFIG_TYPE; -static int debug_output = 0; +void yon_config_parameter_set_load_command(char *key, char *command); + +void yon_config_parameter_set_save_command(char *key, char *command); + +char *yon_config_parameter_get_load_command(char *key); + +char *yon_config_parameter_get_save_command(char *key); + +char *yon_config_get_type_path(YON_CONFIG_TYPE type); /**yon_config_load(char *command, int *str_len) * [EN] @@ -618,6 +641,18 @@ static int debug_output = 0; */ config_str yon_config_load(char *command, int *str_len); +config_str yon_config_load_file(FILE *file, int *str_len); + +config_str yon_config_get_load_parameters_by_list(int *size, config_str parameters, int params_size); + +config_str yon_config_get_save_parameters_by_list(int *size, config_str parameters, int params_size); + +config_str yon_config_get_save_parameters_by_key(int *size, char *parameter,...); + +config_str yon_config_get_save_parameters(int *size); + +char *yon_config_parameter_prepare_command(char *command, char *path, char *section, char *parameter); + /**int yon_config_save_registered(char *path) * [EN] * Saves config at [path] config. @@ -630,6 +665,7 @@ config_str yon_config_load(char *command, int *str_len); * system - локальный конфиг * global - глобальный конфиг */ +[[ deprecated ( "Use yon_config_save_simple for simple saving instead (full-controlled saving is provided with libublsettingsui-gtk3 library)" ) ]] int yon_config_save_registered(char *path); /**char *yon_config_get_parameter(config parameters, int size, char *param) @@ -652,6 +688,10 @@ int yon_config_check_ignore(char *key); int yon_config_parse_parameter(char *parameter,char **key, char **value); +int yon_char_remove_brackets(char *string); + +int yon_config_load_config(YON_CONFIG_TYPE config_type, ...); + /**yon_config_load_register_no_cleaning(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...) * [EN] * @@ -660,6 +700,7 @@ int yon_config_parse_parameter(char *parameter,char **key, char **value); * ... - пара из [section], [parameter], позволяющих загружать параметры из разных разделов конфига, оканчивающихся NULL. * Полученные данные парсятся и регистрируются в конфиг без удаления старых данных. */ +[[ deprecated ( "Use yon_config_load_config instead" ) ]] int yon_config_load_register_no_cleaning(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...); /**yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...) @@ -670,6 +711,7 @@ int yon_config_load_register_no_cleaning(YON_CONFIG_TYPE config_type,char *secti * ... - пара из [section], [parameter], позволяющих загружать параметры из разных разделов конфига, оканчивающихся NULL. * Полученные данные парсятся и регистрируются в конфиг, удаляя старые значения. */ +[[ deprecated ( "Use yon_config_load_config instead" ) ]] int yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...); /**yon_config_remove_by_key(char *key) @@ -765,6 +807,8 @@ int yon_config_clean(); */ void yon_config_register(char *key, char* config_section, void *data); +char *yon_config_save_simple(YON_CONFIG_TYPE target, char *path); + /**int yon_config_force_save_registered(char *path, char *section) * [EN] * Force config to save at [path] config ignoring parameter save status. @@ -777,6 +821,7 @@ void yon_config_register(char *key, char* config_section, void *data); * system - локальный конфиг * global - глобальный конфиг */ +[[ deprecated ( "Will be removed soon" ) ]] int yon_config_force_save_registered(char *path); /**yon_config_get_all(int *size) From 17d4b375e6804961e2f89a6c5d6416095c55a790 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Mon, 11 Mar 2024 17:45:41 +0600 Subject: [PATCH 2/4] Added functions for saving --- source/libublsettings.c | 34 ++++++++++++++++++++++++++++++++-- source/libublsettings.h | 5 +++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/source/libublsettings.c b/source/libublsettings.c index c70cffa..aa8c386 100644 --- a/source/libublsettings.c +++ b/source/libublsettings.c @@ -1580,6 +1580,7 @@ config_str yon_config_get_save_parameters_by_list(int *size, config_str paramete current_size = &removed_size; break; case 1: + case 0: action = "set"; current = &updated; current_size = &updated_size; @@ -1715,10 +1716,17 @@ char *yon_config_save_simple(YON_CONFIG_TYPE target, char *path){ } char *yon_config_parameter_prepare_command(char *command, char *path, char *section, char *parameter){ - if (path||parameter){ + if (!yon_char_is_empty(command)){ int size=0; config_str parsed = yon_char_parse(command,&size," "); - if (path){ + if (path&&!strcmp(path,"")){ + if (size>4&&!strcmp(parsed[1],"--source")){ + free(parsed[1]); + parsed[1]=yon_char_new(""); + free(parsed[2]); + parsed[2]=yon_char_new(""); + } + } else if (path){ if (size>4&&!strcmp(parsed[1],"--source")){ free(parsed[2]); parsed[2]=yon_char_new(path); @@ -1740,6 +1748,7 @@ char *yon_config_parameter_prepare_command(char *command, char *path, char *sect yon_char_parsed_free(parsed,size); return final; } + return NULL; } int yon_config_save_registered(char *path){ @@ -1876,6 +1885,27 @@ char *yon_config_get_parameter(config_str parameters, int size, char *param) return NULL; } +char *yon_file_path_proceed_spaces(char *path){ + int size; + config_str parsed = yon_char_parse(path,&size,"/"); + for (int i=0;i Date: Tue, 12 Mar 2024 17:27:03 +0600 Subject: [PATCH 3/4] Saving fixes --- source/libublsettings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libublsettings.h b/source/libublsettings.h index 59d925a..de1c0ca 100644 --- a/source/libublsettings.h +++ b/source/libublsettings.h @@ -609,7 +609,7 @@ config_str yon_dir_get_contents(char *dir_path, int *size); #define ubconfig_load_command_old "ubconfig --source" #define ubconfig_dull_command "ubconfig " -#define ubconfig_set_command(target) yon_char_unite("ubconfig --target ",target," ",NULL) +#define ubconfig_set_command(target) yon_char_unite("ubconfig ",!yon_char_is_empty(target)?"--target ":"",target," ",NULL) #define ubconfig_load_command(target) yon_char_unite("ubconfig --source ",target," get ",NULL) #define ubconfig_load_command_full(target, data) yon_char_unite("ubconfig --source ",target," get ",data,NULL) From 5552932e9e8cecccec6557a39af1ebdb5cc35e84 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Wed, 13 Mar 2024 14:19:41 +0600 Subject: [PATCH 4/4] Fixed crash at deletion --- source/libublsettings.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/libublsettings.c b/source/libublsettings.c index aa8c386..0f8b94a 100644 --- a/source/libublsettings.c +++ b/source/libublsettings.c @@ -1600,7 +1600,15 @@ config_str yon_config_get_save_parameters_by_list(int *size, config_str paramete } } } - final = yon_char_parsed_merge(updated,updated_size,removed,removed_size,size); + if (updated&&removed){ + final = yon_char_parsed_merge(updated,updated_size,removed,removed_size,size); + } else if (updated&&!removed){ + final=updated; + *size=updated_size; + } else if (!updated&&removed){ + final=removed; + *size=removed_size; + } return final; }