From ab1dfe7f619cb1e546e0669743b8fa9a23f0f347 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Sat, 11 Feb 2023 18:53:31 +0100 Subject: [Dmenu] Small fix that disabled async mode when multi-select is enabled. --- source/modes/dmenu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/modes/dmenu.c b/source/modes/dmenu.c index 0b604e78..c9b55d10 100644 --- a/source/modes/dmenu.c +++ b/source/modes/dmenu.c @@ -514,6 +514,7 @@ static int dmenu_mode_init(Mode *sw) { DmenuModePrivateData *pd = (DmenuModePrivateData *)mode_get_private_data(sw); pd->async = TRUE; + pd->multi_select = FALSE; // For now these only work in sync mode. if (find_arg("-sync") >= 0 || find_arg("-dump") >= 0 || @@ -522,6 +523,10 @@ static int dmenu_mode_init(Mode *sw) { find_arg("-selected-row") >= 0) { pd->async = FALSE; } + if ( find_arg("-multi-select") >= 0 ) { + pd->multi_select = TRUE; + pd->async = FALSE; + } pd->separator = '\n'; pd->selected_line = UINT32_MAX; @@ -907,14 +912,11 @@ int dmenu_mode_dialog(void) { DmenuScriptEntry *cmd_list = pd->cmd_list; pd->only_selected = FALSE; - pd->multi_select = FALSE; pd->ballot_selected = "☑ "; pd->ballot_unselected = "☐ "; find_arg_str("-ballot-selected-str", &(pd->ballot_selected)); find_arg_str("-ballot-unselected-str", &(pd->ballot_unselected)); - if (find_arg("-multi-select") >= 0) { - pd->multi_select = TRUE; - } + if (find_arg("-markup-rows") >= 0) { pd->do_markup = TRUE; } -- cgit v1.2.3 From 1b1aa37f20d1748b161bc70a8a4151204c17d17e Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Tue, 14 Feb 2023 15:53:10 +0100 Subject: #1802: Calc broken fix (#1803) * [Theme] First move to double internal calculations. * [Theme] Allow float numbers. * [Theme] Fix unary - and tighten the grammar parser. * [Theme] Rename % to modulo to fix compiler. * [Theme] Dump right modulo syntax. * [Test] add missing end_test * [Grammar] Allow negative numbers as property value --- doc/rofi-theme.5 | 25 ++++---- doc/rofi-theme.5.markdown | 20 +++---- lexer/theme-lexer.l | 13 ++-- lexer/theme-parser.y | 76 ++++++++---------------- source/theme.c | 32 +++++----- test/theme-parser-test.c | 148 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 218 insertions(+), 96 deletions(-) diff --git a/doc/rofi-theme.5 b/doc/rofi-theme.5 index a5887a46..9b488cbf 100644 --- a/doc/rofi-theme.5 +++ b/doc/rofi-theme.5 @@ -910,25 +910,25 @@ It supports the following operations: .RS .IP \(bu 2 -\fB\fC+\fR : Add +\fB\fC+\fR : Add .IP \(bu 2 -\fB\fC-\fR : Subtract +\fB\fC-\fR : Subtract .IP \(bu 2 -\fB\fC/\fR : Divide +\fB\fC/\fR : Divide .IP \(bu 2 -\fB\fC*\fR : Multiply +\fB\fC*\fR : Multiply .IP \(bu 2 -\fB\fC%\fR : Modulo +\fB\fCmodulo\fR : Modulo .IP \(bu 2 -\fB\fCmin\fR : Minimum of lvalue or rvalue; +\fB\fCmin\fR : Minimum of lvalue or rvalue; .IP \(bu 2 -\fB\fCmax\fR : Maximum of lvalue or rvalue; +\fB\fCmax\fR : Maximum of lvalue or rvalue; .IP \(bu 2 -\fB\fCfloor\fR : Round down lvalue to the next multiple of rvalue +\fB\fCfloor\fR : Round down lvalue to the next multiple of rvalue .IP \(bu 2 -\fB\fCceil\fR : Round up lvalue to the next multiple of rvalue +\fB\fCceil\fR : Round up lvalue to the next multiple of rvalue .IP \(bu 2 -\fB\fCround\fR : Round lvalue to the next multiple of rvalue +\fB\fCround\fR : Round lvalue to the next multiple of rvalue .RE @@ -1615,7 +1615,7 @@ property. These cannot be changed using the \fB\fCchildren\fR property. .PP -Each entries displayed by listview are captured by a \fB\fCbox\fR called \fB\fCelement\fR\&. +Each Entry displayed by listview is captured by a \fB\fCbox\fR called \fB\fCelement\fR\&. An \fB\fCelement\fR widget can contain the following special child widgets: .RS @@ -1630,7 +1630,8 @@ An \fB\fCelement\fR widget can contain the following special child widgets: .PP By default the \fB\fCelement-icon\fR and \fB\fCelement-text\fR child widgets are added to the -\fB\fCelement\fR\&. This can be modified using the \fB\fCchildren\fR property. +\fB\fCelement\fR\&. This can be modified using the \fB\fCchildren\fR property or the +\fB\fC[no]-show-icons\fR option. .PP A child added with another name is seen as a \fB\fCbox\fR, this can be used as dynamic diff --git a/doc/rofi-theme.5.markdown b/doc/rofi-theme.5.markdown index e65c7114..de288738 100644 --- a/doc/rofi-theme.5.markdown +++ b/doc/rofi-theme.5.markdown @@ -573,16 +573,16 @@ width: calc( 20% min 512 ); It supports the following operations: -* `+` : Add -* `-` : Subtract -* `/` : Divide -* `*` : Multiply -* `%` : Modulo -* `min` : Minimum of lvalue or rvalue; -* `max` : Maximum of lvalue or rvalue; -* `floor` : Round down lvalue to the next multiple of rvalue -* `ceil` : Round up lvalue to the next multiple of rvalue -* `round` : Round lvalue to the next multiple of rvalue +* `+` : Add +* `-` : Subtract +* `/` : Divide +* `*` : Multiply +* `modulo` : Modulo +* `min` : Minimum of lvalue or rvalue; +* `max` : Maximum of lvalue or rvalue; +* `floor` : Round down lvalue to the next multiple of rvalue +* `ceil` : Round up lvalue to the next multiple of rvalue +* `round` : Round lvalue to the next multiple of rvalue It uses the C precedence ordering. diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 7ae18da0..a7174226 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -184,8 +184,8 @@ STRING \"{UANYN}*\" STRING_LIST \"{UANYNP}*\" CHAR \'({ASCN}|\\\\|\\\'|\\0)\' HEX [[:xdigit:]] -NUMBER [[:digit:]] -PNNUMBER [-+]?[[:digit:]]+ +NUMBER [[:digit:]]+ +UNARYMIN - PX (px) MM (mm) EM (em) @@ -199,13 +199,13 @@ ASTERIX \* ENV $\{[[:alpha:]_][[:alnum:]_]*\} MODIFIER_ADD \+ -MODIFIER_SUBTRACT - MODIFIER_MULTIPLY \* MODIFIER_MIN (min) MODIFIER_MAX (max) MODIFIER_ROUND (round) MODIFIER_FLOOR (floor) MODIFIER_CEIL (ceil) +MODIFIER_MODULO (modulo) /* Position */ CENTER (?i:center) @@ -510,8 +510,9 @@ if ( queue == NULL ) {
":" { 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;} +{NUMBER}\.{NUMBER} { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} +{NUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} +{UNARYMIN} { return T_MIN; } {STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} {STRING_LIST} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} {CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} @@ -539,13 +540,13 @@ if ( queue == NULL ) { {INHERIT} { return T_INHERIT; } {MODIFIER_ADD} { return T_MODIFIER_ADD; } -{MODIFIER_SUBTRACT} { return T_MODIFIER_SUBTRACT; } {MODIFIER_MULTIPLY} { return T_MODIFIER_MULTIPLY; } {MODIFIER_MIN} { return T_MODIFIER_MIN; } {MODIFIER_MAX} { return T_MODIFIER_MAX; } {MODIFIER_ROUND} { return T_MODIFIER_ROUND; } {MODIFIER_FLOOR} { return T_MODIFIER_FLOOR; } {MODIFIER_CEIL} { return T_MODIFIER_CEIL; } +{MODIFIER_MODULO} { return T_MODIFIER_MODULO; } {CALC} { return T_CALC; } {ENV} { diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 0911cddc..4d118619 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -195,7 +195,6 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %token T_UNIT_MM "mm" %token T_UNIT_EM "em" %token T_UNIT_CH "ch" -%token T_UNIT_PERCENT "%" %token T_ANGLE_DEG "Degrees" %token T_ANGLE_GRAD "Gradians" @@ -231,7 +230,6 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %token T_PARENT_LEFT "Parent left ('(')" %token T_PARENT_RIGHT "Parent right (')')" %token T_COMMA "comma separator (',')" -%token T_OPTIONAL_COMMA "Optional comma separator (',')" %token T_FORWARD_SLASH "forward slash ('/')" %token T_PERCENT "Percent sign ('%')" @@ -239,8 +237,8 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %token T_LIST_CLOSE "List close (']')" %token T_MODIFIER_ADD "Add ('+')" -%token T_MODIFIER_SUBTRACT "Subtract ('-')" %token T_MODIFIER_MULTIPLY "Multiply ('*')" +%token T_MODIFIER_MODULO "Modulo ('modulo')" %token T_MODIFIER_MAX "Max ('max')" %token T_MODIFIER_MIN "Min ('min')" @@ -257,7 +255,6 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %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 ( '* { ... }')" %token T_CONFIGURATION "Configuration block" %token T_RESET_THEME "Reset Theme" @@ -266,13 +263,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %token T_INHERIT "Inherit" -%token T_MEDIA_WIDTH "Width" -%token T_MEDIA_HEIGHT "Height" - -%token T_MEDIA_MIN "Min" -%token T_MEDIA_MONITOR_ID "Monitor-ID" -%token T_MEDIA_MAX "Max" -%token T_MEDIA_SEP "-" +%token T_MIN "-" %token T_VAR_START "var" @@ -313,6 +304,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %type t_property_orientation %type t_property_cursor %type t_name_prefix_optional +%type t_property_number %start t_main %% @@ -390,21 +382,7 @@ t_entry_list T_CONFIGURATION T_BOPEN t_config_property_list_optional T_BCLOSE { g_hash_table_destroy ( $4 ); } } -| t_entry_list T_MEDIA T_PARENT_LEFT T_MEDIA_TYPE T_PSEP T_INT T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE { - gchar *name = g_strdup_printf("@media ( %s: %d )",$4, $6); - ThemeWidget *widget = rofi_theme_find_or_create_name ( $1, name ); - widget->set = TRUE; - widget->media = g_slice_new0(ThemeMedia); - widget->media->type = rofi_theme_parse_media_type ( $4 ); - widget->media->value = (double)$6; - for ( unsigned int i = 0; i < $9->num_widgets; i++ ) { - ThemeWidget *d = $9->widgets[i]; - rofi_theme_parse_merge_widgets(widget, d); - } - g_free ( $4 ); - g_free ( name ); -} -| t_entry_list T_MEDIA T_PARENT_LEFT T_MEDIA_TYPE T_PSEP T_DOUBLE T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE { +| t_entry_list T_MEDIA T_PARENT_LEFT T_MEDIA_TYPE T_PSEP t_property_number T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE { gchar *name = g_strdup_printf("@media ( %s: %f )",$4, $6); ThemeWidget *widget = rofi_theme_find_or_create_name ( $1, name ); widget->set = TRUE; @@ -577,6 +555,14 @@ t_property_element $$ = rofi_theme_property_create ( P_DOUBLE ); $$->value.f = $1; } +| T_MIN T_INT { + $$ = rofi_theme_property_create ( P_INTEGER ); + $$->value.i = -$2; + } +| T_MIN T_DOUBLE { + $$ = rofi_theme_property_create ( P_DOUBLE ); + $$->value.f = -$2; + } | T_STRING { $$ = rofi_theme_property_create ( P_STRING ); $$->value.s = $1; @@ -771,8 +757,8 @@ t_property_highlight_style t_property_distance_zero -: T_INT t_property_line_style { - $$.base.distance = (double) $1; +: t_property_number t_property_line_style { + $$.base.distance = $1; $$.base.type = ROFI_PU_PX; $$.base.left = NULL; $$.base.right = NULL; @@ -784,7 +770,7 @@ t_property_distance_zero /** Distance. */ t_property_distance_unit -: T_INT t_property_unit { +: t_property_number t_property_unit { $$ = g_slice_new0(RofiDistanceUnit); $$->distance = (double)$1; $$->type = $2; @@ -792,7 +778,7 @@ t_property_distance_unit $$->right = NULL; $$->modtype = ROFI_DISTANCE_MODIFIER_NONE; } -| T_INT { +| t_property_number { $$ = g_slice_new0(RofiDistanceUnit); $$->distance = (double)$1; $$->type = ROFI_PU_PX; @@ -800,14 +786,6 @@ t_property_distance_unit $$->right = NULL; $$->modtype = ROFI_DISTANCE_MODIFIER_NONE; } -| T_DOUBLE t_property_unit { - $$ = g_slice_new0(RofiDistanceUnit); - $$->distance = (double)$1; - $$->type = $2; - $$->left = NULL; - $$->right = NULL; - $$->modtype = ROFI_DISTANCE_MODIFIER_NONE; -} | T_PARENT_LEFT t_property_distance_unit_math3 T_PARENT_RIGHT { $$ = g_slice_new0(RofiDistanceUnit); $$->distance = 0; @@ -834,7 +812,7 @@ t_property_distance_unit_math $$->right = $3; $$->modtype = ROFI_DISTANCE_MODIFIER_DIVIDE; } -| t_property_distance_unit_math T_PERCENT t_property_distance_unit { +| t_property_distance_unit_math T_MODIFIER_MODULO t_property_distance_unit { $$ = g_slice_new0(RofiDistanceUnit); $$->left = $1; $$->right = $3; @@ -853,7 +831,7 @@ t_property_distance_unit_math2 $$->right = $3; $$->modtype = ROFI_DISTANCE_MODIFIER_ADD; } -| t_property_distance_unit_math2 T_MODIFIER_SUBTRACT t_property_distance_unit_math { +| t_property_distance_unit_math2 T_MIN t_property_distance_unit_math { $$ = g_slice_new0(RofiDistanceUnit); $$->left = $1; $$->right = $3; @@ -901,23 +879,14 @@ t_property_distance_unit_math3 t_property_distance /** Integer unit and line style */ -: T_INT t_property_unit t_property_line_style { - $$.base.distance = (double)$1; +: t_property_number t_property_unit t_property_line_style { + $$.base.distance = $1; $$.base.type = $2; $$.base.left = NULL; $$.base.right = NULL; $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE; $$.style = $3; } -/** Double unit and line style */ -| T_DOUBLE t_property_unit t_property_line_style { - $$.base.distance = (double)$1; - $$.base.type = $2; - $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE; - $$.base.left = NULL; - $$.base.right = NULL; - $$.style = $3; -} | T_CALC T_PARENT_LEFT t_property_distance_unit_math3 T_PARENT_RIGHT t_property_line_style { $$.base.distance = 0; $$.base.type = ROFI_PU_PX; @@ -927,6 +896,11 @@ t_property_distance $$.style = $5; }; +t_property_number +: T_INT { $$ = (double) $1; } +| T_DOUBLE { $$ = $1; } +| T_MIN t_property_number { $$ = -(double)$2; } + /** distance unit. px, em, % */ t_property_unit : T_UNIT_PX { $$ = ROFI_PU_PX; } diff --git a/source/theme.c b/source/theme.c index c467fd77..984e10a8 100644 --- a/source/theme.c +++ b/source/theme.c @@ -285,7 +285,7 @@ static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit) { } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MULTIPLY) { fputs(" * ", stdout); } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MODULO) { - fputs(" % ", stdout); + fputs(" modulo ", stdout); } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MIN) { fputs(" min ", stdout); } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MAX) { @@ -1336,8 +1336,8 @@ RofiHighlightColorStyle rofi_theme_get_highlight(widget *widget, } return rofi_theme_get_highlight_inside(p, widget, property, th); } -static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori) { - int val = unit->distance; +static double get_pixels(RofiDistanceUnit *unit, RofiOrientation ori) { + double val = unit->distance; if (unit->type == ROFI_PU_EM) { val = unit->distance * textbox_get_estimated_char_height(); @@ -1359,7 +1359,7 @@ static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori) { return val; } -static int distance_unit_get_pixel(RofiDistanceUnit *unit, +static double distance_unit_get_pixel(RofiDistanceUnit *unit, RofiOrientation ori) { switch (unit->modtype) { case ROFI_DISTANCE_MODIFIER_GROUP: @@ -1375,45 +1375,45 @@ static int distance_unit_get_pixel(RofiDistanceUnit *unit, return distance_unit_get_pixel(unit->left, ori) * distance_unit_get_pixel(unit->right, ori); case ROFI_DISTANCE_MODIFIER_DIVIDE: { - int a = distance_unit_get_pixel(unit->left, ori); - int b = distance_unit_get_pixel(unit->right, ori); + double a = distance_unit_get_pixel(unit->left, ori); + double b = distance_unit_get_pixel(unit->right, ori); if (b != 0) { return a / b; } return a; } case ROFI_DISTANCE_MODIFIER_MODULO: { - int a = distance_unit_get_pixel(unit->left, ori); - int b = distance_unit_get_pixel(unit->right, ori); + double a = distance_unit_get_pixel(unit->left, ori); + double b = distance_unit_get_pixel(unit->right, ori); if (b != 0) { - return a % b; + return fmod(a, b); } return 0; } case ROFI_DISTANCE_MODIFIER_MIN: { - int a = distance_unit_get_pixel(unit->left, ori); - int b = distance_unit_get_pixel(unit->right, ori); + double a = distance_unit_get_pixel(unit->left, ori); + double b = distance_unit_get_pixel(unit->right, ori); return MIN(a, b); } case ROFI_DISTANCE_MODIFIER_MAX: { - int a = distance_unit_get_pixel(unit->left, ori); - int b = distance_unit_get_pixel(unit->right, ori); + double a = distance_unit_get_pixel(unit->left, ori); + double b = distance_unit_get_pixel(unit->right, ori); return MAX(a, b); } case ROFI_DISTANCE_MODIFIER_ROUND: { double a = (double)distance_unit_get_pixel(unit->left, ori); double b = (double)distance_unit_get_pixel(unit->right, ori); - return (int)(round(a / b) * b); + return (double)(round(a / b) * b); } case ROFI_DISTANCE_MODIFIER_CEIL: { double a = (double)distance_unit_get_pixel(unit->left, ori); double b = (double)distance_unit_get_pixel(unit->right, ori); - return (int)(ceil(a / b) * b); + return (double)(ceil(a / b) * b); } case ROFI_DISTANCE_MODIFIER_FLOOR: { double a = (double)distance_unit_get_pixel(unit->left, ori); double b = (double)distance_unit_get_pixel(unit->right, ori); - return (int)(floor(a / b) * b); + return (double)(floor(a / b) * b); } default: break; diff --git a/test/theme-parser-test.c b/test/theme-parser-test.c index 527eec2c..f44bf73c 100644 --- a/test/theme-parser-test.c +++ b/test/theme-parser-test.c @@ -1456,7 +1456,7 @@ START_TEST(test_prepare_math_modulo) { widget wid; wid.name = "window"; wid.state = ""; - rofi_theme_parse_string("window { width: calc( 255 % 4 % 3 % );}"); + rofi_theme_parse_string("window { width: calc( 255 modulo 4 modulo 5 );}"); ck_assert_ptr_nonnull(rofi_theme); // ck_assert_ptr_null ( rofi_theme->widgets ); ck_assert_ptr_null(rofi_theme->properties); @@ -1499,6 +1499,143 @@ START_TEST(test_prepare_math_max) { ck_assert_int_eq(dist, 256); } END_TEST + +START_TEST(test_prepare_math_failure) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc( 1/2 * 500 );}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, 250); +} +END_TEST + +START_TEST(test_prepare_math_failure2) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc( -16/2 * 1.5 );}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, -12); +} +END_TEST +START_TEST(test_prepare_math_failure3) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc(10+3);}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, 13); +} +END_TEST +START_TEST(test_prepare_math_failure4) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc(10.0+3.2);}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, 13); +} +END_TEST +START_TEST(test_prepare_math_failure5) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc(10-3);}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, 7); +} +END_TEST +START_TEST(test_prepare_math_failure6) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc(10.0-3.2);}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, 6); +} +END_TEST +START_TEST(test_prepare_math_failure7) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc(-10--3);}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, -7); +} +END_TEST +START_TEST(test_prepare_math_failure8) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: calc(-10.0--3.2);}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, -6); +} +END_TEST +START_TEST(test_prepare_math_failure9) { + widget wid; + wid.name = "window"; + wid.state = ""; + rofi_theme_parse_string("window { width: -128;}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + RofiDistance l = rofi_theme_get_distance(&wid, "width", 0); + int dist = distance_get_pixel(l, ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq(dist, -128); +} +END_TEST START_TEST(test_prepare_default) { rofi_theme_parse_string("@import \"default\""); @@ -1739,6 +1876,15 @@ static Suite *theme_parser_suite(void) { tcase_add_test(tc_prepare_math, test_prepare_math_round); tcase_add_test(tc_prepare_math, test_prepare_math_min); tcase_add_test(tc_prepare_math, test_prepare_math_max); + tcase_add_test(tc_prepare_math, test_prepare_math_failure); + tcase_add_test(tc_prepare_math, test_prepare_math_failure2); + tcase_add_test(tc_prepare_math, test_prepare_math_failure3); + tcase_add_test(tc_prepare_math, test_prepare_math_failure4); + tcase_add_test(tc_prepare_math, test_prepare_math_failure5); + tcase_add_test(tc_prepare_math, test_prepare_math_failure6); + tcase_add_test(tc_prepare_math, test_prepare_math_failure7); + tcase_add_test(tc_prepare_math, test_prepare_math_failure8); + tcase_add_test(tc_prepare_math, test_prepare_math_failure9); suite_add_tcase(s, tc_prepare_math); } return s; -- cgit v1.2.3 From f6248c6ea9f3243986798f8fb1b48fb582d64517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Na=C3=AFm=20Favier?= Date: Thu, 16 Feb 2023 19:34:24 +0100 Subject: More Unicode normalization with `-normalize-match` (#1813) Normalize the string to a fully decomposed form, then filter out mark/accent characters. --- source/helper.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/source/helper.c b/source/helper.c index 4b14f361..a84a7d9e 100644 --- a/source/helper.c +++ b/source/helper.c @@ -175,30 +175,25 @@ static gchar *prefix_regex(const char *input) { return retv; } -static char *utf8_helper_simplify_string(const char *s) { - gunichar buf2[G_UNICHAR_MAX_DECOMPOSITION_LENGTH] = { - 0, - }; +static char *utf8_helper_simplify_string(const char *os) { char buf[6] = { 0, }; - // Compose the string in maximally composed form. + + // Normalize the string to a fully decomposed form, then filter out mark/accent characters. + char *s = g_utf8_normalize(os, -1, G_NORMALIZE_ALL); ssize_t str_size = (g_utf8_strlen(s, -1) * 6 + 2 + 1) * sizeof(char); char *str = g_malloc0(str_size); char *striter = str; for (const char *iter = s; iter && *iter; iter = g_utf8_next_char(iter)) { gunichar uc = g_utf8_get_char(iter); - int l = 0; - gsize dl = g_unichar_fully_decompose(uc, FALSE, buf2, - G_UNICHAR_MAX_DECOMPOSITION_LENGTH); - if (dl) { - l = g_unichar_to_utf8(buf2[0], buf); - } else { - l = g_unichar_to_utf8(uc, buf); + if (!g_unichar_ismark(uc)) { + int l = g_unichar_to_utf8(uc, buf); + memcpy(striter, buf, l); + striter += l; } - memcpy(striter, buf, l); - striter += l; } + g_free(s); return str; } -- cgit v1.2.3