diff mbox series

[iproute2-next,v2,5/5] lib: utils: Have parse_one_of() warn about prefix matches

Message ID f34f1c20dafd61fae337e98ae71a6e8a7889d5eb.1700666420.git.petrm@nvidia.com (mailing list archive)
State Accepted
Commit bd5226437a4c73404a0e50e419f1cd055b032a74
Delegated to: David Ahern
Headers show
Series Change parsing in parse_one_of(), parse_on_off() | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Petr Machata Nov. 22, 2023, 3:23 p.m. UTC
The function parse_one_of() currently uses matches() for string comparison
under the hood. Extending matches()-based parsers is tricky, because newly
added matches might change the way strings are parsed, if the newly-added
string shares a prefix with a string that is matched later in the code.

Therefore in this patch, add a twist to parse_one_of() that partial prefix
matches yield a warning. This will not disturb standard output or the
overall behavior, but will make it obvious that the usage is discouraged
and prompt users to update their scripts and habits.

An example of output:

    # dcb ets set dev swp1 tc-tsa 0:s
    WARNING: 's' matches 'strict' by prefix.
    Matching by prefix is deprecated in this context, please use the full string.

Signed-off-by: Petr Machata <petrm@nvidia.com>
---
 lib/utils.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/lib/utils.c b/lib/utils.c
index 9142dc1d..599e859e 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -887,6 +887,23 @@  int matches(const char *prefix, const char *string)
 	return *prefix;
 }
 
+static int matches_warn(const char *prefix, const char *string)
+{
+	int rc;
+
+	rc = matches(prefix, string);
+	if (rc)
+		return rc;
+
+	if (strlen(prefix) != strlen(string))
+		fprintf(stderr,
+			"WARNING: '%s' matches '%s' by prefix.\n"
+			"Matching by prefix is deprecated in this context, please use the full string.\n",
+			prefix, string);
+
+	return 0;
+}
+
 int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
 {
 	const __u32 *a1 = a->data;
@@ -1755,7 +1772,7 @@  __parse_one_of(const char *msg, const char *realval,
 int parse_one_of(const char *msg, const char *realval, const char * const *list,
 		 size_t len, int *p_err)
 {
-	return __parse_one_of(msg, realval, list, len, p_err, matches);
+	return __parse_one_of(msg, realval, list, len, p_err, matches_warn);
 }
 
 int parse_one_of_deprecated(const char *msg, const char *realval,