After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 685880 - Add g_strv_contains()
Add g_strv_contains()
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: general
unspecified
Other Linux
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on: 685878
Blocks:
 
 
Reported: 2012-10-10 12:34 UTC by Xavier Claessens
Modified: 2016-05-24 13:02 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add g_strv_contains() (2.12 KB, patch)
2013-04-15 15:15 UTC, Xavier Claessens
reviewed Details | Review
Add g_strv_contains() (2.14 KB, patch)
2014-01-30 23:13 UTC, Xavier Claessens
none Details | Review
Add g_strv_contains() (2.05 KB, patch)
2014-04-09 12:46 UTC, Allison Karlitskaya (desrt)
none Details | Review
gstrfuncs: Add g_strv_contains() (3.46 KB, patch)
2014-11-25 12:52 UTC, Philip Withnall
committed Details | Review

Description Xavier Claessens 2012-10-10 12:34:51 UTC
In telepathy-glib we have tp_strv_contains(), and I think lot of projects just reimplement it:

gboolean
tp_strv_contains (const gchar * const *strv,
                  const gchar *str)
{
  g_return_val_if_fail (str != NULL, FALSE);

  if (strv == NULL)
    return FALSE;

  while (*strv != NULL)
    {
      if (!tp_strdiff (str, *strv))
        return TRUE;
      strv++;
    }

  return FALSE;
}

the tp_strdiff() call can trivially be replaced by g_strcmp0(). See https://bugzilla.gnome.org/show_bug.cgi?id=685878.
Comment 1 Xavier Claessens 2013-04-15 15:15:46 UTC
Created attachment 241574 [details] [review]
Add g_strv_contains()

Copied from telepathy-glib's tp_strv_contains().
Comment 2 Colin Walters 2013-04-15 16:13:35 UTC
OK, you're proposing a lot of new API.  There's a basic guideline: link to at least two modules that would use it.
Comment 3 Colin Walters 2013-04-15 16:14:39 UTC
Review of attachment 241574 [details] [review]:

Under what situations does one want to search for an individual string in a strv?  Wouldn't applications be better suited using a GHashTable?
Comment 4 Xavier Claessens 2013-04-15 18:11:03 UTC
(In reply to comment #3)
> Review of attachment 241574 [details] [review]:
> 
> Under what situations does one want to search for an individual string in a
> strv?  Wouldn't applications be better suited using a GHashTable?

For small strv I don't think GHashTable would help. GStrv is also what GVariant gives you for "as" dbus type.

(In reply to comment #2)
> OK, you're proposing a lot of new API.  There's a basic guideline: link to at
> least two modules that would use it.

find -name "*.c" | xargs grep strv_contains | wc -l
191

Most are telepathy components, but I see some in gnome-control-center as well. And it does not count all modules that just reimplemented it, or used another name.
Comment 5 Simon Feltman 2013-04-15 21:36:08 UTC
(In reply to comment #2)
> OK, you're proposing a lot of new API.  There's a basic guideline: link to at
> least two modules that would use it.

I was just looking for this function when working on a patch:
https://bugzilla.gnome.org/review?bug=697363&attachment=241242 (pygi-info.c)

But I'm happy to use GHashTable here as well if you think it is a better solution in this case.
Comment 6 Allison Karlitskaya (desrt) 2013-04-15 21:42:52 UTC
g_strdiff()?

fwiw, I've wanted this functionality on a few occasions.  Why the (skip) and where's the docs?
Comment 7 Xavier Claessens 2013-04-16 06:50:12 UTC
(In reply to comment #6)
> g_strdiff()?
> 
> fwiw, I've wanted this functionality on a few occasions.  Why the (skip) and
> where's the docs?

bug #685878
Comment 8 Xavier Claessens 2013-04-16 06:51:02 UTC
Setting depends on bug #685878, even if it can trivially be implemented with g_strcmp0() instead of g_strdiff.
Comment 9 Xavier Claessens 2013-04-16 06:53:24 UTC
Skip annotation is because language bindings probably already have their string comparison built-in, so I don't think you'll ever use glib's.
Comment 10 Xavier Claessens 2013-04-16 06:56:55 UTC
(In reply to comment #9)
> Skip annotation is because language bindings probably already have their string
> comparison built-in, so I don't think you'll ever use glib's.

and for an strv as well, in python you would do
if "foo" in strv:

and not

if strv.contains("foo"):

I guess. Right?
Comment 11 Simon Feltman 2013-04-16 07:32:42 UTC
In Python strvs are automatically converted to and from lists of strings. So it doesn't make sense for Python at least, not sure if other languages would benefit from it though.
Comment 12 Tim-Philipp Müller 2013-08-22 19:10:20 UTC
I would love to have g_strv_contains() as well. Please?
Comment 13 Xavier Claessens 2014-01-30 23:13:29 UTC
Created attachment 267685 [details] [review]
Add g_strv_contains()
Comment 14 Xavier Claessens 2014-01-30 23:14:24 UTC
g_strdiff() was actually useless in this case since both strings are always != NULL. Any objection on this patch ?
Comment 15 Allison Karlitskaya (desrt) 2014-04-09 12:46:57 UTC
Created attachment 273888 [details] [review]
Add g_strv_contains()

Same patch, removing the special-casing of %NULL and the (skip).
Comment 16 Lars Karlitski 2014-04-09 13:48:33 UTC
Review of attachment 273888 [details] [review]:

::: glib/gstrfuncs.c
@@ +3090,3 @@
+gboolean
+g_strv_contains (const gchar * const *strv,
+    const gchar *str)

Whitespace

@@ +3092,3 @@
+    const gchar *str)
+{
+  g_return_val_if_fail (str != NULL, FALSE);

We should probably also add a precondition for @strv

::: glib/gstrfuncs.h
@@ +302,3 @@
                                                                          gboolean       accept_alternates);
 
+GLIB_AVAILABLE_IN_2_40

2_42
Comment 17 Philip Withnall 2014-11-25 12:52:25 UTC
Created attachment 291448 [details] [review]
gstrfuncs: Add g_strv_contains()

Includes unit tests.
Comment 18 Philip Withnall 2014-11-25 12:55:38 UTC
(In reply to comment #17)
> Created an attachment (id=291448) [details] [review]
> gstrfuncs: Add g_strv_contains()
> 
> Includes unit tests.

This fixes Lars’ points from comment #16, clarifies the nullability of @strv in the docs (since various g_strv*() functions handle NULL GStrvs differently), and changes from a while-loop to a for-loop for clarity. It also adds some unit tests.
Comment 19 Lars Karlitski 2014-11-25 13:01:19 UTC
Review of attachment 291448 [details] [review]:

Thanks!
Comment 20 Christian Persch 2014-11-25 13:04:41 UTC
I don't see why comment 15 removed the handling of NULL strv. IMHO it's quite useful to handle NULL strv too, and the result if obviously FALSE for any string.
Comment 21 Lars Karlitski 2014-11-25 13:12:21 UTC
(In reply to comment #20)
> I don't see why comment 15 removed the handling of NULL strv. IMHO it's quite
> useful to handle NULL strv too, and the result if obviously FALSE for any
> string.

NULL is not a valid strv. Passing NULL when a strv is expected should result in a critical. We don't treat NULL as empty string either in functions accepting strings.

Other functions handlings strvs also don't allow NULL (e.g., g_strv_length and g_strjoinv). The only exceptions are g_strfreev (functions freeing stuff always accept NULL) and g_strdupv (to mirror g_strdup).
Comment 22 Philip Withnall 2014-11-25 16:08:02 UTC
Comment on attachment 291448 [details] [review]
gstrfuncs: Add g_strv_contains()

Committed; thanks for the fast turnaround!

commit 71944b1bfd2cff57e889b806d001458dce6fa2b5
Author: Xavier Claessens <xavier.claessens@collabora.co.uk>
Date:   Mon Apr 15 14:54:31 2013 +0200

    gstrfuncs: Add g_strv_contains()
    
    Includes unit tests.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=685880

 docs/reference/glib/glib-sections.txt |  1 +
 glib/gstrfuncs.c                      | 27 +++++++++++++++++++++++++++
 glib/gstrfuncs.h                      |  4 ++++
 glib/tests/strfuncs.c                 | 19 +++++++++++++++++++
 4 files changed, 51 insertions(+)
Comment 23 Marc-Andre Lureau 2016-05-24 12:52:28 UTC
Can't pass GStrv without ugly casting?

#include <glib.h>

int main(int argc, char *argv[]) {
	GStrv foo = NULL;
	g_strv_contains(foo, "blah");
	return 0;
}

main.c: In function ‘main’:
main.c:5:18: warning: passing argument 1 of ‘g_strv_contains’ from incompatible pointer type [-Wincompatible-pointer-types]
  g_strv_contains(foo, "blah");
                  ^~~
In file included from /usr/include/glib-2.0/glib.h:79:0,
                 from main.c:1:
/usr/include/glib-2.0/glib/gstrfuncs.h:306:23: note: expected ‘const gchar * const* {aka const char * const*}’ but argument is of type ‘GStrv {aka char **}’
 gboolean              g_strv_contains  (const gchar * const *strv,
                       ^~~~~~~~~~~~~~~
Comment 24 Xavier Claessens 2016-05-24 13:02:41 UTC
gcc doesn't want to cast "gchar**" to "const gchar * const *", it has always annoyed me. People often wrongly use "const gchar **" instead to avoid that warning. I'm sure there are really good reasons for this deep inside the C grammar...