On 3/18/21 4:46 AM, Martin Liška wrote:
Hey.

Recently, I noticed a cumbersome construct we use for string startswith function
(most notably in a situation when the prefix is a string literal).

Commonly used patterns are:
1) strncmp (arg, "--sysroot=", 10) == 0
2) strncmp (name, "not found", sizeof ("not found") - 1) == 0
3) strncmp (varname, "__builtin_", strlen ("__builtin_")) == 0
4) #define STR "-foffload-abi="
    if (strncmp (argv[i], STR, strlen (STR)) == 0)

I see all these quite error prone for the following reasons:
1) one needs to correctly calculate string length (in their head)
2) sizeof ("foo") - 1 == strlen ("foo")

Right.  They could be alleviated by either developing a new warning
or extending -Wstring-compare to complain when the length of a string
literal argument isn't the same as the bound in these cases.

3) one needs to undefine a temporary macros

Moreover, there are helper functions that already do the same:

gcc/ada/adadecode.c:
static int
has_prefix (const char *name, const char *prefix)
{
   return strncmp (name, prefix, strlen (prefix)) == 0;
}

gcc/fortran/gfortran.h:
#define gfc_str_startswith(str, pref) \
        (strncmp ((str), (pref), strlen (pref)) == 0)

That said, I'm suggesting a new function 'startswith' in system.h.
I prepared a patch that utilizes the function in gcc/ subfolder
(excluding all target code for now). I can prepare similar mechanical
patch for the rest of the compiler (and run-time libraries).

Thoughts?
Thanks,
Martin

I like it.

...
diff --git a/gcc/system.h b/gcc/system.h
index a3f5948aaee..3e384616d3a 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1291,4 +1291,12 @@ void gcc_stablesort (void *, size_t, size_t,
  #define NULL nullptr
  #endif

+/* Return 1 if STR string starts with PREFIX.  */
+
+static inline int
+startswith (const char *str, const char *prefix)
+{
+  return strncmp (str, prefix, strlen (prefix)) == 0;
+}

The return type of the function should be bool rather than int.

Martin

Reply via email to