Merge branch 'strv-builder' into 'master'

gstrvbuilder: Add a new object to make NULL-terminated string arrays.

See merge request GNOME/glib!1417
This commit is contained in:
Philip Withnall 2020-10-14 11:01:24 +00:00
commit 730a395701
8 changed files with 283 additions and 0 deletions

View File

@ -1806,9 +1806,15 @@ g_strjoinv
<SUBSECTION>
GStrv
GStrvBuilder
g_strv_length
g_strv_contains
g_strv_equal
g_strv_builder_new
g_strv_builder_ref
g_strv_builder_unref
g_strv_builder_add
g_strv_builder_end
<SUBSECTION>
g_strerror

View File

@ -78,6 +78,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSequence, g_sequence_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSList, g_slist_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GString, g_autoptr_cleanup_gstring_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GStringChunk, g_string_chunk_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GStrvBuilder, g_strv_builder_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GThread, g_thread_unref)
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GMutex, g_mutex_clear)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GMutexLocker, g_mutex_locker_free)

View File

@ -82,6 +82,7 @@
#include <glib/gstrfuncs.h>
#include <glib/gstringchunk.h>
#include <glib/gstring.h>
#include <glib/gstrvbuilder.h>
#include <glib/gtestutils.h>
#include <glib/gthread.h>
#include <glib/gthreadpool.h>

134
glib/gstrvbuilder.c Normal file
View File

@ -0,0 +1,134 @@
/*
* Copyright © 2020 Canonical Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gstrvbuilder.h"
#include "garray.h"
#include "gmem.h"
/**
* SECTION:gstrvbuilder
* @title: GStrvBuilder
* @short_description: Helper to create NULL-terminated string arrays.
*
* #GStrvBuilder is a method of easily building dynamically sized
* NULL-terminated string arrays.
*
* The following example shows how to build a two element array:
*
* |[<!-- language="C" -->
* g_autoptr(GStrvBuilder) builder = g_strv_builder_new ();
* g_strv_builder_add (builder, "hello");
* g_strv_builder_add (builder, "world");
* g_auto(GStrv) array = g_strv_builder_end (builder);
* ]|
*
* Since: 2.68
*/
struct _GStrvBuilder
{
GPtrArray array;
};
/**
* g_strv_builder_new:
*
* Creates a new #GStrvBuilder with a reference count of 1.
* Use g_strv_builder_unref() on the returned value when no longer needed.
*
* Returns: (transfer full): the new #GStrvBuilder
*
* Since: 2.68
*/
GStrvBuilder *
g_strv_builder_new (void)
{
return (GStrvBuilder *) g_ptr_array_new_with_free_func (g_free);
}
/**
* g_strv_builder_unref:
* @builder: (transfer full): a #GStrvBuilder allocated by g_strv_builder_new()
*
* Decreases the reference count on @builder.
*
* In the event that there are no more references, releases all memory
* associated with the #GStrvBuilder.
*
* Since: 2.68
**/
void
g_strv_builder_unref (GStrvBuilder *builder)
{
g_ptr_array_unref (&builder->array);
}
/**
* g_strv_builder_ref:
* @builder: (transfer none): a #GStrvBuilder
*
* Atomically increments the reference count of @builder by one.
* This function is thread-safe and may be called from any thread.
*
* Returns: (transfer full): The passed in #GStrvBuilder
*
* Since: 2.68
*/
GStrvBuilder *
g_strv_builder_ref (GStrvBuilder *builder)
{
return (GStrvBuilder *) g_ptr_array_ref (&builder->array);
}
/**
* g_strv_builder_add:
* @builder: a #GStrvBuilder
* @value: a string.
*
* Add a string to the end of the array.
*
* Since 2.68
*/
void
g_strv_builder_add (GStrvBuilder *builder,
const char *value)
{
g_ptr_array_add (&builder->array, g_strdup (value));
}
/**
* g_strv_builder_end:
* @builder: a #GStrvBuilder
*
* Ends the builder process and returns the constructed NULL-terminated string
* array. The returned value should be freed with g_strfreev() when no longer
* needed.
*
* Returns: (transfer full): the constructed string array.
*
* Since 2.68
*/
GStrv
g_strv_builder_end (GStrvBuilder *builder)
{
/* Add NULL terminator */
g_ptr_array_add (&builder->array, NULL);
return (GStrv) g_ptr_array_steal (&builder->array, NULL);
}

58
glib/gstrvbuilder.h Normal file
View File

@ -0,0 +1,58 @@
/*
* Copyright © 2020 Canonical Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __G_STRVBUILDER_H__
#define __G_STRVBUILDER_H__
#if !defined(__GLIB_H_INSIDE__) && !defined(GLIB_COMPILATION)
#error "Only <glib.h> can be included directly."
#endif
#include <glib/gstrfuncs.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS
/**
* GStrvBuilder:
*
* A helper object to build a %NULL-terminated string array
* by appending. See g_strv_builder_new().
*
* Since: 2.68
*/
typedef struct _GStrvBuilder GStrvBuilder;
GLIB_AVAILABLE_IN_2_68
GStrvBuilder *g_strv_builder_new (void);
GLIB_AVAILABLE_IN_2_68
void g_strv_builder_unref (GStrvBuilder *builder);
GLIB_AVAILABLE_IN_2_68
GStrvBuilder *g_strv_builder_ref (GStrvBuilder *builder);
GLIB_AVAILABLE_IN_2_68
void g_strv_builder_add (GStrvBuilder *builder,
const char *value);
GLIB_AVAILABLE_IN_2_68
GStrv g_strv_builder_end (GStrvBuilder *builder);
G_END_DECLS
#endif /* __G_STRVBUILDER_H__ */

View File

@ -198,6 +198,7 @@ glib_sub_headers = files(
'gspawn.h',
'gstdio.h',
'gstrfuncs.h',
'gstrvbuilder.h',
'gtestutils.h',
'gstring.h',
'gstringchunk.h',
@ -286,6 +287,7 @@ glib_sources = files(
'gstrfuncs.c',
'gstring.c',
'gstringchunk.c',
'gstrvbuilder.c',
'gtestutils.c',
'gthread.c',
'gthreadpool.c',

View File

@ -92,6 +92,7 @@ glib_tests = {
'spawn-singlethread' : {},
'strfuncs' : {},
'string' : {},
'strvbuilder' : {},
'testing' : {},
'test-printf' : {},
'thread' : {},

80
glib/tests/strvbuilder.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright © 2020 Canonical Ltd.
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include "glib.h"
static void
test_strvbuilder_empty (void)
{
GStrvBuilder *builder;
GStrv result;
builder = g_strv_builder_new ();
result = g_strv_builder_end (builder);
g_assert_nonnull (result);
g_assert_cmpint (g_strv_length (result), ==, 0);
g_strfreev (result);
g_strv_builder_unref (builder);
}
static void
test_strvbuilder_add (void)
{
GStrvBuilder *builder;
GStrv result;
const gchar *expected[] = { "one", "two", "three", NULL };
builder = g_strv_builder_new ();
g_strv_builder_add (builder, "one");
g_strv_builder_add (builder, "two");
g_strv_builder_add (builder, "three");
result = g_strv_builder_end (builder);
g_assert_nonnull (result);
g_assert_true (g_strv_equal ((const gchar *const *) result, expected));
g_strfreev (result);
g_strv_builder_unref (builder);
}
static void
test_strvbuilder_ref (void)
{
GStrvBuilder *builder;
builder = g_strv_builder_new ();
g_strv_builder_ref (builder);
g_strv_builder_unref (builder);
g_strv_builder_unref (builder);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/strvbuilder/empty", test_strvbuilder_empty);
g_test_add_func ("/strvbuilder/add", test_strvbuilder_add);
g_test_add_func ("/strvbuilder/ref", test_strvbuilder_ref);
return g_test_run ();
}