girara
|
00001 /* See LICENSE file for license and copyright information */ 00002 00003 #include <stdlib.h> 00004 #include <glib.h> 00005 #include <string.h> 00006 00007 #include "settings.h" 00008 #include "datastructures.h" 00009 #include "completion.h" 00010 #include "session.h" 00011 #include "internal.h" 00012 00016 struct girara_setting_s 00017 { 00018 char* name; 00019 union 00020 { 00021 bool b; 00022 int i; 00023 float f; 00024 char *s; 00025 } value; 00026 girara_setting_type_t type; 00027 bool init_only; 00028 char* description; 00029 girara_setting_callback_t callback; 00030 void* data; 00031 }; 00032 00033 void 00034 girara_setting_set_value(girara_session_t* session, girara_setting_t* setting, void* value) 00035 { 00036 g_return_if_fail(setting && (value || setting->type == STRING)); 00037 00038 switch(setting->type) { 00039 case BOOLEAN: 00040 setting->value.b = *((bool *) value); 00041 break; 00042 case FLOAT: 00043 setting->value.f = *((float *) value); 00044 break; 00045 case INT: 00046 setting->value.i = *((int *) value); 00047 break; 00048 case STRING: 00049 if (setting->value.s != NULL) { 00050 g_free(setting->value.s); 00051 } 00052 setting->value.s = value ? g_strdup(value) : NULL; 00053 break; 00054 default: 00055 g_assert(false); 00056 } 00057 00058 if (session && setting->callback != NULL) { 00059 setting->callback(session, setting->name, setting->type, value, setting->data); 00060 } 00061 } 00062 00063 bool 00064 girara_setting_add(girara_session_t* session, const char* name, void* value, girara_setting_type_t type, bool init_only, const char* description, girara_setting_callback_t callback, void* data) 00065 { 00066 g_return_val_if_fail(session != NULL, false); 00067 g_return_val_if_fail(name != NULL, false); 00068 g_return_val_if_fail(type != UNKNOWN, false); 00069 if (type != STRING && value == NULL) { 00070 return false; 00071 } 00072 00073 /* search for existing setting */ 00074 if (girara_setting_find(session, name) != NULL) { 00075 return false; 00076 } 00077 00078 /* add new setting */ 00079 girara_setting_t* setting = g_slice_new0(girara_setting_t); 00080 00081 setting->name = g_strdup(name); 00082 setting->type = type; 00083 setting->init_only = init_only; 00084 setting->description = description ? g_strdup(description) : NULL; 00085 setting->callback = callback; 00086 setting->data = data; 00087 girara_setting_set_value(NULL, setting, value); 00088 00089 girara_list_append(session->settings, setting); 00090 00091 return true; 00092 } 00093 00094 bool 00095 girara_setting_set(girara_session_t* session, const char* name, void* value) 00096 { 00097 g_return_val_if_fail(session != NULL, false); 00098 g_return_val_if_fail(name != NULL, false); 00099 00100 girara_setting_t* setting = girara_setting_find(session, name); 00101 if (setting == NULL) { 00102 return false; 00103 } 00104 00105 girara_setting_set_value(session, setting, value); 00106 return true; 00107 } 00108 00109 bool 00110 girara_setting_get_value(girara_setting_t* setting, void* dest) 00111 { 00112 g_return_val_if_fail(setting != NULL && dest != NULL, false); 00113 00114 bool *bvalue = (bool*) dest; 00115 float *fvalue = (float*) dest; 00116 int *ivalue = (int*) dest; 00117 char **svalue = (char**) dest; 00118 00119 switch(setting->type) { 00120 case BOOLEAN: 00121 *bvalue = setting->value.b; 00122 break; 00123 case FLOAT: 00124 *fvalue = setting->value.f; 00125 break; 00126 case INT: 00127 *ivalue = setting->value.i; 00128 break; 00129 case STRING: 00130 *svalue = setting->value.s ? g_strdup(setting->value.s) : NULL; 00131 break; 00132 default: 00133 g_assert(false); 00134 } 00135 00136 return true; 00137 } 00138 00139 bool 00140 girara_setting_get(girara_session_t* session, const char* name, void* dest) 00141 { 00142 g_return_val_if_fail(session != NULL && name != NULL && dest != NULL, false); 00143 00144 girara_setting_t* setting = girara_setting_find(session, name); 00145 if (setting == NULL) { 00146 return false; 00147 } 00148 00149 return girara_setting_get_value(setting, dest); 00150 } 00151 00152 void 00153 girara_setting_free(girara_setting_t* setting) 00154 { 00155 if (!setting) { 00156 return; 00157 } 00158 00159 g_free(setting->name); 00160 g_free(setting->description); 00161 if (setting->type == STRING) { 00162 g_free(setting->value.s); 00163 } 00164 g_slice_free(girara_setting_t, setting); 00165 } 00166 00167 girara_setting_t* 00168 girara_setting_find(girara_session_t* session, const char* name) 00169 { 00170 g_return_val_if_fail(session != NULL, NULL); 00171 g_return_val_if_fail(name != NULL, NULL); 00172 00173 girara_setting_t* result = NULL; 00174 GIRARA_LIST_FOREACH(session->settings, girara_setting_t*, iter, setting) 00175 if (g_strcmp0(setting->name, name) == 0) { 00176 result = setting; 00177 break; 00178 } 00179 GIRARA_LIST_FOREACH_END(session->settings, girara_setting_t*, iter, setting); 00180 00181 return result; 00182 } 00183 00184 const char* 00185 girara_setting_get_name(girara_setting_t* setting) { 00186 g_return_val_if_fail(setting, NULL); 00187 return setting->name; 00188 } 00189 00190 girara_setting_type_t 00191 girara_setting_get_type(girara_setting_t* setting) { 00192 g_return_val_if_fail(setting, UNKNOWN); 00193 return setting->type; 00194 } 00195 00196 girara_completion_t* 00197 girara_cc_set(girara_session_t* session, const char* input) 00198 { 00199 if (input == NULL) { 00200 return NULL; 00201 } 00202 00203 girara_completion_t* completion = girara_completion_init(); 00204 if (completion == NULL) { 00205 return NULL; 00206 } 00207 girara_completion_group_t* group = girara_completion_group_create(session, NULL); 00208 if (group == NULL) { 00209 girara_completion_free(completion); 00210 return NULL; 00211 } 00212 girara_completion_add_group(completion, group); 00213 00214 unsigned int input_length = strlen(input); 00215 00216 GIRARA_LIST_FOREACH(session->settings, girara_setting_t*, iter, setting) 00217 if ((setting->init_only == false) && (input_length <= strlen(setting->name)) && 00218 !strncmp(input, setting->name, input_length)) { 00219 girara_completion_group_add_element(group, setting->name, setting->description); 00220 } 00221 GIRARA_LIST_FOREACH_END(session->settings, girara_setting_t*, iter, setting); 00222 00223 return completion; 00224 }