Skip to content

Commit

Permalink
Merge pull request #379 from alltilla/app-transform-include-exclude
Browse files Browse the repository at this point in the history
`app-transform()`: add `include-transforms()` and `exclude-transforms()` options
  • Loading branch information
MrAnno authored Nov 13, 2024
2 parents d82c236 + 56f832c commit b916003
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 56 deletions.
4 changes: 2 additions & 2 deletions lib/cfg-block-generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ cfg_block_generator_init_instance(CfgBlockGenerator *self, gint context, const g
self->context = context;
self->name = g_strdup(name);
self->format_name = cfg_block_generator_format_name_method;
self->free_fn = cfg_block_generator_free_instance;
self->free_fn = cfg_block_generator_free_method;
}

void
cfg_block_generator_free_instance(CfgBlockGenerator *self)
cfg_block_generator_free_method(CfgBlockGenerator *self)
{
g_free(self->name);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/cfg-block-generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ cfg_block_generator_format_name(CfgBlockGenerator *self, gchar *buf, gsize buf_l
gboolean cfg_block_generator_generate(CfgBlockGenerator *self, GlobalConfig *cfg, gpointer args, GString *result,
const gchar *reference);
void cfg_block_generator_init_instance(CfgBlockGenerator *self, gint context, const gchar *name);
void cfg_block_generator_free_instance(CfgBlockGenerator *self);
void cfg_block_generator_free_method(CfgBlockGenerator *self);
CfgBlockGenerator *cfg_block_generator_ref(CfgBlockGenerator *self);
void cfg_block_generator_unref(CfgBlockGenerator *self);

Expand Down
2 changes: 1 addition & 1 deletion lib/cfg-block.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ cfg_block_free_instance(CfgBlockGenerator *s)
g_free(self->filename);
g_free(self->content);
cfg_args_unref(self->arg_defs);
cfg_block_generator_free_instance(s);
cfg_block_generator_free_method(s);
}


Expand Down
40 changes: 40 additions & 0 deletions lib/cfg-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,3 +378,43 @@ cfg_process_yesno(const gchar *yesno)
return TRUE;
return FALSE;
}

gboolean
cfg_process_list_of_literals(const gchar *input, GList **result)
{
if (strchr(input, '"') || strchr(input, '\''))
{
fprintf(stderr, "Error: list of literals must not contain single or double quotes: %s\n", input);
return FALSE;
}

*result = NULL;

gchar *input_copy = g_strdup(input);
const gchar delimiters[] = ", \t\n";
const gchar *elem = strtok(input_copy, delimiters);
while (elem)
{
if (strlen(elem) > 0)
*result = g_list_append(*result, __normalize_key(elem));
elem = strtok(NULL, delimiters);
}

g_free(input_copy);
return TRUE;
}

static gint
_compare_literals_normalized(gconstpointer a, gconstpointer b)
{
gchar *normalized_b = __normalize_key(b);
gint result = strcmp(a, normalized_b);
g_free(normalized_b);
return result;
}

gboolean
cfg_is_literal_in_list_of_literals(GList *list, const gchar *literal)
{
return !!g_list_find_custom(list, literal, _compare_literals_normalized);
}
3 changes: 2 additions & 1 deletion lib/cfg-parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ typedef enum _CfgYesNoAuto

gboolean cfg_process_flag(CfgFlagHandler *handlers, gpointer base, const gchar *flag);
gboolean cfg_process_yesno(const gchar *yesno);

gboolean cfg_process_list_of_literals(const gchar *input, GList **result);
gboolean cfg_is_literal_in_list_of_literals(GList *list, const gchar *literal);

extern CfgParser main_parser;

Expand Down
21 changes: 15 additions & 6 deletions modules/appmodel/app-object-generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ app_object_generator_is_application_included(AppObjectGenerator *self, const gch
/* include everything if we don't have the option */
if (!self->included_apps)
return TRUE;
return strstr(self->included_apps, app_name) != NULL;
return cfg_is_literal_in_list_of_literals(self->included_apps, app_name);
}

gboolean
app_object_generator_is_application_excluded(AppObjectGenerator *self, const gchar *app_name)
{
if (!self->excluded_apps)
return FALSE;
return strstr(self->excluded_apps, app_name) != NULL;
return cfg_is_literal_in_list_of_literals(self->excluded_apps, app_name);
}

static gboolean
Expand All @@ -62,8 +62,7 @@ _parse_auto_parse_exclude_arg(AppObjectGenerator *self, CfgArgs *args, const gch
const gchar *v = cfg_args_get(args, "auto-parse-exclude");
if (!v)
return TRUE;
self->excluded_apps = g_strdup(v);
return TRUE;
return cfg_process_list_of_literals(v, &self->excluded_apps);
}

static gboolean
Expand All @@ -72,8 +71,7 @@ _parse_auto_parse_include_arg(AppObjectGenerator *self, CfgArgs *args, const gch
const gchar *v = cfg_args_get(args, "auto-parse-include");
if (!v)
return TRUE;
self->included_apps = g_strdup(v);
return TRUE;
return cfg_process_list_of_literals(v, &self->included_apps);
}

gboolean
Expand Down Expand Up @@ -104,10 +102,21 @@ _generate(CfgBlockGenerator *s, GlobalConfig *cfg, gpointer args, GString *resul
return TRUE;
}

void
app_object_generator_free_method(CfgBlockGenerator *s)
{
AppObjectGenerator *self = (AppObjectGenerator *) s;

g_list_free_full(self->included_apps, g_free);
g_list_free_full(self->excluded_apps, g_free);
cfg_block_generator_free_method(s);
}

void
app_object_generator_init_instance(AppObjectGenerator *self, gint context, const gchar *name)
{
cfg_block_generator_init_instance(&self->super, context, name);
self->super.generate = _generate;
self->parse_arguments = app_object_generator_parse_arguments_method;
self->super.free_fn = app_object_generator_free_method;
}
5 changes: 3 additions & 2 deletions modules/appmodel/app-object-generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ struct _AppObjectGenerator
CfgBlockGenerator super;
gboolean (*parse_arguments)(AppObjectGenerator *self, CfgArgs *args, const gchar *reference);
void (*generate_config)(AppObjectGenerator *self, GlobalConfig *cfg, GString *result);
const gchar *included_apps;
const gchar *excluded_apps;
GList *included_apps;
GList *excluded_apps;
gboolean is_parsing_enabled;
};

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

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


#endif
64 changes: 60 additions & 4 deletions modules/appmodel/app-transform-generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ typedef struct _AppTransformGenerator
AppObjectGenerator super;
const gchar *flavour;
const gchar *filterx_app_variable;
GList *included_transforms;
GList *excluded_transforms;
GString *block;
} AppTransformGenerator;

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

static gboolean
_parse_include_transforms_arg(AppTransformGenerator *self, CfgArgs *args, const gchar *reference)
{
const gchar *v = cfg_args_get(args, "include-transforms");
if (!v)
return TRUE;
return cfg_process_list_of_literals(v, &self->included_transforms);
}

static gboolean
_parse_exclude_transforms_arg(AppTransformGenerator *self, CfgArgs *args, const gchar *reference)
{
const gchar *v = cfg_args_get(args, "exclude-transforms");
if (!v)
return TRUE;
return cfg_process_list_of_literals(v, &self->excluded_transforms);
}

static gboolean
app_transform_generator_parse_arguments(AppObjectGenerator *s, CfgArgs *args, const gchar *reference)
{
Expand All @@ -67,6 +87,12 @@ app_transform_generator_parse_arguments(AppObjectGenerator *s, CfgArgs *args, co
if (!_parse_filterx_app_variable(self, args, reference))
return FALSE;

if (!_parse_include_transforms_arg(self, args, reference))
return FALSE;

if (!_parse_exclude_transforms_arg(self, args, reference))
return FALSE;

if (!app_object_generator_parse_arguments_method(&self->super, args, reference))
return FALSE;

Expand All @@ -78,12 +104,28 @@ _generate_steps(AppTransformGenerator *self, GList *steps)
{
for (GList *l = steps; l; l = l->next)
{
TransformationStep *step = l->data;
TransformStep *step = l->data;
g_string_append_printf(self->block, " # step: %s", step->name);
g_string_append_printf(self->block, " %s\n", step->expr);
}
}

static gboolean
_is_transform_included(AppTransformGenerator *self, const gchar *name)
{
if (!self->included_transforms)
return TRUE;
return cfg_is_literal_in_list_of_literals(self->included_transforms, name);
}

static gboolean
_is_transform_excluded(AppTransformGenerator *self, const gchar *name)
{
if (!self->excluded_transforms)
return FALSE;
return cfg_is_literal_in_list_of_literals(self->excluded_transforms, name);
}

static void
_generate_app_transform(Transformation *transformation, gpointer user_data)
{
Expand All @@ -101,11 +143,14 @@ _generate_app_transform(Transformation *transformation, gpointer user_data)
g_string_append_printf(self->block, "\n#Start Application %s\n", transformation->super.name);
g_string_append_printf(self->block, " if (%s == '%s') {\n", self->filterx_app_variable,
transformation->super.name);
for (GList *l = transformation->blocks; l; l = l->next)
for (GList *l = transformation->transforms; l; l = l->next)
{
TransformationBlock *block = l->data;
Transform *transform = l->data;

_generate_steps(self, block->steps);
if (!_is_transform_included(self, transform->name) || _is_transform_excluded(self, transform->name))
continue;

_generate_steps(self, transform->steps);
}
g_string_append(self->block, " };\n");
g_string_append_printf(self->block, "\n#End Application %s\n", transformation->super.name);
Expand All @@ -127,6 +172,16 @@ app_transform_generate_config(AppObjectGenerator *s, GlobalConfig *cfg, GString
self->block = NULL;
}

static void
_free(CfgBlockGenerator *s)
{
AppTransformGenerator *self = (AppTransformGenerator *) s;

g_list_free_full(self->included_transforms, g_free);
g_list_free_full(self->excluded_transforms, g_free);
app_object_generator_free_method(s);
}

CfgBlockGenerator *
app_transform_generator_new(gint context, const gchar *name)
{
Expand All @@ -135,5 +190,6 @@ app_transform_generator_new(gint context, const gchar *name)
app_object_generator_init_instance(&self->super, context, name);
self->super.parse_arguments = app_transform_generator_parse_arguments;
self->super.generate_config = app_transform_generate_config;
self->super.super.free_fn = _free;
return &self->super.super;
}
16 changes: 8 additions & 8 deletions modules/appmodel/appmodel-grammar.ym
Original file line number Diff line number Diff line change
Expand Up @@ -118,21 +118,21 @@ transformation_options

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

/* $0 is TransformationBlock */
transformation_steps
: transformation_step semicolons { $<ptr>$ = $<ptr>0; } transformation_steps
/* $0 is Transform */
transform_steps
: transform_step semicolons { $<ptr>$ = $<ptr>0; } transform_steps
|
;

/* $0 is TransformationBlock */
transformation_step
/* $0 is Transform */
transform_step
: KW_STEP '[' string ']' _block_content_context_push LL_BLOCK _block_content_context_pop
{
transformation_block_add_step($<ptr>0, $3, $6); free($3); free($6);
transform_add_step($<ptr>0, $3, $6); free($3); free($6);
}
;

Expand Down
35 changes: 17 additions & 18 deletions modules/appmodel/transformation.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,64 +22,63 @@

#include "transformation.h"

/* TransformationStep: a named filterx expression */
/* TransformStep: a named filterx block */

TransformationStep *
transformation_step_new(const gchar *name, const gchar *expr)
TransformStep *
transform_step_new(const gchar *name, const gchar *expr)
{
TransformationStep *self = g_new0(TransformationStep, 1);
TransformStep *self = g_new0(TransformStep, 1);
self->name = g_strdup(name);
self->expr = g_strdup(expr);
return self;
}

void
transformation_step_free(TransformationStep *self)
transform_step_free(TransformStep *self)
{
g_free(self->name);
g_free(self->expr);
g_free(self);
}

/* TransformationBlock: named list of steps */
/* Transform: named list of TransformSteps */

void
transformation_block_add_step(TransformationBlock *self, const gchar *name, const gchar *expr)
transform_add_step(Transform *self, const gchar *name, const gchar *expr)
{
self->steps = g_list_append(self->steps, transformation_step_new(name, expr));
self->steps = g_list_append(self->steps, transform_step_new(name, expr));
}

TransformationBlock *
transformation_block_new(const gchar *name)
Transform *
transform_new(const gchar *name)
{
TransformationBlock *self = g_new0(TransformationBlock, 1);
Transform *self = g_new0(Transform, 1);
self->name = g_strdup(name);
return self;
}

void
transformation_block_free(TransformationBlock *self)
transform_free(Transform *self)
{
g_free(self->name);
g_list_free_full(self->steps, (GDestroyNotify) transformation_step_free);
g_list_free_full(self->steps, (GDestroyNotify) transform_step_free);
g_free(self);
}

/* Transformation */
/* list of blocks */
/* Transformation: list of Transforms corresponding to an app (with optional flavour) */

void
transformation_add_block(Transformation *self, TransformationBlock *block)
transformation_add_transform(Transformation *self, Transform *transform)
{
self->blocks = g_list_append(self->blocks, block);
self->transforms = g_list_append(self->transforms, transform);
}

static void
transformation_free(AppModelObject *s)
{
Transformation *self = (Transformation *) s;

g_list_free_full(self->blocks, (GDestroyNotify) transformation_block_free);
g_list_free_full(self->transforms, (GDestroyNotify) transform_free);
}

Transformation *
Expand Down
Loading

0 comments on commit b916003

Please sign in to comment.