diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 9427bb03..f6921027 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -172,15 +172,14 @@ UNDERLINE "underline" ITALIC "italic" /* Color schema */ -ARGB "argb" RGBA "rgba" RGB "rgb" HWB "hwb" CMYK "cmyk" HSL "hsl" -S_PARENT_LEFT \( -S_PARENT_RIGHT \) +S_T_PARENT_LEFT \( +S_T_PARENT_RIGHT \) COMMA , LS_DASH "dash" @@ -314,50 +313,50 @@ if ( queue == NULL ){ {CONFIGURATION} { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(DEFAULTS); - return CONFIGURATION; + return T_CONFIGURATION; } {ASTERIX} { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(DEFAULTS); - return PDEFAULTS; + return T_PDEFAULTS; } /** Skip all whitespace */ {WHITESPACE} {} "\{" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(SECTION); - return BOPEN; + return T_BOPEN; } /** Everythin not yet parsed is an error. */ . { return T_ERROR_DEFAULTS; } -"#" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(NAMESTR);return NAME_PREFIX;} +"#" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(NAMESTR);return T_NAME_PREFIX;} /* Go into parsing an section*/ "\{" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(SECTION); - return BOPEN; + return T_BOPEN; } /* Pop out of parsing an section. */
"\}" { g_queue_pop_head ( queue ); BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); - return BCLOSE; + return T_BCLOSE; } -\.|{WHITESPACE} { return NSEP; } -
{WORD} { yylval->sval = g_strdup(yytext); return N_STRING;} -{WORD} { yylval->sval = g_strdup(yytext); return NAME_ELEMENT;} +\.|{WHITESPACE} { return T_NSEP; } +
{WORD} { yylval->sval = g_strdup(yytext); return T_PROP_NAME;} +{WORD} { yylval->sval = g_strdup(yytext); return T_NAME_ELEMENT;} /* After Namestr/Classstr we want to go to state str, then to { */ {WHITESPACE}+ ; // ignore all whitespace {WHITESPACE}+ ; // ignore all whitespace -
":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return PSEP; } -";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return PCLOSE;} +
":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; } +";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;} (true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} {PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} {PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} @@ -369,7 +368,7 @@ if ( queue == NULL ){ {EM} { return T_UNIT_EM; } {PX} { return T_UNIT_PX; } -{PERCENT} { return PERCENT; } +{PERCENT} { return T_PERCENT; } {LS_SOLID} { return T_SOLID; } {LS_DASH} { return T_DASH; } @@ -414,16 +413,15 @@ if ( queue == NULL ){ return T_COLOR; } /* Color schemes */ -{ARGB} { return T_COL_ARGB; } {RGBA} { return T_COL_RGBA; } {RGB} { return T_COL_RGB; } {HSL} { return T_COL_HSL; } {HWB} { return T_COL_HWB; } {CMYK} { return T_COL_CMYK; } /* Fluff */ -{S_PARENT_LEFT} { return PARENT_LEFT; } -{S_PARENT_RIGHT} { return PARENT_RIGHT;} -{COMMA} { return COMMA; } +{S_T_PARENT_LEFT} { return T_PARENT_LEFT; } +{S_T_PARENT_RIGHT} { return T_PARENT_RIGHT;} +{COMMA} { return T_COMMA; } /* Position */ {CENTER} { return T_POS_CENTER; } {EAST} { return T_POS_EAST; } diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 54d546e1..0d3fc99b 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -142,76 +142,74 @@ static ThemeColor hsl_to_rgb ( double h, double s, double l ) %token T_ERROR_NAMESTRING 4 "invalid element name" %token T_ERROR_DEFAULTS 5 "invalid defaults name" %token T_ERROR_INCLUDE 6 "invalid import value" -%token T_INT -%token T_DOUBLE -%token T_STRING -%token N_STRING "property name" -%token NAME_ELEMENT "Element name" -%token T_BOOLEAN -%token T_COLOR -%token T_LINK -%token FIRST_NAME -%token T_POS_CENTER "Center" -%token T_POS_EAST "East" -%token T_POS_WEST "West" -%token T_POS_NORTH "North" -%token T_POS_SOUTH "South" +%token T_INT "Integer number" +%token T_DOUBLE "Floating-point number" +%token T_STRING "UTF-8 encoded string" +%token T_PROP_NAME "property name" +%token T_NAME_ELEMENT "Element name" +%token T_BOOLEAN "Boolean value (true or false)" +%token T_COLOR "Hexidecimal color value" +%token T_LINK "Reference" +%token T_POS_CENTER "Center" +%token T_POS_EAST "East" +%token T_POS_WEST "West" +%token T_POS_NORTH "North" +%token T_POS_SOUTH "South" -%token T_NONE "None" -%token T_BOLD "Bold" -%token T_ITALIC "Italic" -%token T_UNDERLINE "Underline" -%token T_DASH "Dash" -%token T_SOLID "Solid" +%token T_NONE "None" +%token T_BOLD "Bold" +%token T_ITALIC "Italic" +%token T_UNDERLINE "Underline" +%token T_DASH "Dash" +%token T_SOLID "Solid" -%token T_UNIT_PX "pixels" -%token T_UNIT_EM "em" -%token T_UNIT_PERCENT "%" +%token T_UNIT_PX "pixels" +%token T_UNIT_EM "em" +%token T_UNIT_PERCENT "%" -%token T_COL_ARGB -%token T_COL_RGBA -%token T_COL_RGB -%token T_COL_HSL -%token T_COL_HWB -%token T_COL_CMYK +%token T_COL_RGBA "rgba colorscheme" +%token T_COL_RGB "rgb colorscheme" +%token T_COL_HSL "hsl colorscheme" +%token T_COL_HWB "hwb colorscheme" +%token T_COL_CMYK "cmyk colorscheme" -%token PARENT_LEFT "Parent left '('" -%token PARENT_RIGHT "Parent right ')'" -%token COMMA "comma separator" -%token PERCENT "Percent sign" +%token T_PARENT_LEFT "Parent left ('(')" +%token T_PARENT_RIGHT "Parent right (')')" +%token T_COMMA "comma separator (',')" +%token T_PERCENT "Percent sign ('%')" -%token BOPEN "bracket open ('{')" -%token BCLOSE "bracket close ('}')" -%token PSEP "property separator (':')" -%token PCLOSE "property close (';')" -%token NSEP "Name separator (' ' or '.')" -%token NAME_PREFIX "Element section ('# {name} { ... }')" -%token WHITESPACE "White space" -%token PDEFAULTS "Default settings section ( '* { ... }')" -%token CONFIGURATION "Configuration block" +%token T_BOPEN "bracket open ('{')" +%token T_BCLOSE "bracket close ('}')" +%token T_PSEP "property separator (':')" +%token T_PCLOSE "property close (';')" +%token T_NSEP "Name separator (' ' or '.')" +%token T_NAME_PREFIX "Element section ('# {name} { ... }')" +%token T_WHITESPACE "White space" +%token T_PDEFAULTS "Default settings section ( '* { ... }')" +%token T_CONFIGURATION "Configuration block" -%type highlight_styles -%type highlight_style -%type t_line_style -%type t_unit -%type color_val -%type t_position -%type t_position_ew -%type t_position_sn -%type entry -%type pvalue -%type entries -%type name_path -%type property -%type property_list -%type optional_properties -%type t_distance -%type t_color -%start entries +%type t_entry +%type t_entry_list +%type t_entry_name_path +%type t_property +%type t_property_list +%type t_property_list_optional +%type t_property_color +%type t_property_color_value +%type t_property_name +%type t_property_distance +%type t_property_unit +%type t_property_position +%type t_property_position_ew +%type t_property_position_sn +%type t_property_highlight_styles +%type t_property_highlight_style +%type t_property_line_style +%start t_entry_list %% -entries: +t_entry_list: %empty { // There is always a base widget. if (rofi_theme == NULL ){ @@ -219,13 +217,13 @@ entries: rofi_theme->name = g_strdup ( "Root" ); } } -| entries - entry { +| t_entry_list + t_entry { } ; -entry: -NAME_PREFIX name_path BOPEN optional_properties BCLOSE +t_entry: +T_NAME_PREFIX t_entry_name_path T_BOPEN t_property_list_optional T_BCLOSE { ThemeWidget *widget = rofi_theme; for ( GList *iter = g_list_first ( $2 ); iter ; iter = g_list_next ( iter ) ) { @@ -237,10 +235,10 @@ NAME_PREFIX name_path BOPEN optional_properties BCLOSE rofi_theme_widget_add_properties ( widget, $4); } | - PDEFAULTS BOPEN optional_properties BCLOSE { + T_PDEFAULTS T_BOPEN t_property_list_optional T_BCLOSE { rofi_theme_widget_add_properties ( rofi_theme, $3); } -| CONFIGURATION BOPEN optional_properties BCLOSE { +| T_CONFIGURATION T_BOPEN t_property_list_optional T_BCLOSE { GHashTableIter iter; g_hash_table_iter_init ( &iter, $3 ); gpointer key,value; @@ -255,85 +253,85 @@ NAME_PREFIX name_path BOPEN optional_properties BCLOSE /** * properties */ -optional_properties +t_property_list_optional : %empty { $$ = NULL; } - | property_list { $$ = $1; } + | t_property_list { $$ = $1; } ; -property_list: - property { +t_property_list: + t_property { $$ = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free ); g_hash_table_replace ( $$, $1->name, $1 ); } -| property_list property { +| t_property_list t_property { // Old will be free'ed, and key/value will be replaced. g_hash_table_replace ( $$, $2->name, $2 ); } ; -property -: pvalue PSEP T_INT PCLOSE { +t_property +: t_property_name T_PSEP T_INT T_PCLOSE { $$ = rofi_theme_property_create ( P_INTEGER ); $$->name = $1; $$->value.i = $3; } -| pvalue PSEP T_DOUBLE PCLOSE { +| t_property_name T_PSEP T_DOUBLE T_PCLOSE { $$ = rofi_theme_property_create ( P_DOUBLE ); $$->name = $1; $$->value.f = $3; } -| pvalue PSEP T_STRING PCLOSE { +| t_property_name T_PSEP T_STRING T_PCLOSE { $$ = rofi_theme_property_create ( P_STRING ); $$->name = $1; $$->value.s = $3; } -| pvalue PSEP T_LINK PCLOSE { +| t_property_name T_PSEP T_LINK T_PCLOSE { $$ = rofi_theme_property_create ( P_LINK ); $$->name = $1; $$->value.link.name = $3; } -| pvalue PSEP T_BOOLEAN PCLOSE { +| t_property_name T_PSEP T_BOOLEAN T_PCLOSE { $$ = rofi_theme_property_create ( P_BOOLEAN ); $$->name = $1; $$->value.b = $3; } -| pvalue PSEP t_distance PCLOSE { +| t_property_name T_PSEP t_property_distance T_PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $3, $3, $3 }; } -| pvalue PSEP t_distance t_distance PCLOSE { +| t_property_name T_PSEP t_property_distance t_property_distance T_PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $3, $4 }; } -| pvalue PSEP t_distance t_distance t_distance PCLOSE { +| t_property_name T_PSEP t_property_distance t_property_distance t_property_distance T_PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $5, $4 }; } -| pvalue PSEP t_distance t_distance t_distance t_distance PCLOSE { +| t_property_name T_PSEP t_property_distance t_property_distance t_property_distance t_property_distance T_PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $5, $6 }; } -| pvalue PSEP t_position PCLOSE{ +| t_property_name T_PSEP t_property_position T_PCLOSE{ $$ = rofi_theme_property_create ( P_POSITION ); $$->name = $1; $$->value.i = $3; } -| pvalue PSEP highlight_styles t_color PCLOSE { +| t_property_name T_PSEP t_property_highlight_styles t_property_color T_PCLOSE { $$ = rofi_theme_property_create ( P_HIGHLIGHT ); $$->name = $1; $$->value.highlight.style = $3|HL_COLOR; $$->value.highlight.color = $4; } -| pvalue PSEP highlight_styles PCLOSE { +| t_property_name T_PSEP t_property_highlight_styles T_PCLOSE { $$ = rofi_theme_property_create ( P_HIGHLIGHT ); $$->name = $1; $$->value.highlight.style = $3; } -| pvalue PSEP t_color PCLOSE { +| t_property_name T_PSEP t_property_color T_PCLOSE { $$ = rofi_theme_property_create ( P_COLOR ); $$->name = $1; $$->value.color = $3; @@ -345,18 +343,18 @@ property * East or West, North Or South * Or combi of East or West and North or South */ -t_position +t_property_position : T_POS_CENTER { $$ =WL_CENTER;} -| t_position_ew -| t_position_sn -| t_position_ew t_position_sn { $$ = $1|$2;} -| t_position_sn t_position_ew { $$ = $1|$2;} +| t_property_position_ew +| t_property_position_sn +| t_property_position_ew t_property_position_sn { $$ = $1|$2;} +| t_property_position_sn t_property_position_ew { $$ = $1|$2;} ; -t_position_ew +t_property_position_ew : T_POS_EAST { $$ = WL_EAST;} | T_POS_WEST { $$ = WL_WEST;} ; -t_position_sn +t_property_position_sn : T_POS_NORTH { $$ = WL_NORTH;} | T_POS_SOUTH { $$ = WL_SOUTH;} ; @@ -365,41 +363,44 @@ t_position_sn * Highlight style, allow mulitple styles to be combined. * Empty not allowed */ -highlight_styles -: highlight_style { $$ = $1;} -| highlight_styles highlight_style { $$ = $1|$2;} +t_property_highlight_styles +: t_property_highlight_style { $$ = $1;} +| t_property_highlight_styles t_property_highlight_style { $$ = $1|$2;} ; /** Single style. */ -highlight_style +t_property_highlight_style : T_NONE { $$ = HL_NONE; } | T_BOLD { $$ = HL_BOLD; } | T_UNDERLINE { $$ = HL_UNDERLINE; } | T_ITALIC { $$ = HL_ITALIC; } ; - -t_distance -: T_INT t_unit t_line_style { +/** Distance. */ +t_property_distance +/** Interger unit and line style */ +: T_INT t_property_unit t_property_line_style { $$.distance = (double)$1; $$.type = $2; $$.style = $3; } -| T_DOUBLE t_unit t_line_style { +/** Double unit and line style */ +| T_DOUBLE t_property_unit t_property_line_style { $$.distance = (double)$1; $$.type = $2; $$.style = $3; }; -t_unit +/** distance unit. px, em, % */ +t_property_unit : T_UNIT_PX { $$ = PW_PX; } | T_UNIT_EM { $$ = PW_EM; } -| PERCENT { $$ = PW_PERCENT; } +| T_PERCENT { $$ = PW_PERCENT; } ; /****** * Line style * If not set, solid. */ -t_line_style +t_property_line_style : %empty { $$ = SOLID; } | T_SOLID { $$ = SOLID; } | T_DASH { $$ = DASH; } @@ -408,8 +409,9 @@ t_line_style /** * Color formats */ -t_color -: T_COL_RGBA PARENT_LEFT T_INT COMMA T_INT COMMA T_INT COMMA T_DOUBLE PARENT_RIGHT { +t_property_color + /** rgba ( 0-255 , 0-255, 0-255, 0-1.0 ) */ +: T_COL_RGBA T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT T_COMMA T_DOUBLE T_PARENT_RIGHT { if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; } if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; } if ( ! check_in_range($7,0,255, &(@$)) ) { YYABORT; } @@ -419,7 +421,8 @@ t_color $$.green = $5/255.0; $$.blue = $7/255.0; } -| T_COL_RGBA PARENT_LEFT T_INT COMMA T_INT COMMA T_INT COMMA color_val PERCENT PARENT_RIGHT { + /** rgba ( 0-255 , 0-255, 0-255, 0-100% ) */ +| T_COL_RGBA T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT { if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; } if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; } if ( ! check_in_range($7,0,255, &(@$)) ) { YYABORT; } @@ -429,7 +432,8 @@ t_color $$.green = $5/255.0; $$.blue = $7/255.0; } -| T_COL_RGB PARENT_LEFT T_INT COMMA T_INT COMMA T_INT PARENT_RIGHT { + /** rgb ( 0-255 , 0-255, 0-255 ) */ +| T_COL_RGB T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT T_PARENT_RIGHT { if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; } if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; } if ( ! check_in_range($7,0,255, &(@$)) ) { YYABORT; } @@ -438,7 +442,8 @@ t_color $$.green = $5/255.0; $$.blue = $7/255.0; } -| T_COL_HWB PARENT_LEFT T_INT COMMA color_val PERCENT COMMA color_val PERCENT PARENT_RIGHT { + /** hwb ( 0-360 , 0-100 %, 0 - 100 %) */ +| T_COL_HWB T_PARENT_LEFT T_INT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT { $$.alpha = 1.0; if ( ! check_in_range($3,0,360, &(@$)) ) { YYABORT; } if ( ! check_in_range($5,0,100, &(@$)) ) { YYABORT; } @@ -454,7 +459,8 @@ t_color $$.blue *= ( 1. - w - b ); $$.blue += w; } -| T_COL_CMYK PARENT_LEFT color_val PERCENT COMMA color_val PERCENT COMMA color_val PERCENT COMMA color_val PERCENT PARENT_RIGHT { + /** cmyk ( 0-100%, 0-100%, 0-100%, 0-100%) */ +| T_COL_CMYK T_PARENT_LEFT t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT { $$.alpha = 1.0; if ( ! check_in_range($3, 0,100, &(@$)) ) { YYABORT; } if ( ! check_in_range($6, 0,100, &(@$)) ) { YYABORT; } @@ -468,7 +474,8 @@ t_color $$.green = (1.0-m)*(1.0-k); $$.blue = (1.0-y)*(1.0-k); } -| T_COL_CMYK PARENT_LEFT color_val COMMA color_val COMMA color_val COMMA color_val PARENT_RIGHT { + /** cmyk ( 0-1.0, 0-1.0, 0-1.0, 0-1.0) */ +| T_COL_CMYK T_PARENT_LEFT t_property_color_value T_COMMA t_property_color_value T_COMMA t_property_color_value T_COMMA t_property_color_value T_PARENT_RIGHT { $$.alpha = 1.0; if ( ! check_in_range($3, 0,1.00, &(@$)) ) { YYABORT; } if ( ! check_in_range($5, 0,1.00, &(@$)) ) { YYABORT; } @@ -482,7 +489,8 @@ t_color $$.green = (1.0-m)*(1.0-k); $$.blue = (1.0-y)*(1.0-k); } -| T_COL_HSL PARENT_LEFT T_INT COMMA color_val PERCENT COMMA color_val PERCENT PARENT_RIGHT { + /** hsl ( 0-360 , 0-100 %, 0 - 100 %) */ +| T_COL_HSL T_PARENT_LEFT T_INT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_PARENT_RIGHT { if ( ! check_in_range($3, 0,360, &(@$)) ) { YYABORT; } if ( ! check_in_range($5, 0,100, &(@$)) ) { YYABORT; } if ( ! check_in_range($8, 0,100, &(@$)) ) { YYABORT; } @@ -492,23 +500,25 @@ t_color $$ = hsl_to_rgb ( h/360.0, s/100.0, l/100.0 ); $$.alpha = 1.0; } +/** Hex colors parsed by lexer. */ | T_COLOR { $$ = $1; } ; -color_val +/** Color value to be double or integer. */ +t_property_color_value : T_DOUBLE { $$ = $1; } | T_INT { $$ = $1; } ; +/** Property name */ +t_property_name: T_PROP_NAME { $$ = $1; } -pvalue: N_STRING { $$ = $1; } - -name_path: -NAME_ELEMENT { $$ = g_list_append ( NULL, $1 );} -| name_path NSEP NAME_ELEMENT { $$ = g_list_append ( $1, $3);} -| name_path NSEP { $$ = $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);} +| t_entry_name_path T_NSEP { $$ = $1; } ; %% diff --git a/test/theme-parser-test.c b/test/theme-parser-test.c index f1f63860..e7ba6711 100644 --- a/test/theme-parser-test.c +++ b/test/theme-parser-test.c @@ -764,6 +764,20 @@ START_TEST ( test_import_empty) } END_TEST +START_TEST ( test_core_properties_error ) +{ + rofi_theme_parse_string ( " * { test: cmky(a,e,3); }"); + const char *errstr = "Error while parsing theme: * { test: cmky(a,e,3); }\n"\ + " Parser error: syntax error, unexpected invalid property value\n"\ + " Location: line 1 column 11 to line 1 column 13\n"; + ck_assert_int_eq ( error, 1); + ck_assert_str_eq ( error_msg->str, errstr ); + g_string_free ( error_msg, TRUE); + error_msg = NULL; + error = 0; +} +END_TEST + static Suite * theme_parser_suite (void) { Suite *s; @@ -781,6 +795,7 @@ static Suite * theme_parser_suite (void) tcase_add_test(tc_core, test_core_error_root ); tcase_add_test(tc_core, test_core_comments ); tcase_add_test(tc_core, test_core_newline ); + tcase_add_test(tc_core, test_core_properties_error ); suite_add_tcase(s, tc_core); } {