This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Neels Hofmeyr gerrit-no-reply at lists.osmocom.orgNeels Hofmeyr has uploaded this change for review. ( https://gerrit.osmocom.org/13394 Change subject: add osmo_str_startswith() ...................................................................... add osmo_str_startswith() Move from a static implementation in tdef_vty.c to utils.c, I also want to use this in osmo-msc. The point is that the telnet VTY allows unambiguous partly matches of keyword args. For example, if I have a command definition of: compare (apples|oranges) then it is perfectly legal as for the vty parser to write only compare app One could expect the VTY to then pass the unambiguous match of "apples" to the parsing function, but that is not the case. Hence a VTY function implementation is faced with parsing a keyword of "app" instead of the expected "apples". This is actually a very widespread bug in our VTY implementations, which assume that exactly one full keyword will always be found. I am now writing new commands in a way that are able to manage only the starts of keywords. Arguably, strstr(a, b) == a does the same thing, but it searches the entire string unnecessarily. Change-Id: Ib2ffb0e9a870dd52e081c7e66d8818057d159513 --- M include/osmocom/core/utils.h M src/utils.c M src/vty/tdef_vty.c M tests/utils/utils_test.c M tests/utils/utils_test.ok 5 files changed, 60 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/94/13394/1 diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index 16159d3..31ef49b 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -230,4 +230,6 @@ #define OSMO_STRBUF_PRINTF(STRBUF, fmt, args...) \ OSMO_STRBUF_APPEND(STRBUF, snprintf, fmt, ##args) +bool osmo_str_startswith(const char *str, const char *startswith_str); + /*! @} */ diff --git a/src/utils.c b/src/utils.c index 2d5bcb0..fb4e71e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -826,4 +826,18 @@ return (sum * 9) % 10 + '0'; } +/*! Compare start of a string. + * This is an optimisation of 'strstr(str, startswith_str) == str' because it doesn't search through the entire string. + * \param str (Longer) string to compare. + * \param startswith_str (Shorter) string to compare with the start of str. + * \return true iff the first characters of str fully match startswith_str or startswith_str is empty. */ +bool osmo_str_startswith(const char *str, const char *startswith_str) +{ + if (!startswith_str || !*startswith_str) + return true; + if (!str) + return false; + return strncmp(str, startswith_str, strlen(startswith_str)) == 0; +} + /*! @} */ diff --git a/src/vty/tdef_vty.c b/src/vty/tdef_vty.c index 28de21a..0dac2bf 100644 --- a/src/vty/tdef_vty.c +++ b/src/vty/tdef_vty.c @@ -247,16 +247,6 @@ /*! Singleton Tnnn groups definition as set by osmo_tdef_vty_groups_init(). */ static struct osmo_tdef_group *global_tdef_groups; -/*! \return true iff the first characters of str fully match startswith_str or both are empty. */ -static bool startswith(const char *str, const char *startswith_str) -{ - if (!startswith_str) - return true; - if (!str) - return false; - return strncmp(str, startswith_str, strlen(startswith_str)) == 0; -} - DEFUN(show_timer, show_timer_cmd, "DYNAMIC", "DYNAMIC") /* show timer [(alpha|beta|gamma)] [TNNNN] */ { @@ -268,7 +258,7 @@ * like "softw" or "t" (which can also be ambiguous). */ osmo_tdef_groups_for_each(g, global_tdef_groups) { - if (!group_arg || startswith(g->name, group_arg)) + if (!group_arg || osmo_str_startswith(g->name, group_arg)) osmo_tdef_vty_show_cmd(vty, g->tdefs, T_arg, "%s: ", g->name); } return CMD_SUCCESS; diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c index d592fe0..9d36c5a 100644 --- a/tests/utils/utils_test.c +++ b/tests/utils/utils_test.c @@ -1022,6 +1022,33 @@ printf("(need %d chars, had size=63) %s\n", rc, buf); } +static void startswith_test_str(const char *str, const char *startswith_str, bool expect_rc) +{ + bool rc = osmo_str_startswith(str, startswith_str); + printf("osmo_str_startswith(%s, ", osmo_quote_str(str, -1)); + printf("%s) == %s\n", osmo_quote_str(startswith_str, -1), rc ? "true" : "false"); + if (rc != expect_rc) + printf(" ERROR: EXPECTED %s\n", expect_rc ? "true" : "false"); +} + +static void startswith_test() +{ + printf("\n%s()\n", __func__); + startswith_test_str(NULL, NULL, true); + startswith_test_str("", NULL, true); + startswith_test_str(NULL, "", true); + startswith_test_str("", "", true); + startswith_test_str("abc", NULL, true); + startswith_test_str("abc", "", true); + startswith_test_str(NULL, "abc", false); + startswith_test_str("", "abc", false); + startswith_test_str("abc", "a", true); + startswith_test_str("abc", "ab", true); + startswith_test_str("abc", "abc", true); + startswith_test_str("abc", "abcd", false); + startswith_test_str("abc", "xyz", false); +} + int main(int argc, char **argv) { static const struct log_info log_info = {}; @@ -1040,5 +1067,6 @@ osmo_sockaddr_to_str_and_uint_test(); osmo_str_tolowupper_test(); strbuf_test(); + startswith_test(); return 0; } diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok index 1215ddd..3579062 100644 --- a/tests/utils/utils_test.ok +++ b/tests/utils/utils_test.ok @@ -342,3 +342,18 @@ (need 134 chars) T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! (need 134 chars, had size=63) T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7 + +startswith_test() +osmo_str_startswith(NULL, NULL) == true +osmo_str_startswith("", NULL) == true +osmo_str_startswith(NULL, "") == true +osmo_str_startswith("", "") == true +osmo_str_startswith("abc", NULL) == true +osmo_str_startswith("abc", "") == true +osmo_str_startswith(NULL, "abc") == false +osmo_str_startswith("", "abc") == false +osmo_str_startswith("abc", "a") == true +osmo_str_startswith("abc", "ab") == true +osmo_str_startswith("abc", "abc") == true +osmo_str_startswith("abc", "abcd") == false +osmo_str_startswith("abc", "xyz") == false -- To view, visit https://gerrit.osmocom.org/13394 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: Ib2ffb0e9a870dd52e081c7e66d8818057d159513 Gerrit-Change-Number: 13394 Gerrit-PatchSet: 1 Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190324/1512c687/attachment.htm>