diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 62794c58e..d91d8d52d 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -31,6 +31,7 @@ New features:: * core: add option `-s` in command `/command` to execute multiple commands separated by semicolons * core: allow case insensitive search of partial buffer name with `(?i)name` in command `/buffer` * core: use function util_strftimeval in evaluation of expression `date:xxx` + * api: return `-1` or `1` if one input string is NULL and not the other in string comparison functions * api: allow search by group and nick id in functions nicklist_search_group and nicklist_search_nick (issue #2081) * api: allow search by buffer id in function buffer_search (issue #2081) * api: add modifier "color_decode" to decode WeeChat colors with a replacement string diff --git a/src/core/core-string.c b/src/core/core-string.c index 8e9917b96..2c46e1d33 100644 --- a/src/core/core-string.c +++ b/src/core/core-string.c @@ -621,6 +621,12 @@ string_strcmp (const char *string1, const char *string2) { int diff; + if (!string1 && string2) + return -1; + + if (string1 && !string2) + return 1; + while (string1 && string1[0] && string2 && string2[0]) { diff = string_charcmp (string1, string2); @@ -649,6 +655,12 @@ string_strncmp (const char *string1, const char *string2, int max) { int count, diff; + if (!string1 && string2) + return -1; + + if (string1 && !string2) + return 1; + count = 0; while ((count < max) && string1 && string1[0] && string2 && string2[0]) { @@ -683,6 +695,12 @@ string_strcasecmp (const char *string1, const char *string2) { int diff; + if (!string1 && string2) + return -1; + + if (string1 && !string2) + return 1; + while (string1 && string1[0] && string2 && string2[0]) { diff = string_charcasecmp (string1, string2); @@ -721,6 +739,12 @@ string_strcasecmp_range (const char *string1, const char *string2, int range) { int diff; + if (!string1 && string2) + return -1; + + if (string1 && !string2) + return 1; + while (string1 && string1[0] && string2 && string2[0]) { diff = string_charcasecmp_range (string1, string2, range); @@ -750,6 +774,12 @@ string_strncasecmp (const char *string1, const char *string2, int max) { int count, diff; + if (!string1 && string2) + return -1; + + if (string1 && !string2) + return 1; + count = 0; while ((count < max) && string1 && string1[0] && string2 && string2[0]) { @@ -794,6 +824,12 @@ string_strncasecmp_range (const char *string1, const char *string2, int max, { int count, diff; + if (!string1 && string2) + return -1; + + if (string1 && !string2) + return 1; + count = 0; while ((count < max) && string1 && string1[0] && string2 && string2[0]) { @@ -830,6 +866,12 @@ string_strcmp_ignore_chars (const char *string1, const char *string2, { int diff; + if (!string1 && string2) + return -1; + + if (string1 && !string2) + return 1; + while (string1 && string1[0] && string2 && string2[0]) { /* skip ignored chars */ diff --git a/tests/unit/core/test-core-string.cpp b/tests/unit/core/test-core-string.cpp index 73750c0ab..fe4c2eccd 100644 --- a/tests/unit/core/test-core-string.cpp +++ b/tests/unit/core/test-core-string.cpp @@ -607,8 +607,12 @@ TEST(CoreString, StringComparison) { /* case-sensitive comparison */ LONGS_EQUAL(0, string_strcmp (NULL, NULL)); - LONGS_EQUAL(-97, string_strcmp (NULL, "abc")); - LONGS_EQUAL(97, string_strcmp ("abc", NULL)); + LONGS_EQUAL(-1, string_strcmp (NULL, "")); + LONGS_EQUAL(1, string_strcmp ("", NULL)); + LONGS_EQUAL(-1, string_strcmp (NULL, "abc")); + LONGS_EQUAL(1, string_strcmp ("abc", NULL)); + LONGS_EQUAL(-97, string_strcmp ("", "abc")); + LONGS_EQUAL(97, string_strcmp ("abc", "")); LONGS_EQUAL(-98, string_strcmp ("", "b")); LONGS_EQUAL(98, string_strcmp ("b", "")); LONGS_EQUAL(0, string_strcmp ("abc", "abc")); @@ -627,8 +631,12 @@ TEST(CoreString, StringComparison) /* case-sensitive comparison with max length */ LONGS_EQUAL(0, string_strncmp (NULL, NULL, 3)); - LONGS_EQUAL(-97, string_strncmp (NULL, "abc", 3)); - LONGS_EQUAL(97, string_strncmp ("abc", NULL, 3)); + LONGS_EQUAL(-1, string_strncmp (NULL, "", 3)); + LONGS_EQUAL(1, string_strncmp ("", NULL, 3)); + LONGS_EQUAL(-1, string_strncmp (NULL, "abc", 3)); + LONGS_EQUAL(1, string_strncmp ("abc", NULL, 3)); + LONGS_EQUAL(-97, string_strncmp ("", "abc", 3)); + LONGS_EQUAL(97, string_strncmp ("abc", "", 3)); LONGS_EQUAL(-98, string_strncmp ("", "b", 3)); LONGS_EQUAL(98, string_strncmp ("b", "", 3)); LONGS_EQUAL(0, string_strncmp ("abc", "abc", 3)); @@ -653,8 +661,12 @@ TEST(CoreString, StringComparison) /* case-insensitive comparison */ LONGS_EQUAL(0, string_strcasecmp (NULL, NULL)); - LONGS_EQUAL(-97, string_strcasecmp (NULL, "abc")); - LONGS_EQUAL(97, string_strcasecmp ("abc", NULL)); + LONGS_EQUAL(-1, string_strcasecmp (NULL, "")); + LONGS_EQUAL(1, string_strcasecmp ("", NULL)); + LONGS_EQUAL(-1, string_strcasecmp (NULL, "abc")); + LONGS_EQUAL(1, string_strcasecmp ("abc", NULL)); + LONGS_EQUAL(-97, string_strcasecmp ("", "abc")); + LONGS_EQUAL(97, string_strcasecmp ("abc", "")); LONGS_EQUAL(-98, string_strcasecmp ("", "b")); LONGS_EQUAL(98, string_strcasecmp ("b", "")); LONGS_EQUAL(0, string_strcasecmp ("abc", "abc")); @@ -673,8 +685,12 @@ TEST(CoreString, StringComparison) /* case-insensitive comparison with max length */ LONGS_EQUAL(0, string_strncasecmp (NULL, NULL, 3)); - LONGS_EQUAL(-97, string_strncasecmp (NULL, "abc", 3)); - LONGS_EQUAL(97, string_strncasecmp ("abc", NULL, 3)); + LONGS_EQUAL(-1, string_strncasecmp (NULL, "", 3)); + LONGS_EQUAL(1, string_strncasecmp ("", NULL, 3)); + LONGS_EQUAL(-1, string_strncasecmp (NULL, "abc", 3)); + LONGS_EQUAL(1, string_strncasecmp ("abc", NULL, 3)); + LONGS_EQUAL(-97, string_strncasecmp ("", "abc", 3)); + LONGS_EQUAL(97, string_strncasecmp ("abc", "", 3)); LONGS_EQUAL(-98, string_strncasecmp ("", "b", 3)); LONGS_EQUAL(98, string_strncasecmp ("b", "", 3)); LONGS_EQUAL(0, string_strncasecmp ("abc", "abc", 3)); @@ -699,8 +715,12 @@ TEST(CoreString, StringComparison) /* case-insensitive comparison with a range */ LONGS_EQUAL(0, string_strcasecmp_range (NULL, NULL, 30)); - LONGS_EQUAL(-97, string_strcasecmp_range (NULL, "abc", 30)); - LONGS_EQUAL(97, string_strcasecmp_range ("abc", NULL, 30)); + LONGS_EQUAL(-1, string_strcasecmp_range (NULL, "", 30)); + LONGS_EQUAL(1, string_strcasecmp_range ("", NULL, 30)); + LONGS_EQUAL(-1, string_strcasecmp_range (NULL, "abc", 30)); + LONGS_EQUAL(1, string_strcasecmp_range ("abc", NULL, 30)); + LONGS_EQUAL(-97, string_strcasecmp_range ("", "abc", 30)); + LONGS_EQUAL(97, string_strcasecmp_range ("abc", "", 30)); LONGS_EQUAL(-98, string_strcasecmp_range ("", "b", 30)); LONGS_EQUAL(98, string_strcasecmp_range ("b", "", 30)); LONGS_EQUAL(-2, string_strcasecmp_range ("A", "C", 30)); @@ -727,8 +747,12 @@ TEST(CoreString, StringComparison) /* case-insensitive comparison with max length and a range */ LONGS_EQUAL(0, string_strncasecmp_range (NULL, NULL, 3, 30)); - LONGS_EQUAL(-97, string_strncasecmp_range (NULL, "abc", 3, 30)); - LONGS_EQUAL(97, string_strncasecmp_range ("abc", NULL, 3, 30)); + LONGS_EQUAL(-1, string_strncasecmp_range (NULL, "", 3, 30)); + LONGS_EQUAL(1, string_strncasecmp_range ("", NULL, 3, 30)); + LONGS_EQUAL(-1, string_strncasecmp_range (NULL, "abc", 3, 30)); + LONGS_EQUAL(1, string_strncasecmp_range ("abc", NULL, 3, 30)); + LONGS_EQUAL(-97, string_strncasecmp_range ("", "abc", 3, 30)); + LONGS_EQUAL(97, string_strncasecmp_range ("abc", "", 3, 30)); LONGS_EQUAL(-98, string_strncasecmp_range ("", "b", 3, 30)); LONGS_EQUAL(98, string_strncasecmp_range ("b", "", 3, 30)); LONGS_EQUAL(-2, string_strncasecmp_range ("ABC", "CCC", 3, 30)); @@ -761,8 +785,12 @@ TEST(CoreString, StringComparison) /* comparison with chars ignored */ LONGS_EQUAL(0, string_strcmp_ignore_chars (NULL, NULL, "", 0)); - LONGS_EQUAL(-97, string_strcmp_ignore_chars (NULL, "abc", "", 0)); - LONGS_EQUAL(97, string_strcmp_ignore_chars ("abc", NULL, "", 0)); + LONGS_EQUAL(-1, string_strcmp_ignore_chars (NULL, "", "", 0)); + LONGS_EQUAL(1, string_strcmp_ignore_chars ("", NULL, "", 0)); + LONGS_EQUAL(-1, string_strcmp_ignore_chars (NULL, "abc", "", 0)); + LONGS_EQUAL(1, string_strcmp_ignore_chars ("abc", NULL, "", 0)); + LONGS_EQUAL(-97, string_strcmp_ignore_chars ("", "abc", "", 0)); + LONGS_EQUAL(97, string_strcmp_ignore_chars ("abc", "", "", 0)); LONGS_EQUAL(-98, string_strcmp_ignore_chars ("", "b", "", 0)); LONGS_EQUAL(98, string_strcmp_ignore_chars ("b", "", "", 0)); LONGS_EQUAL(-2, string_strcmp_ignore_chars ("ABC", "CCC", "", 0));