From: Steven Rostedt <rostedt@goodmis.org>
To: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Joe Perches <joe@perches.com>,
Andreas Schwab <schwab@linux-m68k.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Linux List Kernel Mailing <linux-kernel@vger.kernel.org>,
Ingo Molnar <mingo@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Namhyung Kim <namhyung@kernel.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Tom Zanussi <zanussi@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: [for-next][PATCH 23/24] string.h: Add strncmp_prefix() helper macro
Date: Sun, 23 Dec 2018 19:05:44 -0500 [thread overview]
Message-ID: <20181223190544.6112f598@gandalf.local.home> (raw)
In-Reply-To: <4daf3688-ea36-627a-cd8a-8f9bc6cabc56@rasmusvillemoes.dk>
On Mon, 24 Dec 2018 00:52:13 +0100
Rasmus Villemoes <linux@rasmusvillemoes.dk> wrote:
> On 23/12/2018 23.56, Steven Rostedt wrote:
> > On Sun, 23 Dec 2018 23:01:52 +0100
> > Rasmus Villemoes <linux@rasmusvillemoes.dk> wrote:
> >
> >> On 21/12/2018 23.20, Joe Perches wrote:
> >>>
> >>> Using
> >>>
> >>> static inline bool str_has_prefix(const char *str, const char prefix[])
> >>> {
> >>> return !strncmp(str, prefix, strlen(prefix));
> >>> }
> >>>
> >>
> >> We already have exactly that function, it's called strstarts().
> >
> > It's not exact.
>
> Huh? The str_has_prefix() I quoted is exactly strstarts().
The the implemented str_has_prefix() that you replied to is:
+/*
+ * A common way to test a prefix of a string is to do:
+ * strncmp(str, prefix, sizeof(prefix) - 1)
+ *
+ * But this can lead to bugs due to typos, or if prefix is a pointer
+ * and not a constant. Instead use strncmp_prefix().
+ */
+#define strncmp_prefix(str, prefix) \
+ ({ \
+ int ____strcmp_prefix_ret____; \
+ if (__builtin_constant_p(&prefix)) { \
+ ____strcmp_prefix_ret____ = \
+ strncmp(str, prefix, sizeof(prefix) - 1); \
+ } else { \
+ typeof(prefix) ____strcmp_prefix____ = prefix; \
+ ____strcmp_prefix_ret____ = \
+ strncmp(str, ____strcmp_prefix____, \
+ strlen(____strcmp_prefix____)); \
+ } \
+ ____strcmp_prefix_ret____; \
+ })
+
Note, this has turned into a nice function:
http://lkml.kernel.org/r/20181222162856.518489380@goodmis.org
+/**
+ * str_has_prefix - Test if a string has a given prefix
+ * @str: The string to test
+ * @prefix: The string to see if @str starts with
+ *
+ * A common way to test a prefix of a string is to do:
+ * strncmp(str, prefix, sizeof(prefix) - 1)
+ *
+ * But this can lead to bugs due to typos, or if prefix is a pointer
+ * and not a constant. Instead use str_has_prefix().
+ *
+ * Returns: 0 if @str does not start with @prefix
+ strlen(@prefix) if @str does start with @prefix
+ */
+static __always_inline size_t str_has_prefix(const char *str, const char *prefix)
+{
+ size_t len = strlen(prefix);
+ return strncmp(str, prefix, len) == 0 ? len : 0;
+}
+
>
> >
> > Well, one thing that str_has_prefix() does that strstarts() does not,
> > is to return the prefix length which gets rid of the duplication.
>
> I hadn't seen the patches containing that version of str_has_prefix().
> Anyway, I just wanted to point out that strstarts() exists, so that we
> at least do not add a copy of that.
That's because you didn't read the patch that you quoted, just the
change log.
>
> > Would it be OK to convert strstarts() to return the length of prefix?
>
> Dunno. By far, most users of the strncmp() idiom only seem to be
> interested in the boolean result. It's true that there are some that
> then want to skip the prefix and do further parsing, and I can see how
> avoiding duplicating the prefix length is useful. But the mathematician
> in me can't help consider the corner case of 'the empty string is always
> a prefix of any other string', and having str_has_prefix(str, "") be
> false seems wrong - obviously, nobody would ever use a literal "" there,
> but nothing in str_has_prefix() _requires_ the prefix to be a constant.
Which would be a useless use case. And if you define that it returns
the length of prefix on return, then it both matches and doesn't
match ;-)
>
> Maybe 'bool str_skip_prefix(const char *s, const char *p, const char
> **out)' where *out is set to s+len on success, and set to s on failure
> (just to allow passing &s and continue parsing in elseifs)? That would
> make your 4/5 "tracing: Have the historgram use the result of
> str_has_prefix() for len of prefix" do
>
> if (str_skip_prefix(str, "onmatch(", &action_str)) {
>
> hoisting the action_str declaration to the top, replacing the len variable?
>
The use cases I've used in the final patch series uses the len for
indexing and other cases.
I think I'm keeping the str_has_prefix() and change the other users to
use it in the kernel. Most of the git grep strstarts() is tools
and scripts anyway.
-- Steve
next prev parent reply other threads:[~2018-12-24 0:05 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-21 17:56 [for-next][PATCH 00/24] tracing: Updates for the next (coming soon) merge window Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 01/24] ftrace: Allow ftrace_replace_code() to be schedulable Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 02/24] arm64: ftrace: Set FTRACE_MAY_SLEEP before ftrace_modify_all_code() Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 03/24] fgraph: Add comment to describe ftrace_graph_get_ret_stack Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 04/24] x86/ftrace: Do not call function graph from dynamic trampolines Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 05/24] powerpc/frace: Use ftrace_graph_get_ret_stack() instead of curr_ret_stack Steven Rostedt
2018-12-22 9:51 ` Michael Ellerman
2018-12-22 12:24 ` Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 06/24] sparc64: " Steven Rostedt
2018-12-21 18:24 ` David Miller
2018-12-21 19:29 ` Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 07/24] sh: ftrace: " Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 08/24] arm64: " Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 10/24] seq_buf: Use size_t for len in seq_buf_puts() Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 11/24] tracing: Fix ftrace_graph_get_ret_stack() to use task and not current Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 12/24] tracing: Remove unnecessary hist trigger struct field Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 13/24] tracing: Change strlen to sizeof for hist trigger static strings Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 14/24] tracing: Use var_refs[] for hist trigger reference checking Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 15/24] tracing: Remove open-coding of hist trigger var_ref management Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 16/24] tracing: Use hist triggers var_ref array to destroy var_refs Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 17/24] tracing: Remove hist trigger synth_var_refs Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 18/24] tracing: Add hist trigger comments for variable-related fields Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 19/24] tracing: Merge seq_print_sym_short() and seq_print_sym_offset() Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 21/24] tracing: Simplify printfing in seq_print_sym Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 23/24] string.h: Add strncmp_prefix() helper macro Steven Rostedt
2018-12-21 18:51 ` Linus Torvalds
2018-12-21 19:40 ` Steven Rostedt
2018-12-21 20:01 ` Linus Torvalds
2018-12-21 20:35 ` Steven Rostedt
2018-12-21 20:46 ` Joe Perches
2018-12-21 20:54 ` Steven Rostedt
2018-12-21 20:58 ` Andreas Schwab
2018-12-21 21:08 ` Steven Rostedt
2018-12-21 22:20 ` Joe Perches
2018-12-21 22:29 ` Linus Torvalds
2018-12-21 22:58 ` Steven Rostedt
2018-12-21 22:55 ` Steven Rostedt
2018-12-23 22:01 ` Rasmus Villemoes
2018-12-23 22:56 ` Steven Rostedt
2018-12-23 23:52 ` Rasmus Villemoes
2018-12-24 0:05 ` Steven Rostedt [this message]
2018-12-23 23:01 ` Joe Perches
2018-12-21 20:58 ` Steven Rostedt
[not found] ` <CAHk-=wjtkvFUuRNZU67KccuUKYHw=pYoDMQJ_9OVDFxOwmK9zQ@mail.gmail.com>
2018-12-21 20:55 ` Steven Rostedt
2018-12-21 22:08 ` Linus Torvalds
2018-12-21 22:48 ` Steven Rostedt
2018-12-21 22:57 ` Linus Torvalds
2018-12-21 23:03 ` Steven Rostedt
2018-12-22 10:20 ` Malcolm Priestley
2018-12-22 12:26 ` Steven Rostedt
2018-12-21 17:56 ` [for-next][PATCH 24/24] tracing: Use strncmp_prefix() helper for histogram code Steven Rostedt
[not found] ` <20181221175656.827708767@goodmis.org>
2018-12-21 18:00 ` [for-next][PATCH 09/24] seq_buf: Make seq_buf_puts() null-terminate the buffer Steven Rostedt
2018-12-21 18:05 ` Steven Rostedt
2018-12-27 5:25 ` Michael Ellerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181223190544.6112f598@gandalf.local.home \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=gregkh@linuxfoundation.org \
--cc=joe@perches.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=mhiramat@kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=schwab@linux-m68k.org \
--cc=torvalds@linux-foundation.org \
--cc=zanussi@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).