girara
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
settings.c
Go to the documentation of this file.
1 /* See LICENSE file for license and copyright information */
2 
3 #include <stdlib.h>
4 #include <glib.h>
5 #include <string.h>
6 
7 #include "settings.h"
8 #include "datastructures.h"
9 #include "completion.h"
10 #include "session.h"
11 #include "internal.h"
12 
17 {
18  char* name;
19  union
20  {
21  bool b;
22  int i;
23  float f;
24  char *s;
25  } value;
27  bool init_only;
28  char* description;
30  void* data;
31 };
32 
33 void
34 girara_setting_set_value(girara_session_t* session, girara_setting_t* setting, void* value)
35 {
36  g_return_if_fail(setting && (value || setting->type == STRING));
37 
38  switch(setting->type) {
39  case BOOLEAN:
40  setting->value.b = *((bool *) value);
41  break;
42  case FLOAT:
43  setting->value.f = *((float *) value);
44  break;
45  case INT:
46  setting->value.i = *((int *) value);
47  break;
48  case STRING:
49  if (setting->value.s != NULL) {
50  g_free(setting->value.s);
51  }
52  setting->value.s = value ? g_strdup(value) : NULL;
53  break;
54  default:
55  g_assert(false);
56  }
57 
58  if (session && setting->callback != NULL) {
59  setting->callback(session, setting->name, setting->type, value, setting->data);
60  }
61 }
62 
63 bool
64 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)
65 {
66  g_return_val_if_fail(session != NULL, false);
67  g_return_val_if_fail(name != NULL, false);
68  g_return_val_if_fail(type != UNKNOWN, false);
69  if (type != STRING && value == NULL) {
70  return false;
71  }
72 
73  /* search for existing setting */
74  if (girara_setting_find(session, name) != NULL) {
75  return false;
76  }
77 
78  /* add new setting */
79  girara_setting_t* setting = g_slice_new0(girara_setting_t);
80 
81  setting->name = g_strdup(name);
82  setting->type = type;
83  setting->init_only = init_only;
84  setting->description = description ? g_strdup(description) : NULL;
85  setting->callback = callback;
86  setting->data = data;
87  girara_setting_set_value(NULL, setting, value);
88 
89  girara_list_append(session->settings, setting);
90 
91  return true;
92 }
93 
94 bool
95 girara_setting_set(girara_session_t* session, const char* name, void* value)
96 {
97  g_return_val_if_fail(session != NULL, false);
98  g_return_val_if_fail(name != NULL, false);
99 
100  girara_setting_t* setting = girara_setting_find(session, name);
101  if (setting == NULL) {
102  return false;
103  }
104 
105  girara_setting_set_value(session, setting, value);
106  return true;
107 }
108 
109 bool
110 girara_setting_get_value(girara_setting_t* setting, void* dest)
111 {
112  g_return_val_if_fail(setting != NULL && dest != NULL, false);
113 
114  bool *bvalue = (bool*) dest;
115  float *fvalue = (float*) dest;
116  int *ivalue = (int*) dest;
117  char **svalue = (char**) dest;
118 
119  switch(setting->type) {
120  case BOOLEAN:
121  *bvalue = setting->value.b;
122  break;
123  case FLOAT:
124  *fvalue = setting->value.f;
125  break;
126  case INT:
127  *ivalue = setting->value.i;
128  break;
129  case STRING:
130  *svalue = setting->value.s ? g_strdup(setting->value.s) : NULL;
131  break;
132  default:
133  g_assert(false);
134  }
135 
136  return true;
137 }
138 
139 bool
140 girara_setting_get(girara_session_t* session, const char* name, void* dest)
141 {
142  g_return_val_if_fail(session != NULL && name != NULL && dest != NULL, false);
143 
144  girara_setting_t* setting = girara_setting_find(session, name);
145  if (setting == NULL) {
146  return false;
147  }
148 
149  return girara_setting_get_value(setting, dest);
150 }
151 
152 void
153 girara_setting_free(girara_setting_t* setting)
154 {
155  if (!setting) {
156  return;
157  }
158 
159  g_free(setting->name);
160  g_free(setting->description);
161  if (setting->type == STRING) {
162  g_free(setting->value.s);
163  }
164  g_slice_free(girara_setting_t, setting);
165 }
166 
167 girara_setting_t*
168 girara_setting_find(girara_session_t* session, const char* name)
169 {
170  g_return_val_if_fail(session != NULL, NULL);
171  g_return_val_if_fail(name != NULL, NULL);
172 
173  girara_setting_t* result = NULL;
174  GIRARA_LIST_FOREACH(session->settings, girara_setting_t*, iter, setting)
175  if (g_strcmp0(setting->name, name) == 0) {
176  result = setting;
177  break;
178  }
179  GIRARA_LIST_FOREACH_END(session->settings, girara_setting_t*, iter, setting);
180 
181  return result;
182 }
183 
184 const char*
185 girara_setting_get_name(girara_setting_t* setting) {
186  g_return_val_if_fail(setting, NULL);
187  return setting->name;
188 }
189 
191 girara_setting_get_type(girara_setting_t* setting) {
192  g_return_val_if_fail(setting, UNKNOWN);
193  return setting->type;
194 }
195 
196 girara_completion_t*
197 girara_cc_set(girara_session_t* session, const char* input)
198 {
199  if (input == NULL) {
200  return NULL;
201  }
202 
203  girara_completion_t* completion = girara_completion_init();
204  if (completion == NULL) {
205  return NULL;
206  }
207  girara_completion_group_t* group = girara_completion_group_create(session, NULL);
208  if (group == NULL) {
209  girara_completion_free(completion);
210  return NULL;
211  }
212  girara_completion_add_group(completion, group);
213 
214  unsigned int input_length = strlen(input);
215 
216  GIRARA_LIST_FOREACH(session->settings, girara_setting_t*, iter, setting)
217  if ((setting->init_only == false) && (input_length <= strlen(setting->name)) &&
218  !strncmp(input, setting->name, input_length)) {
219  girara_completion_group_add_element(group, setting->name, setting->description);
220  }
221  GIRARA_LIST_FOREACH_END(session->settings, girara_setting_t*, iter, setting);
222 
223  return completion;
224 }