]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
kern/misc: Implement grub_strtok()
authorAlec Brown <alec.r.brown@oracle.com>
Tue, 12 Aug 2025 03:45:32 +0000 (03:45 +0000)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 4 Sep 2025 12:37:20 +0000 (14:37 +0200)
Add the functions grub_strtok() and grub_strtok_r() to help parse strings into
tokens separated by characters in the "delim" parameter. These functions are
present in gnulib but calling them directly from the gnulib code is quite
challenging since the call "#include <string.h>" would include the header file
grub-core/lib/posix_wrap/string.h instead of grub-core/lib/gnulib/string.h,
where strtok() and strtok_r() are declared. Since this overlap is quite
problematic, the simpler solution was to implement the code in the GRUB based
on gnulib's implementation. For more information on these functions, visit the
Linux Programmer's Manual, man strtok.

Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/kern/misc.c
include/grub/misc.h

index 2b79223935b37c0a877b4718a7eef97229dcb069..258f918935cc4f959f98dd31cf7f3fe8ab369969 100644 (file)
@@ -401,6 +401,68 @@ grub_strword (const char *haystack, const char *needle)
   return 0;
 }
 
+char *
+grub_strtok_r (char *s, const char *delim, char **save_ptr)
+{
+  char *token;
+  const char *c;
+  bool is_delim;
+
+  if (s == NULL)
+    s = *save_ptr;
+
+  /* Scan leading delimiters. */
+  while (*s != '\0')
+    {
+      is_delim = false;
+      for (c = delim; *c != '\0'; c++)
+       {
+         if (*s == *c)
+           {
+             is_delim = true;
+             break;
+           }
+       }
+      if (is_delim == true)
+       s++;
+      else
+       break;
+    }
+
+  if (*s == '\0')
+    {
+      *save_ptr = s;
+      return NULL;
+    }
+
+  /* Find the end of the token. */
+  token = s;
+  while (*s != '\0')
+    {
+      for (c = delim; *c != '\0'; c++)
+       {
+         if (*s == *c)
+           {
+             *s = '\0';
+             *save_ptr = s + 1;
+             return token;
+           }
+       }
+      s++;
+    }
+
+  *save_ptr = s;
+  return token;
+}
+
+char *
+grub_strtok (char *s, const char *delim)
+{
+  static char *last;
+
+  return grub_strtok_r (s, delim, &last);
+}
+
 int
 grub_isspace (int c)
 {
index e087e7b3e85b384a3e2152e637c8148de0829c6b..9522d7305a29260cd5f6768ed399e80b313f9a08 100644 (file)
@@ -126,6 +126,9 @@ char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
 char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
 int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
 
+char *EXPORT_FUNC(grub_strtok_r) (char *s, const char *delim, char **save_ptr);
+char *EXPORT_FUNC(grub_strtok) (char *s, const char *delim);
+
 /* Copied from gnulib.
    Written by Bruno Haible <bruno@clisp.org>, 2005. */
 static inline char *