From 7c1ecb470773843d72a49adb462becb05af299df Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Wed, 6 Sep 2017 23:11:03 +0200 Subject: [PATCH] Add support for multiple selectors. #dummy0, dummy1 {} --- include/theme.h | 6 ++++++ lexer/theme-lexer.l | 1 + lexer/theme-parser.y | 31 ++++++++++++++++++++++++++----- source/theme.c | 34 +++++++++++++++++++++++++++------- 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/include/theme.h b/include/theme.h index 810391f3..df817e7c 100644 --- a/include/theme.h +++ b/include/theme.h @@ -86,6 +86,12 @@ Property *rofi_theme_property_create ( PropertyType type ); */ void rofi_theme_property_free ( Property *p ); +/** + * @param p The property to free. + * + * @returns a copy of p + */ +Property* rofi_theme_property_copy ( Property *p); /** * @param widget * diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 6edea302..1eb47aec 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -394,6 +394,7 @@ if ( queue == NULL ){ } \.|{WHITESPACE} { return T_NSEP; } +,{WHITESPACE}* { return T_SSEP; }
{WORD} { yylval->sval = g_strdup(yytext); return T_PROP_NAME;} {WORD} { yylval->sval = g_strdup(yytext); return T_NAME_ELEMENT;} diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index a2bce6c2..7a13702d 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -212,6 +212,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b) %token T_PSEP "property separator (':')" %token T_PCLOSE "property close (';')" %token T_NSEP "Name separator (' ' or '.')" +%token T_SSEP "Selector separator (',')" %token T_NAME_PREFIX "Element section ('# {name} { ... }')" %token T_WHITESPACE "White space" %token T_PDEFAULTS "Default settings section ( '* { ... }')" @@ -224,6 +225,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b) %type t_entry %type t_entry_list %type t_entry_name_path +%type t_entry_name_path_selectors %type t_property %type t_property_list %type t_property_list_optional @@ -263,20 +265,29 @@ t_entry_list: ; t_entry: -T_NAME_PREFIX t_entry_name_path T_BOPEN t_property_list_optional T_BCLOSE +T_NAME_PREFIX t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE { + for ( GList *liter = g_list_first ( $2); liter; liter = g_list_next ( liter ) ) { ThemeWidget *widget = rofi_theme; - for ( GList *iter = g_list_first ( $2 ); iter ; iter = g_list_next ( iter ) ) { + for ( GList *iter = g_list_first ( (GList*)liter->data ); iter ; iter = g_list_next ( iter ) ) { widget = rofi_theme_find_or_create_name ( widget, iter->data ); } - g_list_foreach ( $2, (GFunc)g_free , NULL ); - g_list_free ( $2 ); + g_list_foreach ( (GList*)liter->data, (GFunc)g_free , NULL ); + g_list_free ( (GList*)liter->data ); widget->set = TRUE; rofi_theme_widget_add_properties ( widget, $4); + } + if ( $4 ) { + g_hash_table_destroy ( $4 ); + } + g_list_free ( $2 ); } | T_PDEFAULTS T_BOPEN t_property_list_optional T_BCLOSE { rofi_theme_widget_add_properties ( rofi_theme, $3); + if ( $3 ) { + g_hash_table_destroy ( $3 ); + } } | T_CONFIGURATION T_BOPEN t_config_property_list_optional T_BCLOSE { // Dummy at this point. @@ -327,7 +338,7 @@ t_property : t_property_name T_PSEP T_INHERIT T_PCLOSE { $$ = rofi_theme_property_create ( P_INHERIT ); $$->name = $1; - } + } | t_property_name T_PSEP T_INT T_PCLOSE { $$ = rofi_theme_property_create ( P_INTEGER ); $$->name = $1; @@ -617,6 +628,16 @@ t_property_name : T_PROP_NAME { $$ = $1; } ; +t_entry_name_path_selectors: +t_entry_name_path { $$ = g_list_append ( NULL, $1 ); } +| t_entry_name_path_selectors T_SSEP t_entry_name_path { + $$ = g_list_append ( $1, $3); +} +| t_entry_name_path_selectors T_SSEP { + $$ = $1; +} + +; t_entry_name_path: T_NAME_ELEMENT { $$ = g_list_append ( NULL, $1 );} | t_entry_name_path T_NSEP T_NAME_ELEMENT { $$ = g_list_append ( $1, $3);} diff --git a/source/theme.c b/source/theme.c index 05156600..a335db10 100644 --- a/source/theme.c +++ b/source/theme.c @@ -74,6 +74,28 @@ Property *rofi_theme_property_create ( PropertyType type ) retv->type = type; return retv; } +Property* rofi_theme_property_copy ( Property *p) +{ + Property *retv = rofi_theme_property_create ( p->type ); + retv->name = g_strdup ( p->name ); + + switch ( p->type ) { + case P_STRING: + retv->value.s = g_strdup ( p->value.s ); + break; + case P_LIST: + retv->value.list = g_list_copy_deep ( p->value.list, (GCopyFunc)g_strdup, NULL ); + break; + case P_LINK: + retv->value.link.name = g_strdup ( p->value.link.name ); + retv->value.link.ref = NULL; + break; + default: + retv->value = p->value; + } + return retv; +} + void rofi_theme_property_free ( Property *p ) { if ( p == NULL ) { @@ -332,11 +354,11 @@ void yyerror ( YYLTYPE *yylloc, const char *what, const char* s ) rofi_add_error_message ( str ); } -static gboolean rofi_theme_steal_property_int ( gpointer key, gpointer value, gpointer user_data ) +static void rofi_theme_copy_property_int ( gpointer key, gpointer value, gpointer user_data ) { GHashTable *table = (GHashTable *) user_data; - g_hash_table_replace ( table, key, value ); - return TRUE; + Property *p = rofi_theme_property_copy( (Property*) value); + g_hash_table_replace ( table, p->name, p ); } void rofi_theme_widget_add_properties ( ThemeWidget *widget, GHashTable *table ) { @@ -344,11 +366,9 @@ void rofi_theme_widget_add_properties ( ThemeWidget *widget, GHashTable *table ) return; } if ( widget->properties == NULL ) { - widget->properties = table; - return; + widget->properties = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free ); } - g_hash_table_foreach_steal ( table, rofi_theme_steal_property_int, widget->properties ); - g_hash_table_destroy ( table ); + g_hash_table_foreach ( table, rofi_theme_copy_property_int, widget->properties ); } /**