Re: #50321, patch with g_strrstr_len etc..



Alex Larsson <alexl redhat com> writes:

> 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.

Looks just about right, except that on second thought, I think
we should just change the signature of g_utf8_strchr(), 
g_utf8_strrchr() to take the extra parameter, instead of 
introducing new variants.

(They aren't used anywhere I can find in Pango/GTK+ currently)

The other thing I wondered about was whether g_strstr()
should be written as a wrapper around g_strstr_len(), but
I think the way you have it should be fine.

With the change to the g_utf8_ functions, should be OK to 
commit.
                                        Owen
 
> / 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]