Skip to content

Commit b916003

Browse files
authored
Merge pull request #379 from alltilla/app-transform-include-exclude
`app-transform()`: add `include-transforms()` and `exclude-transforms()` options
2 parents d82c236 + 56f832c commit b916003

13 files changed

+162
-56
lines changed

lib/cfg-block-generator.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ cfg_block_generator_init_instance(CfgBlockGenerator *self, gint context, const g
7373
self->context = context;
7474
self->name = g_strdup(name);
7575
self->format_name = cfg_block_generator_format_name_method;
76-
self->free_fn = cfg_block_generator_free_instance;
76+
self->free_fn = cfg_block_generator_free_method;
7777
}
7878

7979
void
80-
cfg_block_generator_free_instance(CfgBlockGenerator *self)
80+
cfg_block_generator_free_method(CfgBlockGenerator *self)
8181
{
8282
g_free(self->name);
8383
}

lib/cfg-block-generator.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ cfg_block_generator_format_name(CfgBlockGenerator *self, gchar *buf, gsize buf_l
5959
gboolean cfg_block_generator_generate(CfgBlockGenerator *self, GlobalConfig *cfg, gpointer args, GString *result,
6060
const gchar *reference);
6161
void cfg_block_generator_init_instance(CfgBlockGenerator *self, gint context, const gchar *name);
62-
void cfg_block_generator_free_instance(CfgBlockGenerator *self);
62+
void cfg_block_generator_free_method(CfgBlockGenerator *self);
6363
CfgBlockGenerator *cfg_block_generator_ref(CfgBlockGenerator *self);
6464
void cfg_block_generator_unref(CfgBlockGenerator *self);
6565

lib/cfg-block.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ cfg_block_free_instance(CfgBlockGenerator *s)
196196
g_free(self->filename);
197197
g_free(self->content);
198198
cfg_args_unref(self->arg_defs);
199-
cfg_block_generator_free_instance(s);
199+
cfg_block_generator_free_method(s);
200200
}
201201

202202

lib/cfg-parser.c

+40
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,43 @@ cfg_process_yesno(const gchar *yesno)
378378
return TRUE;
379379
return FALSE;
380380
}
381+
382+
gboolean
383+
cfg_process_list_of_literals(const gchar *input, GList **result)
384+
{
385+
if (strchr(input, '"') || strchr(input, '\''))
386+
{
387+
fprintf(stderr, "Error: list of literals must not contain single or double quotes: %s\n", input);
388+
return FALSE;
389+
}
390+
391+
*result = NULL;
392+
393+
gchar *input_copy = g_strdup(input);
394+
const gchar delimiters[] = ", \t\n";
395+
const gchar *elem = strtok(input_copy, delimiters);
396+
while (elem)
397+
{
398+
if (strlen(elem) > 0)
399+
*result = g_list_append(*result, __normalize_key(elem));
400+
elem = strtok(NULL, delimiters);
401+
}
402+
403+
g_free(input_copy);
404+
return TRUE;
405+
}
406+
407+
static gint
408+
_compare_literals_normalized(gconstpointer a, gconstpointer b)
409+
{
410+
gchar *normalized_b = __normalize_key(b);
411+
gint result = strcmp(a, normalized_b);
412+
g_free(normalized_b);
413+
return result;
414+
}
415+
416+
gboolean
417+
cfg_is_literal_in_list_of_literals(GList *list, const gchar *literal)
418+
{
419+
return !!g_list_find_custom(list, literal, _compare_literals_normalized);
420+
}

lib/cfg-parser.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ typedef enum _CfgYesNoAuto
7474

7575
gboolean cfg_process_flag(CfgFlagHandler *handlers, gpointer base, const gchar *flag);
7676
gboolean cfg_process_yesno(const gchar *yesno);
77-
77+
gboolean cfg_process_list_of_literals(const gchar *input, GList **result);
78+
gboolean cfg_is_literal_in_list_of_literals(GList *list, const gchar *literal);
7879

7980
extern CfgParser main_parser;
8081

modules/appmodel/app-object-generator.c

+15-6
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ app_object_generator_is_application_included(AppObjectGenerator *self, const gch
3333
/* include everything if we don't have the option */
3434
if (!self->included_apps)
3535
return TRUE;
36-
return strstr(self->included_apps, app_name) != NULL;
36+
return cfg_is_literal_in_list_of_literals(self->included_apps, app_name);
3737
}
3838

3939
gboolean
4040
app_object_generator_is_application_excluded(AppObjectGenerator *self, const gchar *app_name)
4141
{
4242
if (!self->excluded_apps)
4343
return FALSE;
44-
return strstr(self->excluded_apps, app_name) != NULL;
44+
return cfg_is_literal_in_list_of_literals(self->excluded_apps, app_name);
4545
}
4646

4747
static gboolean
@@ -62,8 +62,7 @@ _parse_auto_parse_exclude_arg(AppObjectGenerator *self, CfgArgs *args, const gch
6262
const gchar *v = cfg_args_get(args, "auto-parse-exclude");
6363
if (!v)
6464
return TRUE;
65-
self->excluded_apps = g_strdup(v);
66-
return TRUE;
65+
return cfg_process_list_of_literals(v, &self->excluded_apps);
6766
}
6867

6968
static gboolean
@@ -72,8 +71,7 @@ _parse_auto_parse_include_arg(AppObjectGenerator *self, CfgArgs *args, const gch
7271
const gchar *v = cfg_args_get(args, "auto-parse-include");
7372
if (!v)
7473
return TRUE;
75-
self->included_apps = g_strdup(v);
76-
return TRUE;
74+
return cfg_process_list_of_literals(v, &self->included_apps);
7775
}
7876

7977
gboolean
@@ -104,10 +102,21 @@ _generate(CfgBlockGenerator *s, GlobalConfig *cfg, gpointer args, GString *resul
104102
return TRUE;
105103
}
106104

105+
void
106+
app_object_generator_free_method(CfgBlockGenerator *s)
107+
{
108+
AppObjectGenerator *self = (AppObjectGenerator *) s;
109+
110+
g_list_free_full(self->included_apps, g_free);
111+
g_list_free_full(self->excluded_apps, g_free);
112+
cfg_block_generator_free_method(s);
113+
}
114+
107115
void
108116
app_object_generator_init_instance(AppObjectGenerator *self, gint context, const gchar *name)
109117
{
110118
cfg_block_generator_init_instance(&self->super, context, name);
111119
self->super.generate = _generate;
112120
self->parse_arguments = app_object_generator_parse_arguments_method;
121+
self->super.free_fn = app_object_generator_free_method;
113122
}

modules/appmodel/app-object-generator.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ struct _AppObjectGenerator
3434
CfgBlockGenerator super;
3535
gboolean (*parse_arguments)(AppObjectGenerator *self, CfgArgs *args, const gchar *reference);
3636
void (*generate_config)(AppObjectGenerator *self, GlobalConfig *cfg, GString *result);
37-
const gchar *included_apps;
38-
const gchar *excluded_apps;
37+
GList *included_apps;
38+
GList *excluded_apps;
3939
gboolean is_parsing_enabled;
4040
};
4141

@@ -44,6 +44,7 @@ gboolean app_object_generator_is_application_excluded(AppObjectGenerator *self,
4444

4545
gboolean app_object_generator_parse_arguments_method(AppObjectGenerator *self, CfgArgs *args, const gchar *reference);
4646
void app_object_generator_init_instance(AppObjectGenerator *self, gint context, const gchar *name);
47+
void app_object_generator_free_method(CfgBlockGenerator *s);
4748

4849

4950
#endif

modules/appmodel/app-transform-generator.c

+60-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ typedef struct _AppTransformGenerator
3030
AppObjectGenerator super;
3131
const gchar *flavour;
3232
const gchar *filterx_app_variable;
33+
GList *included_transforms;
34+
GList *excluded_transforms;
3335
GString *block;
3436
} AppTransformGenerator;
3537

@@ -55,6 +57,24 @@ _parse_filterx_app_variable(AppTransformGenerator *self, CfgArgs *args, const gc
5557
return TRUE;
5658
}
5759

60+
static gboolean
61+
_parse_include_transforms_arg(AppTransformGenerator *self, CfgArgs *args, const gchar *reference)
62+
{
63+
const gchar *v = cfg_args_get(args, "include-transforms");
64+
if (!v)
65+
return TRUE;
66+
return cfg_process_list_of_literals(v, &self->included_transforms);
67+
}
68+
69+
static gboolean
70+
_parse_exclude_transforms_arg(AppTransformGenerator *self, CfgArgs *args, const gchar *reference)
71+
{
72+
const gchar *v = cfg_args_get(args, "exclude-transforms");
73+
if (!v)
74+
return TRUE;
75+
return cfg_process_list_of_literals(v, &self->excluded_transforms);
76+
}
77+
5878
static gboolean
5979
app_transform_generator_parse_arguments(AppObjectGenerator *s, CfgArgs *args, const gchar *reference)
6080
{
@@ -67,6 +87,12 @@ app_transform_generator_parse_arguments(AppObjectGenerator *s, CfgArgs *args, co
6787
if (!_parse_filterx_app_variable(self, args, reference))
6888
return FALSE;
6989

90+
if (!_parse_include_transforms_arg(self, args, reference))
91+
return FALSE;
92+
93+
if (!_parse_exclude_transforms_arg(self, args, reference))
94+
return FALSE;
95+
7096
if (!app_object_generator_parse_arguments_method(&self->super, args, reference))
7197
return FALSE;
7298

@@ -78,12 +104,28 @@ _generate_steps(AppTransformGenerator *self, GList *steps)
78104
{
79105
for (GList *l = steps; l; l = l->next)
80106
{
81-
TransformationStep *step = l->data;
107+
TransformStep *step = l->data;
82108
g_string_append_printf(self->block, " # step: %s", step->name);
83109
g_string_append_printf(self->block, " %s\n", step->expr);
84110
}
85111
}
86112

113+
static gboolean
114+
_is_transform_included(AppTransformGenerator *self, const gchar *name)
115+
{
116+
if (!self->included_transforms)
117+
return TRUE;
118+
return cfg_is_literal_in_list_of_literals(self->included_transforms, name);
119+
}
120+
121+
static gboolean
122+
_is_transform_excluded(AppTransformGenerator *self, const gchar *name)
123+
{
124+
if (!self->excluded_transforms)
125+
return FALSE;
126+
return cfg_is_literal_in_list_of_literals(self->excluded_transforms, name);
127+
}
128+
87129
static void
88130
_generate_app_transform(Transformation *transformation, gpointer user_data)
89131
{
@@ -101,11 +143,14 @@ _generate_app_transform(Transformation *transformation, gpointer user_data)
101143
g_string_append_printf(self->block, "\n#Start Application %s\n", transformation->super.name);
102144
g_string_append_printf(self->block, " if (%s == '%s') {\n", self->filterx_app_variable,
103145
transformation->super.name);
104-
for (GList *l = transformation->blocks; l; l = l->next)
146+
for (GList *l = transformation->transforms; l; l = l->next)
105147
{
106-
TransformationBlock *block = l->data;
148+
Transform *transform = l->data;
107149

108-
_generate_steps(self, block->steps);
150+
if (!_is_transform_included(self, transform->name) || _is_transform_excluded(self, transform->name))
151+
continue;
152+
153+
_generate_steps(self, transform->steps);
109154
}
110155
g_string_append(self->block, " };\n");
111156
g_string_append_printf(self->block, "\n#End Application %s\n", transformation->super.name);
@@ -127,6 +172,16 @@ app_transform_generate_config(AppObjectGenerator *s, GlobalConfig *cfg, GString
127172
self->block = NULL;
128173
}
129174

175+
static void
176+
_free(CfgBlockGenerator *s)
177+
{
178+
AppTransformGenerator *self = (AppTransformGenerator *) s;
179+
180+
g_list_free_full(self->included_transforms, g_free);
181+
g_list_free_full(self->excluded_transforms, g_free);
182+
app_object_generator_free_method(s);
183+
}
184+
130185
CfgBlockGenerator *
131186
app_transform_generator_new(gint context, const gchar *name)
132187
{
@@ -135,5 +190,6 @@ app_transform_generator_new(gint context, const gchar *name)
135190
app_object_generator_init_instance(&self->super, context, name);
136191
self->super.parse_arguments = app_transform_generator_parse_arguments;
137192
self->super.generate_config = app_transform_generate_config;
193+
self->super.super.free_fn = _free;
138194
return &self->super.super;
139195
}

modules/appmodel/appmodel-grammar.ym

+8-8
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,21 @@ transformation_options
118118

119119
/* $0 is Transformation */
120120
transformation_option
121-
: KW_TRANSFORM '[' string ']' '{' { $<ptr>$ = transformation_block_new($3); } transformation_steps '}'
122-
{ free($3); transformation_add_block($<ptr>0, $<ptr>6); }
121+
: KW_TRANSFORM '[' string ']' '{' { $<ptr>$ = transform_new($3); } transform_steps '}'
122+
{ free($3); transformation_add_transform($<ptr>0, $<ptr>6); }
123123
;
124124

125-
/* $0 is TransformationBlock */
126-
transformation_steps
127-
: transformation_step semicolons { $<ptr>$ = $<ptr>0; } transformation_steps
125+
/* $0 is Transform */
126+
transform_steps
127+
: transform_step semicolons { $<ptr>$ = $<ptr>0; } transform_steps
128128
|
129129
;
130130

131-
/* $0 is TransformationBlock */
132-
transformation_step
131+
/* $0 is Transform */
132+
transform_step
133133
: KW_STEP '[' string ']' _block_content_context_push LL_BLOCK _block_content_context_pop
134134
{
135-
transformation_block_add_step($<ptr>0, $3, $6); free($3); free($6);
135+
transform_add_step($<ptr>0, $3, $6); free($3); free($6);
136136
}
137137
;
138138

modules/appmodel/transformation.c

+17-18
Original file line numberDiff line numberDiff line change
@@ -22,64 +22,63 @@
2222

2323
#include "transformation.h"
2424

25-
/* TransformationStep: a named filterx expression */
25+
/* TransformStep: a named filterx block */
2626

27-
TransformationStep *
28-
transformation_step_new(const gchar *name, const gchar *expr)
27+
TransformStep *
28+
transform_step_new(const gchar *name, const gchar *expr)
2929
{
30-
TransformationStep *self = g_new0(TransformationStep, 1);
30+
TransformStep *self = g_new0(TransformStep, 1);
3131
self->name = g_strdup(name);
3232
self->expr = g_strdup(expr);
3333
return self;
3434
}
3535

3636
void
37-
transformation_step_free(TransformationStep *self)
37+
transform_step_free(TransformStep *self)
3838
{
3939
g_free(self->name);
4040
g_free(self->expr);
4141
g_free(self);
4242
}
4343

44-
/* TransformationBlock: named list of steps */
44+
/* Transform: named list of TransformSteps */
4545

4646
void
47-
transformation_block_add_step(TransformationBlock *self, const gchar *name, const gchar *expr)
47+
transform_add_step(Transform *self, const gchar *name, const gchar *expr)
4848
{
49-
self->steps = g_list_append(self->steps, transformation_step_new(name, expr));
49+
self->steps = g_list_append(self->steps, transform_step_new(name, expr));
5050
}
5151

52-
TransformationBlock *
53-
transformation_block_new(const gchar *name)
52+
Transform *
53+
transform_new(const gchar *name)
5454
{
55-
TransformationBlock *self = g_new0(TransformationBlock, 1);
55+
Transform *self = g_new0(Transform, 1);
5656
self->name = g_strdup(name);
5757
return self;
5858
}
5959

6060
void
61-
transformation_block_free(TransformationBlock *self)
61+
transform_free(Transform *self)
6262
{
6363
g_free(self->name);
64-
g_list_free_full(self->steps, (GDestroyNotify) transformation_step_free);
64+
g_list_free_full(self->steps, (GDestroyNotify) transform_step_free);
6565
g_free(self);
6666
}
6767

68-
/* Transformation */
69-
/* list of blocks */
68+
/* Transformation: list of Transforms corresponding to an app (with optional flavour) */
7069

7170
void
72-
transformation_add_block(Transformation *self, TransformationBlock *block)
71+
transformation_add_transform(Transformation *self, Transform *transform)
7372
{
74-
self->blocks = g_list_append(self->blocks, block);
73+
self->transforms = g_list_append(self->transforms, transform);
7574
}
7675

7776
static void
7877
transformation_free(AppModelObject *s)
7978
{
8079
Transformation *self = (Transformation *) s;
8180

82-
g_list_free_full(self->blocks, (GDestroyNotify) transformation_block_free);
81+
g_list_free_full(self->transforms, (GDestroyNotify) transform_free);
8382
}
8483

8584
Transformation *

0 commit comments

Comments
 (0)