[libglnx] Add G_IN_SET, patch our internal users via spatch
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libglnx] Add G_IN_SET, patch our internal users via spatch
- Date: Wed, 14 Jun 2017 16:49:57 +0000 (UTC)
commit 9a1b77ef96b4eb9a916a71e7a04055c4c5665dea
Author: Colin Walters <walters verbum org>
Date: Tue Jun 13 16:22:09 2017 -0400
Add G_IN_SET, patch our internal users via spatch
I originally tried to get this into GLib:
https://bugzilla.gnome.org/show_bug.cgi?id=783751
But that looks like it's going to fail due to MSVC. Let's add it here at least
so I can start using it tomorrow and not wait for the MSVC team to catch up.
I renamed `glnx-alloca.h` to `glnx-macros.h` as a more natural collective
home for things from systemd's `macro.h`.
Finally, I used a Coccinelle spatch similar to the one referenced
in the above BZ to patch our uses.
Makefile-libglnx.am | 8 ++-
glnx-alloca.h | 47 -----------------
glnx-fdio.c | 7 +--
glnx-fdio.h | 3 +-
glnx-macros.h | 115 +++++++++++++++++++++++++++++++++++++++++++
glnx-xattrs.c | 5 +-
libglnx.h | 2 +-
tests/test-libglnx-macros.c | 48 ++++++++++++++++++
8 files changed, 178 insertions(+), 57 deletions(-)
---
diff --git a/Makefile-libglnx.am b/Makefile-libglnx.am
index 805a9d0..6df05ea 100644
--- a/Makefile-libglnx.am
+++ b/Makefile-libglnx.am
@@ -22,7 +22,7 @@ EXTRA_DIST += \
$(NULL)
libglnx_la_SOURCES = \
- $(libglnx_srcpath)/glnx-alloca.h \
+ $(libglnx_srcpath)/glnx-macros.h \
$(libglnx_srcpath)/glnx-backport-autocleanups.h \
$(libglnx_srcpath)/glnx-backport-autoptr.h \
$(libglnx_srcpath)/glnx-backports.h \
@@ -52,7 +52,7 @@ libglnx_la_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
libglnx_la_LDFLAGS = -avoid-version -Bsymbolic-functions -export-symbols-regex "^glnx_" -no-undefined
-export-dynamic
libglnx_la_LIBADD = $(libglnx_libs)
-libglnx_tests = test-libglnx-xattrs test-libglnx-fdio test-libglnx-errors
+libglnx_tests = test-libglnx-xattrs test-libglnx-fdio test-libglnx-errors test-libglnx-macros
TESTS += $(libglnx_tests)
check_PROGRAMS += $(libglnx_tests)
@@ -67,3 +67,7 @@ test_libglnx_fdio_LDADD = $(libglnx_libs) libglnx.la
test_libglnx_errors_SOURCES = $(libglnx_srcpath)/tests/test-libglnx-errors.c
test_libglnx_errors_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
test_libglnx_errors_LDADD = $(libglnx_libs) libglnx.la
+
+test_libglnx_macros_SOURCES = $(libglnx_srcpath)/tests/test-libglnx-macros.c
+test_libglnx_macros_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags)
+test_libglnx_macros_LDADD = $(libglnx_libs) libglnx.la
diff --git a/glnx-fdio.c b/glnx-fdio.c
index 87e2dbb..e496828 100644
--- a/glnx-fdio.c
+++ b/glnx-fdio.c
@@ -37,7 +37,6 @@
#include <glnx-fdio.h>
#include <glnx-dirfd.h>
-#include <glnx-alloca.h>
#include <glnx-errors.h>
#include <glnx-xattrs.h>
#include <glnx-backport-autoptr.h>
@@ -65,7 +64,7 @@ glnx_renameat2_noreplace (int olddirfd, const char *oldpath,
#ifndef ENABLE_WRPSEUDO_COMPAT
if (renameat2 (olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE) < 0)
{
- if (errno == EINVAL || errno == ENOSYS)
+ if (G_IN_SET(errno, EINVAL, ENOSYS))
{
/* Fall through */
}
@@ -119,7 +118,7 @@ glnx_renameat2_exchange (int olddirfd, const char *oldpath,
return 0;
else
{
- if (errno == ENOSYS || errno == EINVAL)
+ if (G_IN_SET(errno, ENOSYS, EINVAL))
{
/* Fall through */
}
@@ -195,7 +194,7 @@ glnx_open_tmpfile_linkable_at (int dfd,
* in full. */
#if defined(O_TMPFILE) && !defined(DISABLE_OTMPFILE) && !defined(ENABLE_WRPSEUDO_COMPAT)
fd = openat (dfd, subpath, O_TMPFILE|flags, 0600);
- if (fd == -1 && !(errno == ENOSYS || errno == EISDIR || errno == EOPNOTSUPP))
+ if (fd == -1 && !(G_IN_SET(errno, ENOSYS, EISDIR, EOPNOTSUPP)))
return glnx_throw_errno_prefix (error, "open(O_TMPFILE)");
if (fd != -1)
{
diff --git a/glnx-fdio.h b/glnx-fdio.h
index e52c823..95574bd 100644
--- a/glnx-fdio.h
+++ b/glnx-fdio.h
@@ -35,6 +35,7 @@
#include <libgen.h>
#undef basename
+#include <glnx-macros.h>
#include <glnx-errors.h>
G_BEGIN_DECLS
@@ -189,7 +190,7 @@ glnx_try_fallocate (int fd,
if (fallocate (fd, 0, offset, size) < 0)
{
- if (errno == ENOSYS || errno == EOPNOTSUPP)
+ if (G_IN_SET(errno, ENOSYS, EOPNOTSUPP))
; /* Ignore */
else
return glnx_throw_errno_prefix (error, "fallocate");
diff --git a/glnx-macros.h b/glnx-macros.h
new file mode 100644
index 0000000..87c25ca
--- /dev/null
+++ b/glnx-macros.h
@@ -0,0 +1,115 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2017 Colin Walters <walters verbum org>
+ * With original source from systemd:
+ * Copyright 2010 Lennart Poettering
+ *
+ * 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 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#pragma once
+
+#include <stdlib.h>
+#include <string.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+/* Taken from https://github.com/systemd/systemd/src/basic/string-util.h
+ * at revision v228-666-gcf6c8c4
+ */
+#define glnx_strjoina(a, ...) \
+ ({ \
+ const char *_appendees_[] = { a, __VA_ARGS__ }; \
+ char *_d_, *_p_; \
+ int _len_ = 0; \
+ unsigned _i_; \
+ for (_i_ = 0; _i_ < G_N_ELEMENTS(_appendees_) && _appendees_[_i_]; _i_++) \
+ _len_ += strlen(_appendees_[_i_]); \
+ _p_ = _d_ = alloca(_len_ + 1); \
+ for (_i_ = 0; _i_ < G_N_ELEMENTS(_appendees_) && _appendees_[_i_]; _i_++) \
+ _p_ = stpcpy(_p_, _appendees_[_i_]); \
+ *_p_ = 0; \
+ _d_; \
+ })
+
+#ifndef G_IN_SET
+
+/* Infrastructure for `G_IN_SET`; this code is copied from
+ * systemd's macro.h - please treat that version as canonical
+ * and submit patches first to systemd.
+ */
+#define _G_INSET_CASE_F(X) case X:
+#define _G_INSET_CASE_F_1(CASE, X) _G_INSET_CASE_F(X)
+#define _G_INSET_CASE_F_2(CASE, X, ...) CASE(X) _G_INSET_CASE_F_1(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_3(CASE, X, ...) CASE(X) _G_INSET_CASE_F_2(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_4(CASE, X, ...) CASE(X) _G_INSET_CASE_F_3(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_5(CASE, X, ...) CASE(X) _G_INSET_CASE_F_4(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_6(CASE, X, ...) CASE(X) _G_INSET_CASE_F_5(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_7(CASE, X, ...) CASE(X) _G_INSET_CASE_F_6(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_8(CASE, X, ...) CASE(X) _G_INSET_CASE_F_7(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_9(CASE, X, ...) CASE(X) _G_INSET_CASE_F_8(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_10(CASE, X, ...) CASE(X) _G_INSET_CASE_F_9(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_11(CASE, X, ...) CASE(X) _G_INSET_CASE_F_10(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_12(CASE, X, ...) CASE(X) _G_INSET_CASE_F_11(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_13(CASE, X, ...) CASE(X) _G_INSET_CASE_F_12(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_14(CASE, X, ...) CASE(X) _G_INSET_CASE_F_13(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_15(CASE, X, ...) CASE(X) _G_INSET_CASE_F_14(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_16(CASE, X, ...) CASE(X) _G_INSET_CASE_F_15(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_17(CASE, X, ...) CASE(X) _G_INSET_CASE_F_16(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_18(CASE, X, ...) CASE(X) _G_INSET_CASE_F_17(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_19(CASE, X, ...) CASE(X) _G_INSET_CASE_F_18(CASE, __VA_ARGS__)
+#define _G_INSET_CASE_F_20(CASE, X, ...) CASE(X) _G_INSET_CASE_F_19(CASE, __VA_ARGS__)
+
+#define _G_INSET_GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...)
NAME
+#define _G_INSET_FOR_EACH_MAKE_CASE(...) \
+
_G_INSET_GET_CASE_F(__VA_ARGS__,_G_INSET_CASE_F_20,_G_INSET_CASE_F_19,_G_INSET_CASE_F_18,_G_INSET_CASE_F_17,_G_INSET_CASE_F_16,_G_INSET_CASE_F_15,_G_INSET_CASE_F_14,_G_INSET_CASE_F_13,_G_INSET_CASE_F_12,_G_INSET_CASE_F_11,
\
+
_G_INSET_CASE_F_10,_G_INSET_CASE_F_9,_G_INSET_CASE_F_8,_G_INSET_CASE_F_7,_G_INSET_CASE_F_6,_G_INSET_CASE_F_5,_G_INSET_CASE_F_4,_G_INSET_CASE_F_3,_G_INSET_CASE_F_2,_G_INSET_CASE_F_1)
\
+ (_G_INSET_CASE_F,__VA_ARGS__)
+
+/* Note: claiming the name here even though it isn't upstream yet
+ * https://bugzilla.gnome.org/show_bug.cgi?id=783751
+ */
+/**
+ * G_IN_SET:
+ * @x: Integer (or smaller) sized value
+ * @...: Elements to compare
+ *
+ * It's quite common to test whether or not `char` values or Unix @errno (among) others
+ * are members of a small set. Normally one has to choose to either use `if (x == val || x == otherval ...)`
+ * or a `switch` statement. This macro is useful to reduce duplication in the first case,
+ * where one can write simply `if (G_IN_SET (x, val, otherval))`, and avoid the verbosity
+ * that the `switch` statement requires.
+ */
+#define G_IN_SET(x, ...) \
+ ({ \
+ gboolean _g_inset_found = FALSE; \
+ /* If the build breaks in the line below, you need to extend the case macros */ \
+ static G_GNUC_UNUSED char _static_assert__macros_need_to_be_extended[20 -
sizeof((int[]){__VA_ARGS__})/sizeof(int)]; \
+ switch(x) { \
+ _G_INSET_FOR_EACH_MAKE_CASE(__VA_ARGS__) \
+ _g_inset_found = TRUE; \
+ break; \
+ default: \
+ break; \
+ } \
+ _g_inset_found; \
+ })
+
+#endif /* ifndef G_IN_SET */
+
+
+G_END_DECLS
diff --git a/glnx-xattrs.c b/glnx-xattrs.c
index 3c1a9c5..3ade89c 100644
--- a/glnx-xattrs.c
+++ b/glnx-xattrs.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <stdio.h>
+#include <glnx-macros.h>
#include <glnx-xattrs.h>
#include <glnx-errors.h>
#include <glnx-local-alloc.h>
@@ -249,7 +250,7 @@ glnx_dfd_name_get_all_xattrs (int dfd,
GCancellable *cancellable,
GError **error)
{
- if (dfd == AT_FDCWD || dfd == -1)
+ if (G_IN_SET(dfd, AT_FDCWD, -1))
{
return get_xattrs_impl (name, -1, out_xattrs, cancellable, error);
}
@@ -306,7 +307,7 @@ glnx_dfd_name_set_all_xattrs (int dfd,
GCancellable *cancellable,
GError **error)
{
- if (dfd == AT_FDCWD || dfd == -1)
+ if (G_IN_SET(dfd, AT_FDCWD, -1))
{
return set_all_xattrs_for_path (name, xattrs, cancellable, error);
}
diff --git a/libglnx.h b/libglnx.h
index a5b23d0..494810d 100644
--- a/libglnx.h
+++ b/libglnx.h
@@ -24,7 +24,7 @@
G_BEGIN_DECLS
-#include <glnx-alloca.h>
+#include <glnx-macros.h>
#include <glnx-local-alloc.h>
#include <glnx-backport-autocleanups.h>
#include <glnx-backports.h>
diff --git a/tests/test-libglnx-macros.c b/tests/test-libglnx-macros.c
new file mode 100644
index 0000000..d16c100
--- /dev/null
+++ b/tests/test-libglnx-macros.c
@@ -0,0 +1,48 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * 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 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "libglnx.h"
+#include <glib.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <string.h>
+
+static void
+test_inset (void)
+{
+ g_assert (G_IN_SET (7, 7));
+ g_assert (G_IN_SET (7, 42, 7));
+ g_assert (G_IN_SET (7, 7,42,3,9));
+ g_assert (G_IN_SET (42, 7,42,3,9));
+ g_assert (G_IN_SET (3, 7,42,3,9));
+ g_assert (G_IN_SET (9, 7,42,3,9));
+ g_assert (!G_IN_SET (8, 7,42,3,9));
+ g_assert (!G_IN_SET (-1, 7,42,3,9));
+ g_assert (G_IN_SET ('x', 'a', 'x', 'c'));
+ g_assert (!G_IN_SET ('y', 'a', 'x', 'c'))
+}
+
+int main (int argc, char **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+ g_test_add_func ("/inset", test_inset);
+ return g_test_run();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]