9 G_DEFINE_TYPE(GiraraTemplate, girara_template, G_TYPE_OBJECT)
14 typedef struct private_s {
25 #define GET_PRIVATE(obj) \
26 (G_TYPE_INSTANCE_GET_PRIVATE((obj), GIRARA_TYPE_TEMPLATE, private_t))
31 typedef struct variable_s {
37 new_variable(
const char* name)
44 if (variable == NULL) {
48 variable->
name = g_strdup(name);
49 variable->
value = g_strdup(
"");
55 free_variable(
void* data)
59 g_free(variable->
name);
60 g_free(variable->
value);
62 variable->
name = NULL;
63 variable->
value = NULL;
69 compare_variable_name(
const void* data1,
const void* data2)
72 const char* name = data2;
74 if (variable == NULL) {
78 return g_strcmp0(variable->
name, name);
82 static void dispose(GObject*
object);
83 static void finalize(GObject*
object);
84 static void set_property(GObject*
object, guint prop_id,
85 const GValue* value, GParamSpec* pspec);
86 static void get_property(GObject*
object, guint prop_id, GValue* value,
88 static void base_changed(GiraraTemplate*
object);
89 static void variable_changed(GiraraTemplate*
object,
const char* name);
90 static void template_changed(GiraraTemplate*
object);
110 girara_template_class_init(GiraraTemplateClass*
class)
113 g_type_class_add_private(
class,
sizeof(
private_t));
116 GObjectClass* object_class = G_OBJECT_CLASS(
class);
117 object_class->dispose = dispose;
118 object_class->finalize = finalize;
119 object_class->set_property = set_property;
120 object_class->get_property = get_property;
122 class->base_changed = base_changed;
123 class->variable_changed = variable_changed;
124 class->changed = template_changed;
127 g_object_class_install_property(object_class,
PROP_BASE,
128 g_param_spec_object(
"base",
130 "String used as base for the template.",
132 G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
138 G_STRUCT_OFFSET(GiraraTemplateClass, base_changed),
148 G_STRUCT_OFFSET(GiraraTemplateClass, variable_changed),
159 G_STRUCT_OFFSET(GiraraTemplateClass, changed),
169 girara_template_init(GiraraTemplate* history)
171 GError* error = NULL;
172 GRegex* regex = g_regex_new(
"@([A-Za-z0-9][A-Za-z0-9_-]*)@",
173 G_REGEX_OPTIMIZE, 0, &error);
175 girara_error(
"Failed to create regex: %s", error->message);
179 GRegex* check_regex = g_regex_new(
"^[A-Za-z0-9][A-Za-z0-9_-]*$",
180 G_REGEX_OPTIMIZE, 0, &error);
181 if (check_regex == NULL) {
182 girara_error(
"Failed to create regex: %s", error->message);
183 g_regex_unref(regex);
188 priv->
base = g_strdup(
"");
198 dispose(GObject*
object)
208 G_OBJECT_CLASS(girara_template_parent_class)->dispose(
object);
213 finalize(GObject*
object)
225 G_OBJECT_CLASS(girara_template_parent_class)->finalize(
object);
230 set_property(GObject* obj, guint prop_id,
const GValue* value,
241 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
247 get_property(GObject* obj, guint prop_id, GValue* value,
257 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
266 g_return_val_if_fail(obj, NULL);
284 if (g_strcmp0(base, priv->
base) != 0) {
286 priv->
base = g_strdup(base != NULL ? base :
"");
303 base_changed(GiraraTemplate*
object)
309 GMatchInfo* match_info = NULL;
311 while (g_match_info_matches(match_info) ==
true) {
312 char* variable = g_match_info_fetch(match_info, 1);
316 if (priv->
valid ==
true) {
329 g_match_info_next(match_info, NULL);
332 g_match_info_free(match_info);
336 variable_changed(GiraraTemplate*
object,
const char*
GIRARA_UNUSED(name))
342 if (priv->valid == true &&
368 g_return_val_if_fail(name != NULL,
false);
373 girara_debug(
"'%s' is not a valid variable name.", name);
379 if (variable != NULL) {
384 variable = new_variable(name);
385 if (variable == NULL) {
402 g_return_if_fail(name != NULL);
403 g_return_if_fail(value != NULL);
409 if (variable == NULL) {
414 if (g_strcmp0(variable->
value, value) != 0)
416 g_free(variable->
value);
417 variable->
value = g_strdup(value);
425 eval_replace_cb(
const GMatchInfo* info, GString* res,
void* data)
427 girara_list_t* variables = data;
429 char* name = g_match_info_fetch(info, 1);
432 g_return_val_if_fail(variable != NULL, TRUE);
434 g_string_append(res, variable->
value);
446 if (priv->
valid ==
false) {
447 girara_error(
"Base contains variables that do not have a value assigned.");
GType girara_template_get_type(void)
#define girara_debug(...)
void girara_list_append(girara_list_t *list, void *data)
GRegex * variable_check_regex
girara_list_t * girara_list_new2(girara_free_function_t gfree)
void girara_list_free(girara_list_t *list)
void * girara_list_find(girara_list_t *list, girara_compare_function_t compare, const void *data)
int(* girara_compare_function_t)(const void *data1, const void *data2)
GiraraTemplate * girara_template_new(const char *base)
void girara_template_set_variable_value(GiraraTemplate *object, const char *name, const char *value)
const char * girara_template_get_base(GiraraTemplate *object)
char * girara_template_evaluate(GiraraTemplate *object)
struct private_s GiraraTemplatePrivate
#define girara_error(...)
#define GIRARA_IS_TEMPLATE(obj)
bool girara_template_add_variable(GiraraTemplate *object, const char *name)
void girara_template_set_base(GiraraTemplate *object, const char *base)
girara_list_t * girara_template_referenced_variables(GiraraTemplate *object)
girara_list_t * variables
void girara_list_clear(girara_list_t *list)
#define GIRARA_TYPE_TEMPLATE
#define GIRARA_TEMPLATE(obj)
#define GIRARA_LIST_FOREACH_END(list, type, iter, data)
#define GIRARA_LIST_FOREACH(list, type, iter, data)
girara_list_t * variables_in_base