#50321, patch with g_strrstr_len etc..



This patch adds the following functions to glib:
 g_strstr_len()
 g_strrstr()
 g_strrstr_len()
 g_utf8_strchr_len()
 g_utf8_strrchr_len()
and fixes
 g_utf8_strrchr()

This closed bug #50321.

Is this ok to check in.

/ Alex

Index: gstrfuncs.c
===================================================================
RCS file: /cvs/gnome/glib/gstrfuncs.c,v
retrieving revision 1.55
diff -u -p -r1.55 gstrfuncs.c
--- gstrfuncs.c	2001/06/04 20:06:14	1.55
+++ gstrfuncs.c	2001/06/08 22:30:41
@@ -1497,3 +1497,149 @@ g_strjoin (const gchar  *separator,

   return string;
 }
+
+
+/**
+ * g_strstr_len:
+ * @haystack: a string
+ * @haystack_len: The maximum length of haystack
+ * @needle: The string to search for.
+ *
+ * Searches the string haystack for the first occurrence
+ * of the string needle, limiting the length of the search
+ * to haystack_len.
+ *
+ * Return value: A pointer to the found occurrence, or
+ * NULL if not found.
+ **/
+gchar *
+g_strstr_len (const gchar *haystack,
+	      gint         haystack_len,
+	      const gchar *needle)
+{
+  int i;
+
+  g_return_val_if_fail (haystack != NULL, NULL);
+  g_return_val_if_fail (needle != NULL, NULL);
+
+  if (haystack_len < 0)
+    return strstr (haystack, needle);
+  else
+    {
+      const char *p = haystack;
+      int needle_len = strlen (needle);
+      const char *end = haystack + haystack_len - needle_len;
+
+      if (needle_len == 0)
+	return (char *)haystack;
+
+      while (*p && p <= end)
+	{
+	  for (i = 0; i < needle_len; i++)
+	    if (p[i] != needle[i])
+	      goto next;
+
+	  return (char *)p;
+
+	next:
+	  p++;
+	}
+    }
+
+  return NULL;
+}
+
+/**
+ * g_strrstr_len:
+ * @haystack: a nul-terminated string
+ * @needle: The nul-terminated string to search for.
+ *
+ * Searches the string haystack for the last occurrence
+ * of the string needle.
+ *
+ * Return value: A pointer to the found occurrence, or
+ * NULL if not found.
+ **/
+gchar *
+g_strrstr (const gchar *haystack,
+	   const gchar *needle)
+{
+  int i;
+  int needle_len = strlen (needle);
+  int haystack_len = strlen (haystack);
+  const char *p = haystack + haystack_len - needle_len;
+
+  g_return_val_if_fail (haystack != NULL, NULL);
+  g_return_val_if_fail (needle != NULL, NULL);
+
+  if (needle_len == 0)
+    return (char *)p;
+
+  while (p >= haystack)
+    {
+      for (i = 0; i < needle_len; i++)
+	if (p[i] != needle[i])
+	  goto next;
+
+      return (char *)p;
+
+    next:
+      p--;
+    }
+
+  return NULL;
+}
+
+/**
+ * g_strrstr_len:
+ * @haystack: a nul-terminated string
+ * @haystack_len: The maximum length of haystack
+ * @needle: The nul-terminated string to search for.
+ *
+ * Searches the string haystack for the last occurrence
+ * of the string needle, limiting the length of the search
+ * to haystack_len.
+ *
+ * Return value: A pointer to the found occurrence, or
+ * NULL if not found.
+ **/
+gchar *
+g_strrstr_len (const gchar *haystack,
+	       gint         haystack_len,
+	       const gchar *needle)
+{
+  int i;
+
+  g_return_val_if_fail (haystack != NULL, NULL);
+  g_return_val_if_fail (needle != NULL, NULL);
+
+  if (haystack_len < 0)
+    return g_strrstr (haystack, needle);
+  else
+    {
+      int needle_len = strlen (needle);
+      const char *haystack_max = haystack + haystack_len;
+      const char *p = haystack;
+
+      while (p < haystack_max && *p)
+	p++;
+
+      p -= needle_len;
+
+      while (p >= haystack)
+	{
+	  for (i = 0; i < needle_len; i++)
+	    if (p[i] != needle[i])
+	      goto next;
+
+	  return (char *)p;
+
+	next:
+	  p--;
+	}
+    }
+
+  return NULL;
+}
+
+
Index: gstrfuncs.h
===================================================================
RCS file: /cvs/gnome/glib/gstrfuncs.h,v
retrieving revision 1.6
diff -u -p -r1.6 gstrfuncs.h
--- gstrfuncs.h	2001/04/16 20:05:23	1.6
+++ gstrfuncs.h	2001/06/08 22:30:41
@@ -60,6 +60,15 @@ gsize	              g_strlcpy	       (gc
 gsize	              g_strlcat        (gchar	     *dest,
 					const gchar  *src,
 					gsize         dest_size);
+gchar *               g_strstr_len     (const gchar  *haystack,
+					gint          haystack_len,
+					const gchar  *needle);
+gchar *               g_strrstr        (const gchar  *haystack,
+					const gchar  *needle);
+gchar *               g_strrstr_len    (const gchar  *haystack,
+					gint          haystack_len,
+					const gchar  *needle);
+
 /* removes leading spaces */
 gchar*                g_strchug        (gchar        *string);
 /* removes trailing spaces */
Index: gunicode.h
===================================================================
RCS file: /cvs/gnome/glib/gunicode.h,v
retrieving revision 1.18
diff -u -p -r1.18 gunicode.h
--- gunicode.h	2001/06/04 20:00:26	1.18
+++ gunicode.h	2001/06/08 22:30:41
@@ -189,10 +189,17 @@ gchar* g_utf8_strncpy (gchar       *dest
 /* Find the UTF-8 character corresponding to ch, in string p. These
    functions are equivalants to strchr and strrchr */

-gchar* g_utf8_strchr  (const gchar *p,
-		       gunichar     c);
-gchar* g_utf8_strrchr (const gchar *p,
-		       gunichar     c);
+gchar* g_utf8_strchr      (const gchar *p,
+			   gunichar     c);
+gchar* g_utf8_strrchr     (const gchar *p,
+			   gunichar     c);
+/* Max length versions: */
+gchar* g_utf8_strchr_len  (const gchar *p,
+			   gint         len,
+			   gunichar     c);
+gchar* g_utf8_strrchr_len (const gchar *p,
+			   gint         len,
+			   gunichar     c);

 gunichar2 *g_utf8_to_utf16     (const gchar      *str,
 				gint              len,
Index: gutf8.c
===================================================================
RCS file: /cvs/gnome/glib/gutf8.c,v
retrieving revision 1.19
diff -u -p -r1.19 gutf8.c
--- gutf8.c	2001/05/19 05:32:49	1.19
+++ gutf8.c	2001/06/08 22:30:41
@@ -510,11 +510,36 @@ g_utf8_strchr (const char *p, gunichar c
   gint len = g_unichar_to_utf8 (c, ch);
   ch[len] = '\0';

-  return strstr(p, ch);
+  return strstr (p, ch);
 }

-#if 0
 /**
+ * g_utf8_strchr_len:
+ * @p: a nul-terminated utf-8 string
+ * @len: the maximum length of p
+ * @c: a iso-10646 character
+ *
+ * Find the leftmost occurence of the given iso-10646 character
+ * in a UTF-8 string, while limiting the search to len bytes.
+ *
+ * Return value: NULL if the string does not contain the character, otherwise, a
+ *               a pointer to the start of the leftmost of the character in the string.
+ **/
+gchar *
+g_utf8_strchr_len (const char *p,
+		   gint        p_len,
+		   gunichar    c)
+{
+  gchar ch[10];
+
+  gint len = g_unichar_to_utf8 (c, ch);
+  ch[len] = '\0';
+
+  return g_strstr_len (p, p_len, ch);
+}
+
+
+/**
  * g_utf8_strrchr:
  * @p: a nul-terminated utf-8 string
  * @c: a iso-10646 character/
@@ -525,20 +550,41 @@ g_utf8_strchr (const char *p, gunichar c
  * Return value: NULL if the string does not contain the character, otherwise, a
  *               a pointer to the start of the rightmost of the character in the string.
  **/
+gchar *
+g_utf8_strrchr (const char *p, gunichar c)
+{
+  gchar ch[10];
+
+  gint len = g_unichar_to_utf8 (c, ch);
+  ch[len] = '\0';
+
+  return g_strrstr (p, ch);
+}

-/* This is ifdefed out atm as there is no strrstr function in libc.
- */
+/**
+ * g_utf8_strrchr_len:
+ * @p: a nul-terminated utf-8 string
+ * @len: the maximum length of p
+ * @c: a iso-10646 character/
+ *
+ * Find the rightmost occurence of the given iso-10646 character
+ * in a UTF-8 string, while limiting the search to len bytes.
+ *
+ * Return value: NULL if the string does not contain the character, otherwise, a
+ *               a pointer to the start of the rightmost of the character in the string.
+ **/
 gchar *
-unicode_strrchr (const char *p, gunichar c)
+g_utf8_strrchr_len (const char *p,
+		    gint        p_len,
+		    gunichar    c)
 {
   gchar ch[10];

-  len = g_unichar_to_utf8 (c, ch);
+  gint len = g_unichar_to_utf8 (c, ch);
   ch[len] = '\0';

-  return strrstr(p, ch);
+  return g_strrstr_len (p, p_len, ch);
 }
-#endif


 /* Like g_utf8_get_char, but take a maximum length
Index: tests/strfunc-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/strfunc-test.c,v
retrieving revision 1.6
diff -u -p -r1.6 strfunc-test.c
--- tests/strfunc-test.c	2000/12/07 04:48:37	1.6
+++ tests/strfunc-test.c	2001/06/08 22:30:41
@@ -116,7 +116,13 @@ main (int   argc,
   g_assert (strcmp (copy[1], "Bar") == 0);
   g_assert (copy[2] == NULL);
   g_strfreev (copy);
-
+
+  g_assert (strcmp (g_strstr_len ("FooBarFooBarFoo", 6, "Bar"),
+		    "BarFooBarFoo") == 0);
+  g_assert (strcmp (g_strrstr ("FooBarFooBarFoo", "Bar"),
+		    "BarFoo") == 0);
+  g_assert (strcmp (g_strrstr_len ("FooBarFooBarFoo", 14, "BarFoo"),
+		    "BarFooBarFoo") == 0);
   return 0;
 }








[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]