release: bump version to 1.33.1 (development)
This commit is contained in:
@@ -230,3 +230,51 @@ source code and navigate it. These tools can integrate with editors like `Vim` a
|
||||
|
||||
- http://cscope.sourceforge.net/cscope_vim_tutorial.html
|
||||
- https://www.emacswiki.org/emacs/CScopeAndEmacs
|
||||
|
||||
|
||||
Miscellaneous
|
||||
---------------------------
|
||||
|
||||
### GObject Properties
|
||||
|
||||
We use GObjects and GObject Properties in various cases. For example:
|
||||
|
||||
1. In public API in libnm they are used and useful for providing a standard
|
||||
GObject API. One advantage of GObject properties is that they work well
|
||||
with introspection and bindings.
|
||||
|
||||
1. `NMSetting` properties commonly are GObject properties. While we provide
|
||||
C getters, they commonly don't have a setter. That is, settings can often
|
||||
only set via `g_object_set()`.
|
||||
|
||||
1. Our D-Bus API uses glue code. For the daemon, this is
|
||||
[`nm-dbus-manager.[ch]`](src/core/nm-dbus-manager.c) and
|
||||
[`nm-dbus-object.[ch]`](src/core/nm-dbus-object.c). For libnm's
|
||||
`NMClient`, this is [`nm-object.c`](src/libnm-client-impl/nm-object.c).
|
||||
These bindings rely on GObject properties.
|
||||
|
||||
1. Sometimes it is convenient to use the functionality that GObject
|
||||
properties provide. In particular, `notify::` property changed signals
|
||||
or the ability to freeze/thaw the signals.
|
||||
|
||||
1. Immutable objects are great, so there is a desire to have `G_PARAM_CONSTRUCT_ONLY`
|
||||
properties. In that case, avoid adding a getter too, the property only needs to be
|
||||
writable and you should access it via the C wrapper.
|
||||
|
||||
In general, use GObject sparsely and avoid them (unless you need them for one of the
|
||||
reasons above).
|
||||
|
||||
Almost always add a `#define` for the property name, and use for example
|
||||
`g_signal_connect(obj, "notify::"NM_TARGET_SOME_PROPERTY", ...)`. The goal is to
|
||||
be able to search the use of all properties.
|
||||
|
||||
Almost always add C getter and setters and prefer them over `g_object_get()`
|
||||
and `g_object_set()`. This also stresses the point that you usually wouldn't use
|
||||
a GObject property aside the reasons above.
|
||||
|
||||
When adding a GObject properties, do it for only one of the reasons above.
|
||||
For example, the property `NM_MANAGER_DEVICES` in the daemon is added to bind
|
||||
the property to D-Bus. Don't use that property otherwise and don't register
|
||||
a `notify::NM_MANAGER_DEVICES` for your own purpose. The reason is that GObject
|
||||
properties are harder to understand and they should be used sparsely and for
|
||||
one specific reason.
|
||||
|
@@ -187,6 +187,7 @@ EXTRA_DIST += \
|
||||
examples/python/gi/nm-add-connection2.py \
|
||||
examples/python/gi/nm-connection-update-stable-id.py \
|
||||
examples/python/gi/nm-keyfile.py \
|
||||
examples/python/gi/nm-up-many.py \
|
||||
examples/python/gi/nm-update2.py \
|
||||
examples/python/gi/nm-wg-set \
|
||||
examples/python/gi/ovs-external-ids.py \
|
||||
|
10
NEWS
10
NEWS
@@ -1,3 +1,13 @@
|
||||
=============================================
|
||||
NetworkManager-1.34
|
||||
Overview of changes since NetworkManager-1.32
|
||||
=============================================
|
||||
|
||||
This is a snapshot of NetworkManager development. The API is
|
||||
subject to change and not guaranteed to be compatible with
|
||||
the later release.
|
||||
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
||||
|
||||
=============================================
|
||||
NetworkManager-1.32
|
||||
Overview of changes since NetworkManager-1.30
|
||||
|
@@ -7,8 +7,8 @@ dnl - add corresponding NM_VERSION_x_y_z macros in
|
||||
dnl "shared/nm-version-macros.h.in"
|
||||
dnl - update number in meson.build
|
||||
m4_define([nm_major_version], [1])
|
||||
m4_define([nm_minor_version], [32])
|
||||
m4_define([nm_micro_version], [0])
|
||||
m4_define([nm_minor_version], [33])
|
||||
m4_define([nm_micro_version], [1])
|
||||
m4_define([nm_version],
|
||||
[nm_major_version.nm_minor_version.nm_micro_version])
|
||||
|
||||
|
@@ -38,7 +38,7 @@ NM-colorize() {
|
||||
GREP_COLOR='01;31' grep -a --color=always '^\|^\(.* \)\?<\(warn> \|error>\) \[[0-9.]*\]' | \
|
||||
GREP_COLOR='01;33' grep -a --color=always '^\|^\(.* \)\?<info> \[[0-9.]*\]\( .*\<is starting\>.*$\)\?' | \
|
||||
GREP_COLOR='01;37' grep -a --color=always '^\|\<platform:\( (.*)\)\? signal: .*$' | \
|
||||
GREP_COLOR='01;34' grep -a --color=always '^\|\<platform\(-linux\)\?:\( (.*)\)\? link: \(add\|adding\|change\|setting\|deleting\)\>\|\<platform: routing-rule: \(adding or updating:\|delete \)\|\<platform:\( (.*)\)\? address: \(deleting\|adding or updating\) IPv. address:\? \|\<platform:\( (.*)\)\? \(route\|ip4-route\|ip6-route\|qdisc\|tfilter\): \([a-z]\+\|adding or updating\|new\[0x[0-9A-Za-z]*\]\) \|\<platform-linux: sysctl: setting ' | \
|
||||
GREP_COLOR='01;34' grep -a --color=always '^\|\<platform\(-linux\)\?:\( (.*)\)\? link: \(add\|adding\|change\|setting\|deleting\|enslaving to master\)\>\|\<platform: routing-rule: \(adding or updating:\|delete \)\|\<platform:\( (.*)\)\? address: \(deleting\|adding or updating\) IPv. address:\? \|\<platform:\( (.*)\)\? \(route\|ip4-route\|ip6-route\|qdisc\|tfilter\): \([a-z]\+\|adding or updating\|new\[0x[0-9A-Za-z]*\]\) \|\<platform-linux: sysctl: setting ' | \
|
||||
GREP_COLOR='01;35' grep -a --color=always '^\|\<audit: .*$' | \
|
||||
GREP_COLOR='01;32' grep -a --color=always '^\|\<device (.*): state change: ' |
|
||||
if [[ "$NM_LOG_GREP" != "" ]]; then
|
||||
|
117
contrib/scripts/test-create-many-device-setup.sh
Executable file
117
contrib/scripts/test-create-many-device-setup.sh
Executable file
@@ -0,0 +1,117 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
|
||||
die() {
|
||||
printf '%s\n' "$*" >&1
|
||||
exit 1
|
||||
}
|
||||
|
||||
ARG_OP="$1"
|
||||
shift
|
||||
test -n "$ARG_OP" || die "specify the operation (setup, cleanup)"
|
||||
|
||||
test "$USER" = root || die "must run as root"
|
||||
|
||||
NUM_DEVS="${NUM_DEVS:-50}"
|
||||
|
||||
|
||||
DNSMASQ_PIDFILE="/tmp/nm-test-create-many-device-setup.dnsmasq.pid"
|
||||
NM_TEST_CONF="/etc/NetworkManager/conf.d/99-my-test.conf"
|
||||
TEST_NETNS="T"
|
||||
|
||||
|
||||
_dnsmasq_kill() {
|
||||
pkill -F "$DNSMASQ_PIDFILE"
|
||||
rm -rf "$DNSMASQ_PIDFILE"
|
||||
}
|
||||
|
||||
_link_delete_all() {
|
||||
ip link | sed -n 's/^[0-9]\+:.*\(t-[^@:]\+\)@.*/\1/p' | xargs -n 1 ip link delete
|
||||
}
|
||||
|
||||
cleanup_base() {
|
||||
ip netns delete "$TEST_NETNS"
|
||||
_dnsmasq_kill
|
||||
_link_delete_all
|
||||
rm -rf "$NM_TEST_CONF"
|
||||
rm -rf /run/NetworkManager/system-connections/c-*.nmconnection
|
||||
}
|
||||
|
||||
cmd_cleanup() {
|
||||
systemctl stop NetworkManager
|
||||
cleanup_base
|
||||
systemctl unmask NetworkManager-dispatcher
|
||||
systemctl enable NetworkManager-dispatcher
|
||||
systemctl start NetworkManager
|
||||
}
|
||||
|
||||
cmd_setup() {
|
||||
|
||||
systemctl stop NetworkManager
|
||||
systemctl mask NetworkManager-dispatcher
|
||||
systemctl stop NetworkManager-dispatcher
|
||||
|
||||
cleanup_base
|
||||
|
||||
ip netns add "$TEST_NETNS"
|
||||
ip --netns "$TEST_NETNS" link add t-br0 type bridge
|
||||
ip --netns "$TEST_NETNS" link set t-br0 type bridge stp_state 0
|
||||
ip --netns "$TEST_NETNS" link set t-br0 up
|
||||
ip --netns "$TEST_NETNS" addr add 172.16.0.1/16 dev t-br0
|
||||
ip netns exec "$TEST_NETNS" \
|
||||
dnsmasq \
|
||||
--conf-file=/dev/null \
|
||||
--pid-file="$DNSMASQ_PIDFILE" \
|
||||
--no-hosts \
|
||||
--keep-in-foreground \
|
||||
--bind-interfaces \
|
||||
--except-interface=lo \
|
||||
--clear-on-reload \
|
||||
--listen-address=172.16.0.1 \
|
||||
--dhcp-range=172.16.1.1,172.16.20.1,60 \
|
||||
--no-ping \
|
||||
&
|
||||
disown
|
||||
for i in `seq "$NUM_DEVS"`; do
|
||||
ip --netns "$TEST_NETNS" link add t-a$i type veth peer t-b$i
|
||||
ip --netns "$TEST_NETNS" link set t-a$i up
|
||||
ip --netns "$TEST_NETNS" link set t-b$i up master t-br0
|
||||
done
|
||||
|
||||
cat <<EOF > "$NM_TEST_CONF"
|
||||
[main]
|
||||
dhcp=internal
|
||||
no-auto-default=interface-name:t-a*
|
||||
[device-99-my-test]
|
||||
match-device=interface-name:t-a*
|
||||
managed=1
|
||||
[logging]
|
||||
level=INFO
|
||||
[connectivity]
|
||||
enabled=0
|
||||
EOF
|
||||
|
||||
systemctl start NetworkManager
|
||||
|
||||
for i in `seq "$NUM_DEVS"`; do
|
||||
ip --netns "$TEST_NETNS" link set t-a$i netns $$
|
||||
done
|
||||
|
||||
for i in `seq "$NUM_DEVS"`; do
|
||||
nmcli connection add save no type ethernet con-name c-a$i ifname t-a$i autoconnect no ipv4.method auto ipv6.method auto
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
case "$ARG_OP" in
|
||||
"setup")
|
||||
cmd_setup
|
||||
;;
|
||||
"cleanup")
|
||||
cmd_cleanup
|
||||
;;
|
||||
*)
|
||||
die "Unknown command \"$ARG_OP\""
|
||||
;;
|
||||
esac
|
373
examples/python/gi/nm-up-many.py
Executable file
373
examples/python/gi/nm-up-many.py
Executable file
@@ -0,0 +1,373 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
# A example script to activate many profiles in parallel.
|
||||
#
|
||||
# It uses entirely asynchronous API. At various points the
|
||||
# script explicitly iterates the main context, which is unlike
|
||||
# a more complex application that uses the GMainContext, which
|
||||
# probably would run the context only at one point as long as
|
||||
# the application is running (from the main function).
|
||||
|
||||
import sys
|
||||
import os
|
||||
import gi
|
||||
import time
|
||||
|
||||
gi.require_version("NM", "1.0")
|
||||
from gi.repository import NM, GLib, Gio
|
||||
|
||||
|
||||
start_time = time.monotonic()
|
||||
|
||||
|
||||
class MyError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def log(msg):
|
||||
# use nm_utils_print(), so that the log messages are in synch with
|
||||
# LIBNM_CLIENT_DEBUG=trace messages.
|
||||
NM.utils_print(0, "[%015.10f] %s\n" % (time.monotonic() - start_time, msg))
|
||||
|
||||
|
||||
def nmc_new(io_priority=GLib.PRIORITY_DEFAULT, cancellable=None):
|
||||
# create a NMClient instance using the async initialization
|
||||
# (but the function itself iterates the main context until
|
||||
# the initialization completes).
|
||||
|
||||
result = []
|
||||
|
||||
def cb(source_object, res):
|
||||
|
||||
try:
|
||||
source_object.init_finish(res)
|
||||
except Exception as e:
|
||||
result.append(e)
|
||||
else:
|
||||
result.append(None)
|
||||
|
||||
nmc = NM.Client()
|
||||
nmc.init_async(io_priority, cancellable, cb)
|
||||
while not result:
|
||||
nmc.get_main_context().iteration(may_block=True)
|
||||
|
||||
if result[0]:
|
||||
raise result[0]
|
||||
|
||||
log("initialized NMClient cache")
|
||||
|
||||
return nmc
|
||||
|
||||
|
||||
def nmc_destroy(nmc_transfer_ref):
|
||||
|
||||
# Just for fun, show how to completely cleanup a NMClient instance.
|
||||
# An NMClient instance registers D-Bus signals and unrefing the instance
|
||||
# will cancel/unsubscribe those signals, but there might still be some
|
||||
# pending operations scheduled on the main context. That means, after
|
||||
# unrefing the NMClient instance, we may need to iterate the GMainContext
|
||||
# a bit longer, go get rid of all resources (otherwise, the GMainContext
|
||||
# itself cannot be destroyed and leaks).
|
||||
#
|
||||
# We can use nm_client_get_context_busy_watcher() for that, by subscribing
|
||||
# a weak reference and iterating the context as long as the object is
|
||||
# alive.
|
||||
|
||||
nmc = nmc_transfer_ref[0]
|
||||
del nmc_transfer_ref[0]
|
||||
|
||||
alive = [1]
|
||||
|
||||
def weak_ref_cb(alive):
|
||||
del alive[0]
|
||||
|
||||
nmc.get_context_busy_watcher().weak_ref(weak_ref_cb, alive)
|
||||
main_context = nmc.get_main_context()
|
||||
|
||||
del nmc
|
||||
|
||||
while alive:
|
||||
main_context.iteration(may_block=True)
|
||||
|
||||
log("NMClient instance cleaned up")
|
||||
|
||||
|
||||
def find_connections(nmc, argv):
|
||||
|
||||
# parse the inpurt argv and select the connection profiles to activate.
|
||||
# The arguments are either "connection.id" or "connection.uuid", possibly
|
||||
# qualified by "id" or "uuid".
|
||||
|
||||
result = []
|
||||
|
||||
while True:
|
||||
if not argv:
|
||||
break
|
||||
arg_type = argv.pop(0)
|
||||
if arg_type in ["id", "uuid"]:
|
||||
if not argv:
|
||||
raise MyError('missing specifier after "%s"' % (arg_type))
|
||||
arg_param = argv.pop(0)
|
||||
else:
|
||||
arg_param = arg_type
|
||||
arg_type = "*"
|
||||
|
||||
cc = []
|
||||
for c in nmc.get_connections():
|
||||
if arg_type in ["id", "*"] and arg_param == c.get_id():
|
||||
cc.append(c)
|
||||
if arg_type in ["uuid", "*"] and arg_param == c.get_uuid():
|
||||
cc.append(c)
|
||||
|
||||
if not cc:
|
||||
raise MyError(
|
||||
'Could not find a matching connection "%s" "%s"' % (arg_type, arg_param)
|
||||
)
|
||||
if len(cc) > 1:
|
||||
raise MyError(
|
||||
'Could not find a unique matching connection "%s" "%s", instead %d profiles found'
|
||||
% (arg_type, arg_param, len(cc))
|
||||
)
|
||||
|
||||
if cc[0] not in result:
|
||||
# we allow duplicates, but combine them.
|
||||
result.extend(cc)
|
||||
|
||||
for c in result:
|
||||
log(
|
||||
"requested connection: %s (%s) (%s)"
|
||||
% (c.get_id(), c.get_uuid(), c.get_path())
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def nmc_activate_start(nmc, con):
|
||||
|
||||
# Call nmc.activate_connection_async() and return a user data
|
||||
# with the information about the pending operation.
|
||||
|
||||
activation = {
|
||||
"con": con,
|
||||
"result": None,
|
||||
"result_msg": None,
|
||||
"result_ac": None,
|
||||
"ac_result": None,
|
||||
}
|
||||
|
||||
log("activation %s (%s) start asynchronously" % (con.get_id(), con.get_uuid()))
|
||||
|
||||
def cb(source_object, res, activation):
|
||||
# The callback does not call other code for signaling the
|
||||
# completion. Instead, we remember in "activation" that
|
||||
# the callback was completed.
|
||||
#
|
||||
# Other code will repeatedly go through the "activation_list"
|
||||
# and find those that are completed (nmc_activate_find_completed()).
|
||||
try:
|
||||
ac = nmc.activate_connection_finish(res)
|
||||
except Exception as e:
|
||||
activation["result"] = False
|
||||
activation["result_msg"] = str(e)
|
||||
else:
|
||||
activation["result"] = True
|
||||
activation["result_msg"] = "success"
|
||||
activation["result_ac"] = ac
|
||||
|
||||
nmc.activate_connection_async(con, None, None, None, cb, activation)
|
||||
|
||||
return activation
|
||||
|
||||
|
||||
def nmc_activate_find_completed(activation_list):
|
||||
|
||||
# Iterate over list of "activation" data, find the first
|
||||
# one that is completed, remove it from the list and return
|
||||
# it.
|
||||
|
||||
for idx, activation in enumerate(activation_list):
|
||||
if activation["result"] is not None:
|
||||
del activation_list[idx]
|
||||
return activation
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def nmc_activate_complete(
|
||||
nmc, activation_list, completed_list, num_parallel_invocations
|
||||
):
|
||||
|
||||
# We schedule activations asynchronously and in parallel. However, we
|
||||
# still want to rate limit the number of parallel activations. This
|
||||
# function does that: if there are more than "num_parallel_invocations" activations
|
||||
# in progress, then wait until the excess number of them completed.
|
||||
# The completed ones move from "activation_list" over to "completed_list".
|
||||
|
||||
completed = 0
|
||||
while True:
|
||||
|
||||
need_to_wait = len(activation_list) > num_parallel_invocations
|
||||
|
||||
# Even if we don't need to wait (that is, the list of pending activations
|
||||
# is reasonably short), we still tentatively iterate the GMainContext a bit.
|
||||
if not nmc.get_main_context().iteration(may_block=need_to_wait):
|
||||
if need_to_wait:
|
||||
continue
|
||||
# Ok, nothing ready yet.
|
||||
break
|
||||
|
||||
# this is not efficient after each iteration(), but it's good enough.
|
||||
# The activation list is supposed to be short.
|
||||
activation = nmc_activate_find_completed(activation_list)
|
||||
|
||||
if activation is None:
|
||||
continue
|
||||
|
||||
con = activation["con"]
|
||||
log(
|
||||
"activation %s (%s) start complete: %s%s"
|
||||
% (
|
||||
con.get_id(),
|
||||
con.get_uuid(),
|
||||
activation["result_msg"],
|
||||
(
|
||||
""
|
||||
if not activation["result"]
|
||||
else (" (%s)" % (activation["result_ac"].get_path()))
|
||||
),
|
||||
)
|
||||
)
|
||||
completed += 1
|
||||
|
||||
completed_list.append(activation)
|
||||
|
||||
if completed > 0:
|
||||
log(
|
||||
"completed %d activations, %d activations still pending"
|
||||
% (completed, len(activation_list))
|
||||
)
|
||||
|
||||
|
||||
def nmc_activate_all(nmc, cons):
|
||||
|
||||
# iterate of all connections ("cons") and activate them
|
||||
# in parallel. nmc_activate_complete() is used to rate limits
|
||||
# how many parallel invocations we allow.
|
||||
|
||||
num_parallel_invocations = 100
|
||||
|
||||
activation_list = []
|
||||
completed_list = []
|
||||
for c in cons:
|
||||
activation = nmc_activate_start(nmc, c)
|
||||
activation_list.append(activation)
|
||||
nmc_activate_complete(
|
||||
nmc, activation_list, completed_list, num_parallel_invocations
|
||||
)
|
||||
nmc_activate_complete(nmc, activation_list, completed_list, 0)
|
||||
assert not activation_list
|
||||
assert len(completed_list) == len(cons)
|
||||
|
||||
return completed_list
|
||||
|
||||
|
||||
def nmc_activate_wait_for_pending(nmc, completed_list):
|
||||
|
||||
# go through the list of activations and wait that they
|
||||
# all reach a final state. That is, either that they are failed
|
||||
# or fully ACTIVATED state.
|
||||
|
||||
log("wait for all active connection to either reach ACTIVATED state or fail...")
|
||||
|
||||
def log_result(activation, message):
|
||||
activation["ac_result"] = message
|
||||
log(
|
||||
"connection %s (%s) activation fully completed: %s"
|
||||
% (ac.get_id(), ac.get_uuid(), message)
|
||||
)
|
||||
|
||||
while True:
|
||||
|
||||
# again, it's not efficient to check the entire list for completion
|
||||
# after each g_main_context_iteration(). But "completed_list" should
|
||||
# be reasonably small.
|
||||
|
||||
activation = None
|
||||
for idx, activ in enumerate(completed_list):
|
||||
if activ["ac_result"] is not None:
|
||||
continue
|
||||
if activ["result"] is False:
|
||||
log_result(activ, "failed to start activation")
|
||||
continue
|
||||
ac = activ["result_ac"]
|
||||
if ac.get_client() is None:
|
||||
log_result(activ, "active connection disappeared")
|
||||
continue
|
||||
if ac.get_state() == NM.ActiveConnectionState.ACTIVATED:
|
||||
log_result(activ, "connection successfully activated")
|
||||
continue
|
||||
if ac.get_state() > NM.ActiveConnectionState.ACTIVATED:
|
||||
log_result(
|
||||
activ, "connection failed to activate (state %s)" % (ac.get_state())
|
||||
)
|
||||
continue
|
||||
activation = activ
|
||||
break
|
||||
|
||||
if activation is None:
|
||||
log("no more activation to wait for")
|
||||
break
|
||||
|
||||
nmc.get_main_context().iteration(may_block=True)
|
||||
|
||||
|
||||
def nmc_activate_check_good(nmc, completed_list):
|
||||
|
||||
# go through the list of activations and check that all of them are
|
||||
# in a good state.
|
||||
|
||||
n_good = 0
|
||||
n_bad = 0
|
||||
|
||||
for activ in completed_list:
|
||||
if activ["result"] is False:
|
||||
n_bad += 1
|
||||
continue
|
||||
ac = activ["result_ac"]
|
||||
if ac.get_client() is None:
|
||||
n_bad += 1
|
||||
continue
|
||||
if ac.get_state() != NM.ActiveConnectionState.ACTIVATED:
|
||||
n_bad += 1
|
||||
continue
|
||||
n_good += 1
|
||||
|
||||
log(
|
||||
"%d out of %d activations are now successfully activated"
|
||||
% (n_good, n_good + n_bad)
|
||||
)
|
||||
|
||||
return n_bad == 0
|
||||
|
||||
|
||||
def main():
|
||||
nmc = nmc_new()
|
||||
|
||||
cons = find_connections(nmc, sys.argv[1:])
|
||||
|
||||
completed_list = nmc_activate_all(nmc, cons)
|
||||
|
||||
nmc_activate_wait_for_pending(nmc, completed_list)
|
||||
|
||||
all_good = nmc_activate_check_good(nmc, completed_list)
|
||||
|
||||
nmc_transfer_ref = [nmc]
|
||||
del nmc
|
||||
nmc_destroy(nmc_transfer_ref)
|
||||
|
||||
sys.exit(0 if all_good else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@@ -6,7 +6,7 @@ project(
|
||||
# - add corresponding NM_VERSION_x_y_z macros in
|
||||
# "src/libnm-core-public/nm-version-macros.h.in"
|
||||
# - update number in configure.ac
|
||||
version: '1.32.0',
|
||||
version: '1.33.1',
|
||||
license: 'GPL2+',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
|
@@ -1051,6 +1051,12 @@ nm_shutdown_wait_obj_register_full(gpointer watched_obj,
|
||||
if (G_UNLIKELY(!_shutdown_waitobj_lst_head.next))
|
||||
c_list_init(&_shutdown_waitobj_lst_head);
|
||||
|
||||
/* Beware: there are callers with g_main_context_get_thread_default()
|
||||
* not being g_main_context_get_default(). For example _fw_nft_call().
|
||||
*
|
||||
* If you schedule any sources or async operations, you probably need to
|
||||
* make sure to use the default context. */
|
||||
|
||||
handle = g_slice_new(NMShutdownWaitObjHandle);
|
||||
*handle = (NMShutdownWaitObjHandle){
|
||||
/* depending on @free_msg_reason, we take ownership of @msg_reason.
|
||||
|
@@ -2378,8 +2378,6 @@ out:
|
||||
|
||||
typedef struct {
|
||||
NMUuid bin;
|
||||
char
|
||||
_nul_sentinel; /* just for safety, if somebody accidentally uses the binary in a string context. */
|
||||
|
||||
/* depending on whether the string is packed or not (with/without hyphens),
|
||||
* it's 32 or 36 characters long (plus the trailing NUL).
|
||||
@@ -2397,9 +2395,8 @@ _uuid_data_init(UuidData *uuid_data, gboolean packed, gboolean is_fake, const NM
|
||||
nm_assert(uuid_data);
|
||||
nm_assert(uuid);
|
||||
|
||||
uuid_data->bin = *uuid;
|
||||
uuid_data->_nul_sentinel = '\0';
|
||||
uuid_data->is_fake = is_fake;
|
||||
uuid_data->bin = *uuid;
|
||||
uuid_data->is_fake = is_fake;
|
||||
if (packed) {
|
||||
G_STATIC_ASSERT_EXPR(sizeof(uuid_data->str) >= (sizeof(*uuid) * 2 + 1));
|
||||
nm_utils_bin2hexstr_full(uuid, sizeof(*uuid), '\0', FALSE, uuid_data->str);
|
||||
@@ -2467,7 +2464,7 @@ again:
|
||||
|
||||
if (is_fake) {
|
||||
const guint8 *seed_bin;
|
||||
const char * hash_seed;
|
||||
const NMUuid *hash_seed;
|
||||
gsize seed_len;
|
||||
|
||||
if (!allow_fake) {
|
||||
@@ -2477,6 +2474,9 @@ again:
|
||||
}
|
||||
|
||||
if (nm_utils_host_id_get(&seed_bin, &seed_len)) {
|
||||
static const NMUuid u =
|
||||
NM_UUID_INIT(ab, 08, 5f, 06, b6, 29, 46, d1, a5, 53, 84, ee, ba, 56, 83, b6);
|
||||
|
||||
/* We have no valid machine-id but we have a valid secrey_key.
|
||||
* Generate a fake machine ID by hashing the secret-key. The secret_key
|
||||
* is commonly persisted, so it should be stable across reboots (despite
|
||||
@@ -2489,8 +2489,11 @@ again:
|
||||
* will call _machine_id_get(FALSE), so it won't allow accessing a fake
|
||||
* machine-id, thus avoiding the problem. */
|
||||
fake_type = "secret-key";
|
||||
hash_seed = "ab085f06-b629-46d1-a553-84eeba5683b6";
|
||||
hash_seed = &u;
|
||||
} else {
|
||||
static const NMUuid u =
|
||||
NM_UUID_INIT(7f, f0, c8, f5, 53, 99, 49, 01, ab, 63, 61, bf, 59, 4a, be, 8b);
|
||||
|
||||
/* the secret-key is not valid/persistent either. That happens when we fail
|
||||
* to read/write the secret-key to disk. Fallback to boot-id. The boot-id
|
||||
* itself may be fake and randomly generated ad-hoc, but that is as best
|
||||
@@ -2498,7 +2501,7 @@ again:
|
||||
seed_bin = (const guint8 *) nm_utils_boot_id_bin();
|
||||
seed_len = sizeof(NMUuid);
|
||||
fake_type = "boot-id";
|
||||
hash_seed = "7ff0c8f5-5399-4901-ab63-61bf594abe8b";
|
||||
hash_seed = &u;
|
||||
}
|
||||
|
||||
/* the fake machine-id is based on secret-key/boot-id, but we hash it
|
||||
@@ -2507,7 +2510,7 @@ again:
|
||||
(const char *) seed_bin,
|
||||
seed_len,
|
||||
NM_UUID_TYPE_VERSION5,
|
||||
(gpointer) hash_seed);
|
||||
hash_seed);
|
||||
}
|
||||
|
||||
if (!g_once_init_enter(&lock))
|
||||
|
@@ -758,21 +758,29 @@ struct _NMObjectClass {
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
#define _NM_OBJECT_CLASS_INIT_FIELD_INFO(_nm_object_class, _field_name, _offset, _num) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
(_nm_object_class)->_field_name = ({ \
|
||||
static _NMObjectClassFieldInfo _f; \
|
||||
\
|
||||
_f = (_NMObjectClassFieldInfo){ \
|
||||
.parent = (_nm_object_class)->_field_name, \
|
||||
.klass = (_nm_object_class), \
|
||||
.offset = _offset, \
|
||||
.num = _num, \
|
||||
}; \
|
||||
&_f; \
|
||||
}); \
|
||||
} \
|
||||
#define _NM_OBJECT_CLASS_INIT_FIELD_INFO(nm_object_class, field_name, _offset, _num) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
NMObjectClass *const _klass = (nm_object_class); \
|
||||
\
|
||||
_klass->field_name = ({ \
|
||||
static _NMObjectClassFieldInfo _f; \
|
||||
\
|
||||
/* this code is called inside a _class_init() function, it thus
|
||||
* is only executed once, so we are fine to initialize a static
|
||||
* variable here. */ \
|
||||
nm_assert(!_f.klass); \
|
||||
\
|
||||
_f = (_NMObjectClassFieldInfo){ \
|
||||
.parent = _klass->field_name, \
|
||||
.klass = _klass, \
|
||||
.offset = (_offset), \
|
||||
.num = (_num), \
|
||||
}; \
|
||||
\
|
||||
&_f; \
|
||||
}); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
#define _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, type_name, field_name) \
|
||||
|
@@ -478,6 +478,36 @@ test_nm_hash(void)
|
||||
g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031);
|
||||
g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 0, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x031);
|
||||
g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 1, 0, 0, 1, 1, 0, 0, 0, 1), ==, 0x131);
|
||||
g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1),
|
||||
==,
|
||||
0x131);
|
||||
g_assert_cmpint(NM_HASH_COMBINE_BOOLS(guint16, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1),
|
||||
==,
|
||||
0x8131);
|
||||
g_assert_cmpint(
|
||||
NM_HASH_COMBINE_BOOLS(guint32, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1),
|
||||
==,
|
||||
0x8131);
|
||||
g_assert_cmpint(
|
||||
NM_HASH_COMBINE_BOOLS(guint32, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1),
|
||||
==,
|
||||
0x28131);
|
||||
|
||||
#if _NM_CC_SUPPORT_AUTO_TYPE
|
||||
{
|
||||
_nm_auto_type x = NM_HASH_COMBINE_BOOLS(guint8, 0, 0, 1, 1, 0, 0, 0, 1);
|
||||
|
||||
G_STATIC_ASSERT(sizeof(x) == 1);
|
||||
g_assert(((typeof(x)) -1) > 0);
|
||||
}
|
||||
|
||||
{
|
||||
_nm_auto_type x = NM_HASH_COMBINE_BOOLS(guint16, 0, 0, 1, 1, 0, 0, 0, 1);
|
||||
|
||||
G_STATIC_ASSERT(sizeof(x) == 2);
|
||||
g_assert(((typeof(x)) -1) > 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -7208,11 +7238,10 @@ test_nm_strquote(void)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define UUID_NS_ZERO "00000000-0000-0000-0000-000000000000"
|
||||
#define UUID_NS_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||
#define UUID_NS_URL "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
|
||||
#define UUID_NS_OID "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
|
||||
#define UUID_NS_X500 "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
|
||||
#define NM_UUID_NS_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
|
||||
#define NM_UUID_NS_URL "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
|
||||
#define NM_UUID_NS_OID "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
|
||||
#define NM_UUID_NS_X500 "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
|
||||
|
||||
static const NMUuid *
|
||||
_uuid(const char *str)
|
||||
@@ -7229,11 +7258,18 @@ _test_uuid(int uuid_type,
|
||||
const char *expected_uuid,
|
||||
const char *str,
|
||||
gssize slen,
|
||||
gpointer type_args)
|
||||
const char *type_args)
|
||||
{
|
||||
gs_free char *uuid_test = NULL;
|
||||
gs_free char *uuid_test = NULL;
|
||||
NMUuid type_args_u = NM_UUID_INIT_ZERO();
|
||||
|
||||
uuid_test = nm_uuid_generate_from_string_str(str, slen, uuid_type, type_args);
|
||||
if (type_args) {
|
||||
if (!nm_uuid_parse(type_args, &type_args_u))
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
uuid_test =
|
||||
nm_uuid_generate_from_string_str(str, slen, uuid_type, type_args ? &type_args_u : NULL);
|
||||
|
||||
g_assert(uuid_test);
|
||||
g_assert(nm_utils_is_uuid(uuid_test));
|
||||
@@ -7244,7 +7280,7 @@ _test_uuid(int uuid_type,
|
||||
str,
|
||||
(long long) slen,
|
||||
NM_IN_SET(uuid_type, NM_UUID_TYPE_VERSION3, NM_UUID_TYPE_VERSION5)
|
||||
? (((const char *) type_args) ?: "(all-zero)")
|
||||
? (type_args ?: "(all-zero)")
|
||||
: (type_args ? "(unknown)" : "(null)"),
|
||||
uuid_test,
|
||||
expected_uuid);
|
||||
@@ -7259,8 +7295,8 @@ _test_uuid(int uuid_type,
|
||||
}
|
||||
|
||||
if (NM_IN_SET(uuid_type, NM_UUID_TYPE_VERSION3, NM_UUID_TYPE_VERSION5) && !type_args) {
|
||||
/* For version3 and version5, a missing @type_args is equal to UUID_NS_ZERO */
|
||||
_test_uuid(uuid_type, expected_uuid, str, slen, UUID_NS_ZERO);
|
||||
/* For version3 and version5, a missing @type_args is equal to NM_UUID_NS_ZERO */
|
||||
_test_uuid(uuid_type, expected_uuid, str, slen, NM_UUID_NS_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7694,33 +7730,53 @@ test_nm_utils_uuid_generate_from_string(void)
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3, "96e17d7a-ac89-38cf-95e1-bf5098da34e1", "test", -1, NULL);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3, "8156568e-4ae6-3f34-a93e-18e2c6cbbf78", "a\0b", 3, NULL);
|
||||
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3, "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", "", -1, UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3, "4c104dd0-4821-30d5-9ce3-0e7a1f8b7c0d", "a", -1, UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"c87ee674-4ddc-3efe-a74e-dfe25da5d7b3",
|
||||
"",
|
||||
-1,
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"4c104dd0-4821-30d5-9ce3-0e7a1f8b7c0d",
|
||||
"a",
|
||||
-1,
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"45a113ac-c7f2-30b0-90a5-a399ab912716",
|
||||
"test",
|
||||
-1,
|
||||
UUID_NS_DNS);
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"002a0ada-f547-375a-bab5-896a11d1927e",
|
||||
"a\0b",
|
||||
3,
|
||||
UUID_NS_DNS);
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"9a75f5f2-195e-31a9-9d07-8c18b5d3b285",
|
||||
"test123",
|
||||
-1,
|
||||
UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3, "ec794efe-a384-3b11-a0b6-ec8995bc6acc", "x", -1, UUID_NS_DNS);
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"ec794efe-a384-3b11-a0b6-ec8995bc6acc",
|
||||
"x",
|
||||
-1,
|
||||
NM_UUID_NS_DNS);
|
||||
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5, "a7650b9f-f19f-5300-8a13-91160ea8de2c", "a\0b", 3, NULL);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5, "4f3f2898-69e3-5a0d-820a-c4e87987dbce", "a", -1, UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5, "05b16a01-46c6-56dd-bd6e-c6dfb4a1427a", "x", -1, UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"4f3f2898-69e3-5a0d-820a-c4e87987dbce",
|
||||
"a",
|
||||
-1,
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"05b16a01-46c6-56dd-bd6e-c6dfb4a1427a",
|
||||
"x",
|
||||
-1,
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"c9ed566a-6b79-5d3a-b2b7-96a936b48cf3",
|
||||
"test123",
|
||||
-1,
|
||||
UUID_NS_DNS);
|
||||
NM_UUID_NS_DNS);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(zero_uuids); i++) {
|
||||
nm_sprintf_buf(i_str, "%u", i),
|
||||
@@ -7729,8 +7785,8 @@ test_nm_utils_uuid_generate_from_string(void)
|
||||
}
|
||||
for (i = 0; i < G_N_ELEMENTS(dns_uuids); i++) {
|
||||
nm_sprintf_buf(i_str, "%u", i),
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3, dns_uuids[i].uuid3, i_str, -1, UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5, dns_uuids[i].uuid5, i_str, -1, UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3, dns_uuids[i].uuid3, i_str, -1, NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5, dns_uuids[i].uuid5, i_str, -1, NM_UUID_NS_DNS);
|
||||
}
|
||||
|
||||
/* examples from cpython unit tests: */
|
||||
@@ -7738,48 +7794,48 @@ test_nm_utils_uuid_generate_from_string(void)
|
||||
"6fa459ea-ee8a-3ca4-894e-db77e160355e",
|
||||
"python.org",
|
||||
-1,
|
||||
UUID_NS_DNS);
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"886313e1-3b8a-5372-9b90-0c9aee199e5d",
|
||||
"python.org",
|
||||
-1,
|
||||
UUID_NS_DNS);
|
||||
NM_UUID_NS_DNS);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"9fe8e8c4-aaa8-32a9-a55c-4535a88b748d",
|
||||
"http://python.org/",
|
||||
-1,
|
||||
UUID_NS_URL);
|
||||
NM_UUID_NS_URL);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"4c565f0d-3f5a-5890-b41b-20cf47701c5e",
|
||||
"http://python.org/",
|
||||
-1,
|
||||
UUID_NS_URL);
|
||||
NM_UUID_NS_URL);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"dd1a1cef-13d5-368a-ad82-eca71acd4cd1",
|
||||
"1.3.6.1",
|
||||
-1,
|
||||
UUID_NS_OID);
|
||||
NM_UUID_NS_OID);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"1447fa61-5277-5fef-a9b3-fbc6e44f4af3",
|
||||
"1.3.6.1",
|
||||
-1,
|
||||
UUID_NS_OID);
|
||||
NM_UUID_NS_OID);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION3,
|
||||
"658d3002-db6b-3040-a1d1-8ddd7d189a4d",
|
||||
"c=ca",
|
||||
-1,
|
||||
UUID_NS_X500);
|
||||
NM_UUID_NS_X500);
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"cc957dd1-a972-5349-98cd-874190002798",
|
||||
"c=ca",
|
||||
-1,
|
||||
UUID_NS_X500);
|
||||
NM_UUID_NS_X500);
|
||||
|
||||
_test_uuid(NM_UUID_TYPE_VERSION5,
|
||||
"74738ff5-5367-5958-9aee-98fffdcd1876",
|
||||
"www.example.org",
|
||||
-1,
|
||||
UUID_NS_DNS);
|
||||
NM_UUID_NS_DNS);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -7799,7 +7855,7 @@ __test_uuid(const char *expected_uuid, const char *str, gssize slen, char *uuid_
|
||||
}
|
||||
g_free(uuid_test);
|
||||
|
||||
uuid_test = nm_uuid_generate_from_string_str(str, slen, NM_UUID_TYPE_VERSION3, NM_UUID_NS1);
|
||||
uuid_test = nm_uuid_generate_from_string_str(str, slen, NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1);
|
||||
|
||||
g_assert(uuid_test);
|
||||
g_assert(nm_utils_is_uuid(uuid_test));
|
||||
@@ -7820,15 +7876,23 @@ __test_uuid(const char *expected_uuid, const char *str, gssize slen, char *uuid_
|
||||
static void
|
||||
test_nm_utils_uuid_generate_from_strings(void)
|
||||
{
|
||||
const NMUuid uuid0 = {};
|
||||
const NMUuid uuid0 = NM_UUID_INIT_ZERO();
|
||||
const NMUuid uuid1 = {};
|
||||
char buf[37];
|
||||
|
||||
g_assert_cmpmem(&uuid0, sizeof(uuid0), _uuid("00000000-0000-0000-0000-000000000000"), 16);
|
||||
|
||||
g_assert_cmpmem(&uuid0, sizeof(NMUuid), &uuid1, sizeof(NMUuid));
|
||||
|
||||
g_assert(nm_uuid_is_null(NULL));
|
||||
g_assert(nm_uuid_is_null(&uuid0));
|
||||
g_assert(nm_uuid_is_null(&nm_uuid_ns_zero));
|
||||
g_assert(nm_uuid_is_null(_uuid("00000000-0000-0000-0000-000000000000")));
|
||||
g_assert(!nm_uuid_is_null(_uuid("10000000-0000-0000-0000-000000000000")));
|
||||
|
||||
g_assert_cmpstr(NM_UUID_NS_1, ==, nm_uuid_unparse(&nm_uuid_ns_1, buf));
|
||||
g_assert_cmpstr(NM_UUID_NS_ZERO, ==, nm_uuid_unparse(&nm_uuid_ns_zero, buf));
|
||||
|
||||
_test_uuid("b07c334a-399b-32de-8d50-58e4e08f98e3", "", 0, NULL);
|
||||
_test_uuid("b8a426cb-bcb5-30a3-bd8f-6786fea72df9", "\0", 1, "");
|
||||
_test_uuid("12a4a982-7aae-39e1-951e-41aeb1250959", "a\0", 2, "a");
|
||||
@@ -7845,6 +7909,32 @@ test_nm_utils_uuid_generate_from_strings(void)
|
||||
_test_uuid("dd265bf7-c05a-3037-9939-b9629858a477", "a\0b\0", 4, "a", "b");
|
||||
}
|
||||
|
||||
static void
|
||||
test_nm_uuid_init(void)
|
||||
{
|
||||
char buf[37];
|
||||
|
||||
{
|
||||
NMUuid u;
|
||||
|
||||
u = NM_UUID_INIT(47, c4, d7, f9, 2c, 81, 4f, 7b, be, ed, 63, 0a, 7f, 65, cc, 02);
|
||||
g_assert_cmpstr("47c4d7f9-2c81-4f7b-beed-630a7f65cc02", ==, nm_uuid_unparse(&u, buf));
|
||||
}
|
||||
{
|
||||
const NMUuid u =
|
||||
NM_UUID_INIT(47, c4, d7, f9, 2c, 81, 4f, 7b, be, ed, 63, 0a, 7f, 65, cc, 02);
|
||||
|
||||
g_assert_cmpstr("47c4d7f9-2c81-4f7b-beed-630a7f65cc02", ==, nm_uuid_unparse(&u, buf));
|
||||
}
|
||||
{
|
||||
const struct {
|
||||
NMUuid u;
|
||||
} u = {NM_UUID_INIT(47, c4, d7, f9, 2c, 81, 4f, 7b, be, ed, 63, 0a, 7f, 65, cc, 02)};
|
||||
|
||||
g_assert_cmpstr("47c4d7f9-2c81-4f7b-beed-630a7f65cc02", ==, nm_uuid_unparse(&u.u, buf));
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
@@ -9773,11 +9863,53 @@ test_nm_va_args_macros(void)
|
||||
g_assert_cmpint(7, ==, GET_NARG_1(x, x, x, x, x, x, x));
|
||||
g_assert_cmpint(8, ==, GET_NARG_1(x, x, x, x, x, x, x, x));
|
||||
g_assert_cmpint(9, ==, GET_NARG_1(x, x, x, x, x, x, x, x, x));
|
||||
g_assert_cmpint(10, ==, GET_NARG_1(x, x, x, x, x, x, x, x, x, x));
|
||||
g_assert_cmpint(10, ==, NM_NARG(x, x, x, x, x, x, x, x, x, x));
|
||||
|
||||
G_STATIC_ASSERT_EXPR(0 == GET_NARG_1());
|
||||
G_STATIC_ASSERT_EXPR(1 == GET_NARG_1(x));
|
||||
G_STATIC_ASSERT_EXPR(2 == GET_NARG_1(x, x));
|
||||
|
||||
/* clang-format off */
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG(
|
||||
1,2,3,4,5,6,7,8,9,10,
|
||||
1,2,3,4,5,6,7,8,9,20,
|
||||
1,2,3,4,5,6,7,8,9,30
|
||||
) == 30);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG(
|
||||
1,2,3,4,5,6,7,8,9,10,
|
||||
1,2,3,4,5,6,7,8,9,20,
|
||||
1,2,3,4,5,6,7,8,9,30,
|
||||
1,2,3,4,5,6,7,8,9,40,
|
||||
1,2,3,4,5,6,7,8,9,50,
|
||||
1,2,3,4,5,6,7,8,9,60,
|
||||
1,2,3,4,5,6,7,8,9,70,
|
||||
1,2,3,4,5,6,7,8,9,80
|
||||
) == 80);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG(
|
||||
1,2,3,4,5,6,7,8,9,10,
|
||||
1,2,3,4,5,6,7,8,9,20,
|
||||
1,2,3,4,5,6,7,8,9,30,
|
||||
1,2,3,4,5,6,7,8,9,40,
|
||||
1,2,3,4,5,6,7,8,9,50,
|
||||
1,2,3,4,5,6,7,8,9,60,
|
||||
1,2,3,4,5,6,7,8,9,70,
|
||||
1,2,3,4,5,6,7,8,9,80,
|
||||
1,2,3,4,5,6,7,8,9,90,
|
||||
1,2,3,4,5,6,7,8,9,100,
|
||||
1,2,3,4,5,6,7,8,9,110,
|
||||
1,2,3,4,5,6,7,8,9,120
|
||||
) == 120);
|
||||
/* clang-format on */
|
||||
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX1() == 0);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX1(1) == 1);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX1(1, 2) == 1);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX1(1, 2, 3) == 1);
|
||||
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX2() == 0);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX2(1) == 1);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX2(1, 2) == 2);
|
||||
G_STATIC_ASSERT_EXPR(NM_NARG_MAX2(1, 2, 3) == 2);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -10796,6 +10928,7 @@ main(int argc, char **argv)
|
||||
test_nm_utils_uuid_generate_from_string);
|
||||
g_test_add_func("/core/general/nm_uuid_generate_from_strings",
|
||||
test_nm_utils_uuid_generate_from_strings);
|
||||
g_test_add_func("/core/general/test_nm_uuid_init", test_nm_uuid_init);
|
||||
|
||||
g_test_add_func("/core/general/_nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64);
|
||||
g_test_add_func("/core/general/nm_utils_is_power_of_two", test_nm_utils_is_power_of_two);
|
||||
|
@@ -122,138 +122,32 @@ nm_hash_update_bool(NMHashState *state, bool val)
|
||||
nm_hash_update(state, &val, sizeof(val));
|
||||
}
|
||||
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_1(t, y) ((y) ? ((t) (1ull << 0)) : ((t) 0ull))
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_2(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 1)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_1(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_3(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 2)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_2(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_4(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 3)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_3(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_5(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 4)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_4(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_6(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 5)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_5(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_7(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 6)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_6(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_8(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 7)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_7(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_9(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 8)) : ((t) 0ull)) \
|
||||
| (G_STATIC_ASSERT_EXPR(sizeof(t) >= 2), (_NM_HASH_COMBINE_BOOLS_x_8(t, __VA_ARGS__)))
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_10(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 9)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_9(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_x_11(t, y, ...) \
|
||||
((y) ? ((t) (1ull << 10)) : ((t) 0ull)) | _NM_HASH_COMBINE_BOOLS_x_10(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_n2(t, n, ...) _NM_HASH_COMBINE_BOOLS_x_##n(t, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_n(t, n, ...) _NM_HASH_COMBINE_BOOLS_n2(t, n, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_BOOLS_OP(x, n) \
|
||||
((x) ? ((_nm_hash_combine_bools_type) NM_BIT((n))) : ((_nm_hash_combine_bools_type) 0))
|
||||
|
||||
#define NM_HASH_COMBINE_BOOLS(type, ...) \
|
||||
((type) (_NM_HASH_COMBINE_BOOLS_n(type, NM_NARG(__VA_ARGS__), __VA_ARGS__)))
|
||||
#define NM_HASH_COMBINE_BOOLS(type, ...) \
|
||||
({ \
|
||||
typedef type _nm_hash_combine_bools_type; \
|
||||
\
|
||||
G_STATIC_ASSERT(NM_NARG(__VA_ARGS__) <= 8 * sizeof(_nm_hash_combine_bools_type)); \
|
||||
\
|
||||
(_nm_hash_combine_bools_type)( \
|
||||
NM_VA_ARGS_FOREACH(, , |, _NM_HASH_COMBINE_BOOLS_OP, __VA_ARGS__)); \
|
||||
})
|
||||
|
||||
#define nm_hash_update_bools(state, ...) \
|
||||
nm_hash_update_val(state, NM_HASH_COMBINE_BOOLS(guint8, __VA_ARGS__))
|
||||
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_1(y) typeof(y) _v1;
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_2(y, ...) \
|
||||
typeof(y) _v2; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_1(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_3(y, ...) \
|
||||
typeof(y) _v3; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_2(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_4(y, ...) \
|
||||
typeof(y) _v4; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_3(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_5(y, ...) \
|
||||
typeof(y) _v5; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_4(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_6(y, ...) \
|
||||
typeof(y) _v6; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_5(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_7(y, ...) \
|
||||
typeof(y) _v7; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_6(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_8(y, ...) \
|
||||
typeof(y) _v8; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_7(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_9(y, ...) \
|
||||
typeof(y) _v9; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_8(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_10(y, ...) \
|
||||
typeof(y) _v10; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_9(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_11(y, ...) \
|
||||
typeof(y) _v11; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_10(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_12(y, ...) \
|
||||
typeof(y) _v12; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_11(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_13(y, ...) \
|
||||
typeof(y) _v13; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_12(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_14(y, ...) \
|
||||
typeof(y) _v14; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_13(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_15(y, ...) \
|
||||
typeof(y) _v15; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_14(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_16(y, ...) \
|
||||
typeof(y) _v16; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_15(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_17(y, ...) \
|
||||
typeof(y) _v17; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_16(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_18(y, ...) \
|
||||
typeof(y) _v18; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_17(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_19(y, ...) \
|
||||
typeof(y) _v19; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_18(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_x_20(y, ...) \
|
||||
typeof(y) _v20; \
|
||||
_NM_HASH_COMBINE_VALS_typ_x_19(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_n2(n, ...) _NM_HASH_COMBINE_VALS_typ_x_##n(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_typ_n(n, ...) _NM_HASH_COMBINE_VALS_typ_n2(n, __VA_ARGS__)
|
||||
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_1(y) ._v1 = (y),
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_2(y, ...) ._v2 = (y), _NM_HASH_COMBINE_VALS_val_x_1(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_3(y, ...) ._v3 = (y), _NM_HASH_COMBINE_VALS_val_x_2(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_4(y, ...) ._v4 = (y), _NM_HASH_COMBINE_VALS_val_x_3(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_5(y, ...) ._v5 = (y), _NM_HASH_COMBINE_VALS_val_x_4(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_6(y, ...) ._v6 = (y), _NM_HASH_COMBINE_VALS_val_x_5(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_7(y, ...) ._v7 = (y), _NM_HASH_COMBINE_VALS_val_x_6(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_8(y, ...) ._v8 = (y), _NM_HASH_COMBINE_VALS_val_x_7(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_9(y, ...) ._v9 = (y), _NM_HASH_COMBINE_VALS_val_x_8(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_10(y, ...) \
|
||||
._v10 = (y), _NM_HASH_COMBINE_VALS_val_x_9(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_11(y, ...) \
|
||||
._v11 = (y), _NM_HASH_COMBINE_VALS_val_x_10(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_12(y, ...) \
|
||||
._v12 = (y), _NM_HASH_COMBINE_VALS_val_x_11(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_13(y, ...) \
|
||||
._v13 = (y), _NM_HASH_COMBINE_VALS_val_x_12(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_14(y, ...) \
|
||||
._v14 = (y), _NM_HASH_COMBINE_VALS_val_x_13(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_15(y, ...) \
|
||||
._v15 = (y), _NM_HASH_COMBINE_VALS_val_x_14(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_16(y, ...) \
|
||||
._v16 = (y), _NM_HASH_COMBINE_VALS_val_x_15(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_17(y, ...) \
|
||||
._v17 = (y), _NM_HASH_COMBINE_VALS_val_x_16(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_18(y, ...) \
|
||||
._v18 = (y), _NM_HASH_COMBINE_VALS_val_x_17(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_19(y, ...) \
|
||||
._v19 = (y), _NM_HASH_COMBINE_VALS_val_x_18(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_x_20(y, ...) \
|
||||
._v20 = (y), _NM_HASH_COMBINE_VALS_val_x_19(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_n2(n, ...) _NM_HASH_COMBINE_VALS_val_x_##n(__VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_val_n(n, ...) _NM_HASH_COMBINE_VALS_val_n2(n, __VA_ARGS__)
|
||||
#define _NM_HASH_COMBINE_VALS_TYPE_OP(x, idx) typeof(x) _v##idx;
|
||||
#define _NM_HASH_COMBINE_VALS_INIT_OP(x, idx) ._v##idx = (x),
|
||||
|
||||
/* NM_HASH_COMBINE_VALS() is faster then nm_hash_update_val() as it combines multiple
|
||||
* calls to nm_hash_update() using a packed structure. */
|
||||
#define NM_HASH_COMBINE_VALS(var, ...) \
|
||||
const struct _nm_packed { \
|
||||
_NM_HASH_COMBINE_VALS_typ_n(NM_NARG(__VA_ARGS__), __VA_ARGS__) \
|
||||
} var _nm_alignas(guint64) = {_NM_HASH_COMBINE_VALS_val_n(NM_NARG(__VA_ARGS__), __VA_ARGS__)}
|
||||
#define NM_HASH_COMBINE_VALS(var, ...) \
|
||||
const struct _nm_packed { \
|
||||
NM_VA_ARGS_FOREACH(, , , _NM_HASH_COMBINE_VALS_TYPE_OP, __VA_ARGS__) \
|
||||
} var _nm_alignas(guint64) = { \
|
||||
NM_VA_ARGS_FOREACH(, , , _NM_HASH_COMBINE_VALS_INIT_OP, __VA_ARGS__)}
|
||||
|
||||
/* nm_hash_update_vals() is faster then nm_hash_update_val() as it combines multiple
|
||||
* calls to nm_hash_update() using a packed structure. */
|
||||
|
@@ -163,280 +163,6 @@ _nm_auto_freev(gpointer ptr)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_MACRO_SELECT_ARG_64(_1, \
|
||||
_2, \
|
||||
_3, \
|
||||
_4, \
|
||||
_5, \
|
||||
_6, \
|
||||
_7, \
|
||||
_8, \
|
||||
_9, \
|
||||
_10, \
|
||||
_11, \
|
||||
_12, \
|
||||
_13, \
|
||||
_14, \
|
||||
_15, \
|
||||
_16, \
|
||||
_17, \
|
||||
_18, \
|
||||
_19, \
|
||||
_20, \
|
||||
_21, \
|
||||
_22, \
|
||||
_23, \
|
||||
_24, \
|
||||
_25, \
|
||||
_26, \
|
||||
_27, \
|
||||
_28, \
|
||||
_29, \
|
||||
_30, \
|
||||
_31, \
|
||||
_32, \
|
||||
_33, \
|
||||
_34, \
|
||||
_35, \
|
||||
_36, \
|
||||
_37, \
|
||||
_38, \
|
||||
_39, \
|
||||
_40, \
|
||||
_41, \
|
||||
_42, \
|
||||
_43, \
|
||||
_44, \
|
||||
_45, \
|
||||
_46, \
|
||||
_47, \
|
||||
_48, \
|
||||
_49, \
|
||||
_50, \
|
||||
_51, \
|
||||
_52, \
|
||||
_53, \
|
||||
_54, \
|
||||
_55, \
|
||||
_56, \
|
||||
_57, \
|
||||
_58, \
|
||||
_59, \
|
||||
_60, \
|
||||
_61, \
|
||||
_62, \
|
||||
_63, \
|
||||
N, \
|
||||
...) \
|
||||
N
|
||||
|
||||
/* http://stackoverflow.com/a/2124385/354393
|
||||
* https://stackoverflow.com/questions/11317474/macro-to-count-number-of-arguments
|
||||
*/
|
||||
|
||||
#define NM_NARG(...) \
|
||||
_NM_MACRO_SELECT_ARG_64(, \
|
||||
##__VA_ARGS__, \
|
||||
62, \
|
||||
61, \
|
||||
60, \
|
||||
59, \
|
||||
58, \
|
||||
57, \
|
||||
56, \
|
||||
55, \
|
||||
54, \
|
||||
53, \
|
||||
52, \
|
||||
51, \
|
||||
50, \
|
||||
49, \
|
||||
48, \
|
||||
47, \
|
||||
46, \
|
||||
45, \
|
||||
44, \
|
||||
43, \
|
||||
42, \
|
||||
41, \
|
||||
40, \
|
||||
39, \
|
||||
38, \
|
||||
37, \
|
||||
36, \
|
||||
35, \
|
||||
34, \
|
||||
33, \
|
||||
32, \
|
||||
31, \
|
||||
30, \
|
||||
29, \
|
||||
28, \
|
||||
27, \
|
||||
26, \
|
||||
25, \
|
||||
24, \
|
||||
23, \
|
||||
22, \
|
||||
21, \
|
||||
20, \
|
||||
19, \
|
||||
18, \
|
||||
17, \
|
||||
16, \
|
||||
15, \
|
||||
14, \
|
||||
13, \
|
||||
12, \
|
||||
11, \
|
||||
10, \
|
||||
9, \
|
||||
8, \
|
||||
7, \
|
||||
6, \
|
||||
5, \
|
||||
4, \
|
||||
3, \
|
||||
2, \
|
||||
1, \
|
||||
0)
|
||||
#define NM_NARG_MAX1(...) \
|
||||
_NM_MACRO_SELECT_ARG_64(, \
|
||||
##__VA_ARGS__, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
0)
|
||||
#define NM_NARG_MAX2(...) \
|
||||
_NM_MACRO_SELECT_ARG_64(, \
|
||||
##__VA_ARGS__, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
2, \
|
||||
1, \
|
||||
0)
|
||||
|
||||
#define _NM_MACRO_CALL(macro, ...) macro(__VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_MACRO_COMMA_IF_ARGS(...) \
|
||||
_NM_MACRO_CALL(G_PASTE(__NM_MACRO_COMMA_IF_ARGS_, NM_NARG_MAX1(__VA_ARGS__)), __VA_ARGS__)
|
||||
#define __NM_MACRO_COMMA_IF_ARGS_0()
|
||||
@@ -1253,27 +979,21 @@ nm_g_variant_take_ref(GVariant *v)
|
||||
return (v); \
|
||||
}
|
||||
#define NM_UTILS_LOOKUP_ITEM(v, n) \
|
||||
(void) 0; \
|
||||
case v: \
|
||||
return (n); \
|
||||
(void) 0
|
||||
return (n);
|
||||
#define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, "" n "")
|
||||
#define NM_UTILS_LOOKUP_ITEM_IGNORE(v) \
|
||||
(void) 0; \
|
||||
case v: \
|
||||
break; \
|
||||
(void) 0
|
||||
break;
|
||||
#define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() \
|
||||
(void) 0; \
|
||||
default: \
|
||||
break; \
|
||||
(void) 0
|
||||
break;
|
||||
|
||||
#define NM_UTILS_LOOKUP_DEFINE(fcn_name, lookup_type, result_type, unknown_val, ...) \
|
||||
result_type fcn_name(lookup_type val) \
|
||||
{ \
|
||||
switch (val) { \
|
||||
(void) 0, __VA_ARGS__(void) 0; \
|
||||
NM_VA_ARGS_JOIN(, __VA_ARGS__) \
|
||||
}; \
|
||||
{ \
|
||||
unknown_val; \
|
||||
@@ -1479,17 +1199,15 @@ nm_strcmp_p(gconstpointer a, gconstpointer b)
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline int
|
||||
_NM_IN_STRSET_ASCII_CASE_op_streq(const char *x, const char *s)
|
||||
_NM_IN_STRSET_EVAL_op_streq_ascii_case(const char *x1, const char *x)
|
||||
{
|
||||
return s && g_ascii_strcasecmp(x, s) == 0;
|
||||
return x && g_ascii_strcasecmp(x1, x) == 0;
|
||||
}
|
||||
|
||||
#define NM_IN_STRSET_ASCII_CASE(x, ...) \
|
||||
_NM_IN_STRSET_EVAL_N(||, \
|
||||
_NM_IN_STRSET_ASCII_CASE_op_streq, \
|
||||
x, \
|
||||
NM_NARG(__VA_ARGS__), \
|
||||
__VA_ARGS__)
|
||||
#define _NM_IN_STRSET_EVAL_OP_STREQ_ASCII_CASE(x, idx) \
|
||||
_NM_IN_STRSET_EVAL_op_streq_ascii_case(_x1, x)
|
||||
#define NM_IN_STRSET_ASCII_CASE(x1, ...) \
|
||||
_NM_IN_STRSET_EVAL(||, _NM_IN_STRSET_EVAL_OP_STREQ_ASCII_CASE, x1, __VA_ARGS__)
|
||||
|
||||
#define NM_STR_HAS_SUFFIX_ASCII_CASE(str, suffix) \
|
||||
({ \
|
||||
|
@@ -1068,16 +1068,12 @@ const char *nm_utils_flags2str(const NMUtilsFlags2StrDesc *descs,
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_UTILS_ENUM2STR(v, n) \
|
||||
(void) 0; \
|
||||
case v: \
|
||||
s = "" n ""; \
|
||||
break; \
|
||||
(void) 0
|
||||
break;
|
||||
#define NM_UTILS_ENUM2STR_IGNORE(v) \
|
||||
(void) 0; \
|
||||
case v: \
|
||||
break; \
|
||||
(void) 0
|
||||
break;
|
||||
|
||||
#define NM_UTILS_ENUM2STR_DEFINE_FULL(fcn_name, lookup_type, int_fmt, ...) \
|
||||
const char *fcn_name(lookup_type val, char *buf, gsize len) \
|
||||
@@ -1086,7 +1082,7 @@ case v: \
|
||||
if (len) { \
|
||||
const char *s = NULL; \
|
||||
switch (val) { \
|
||||
(void) 0, __VA_ARGS__(void) 0; \
|
||||
NM_VA_ARGS_JOIN(, __VA_ARGS__) \
|
||||
}; \
|
||||
if (s) \
|
||||
g_strlcpy(buf, s, len); \
|
||||
@@ -1106,14 +1102,26 @@ case v: \
|
||||
static inline void _nm_g_slice_free_fcn_##mem_size(gpointer mem_block) \
|
||||
{ \
|
||||
g_slice_free1(mem_size, mem_block); \
|
||||
}
|
||||
} \
|
||||
_NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON
|
||||
|
||||
_nm_g_slice_free_fcn_define(1) _nm_g_slice_free_fcn_define(2) _nm_g_slice_free_fcn_define(4)
|
||||
_nm_g_slice_free_fcn_define(8) _nm_g_slice_free_fcn_define(10) _nm_g_slice_free_fcn_define(12)
|
||||
_nm_g_slice_free_fcn_define(16) _nm_g_slice_free_fcn_define(32)
|
||||
_nm_g_slice_free_fcn_define(1);
|
||||
_nm_g_slice_free_fcn_define(2);
|
||||
_nm_g_slice_free_fcn_define(4);
|
||||
_nm_g_slice_free_fcn_define(8);
|
||||
_nm_g_slice_free_fcn_define(10);
|
||||
_nm_g_slice_free_fcn_define(12);
|
||||
_nm_g_slice_free_fcn_define(16);
|
||||
_nm_g_slice_free_fcn_define(32);
|
||||
|
||||
_nm_warn_unused_result static inline GDestroyNotify
|
||||
_nm_get_warn_unused_result_gdestroynotify(GDestroyNotify f)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
#define nm_g_slice_free_fcn1(mem_size) \
|
||||
({ \
|
||||
_nm_get_warn_unused_result_gdestroynotify(({ \
|
||||
void (*_fcn)(gpointer); \
|
||||
\
|
||||
/* If mem_size is a compile time constant, the compiler
|
||||
@@ -1152,8 +1160,9 @@ _nm_g_slice_free_fcn_define(1) _nm_g_slice_free_fcn_define(2) _nm_g_slice_free_f
|
||||
_fcn = NULL; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
_fcn; \
|
||||
})
|
||||
}))
|
||||
|
||||
/**
|
||||
* nm_g_slice_free_fcn:
|
||||
@@ -1184,7 +1193,8 @@ _nm_g_slice_free_fcn_define(1) _nm_g_slice_free_fcn_define(2) _nm_g_slice_free_f
|
||||
_error && _error->domain == (err_domain) && NM_IN_SET(_error->code, __VA_ARGS__); \
|
||||
})
|
||||
|
||||
static inline void nm_g_set_error_take(GError **error, GError *error_take)
|
||||
static inline void
|
||||
nm_g_set_error_take(GError **error, GError *error_take)
|
||||
{
|
||||
if (!error_take)
|
||||
g_return_if_reached();
|
||||
|
@@ -9,6 +9,13 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const NMUuid nm_uuid_ns_zero =
|
||||
NM_UUID_INIT(00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00);
|
||||
|
||||
/* arbitrarily chosen namespace UUID for nm_uuid_generate_from_strings() */
|
||||
const NMUuid nm_uuid_ns_1 =
|
||||
NM_UUID_INIT(b4, 25, e9, fb, 75, 98, 44, b4, 9e, 3b, 5a, 2e, 3a, aa, 49, 05);
|
||||
|
||||
char *
|
||||
nm_uuid_unparse_case(const NMUuid *uuid, char out_str[static 37], gboolean upper_case)
|
||||
{
|
||||
@@ -239,11 +246,12 @@ nm_uuid_is_valid_nm(const char *str,
|
||||
str_lower[i] = g_ascii_tolower(str_lower[i]);
|
||||
|
||||
/* The namespace UUID is chosen randomly. */
|
||||
nm_uuid_generate_from_string(&uuid,
|
||||
str_lower,
|
||||
-1,
|
||||
NM_UUID_TYPE_VERSION5,
|
||||
"4e72f709-ca95-4405-9053-1f43294a618c");
|
||||
nm_uuid_generate_from_string(
|
||||
&uuid,
|
||||
str_lower,
|
||||
-1,
|
||||
NM_UUID_TYPE_VERSION5,
|
||||
&NM_UUID_INIT(4e, 72, f7, 09, ca, 95, 44, 05, 90, 53, 1f, 43, 29, 4a, 61, 8c));
|
||||
nm_uuid_unparse(&uuid, out_normalized_str);
|
||||
}
|
||||
return TRUE;
|
||||
@@ -299,11 +307,11 @@ nm_uuid_generate_random_str(char buf[static 37])
|
||||
* Returns: the input @uuid. This function cannot fail.
|
||||
**/
|
||||
NMUuid *
|
||||
nm_uuid_generate_from_string(NMUuid * uuid,
|
||||
const char *s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
gpointer type_args)
|
||||
nm_uuid_generate_from_string(NMUuid * uuid,
|
||||
const char * s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
const NMUuid *type_args)
|
||||
{
|
||||
g_return_val_if_fail(uuid, FALSE);
|
||||
g_return_val_if_fail(slen == 0 || s, FALSE);
|
||||
@@ -313,26 +321,20 @@ nm_uuid_generate_from_string(NMUuid * uuid,
|
||||
|
||||
switch (uuid_type) {
|
||||
case NM_UUID_TYPE_LEGACY:
|
||||
g_return_val_if_fail(!type_args, NULL);
|
||||
nm_assert(!type_args);
|
||||
nm_crypto_md5_hash(NULL, 0, (guint8 *) s, slen, (guint8 *) uuid, sizeof(*uuid));
|
||||
break;
|
||||
case NM_UUID_TYPE_VERSION3:
|
||||
case NM_UUID_TYPE_VERSION5:
|
||||
{
|
||||
NMUuid ns_uuid;
|
||||
|
||||
if (type_args) {
|
||||
/* type_args can be a name space UUID. Interpret it as (char *) */
|
||||
if (!nm_uuid_parse(type_args, &ns_uuid))
|
||||
g_return_val_if_reached(NULL);
|
||||
} else
|
||||
ns_uuid = (NMUuid){};
|
||||
if (!type_args)
|
||||
type_args = &nm_uuid_ns_zero;
|
||||
|
||||
if (uuid_type == NM_UUID_TYPE_VERSION3) {
|
||||
nm_crypto_md5_hash((guint8 *) s,
|
||||
slen,
|
||||
(guint8 *) &ns_uuid,
|
||||
sizeof(ns_uuid),
|
||||
(guint8 *) type_args,
|
||||
sizeof(*type_args),
|
||||
(guint8 *) uuid,
|
||||
sizeof(*uuid));
|
||||
} else {
|
||||
@@ -343,7 +345,7 @@ nm_uuid_generate_from_string(NMUuid * uuid,
|
||||
} digest;
|
||||
|
||||
sum = g_checksum_new(G_CHECKSUM_SHA1);
|
||||
g_checksum_update(sum, (guchar *) &ns_uuid, sizeof(ns_uuid));
|
||||
g_checksum_update(sum, (guchar *) type_args, sizeof(*type_args));
|
||||
g_checksum_update(sum, (guchar *) s, slen);
|
||||
nm_utils_checksum_get_digest(sum, digest.sha1);
|
||||
|
||||
@@ -377,10 +379,10 @@ nm_uuid_generate_from_string(NMUuid * uuid,
|
||||
* object's #NMSettingConnection:id: property
|
||||
**/
|
||||
char *
|
||||
nm_uuid_generate_from_string_str(const char *s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
gpointer type_args)
|
||||
nm_uuid_generate_from_string_str(const char * s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
const NMUuid *type_args)
|
||||
{
|
||||
NMUuid uuid;
|
||||
|
||||
@@ -405,7 +407,7 @@ char *
|
||||
nm_uuid_generate_from_strings(const char *string1, ...)
|
||||
{
|
||||
if (!string1)
|
||||
return nm_uuid_generate_from_string_str(NULL, 0, NM_UUID_TYPE_VERSION3, NM_UUID_NS1);
|
||||
return nm_uuid_generate_from_string_str(NULL, 0, NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1);
|
||||
|
||||
{
|
||||
nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE);
|
||||
@@ -425,6 +427,6 @@ nm_uuid_generate_from_strings(const char *string1, ...)
|
||||
return nm_uuid_generate_from_string_str(nm_str_buf_get_str_unsafe(&str),
|
||||
str.len,
|
||||
NM_UUID_TYPE_VERSION3,
|
||||
NM_UUID_NS1);
|
||||
&nm_uuid_ns_1);
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,28 @@ typedef struct _NMUuid {
|
||||
guint8 uuid[16];
|
||||
} NMUuid;
|
||||
|
||||
#define NM_UUID_INIT_ZERO() ((NMUuid){.uuid = {0}})
|
||||
|
||||
#define NM_UUID_INIT(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) \
|
||||
((NMUuid){ \
|
||||
.uuid = {(0x##a0), \
|
||||
(0x##a1), \
|
||||
(0x##a2), \
|
||||
(0x##a3), \
|
||||
(0x##a4), \
|
||||
(0x##a5), \
|
||||
(0x##a6), \
|
||||
(0x##a7), \
|
||||
(0x##a8), \
|
||||
(0x##a9), \
|
||||
(0x##a10), \
|
||||
(0x##a11), \
|
||||
(0x##a12), \
|
||||
(0x##a13), \
|
||||
(0x##a14), \
|
||||
(0x##a15)}, \
|
||||
})
|
||||
|
||||
char *nm_uuid_unparse_case(const NMUuid *uuid, char out_str[static 37], gboolean upper_case);
|
||||
|
||||
static inline char *
|
||||
@@ -73,25 +95,30 @@ char *nm_uuid_generate_random_str(char buf[static 37]);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern const NMUuid nm_uuid_ns_zero;
|
||||
extern const NMUuid nm_uuid_ns_1;
|
||||
|
||||
#define NM_UUID_NS_ZERO "00000000-0000-0000-0000-000000000000"
|
||||
#define NM_UUID_NS_1 "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
NM_UUID_TYPE_LEGACY = 0,
|
||||
NM_UUID_TYPE_VERSION3 = 3,
|
||||
NM_UUID_TYPE_VERSION5 = 5,
|
||||
} NMUuidType;
|
||||
|
||||
NMUuid *nm_uuid_generate_from_string(NMUuid * uuid,
|
||||
const char *s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
gpointer type_args);
|
||||
NMUuid *nm_uuid_generate_from_string(NMUuid * uuid,
|
||||
const char * s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
const NMUuid *type_args);
|
||||
|
||||
char *nm_uuid_generate_from_string_str(const char *s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
gpointer type_args);
|
||||
|
||||
/* arbitrarily chosen namespace UUID for nm_uuid_generate_from_strings() */
|
||||
#define NM_UUID_NS1 "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905"
|
||||
char *nm_uuid_generate_from_string_str(const char * s,
|
||||
gssize slen,
|
||||
NMUuidType uuid_type,
|
||||
const NMUuid *type_args);
|
||||
|
||||
char *nm_uuid_generate_from_strings(const char *string1, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
|
@@ -13,17 +13,18 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _nm_packed __attribute__((__packed__))
|
||||
#define _nm_unused __attribute__((__unused__))
|
||||
#define _nm_used __attribute__((__used__))
|
||||
#define _nm_pure __attribute__((__pure__))
|
||||
#define _nm_const __attribute__((__const__))
|
||||
#define _nm_printf(a, b) __attribute__((__format__(__printf__, a, b)))
|
||||
#define _nm_align(s) __attribute__((__aligned__(s)))
|
||||
#define _nm_section(s) __attribute__((__section__(s)))
|
||||
#define _nm_alignof(type) __alignof(type)
|
||||
#define _nm_alignas(type) _nm_align(_nm_alignof(type))
|
||||
#define nm_auto(fcn) __attribute__((__cleanup__(fcn)))
|
||||
#define _nm_packed __attribute__((__packed__))
|
||||
#define _nm_unused __attribute__((__unused__))
|
||||
#define _nm_used __attribute__((__used__))
|
||||
#define _nm_pure __attribute__((__pure__))
|
||||
#define _nm_const __attribute__((__const__))
|
||||
#define _nm_warn_unused_result __attribute__((__warn_unused_result__))
|
||||
#define _nm_printf(a, b) __attribute__((__format__(__printf__, a, b)))
|
||||
#define _nm_align(s) __attribute__((__aligned__(s)))
|
||||
#define _nm_section(s) __attribute__((__section__(s)))
|
||||
#define _nm_alignof(type) __alignof(type)
|
||||
#define _nm_alignas(type) _nm_align(_nm_alignof(type))
|
||||
#define nm_auto(fcn) __attribute__((__cleanup__(fcn)))
|
||||
|
||||
/* This is required to make LTO working.
|
||||
*
|
||||
@@ -81,6 +82,10 @@ typedef uint64_t _nm_bitwise nm_be64_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_BIT(n) (1ull << (n))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_PASTE_ARGS(identifier1, identifier2) identifier1##identifier2
|
||||
#define NM_PASTE(identifier1, identifier2) NM_PASTE_ARGS(identifier1, identifier2)
|
||||
|
||||
@@ -187,6 +192,12 @@ typedef uint64_t _nm_bitwise nm_be64_t;
|
||||
|
||||
#define NM_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
/* This does a compile time check that "type" is a suitable C type. It either
|
||||
* returns a compile time constant of 1 or it fails compilation. The point
|
||||
* is only in macros to check that a macro parameter (what we might pass to
|
||||
* sizeof() is really a type, and not a variable. */
|
||||
#define NM_ENSURE_IS_TYPE(type) (sizeof(void (*)(type[])) == sizeof(void (*)(void *)))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline uint32_t
|
||||
@@ -404,51 +415,231 @@ nm_streq0(const char *s1, const char *s2)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_IN_SET_EVAL_1(op, _x, y) (_x == (y))
|
||||
#define _NM_IN_SET_EVAL_2(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_1(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_3(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_2(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_4(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_3(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_5(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_4(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_6(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_5(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_7(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_6(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_8(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_7(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_9(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_8(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_10(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_9(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_11(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_10(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_12(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_11(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_13(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_12(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_14(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_13(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_15(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_14(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_17(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_16(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_18(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_17(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_19(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_18(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_20(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_19(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_21(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_20(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_22(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_21(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_23(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_22(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_24(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_23(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_25(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_24(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_26(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_25(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_27(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_26(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_28(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_27(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_29(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_28(op, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SET_EVAL_30(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_29(op, _x, __VA_ARGS__)
|
||||
/* clang-format off */
|
||||
#define _NM_MACRO_SELECT_ARG_120(_empty, \
|
||||
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
|
||||
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
|
||||
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
|
||||
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
|
||||
_51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
|
||||
_61, _62, _63, _64, _65, _66, _67, _68, _69, _70, \
|
||||
_71, _72, _73, _74, _75, _76, _77, _78, _79, _80, \
|
||||
_81, _82, _83, _84, _85, _86, _87, _88, _89, _90, \
|
||||
_91, _92, _93, _94, _95, _96, _97, _98, _99, _100, \
|
||||
_101, _102, _103, _104, _105, _106, _107, _108, _109, _110, \
|
||||
_111, _112, _113, _114, _115, _116, _117, _118, _119, _120, \
|
||||
N, \
|
||||
...) \
|
||||
N
|
||||
|
||||
#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__))
|
||||
#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \
|
||||
({ \
|
||||
type _x = (x); \
|
||||
\
|
||||
/* trigger a -Wenum-compare warning */ \
|
||||
nm_assert(true || _x == (x)); \
|
||||
\
|
||||
!!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \
|
||||
#define NM_NARG(...) \
|
||||
_NM_MACRO_SELECT_ARG_120(, ##__VA_ARGS__, \
|
||||
120, \
|
||||
119, 118, 117, 116, 115, 114, 113, 112, 111, 110, \
|
||||
109, 108, 107, 106, 105, 104, 103, 102, 101, 100, \
|
||||
99, 98, 97, 96, 95, 94, 93, 92, 91, 90, \
|
||||
89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
|
||||
79, 78, 77, 76, 75, 74, 73, 72, 71, 70, \
|
||||
69, 68, 67, 66, 65, 64, 63, 62, 61, 60, \
|
||||
59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
|
||||
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
|
||||
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
|
||||
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
|
||||
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
|
||||
9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
#define NM_NARG_MAX1(...) \
|
||||
_NM_MACRO_SELECT_ARG_120(, ##__VA_ARGS__, \
|
||||
1, \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 110 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 100 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
|
||||
#define NM_NARG_MAX2(...) \
|
||||
_NM_MACRO_SELECT_ARG_120(, ##__VA_ARGS__, \
|
||||
2, \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 110 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 100 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 90 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 80 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 70 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 60 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 50 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 40 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 30 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 20 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 10 */ \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 0)
|
||||
/* clang-format on */
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_MACRO_IDENTITY(...) __VA_ARGS__
|
||||
|
||||
#define _NM_MACRO_SELECT_FIRST(...) _NM_MACRO_SELECT_FIRST_IMPL(__VA_ARGS__, throwaway)
|
||||
#define _NM_MACRO_SELECT_FIRST_IMPL(first, ...) first
|
||||
|
||||
#define _NM_MACRO_CALL(macro, ...) macro(__VA_ARGS__)
|
||||
#define _NM_MACRO_CALL2(macro, ...) macro(__VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* clang-format off */
|
||||
#define _NM_VA_ARGS_FOREACH_0(prefix, postfix, sep, op)
|
||||
#define _NM_VA_ARGS_FOREACH_1(prefix, postfix, sep, op, x) prefix _NM_MACRO_CALL2(op, x, 0 ) postfix
|
||||
#define _NM_VA_ARGS_FOREACH_2(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 1 ) postfix sep _NM_VA_ARGS_FOREACH_1(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_3(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 2 ) postfix sep _NM_VA_ARGS_FOREACH_2(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_4(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 3 ) postfix sep _NM_VA_ARGS_FOREACH_3(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_5(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 4 ) postfix sep _NM_VA_ARGS_FOREACH_4(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_6(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 5 ) postfix sep _NM_VA_ARGS_FOREACH_5(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_7(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 6 ) postfix sep _NM_VA_ARGS_FOREACH_6(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_8(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 7 ) postfix sep _NM_VA_ARGS_FOREACH_7(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_9(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 8 ) postfix sep _NM_VA_ARGS_FOREACH_8(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_10(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 9 ) postfix sep _NM_VA_ARGS_FOREACH_9(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_11(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 10 ) postfix sep _NM_VA_ARGS_FOREACH_10(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_12(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 11 ) postfix sep _NM_VA_ARGS_FOREACH_11(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_13(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 12 ) postfix sep _NM_VA_ARGS_FOREACH_12(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_14(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 13 ) postfix sep _NM_VA_ARGS_FOREACH_13(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_15(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 14 ) postfix sep _NM_VA_ARGS_FOREACH_14(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_16(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 15 ) postfix sep _NM_VA_ARGS_FOREACH_15(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_17(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 16 ) postfix sep _NM_VA_ARGS_FOREACH_16(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_18(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 17 ) postfix sep _NM_VA_ARGS_FOREACH_17(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_19(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 18 ) postfix sep _NM_VA_ARGS_FOREACH_18(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_20(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 19 ) postfix sep _NM_VA_ARGS_FOREACH_19(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_21(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 20 ) postfix sep _NM_VA_ARGS_FOREACH_20(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_22(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 21 ) postfix sep _NM_VA_ARGS_FOREACH_21(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_23(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 22 ) postfix sep _NM_VA_ARGS_FOREACH_22(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_24(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 23 ) postfix sep _NM_VA_ARGS_FOREACH_23(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_25(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 24 ) postfix sep _NM_VA_ARGS_FOREACH_24(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_26(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 25 ) postfix sep _NM_VA_ARGS_FOREACH_25(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_27(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 26 ) postfix sep _NM_VA_ARGS_FOREACH_26(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_28(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 27 ) postfix sep _NM_VA_ARGS_FOREACH_27(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_29(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 28 ) postfix sep _NM_VA_ARGS_FOREACH_28(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_30(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 29 ) postfix sep _NM_VA_ARGS_FOREACH_29(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_31(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 30 ) postfix sep _NM_VA_ARGS_FOREACH_30(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_32(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 31 ) postfix sep _NM_VA_ARGS_FOREACH_31(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_33(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 32 ) postfix sep _NM_VA_ARGS_FOREACH_32(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_34(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 33 ) postfix sep _NM_VA_ARGS_FOREACH_33(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_35(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 34 ) postfix sep _NM_VA_ARGS_FOREACH_34(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_36(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 35 ) postfix sep _NM_VA_ARGS_FOREACH_35(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_37(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 36 ) postfix sep _NM_VA_ARGS_FOREACH_36(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_38(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 37 ) postfix sep _NM_VA_ARGS_FOREACH_37(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_39(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 38 ) postfix sep _NM_VA_ARGS_FOREACH_38(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_40(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 39 ) postfix sep _NM_VA_ARGS_FOREACH_39(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_41(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 40 ) postfix sep _NM_VA_ARGS_FOREACH_40(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_42(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 41 ) postfix sep _NM_VA_ARGS_FOREACH_41(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_43(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 42 ) postfix sep _NM_VA_ARGS_FOREACH_42(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_44(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 43 ) postfix sep _NM_VA_ARGS_FOREACH_43(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_45(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 44 ) postfix sep _NM_VA_ARGS_FOREACH_44(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_46(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 45 ) postfix sep _NM_VA_ARGS_FOREACH_45(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_47(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 46 ) postfix sep _NM_VA_ARGS_FOREACH_46(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_48(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 47 ) postfix sep _NM_VA_ARGS_FOREACH_47(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_49(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 48 ) postfix sep _NM_VA_ARGS_FOREACH_48(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_50(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 49 ) postfix sep _NM_VA_ARGS_FOREACH_49(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_51(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 50 ) postfix sep _NM_VA_ARGS_FOREACH_50(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_52(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 51 ) postfix sep _NM_VA_ARGS_FOREACH_51(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_53(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 52 ) postfix sep _NM_VA_ARGS_FOREACH_52(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_54(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 53 ) postfix sep _NM_VA_ARGS_FOREACH_53(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_55(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 54 ) postfix sep _NM_VA_ARGS_FOREACH_54(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_56(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 55 ) postfix sep _NM_VA_ARGS_FOREACH_55(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_57(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 56 ) postfix sep _NM_VA_ARGS_FOREACH_56(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_58(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 57 ) postfix sep _NM_VA_ARGS_FOREACH_57(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_59(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 58 ) postfix sep _NM_VA_ARGS_FOREACH_58(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_60(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 59 ) postfix sep _NM_VA_ARGS_FOREACH_59(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_61(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 10 ) postfix sep _NM_VA_ARGS_FOREACH_60(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_62(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 61 ) postfix sep _NM_VA_ARGS_FOREACH_61(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_63(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 62 ) postfix sep _NM_VA_ARGS_FOREACH_62(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_64(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 63 ) postfix sep _NM_VA_ARGS_FOREACH_63(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_65(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 64 ) postfix sep _NM_VA_ARGS_FOREACH_64(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_66(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 65 ) postfix sep _NM_VA_ARGS_FOREACH_65(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_67(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 66 ) postfix sep _NM_VA_ARGS_FOREACH_66(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_68(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 67 ) postfix sep _NM_VA_ARGS_FOREACH_67(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_69(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 68 ) postfix sep _NM_VA_ARGS_FOREACH_68(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_70(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 69 ) postfix sep _NM_VA_ARGS_FOREACH_69(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_71(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 70 ) postfix sep _NM_VA_ARGS_FOREACH_70(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_72(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 71 ) postfix sep _NM_VA_ARGS_FOREACH_71(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_73(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 72 ) postfix sep _NM_VA_ARGS_FOREACH_72(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_74(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 73 ) postfix sep _NM_VA_ARGS_FOREACH_73(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_75(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 74 ) postfix sep _NM_VA_ARGS_FOREACH_74(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_76(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 75 ) postfix sep _NM_VA_ARGS_FOREACH_75(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_77(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 76 ) postfix sep _NM_VA_ARGS_FOREACH_76(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_78(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 77 ) postfix sep _NM_VA_ARGS_FOREACH_77(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_79(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 78 ) postfix sep _NM_VA_ARGS_FOREACH_78(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_80(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 79 ) postfix sep _NM_VA_ARGS_FOREACH_79(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_81(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 80 ) postfix sep _NM_VA_ARGS_FOREACH_80(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_82(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 81 ) postfix sep _NM_VA_ARGS_FOREACH_81(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_83(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 82 ) postfix sep _NM_VA_ARGS_FOREACH_82(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_84(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 83 ) postfix sep _NM_VA_ARGS_FOREACH_83(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_85(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 84 ) postfix sep _NM_VA_ARGS_FOREACH_84(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_86(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 85 ) postfix sep _NM_VA_ARGS_FOREACH_85(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_87(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 86 ) postfix sep _NM_VA_ARGS_FOREACH_86(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_88(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 87 ) postfix sep _NM_VA_ARGS_FOREACH_87(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_89(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 88 ) postfix sep _NM_VA_ARGS_FOREACH_88(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_90(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 89 ) postfix sep _NM_VA_ARGS_FOREACH_89(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_91(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 90 ) postfix sep _NM_VA_ARGS_FOREACH_90(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_92(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 91 ) postfix sep _NM_VA_ARGS_FOREACH_91(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_93(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 92 ) postfix sep _NM_VA_ARGS_FOREACH_92(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_94(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 93 ) postfix sep _NM_VA_ARGS_FOREACH_93(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_95(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 94 ) postfix sep _NM_VA_ARGS_FOREACH_94(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_96(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 95 ) postfix sep _NM_VA_ARGS_FOREACH_95(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_97(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 96 ) postfix sep _NM_VA_ARGS_FOREACH_96(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_98(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 97 ) postfix sep _NM_VA_ARGS_FOREACH_97(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_99(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 98 ) postfix sep _NM_VA_ARGS_FOREACH_98(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_100(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 99 ) postfix sep _NM_VA_ARGS_FOREACH_99(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_101(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 100) postfix sep _NM_VA_ARGS_FOREACH_100(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_102(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 101) postfix sep _NM_VA_ARGS_FOREACH_101(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_103(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 102) postfix sep _NM_VA_ARGS_FOREACH_102(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_104(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 103) postfix sep _NM_VA_ARGS_FOREACH_103(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_105(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 104) postfix sep _NM_VA_ARGS_FOREACH_104(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_106(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 105) postfix sep _NM_VA_ARGS_FOREACH_105(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_107(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 106) postfix sep _NM_VA_ARGS_FOREACH_106(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_108(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 107) postfix sep _NM_VA_ARGS_FOREACH_107(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_109(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 108) postfix sep _NM_VA_ARGS_FOREACH_108(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_110(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 109) postfix sep _NM_VA_ARGS_FOREACH_109(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_111(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 100) postfix sep _NM_VA_ARGS_FOREACH_110(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_112(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 111) postfix sep _NM_VA_ARGS_FOREACH_111(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_113(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 112) postfix sep _NM_VA_ARGS_FOREACH_112(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_114(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 113) postfix sep _NM_VA_ARGS_FOREACH_113(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_115(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 114) postfix sep _NM_VA_ARGS_FOREACH_114(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_116(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 115) postfix sep _NM_VA_ARGS_FOREACH_115(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_117(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 116) postfix sep _NM_VA_ARGS_FOREACH_116(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_118(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 117) postfix sep _NM_VA_ARGS_FOREACH_117(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_119(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 118) postfix sep _NM_VA_ARGS_FOREACH_118(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
#define _NM_VA_ARGS_FOREACH_120(prefix, postfix, sep, op, x, ...) prefix _NM_MACRO_CALL2(op, x, 119) postfix sep _NM_VA_ARGS_FOREACH_119(prefix, postfix, sep, op, __VA_ARGS__)
|
||||
/* clang-format on */
|
||||
#define NM_VA_ARGS_FOREACH(prefix, postfix, sep, op, ...) \
|
||||
_NM_MACRO_CALL(NM_PASTE(_NM_VA_ARGS_FOREACH_, NM_NARG(__VA_ARGS__)), \
|
||||
prefix, \
|
||||
postfix, \
|
||||
sep, \
|
||||
op, \
|
||||
##__VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_VA_ARGS_JOIN(sep, ...) NM_VA_ARGS_FOREACH(, , sep, _NM_MACRO_SELECT_FIRST, __VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_IN_SET_OP(x, idx) (_x == (x))
|
||||
#define _NM_IN_SET(op, type, x, ...) \
|
||||
({ \
|
||||
type _x = (x); \
|
||||
\
|
||||
/* trigger a -Wenum-compare warning */ \
|
||||
nm_assert(true || _x == (x)); \
|
||||
\
|
||||
!!(NM_VA_ARGS_FOREACH(, , op, _NM_IN_SET_OP, __VA_ARGS__)); \
|
||||
})
|
||||
|
||||
#define _NM_IN_SET(op, type, x, ...) \
|
||||
_NM_IN_SET_EVAL_N(op, type, x, NM_NARG(__VA_ARGS__), __VA_ARGS__)
|
||||
|
||||
/* Beware that this does short-circuit evaluation (use "||" instead of "|")
|
||||
* which has a possibly unexpected non-function-like behavior.
|
||||
* Use NM_IN_SET_SE if you need all arguments to be evaluated. */
|
||||
@@ -468,96 +659,31 @@ nm_streq0(const char *s1, const char *s2)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_IN_SETOP_EVAL_1(op, op_eq, _x, y) (op_eq(_x, y))
|
||||
#define _NM_IN_SETOP_EVAL_2(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_1(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_3(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_2(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_4(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_3(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_5(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_4(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_6(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_5(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_7(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_6(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_8(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_7(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_9(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_8(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_10(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_9(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_11(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_10(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_12(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_11(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_13(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_12(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_14(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_13(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_15(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_14(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_16(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_15(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_17(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_16(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_18(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_17(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_19(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_18(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_20(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_19(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_21(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_20(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_22(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_21(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_23(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_22(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_24(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_23(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_25(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_24(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_26(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_25(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_27(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_26(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_28(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_27(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_29(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_28(op, op_eq, _x, __VA_ARGS__)
|
||||
#define _NM_IN_SETOP_EVAL_30(op, op_eq, _x, y, ...) \
|
||||
(op_eq(_x, y)) op _NM_IN_SETOP_EVAL_29(op, op_eq, _x, __VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_IN_STRSET_EVAL_N2(op, op_ed, _x, n, ...) \
|
||||
(_NM_IN_SETOP_EVAL_##n(op, op_ed, _x, __VA_ARGS__))
|
||||
#define _NM_IN_STRSET_EVAL_N(op, op_ed, x, n, ...) \
|
||||
({ \
|
||||
const char *_x = (x); \
|
||||
(((_x == NULL) && _NM_IN_SET_EVAL_N2(op, ((const char *) NULL), n, __VA_ARGS__)) \
|
||||
|| ((_x != NULL) && _NM_IN_STRSET_EVAL_N2(op, op_ed, _x, n, __VA_ARGS__))); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline int
|
||||
_NM_IN_STRSET_op_streq(const char *x, const char *s)
|
||||
_NM_IN_STRSET_EVAL_op_streq(const char *x1, const char *x)
|
||||
{
|
||||
return s && strcmp(x, s) == 0;
|
||||
return x && nm_streq(x1, x);
|
||||
}
|
||||
|
||||
#define _NM_IN_STRSET_EVAL_OP_NULL(x, idx) (((const char *) NULL) == (x))
|
||||
#define _NM_IN_STRSET_EVAL_OP_STREQ(x, idx) _NM_IN_STRSET_EVAL_op_streq(_x1, x)
|
||||
#define _NM_IN_STRSET_EVAL(op, eval_op, x1, ...) \
|
||||
({ \
|
||||
const char *const _x1 = (x1); \
|
||||
\
|
||||
!!(_x1 ? (NM_VA_ARGS_FOREACH(, , op, eval_op, __VA_ARGS__)) \
|
||||
: (NM_VA_ARGS_FOREACH(, , op, _NM_IN_STRSET_EVAL_OP_NULL, __VA_ARGS__))); \
|
||||
})
|
||||
|
||||
/* Beware that this does short-circuit evaluation (use "||" instead of "|")
|
||||
* which has a possibly unexpected non-function-like behavior.
|
||||
* Use NM_IN_STRSET_SE if you need all arguments to be evaluated. */
|
||||
#define NM_IN_STRSET(x, ...) \
|
||||
_NM_IN_STRSET_EVAL_N(||, _NM_IN_STRSET_op_streq, x, NM_NARG(__VA_ARGS__), __VA_ARGS__)
|
||||
#define NM_IN_STRSET(x1, ...) _NM_IN_STRSET_EVAL(||, _NM_IN_STRSET_EVAL_OP_STREQ, x1, __VA_ARGS__)
|
||||
|
||||
/* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do
|
||||
* short-circuit evaluation, which can make a difference if the arguments have
|
||||
* side-effects. */
|
||||
#define NM_IN_STRSET_SE(x, ...) \
|
||||
_NM_IN_STRSET_EVAL_N(|, _NM_IN_STRSET_op_streq, x, NM_NARG(__VA_ARGS__), __VA_ARGS__)
|
||||
#define NM_IN_STRSET_SE(x1, ...) _NM_IN_STRSET_EVAL(|, _NM_IN_STRSET_EVAL_OP_STREQ, x1, __VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@@ -9,6 +9,14 @@ import xml.etree.ElementTree as ET
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
def dbg(msg):
|
||||
pass
|
||||
# print("%s" % (msg,))
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
_setting_name_order = [
|
||||
"connection",
|
||||
"6lowpan",
|
||||
@@ -123,6 +131,9 @@ gl_input_files = list(argv[1:])
|
||||
|
||||
###############################################################################
|
||||
|
||||
for f in gl_input_files:
|
||||
dbg("> input file %s" % (f))
|
||||
|
||||
xml_roots = list([ET.parse(f).getroot() for f in gl_input_files])
|
||||
|
||||
assert all([root.tag == "nm-setting-docs" for root in xml_roots])
|
||||
@@ -133,14 +144,18 @@ root_node = ET.Element("nm-setting-docs")
|
||||
|
||||
for setting_name in iter_keys_of_dicts(settings_roots, key_fcn_setting_name):
|
||||
|
||||
dbg("> > setting_name: %s" % (setting_name))
|
||||
|
||||
settings = list([d.get(setting_name) for d in settings_roots])
|
||||
|
||||
if gl_only_from_first and settings[0] is None:
|
||||
dbg("> > > skip (only-from-first")
|
||||
continue
|
||||
|
||||
properties = list([node_to_dict(s, "property", "name") for s in settings])
|
||||
|
||||
if gl_only_from_first and not properties[0]:
|
||||
dbg("> > > skip (no properties")
|
||||
continue
|
||||
|
||||
setting_node = ET.SubElement(root_node, "setting")
|
||||
@@ -151,17 +166,24 @@ for setting_name in iter_keys_of_dicts(settings_roots, key_fcn_setting_name):
|
||||
node_set_attr(setting_node, "name_upper", settings)
|
||||
node_set_attr(setting_node, "alias", settings)
|
||||
|
||||
dbg("> > > create node")
|
||||
|
||||
for property_name in iter_keys_of_dicts(properties):
|
||||
|
||||
dbg("> > > > property_name: %s" % (property_name))
|
||||
|
||||
properties_attrs = list([p.get(property_name) for p in properties])
|
||||
|
||||
if gl_only_from_first and properties_attrs[0] is None:
|
||||
dbg("> > > > skip (only-from-first")
|
||||
continue
|
||||
|
||||
property_node = ET.SubElement(setting_node, "property")
|
||||
property_node.set("name", property_name)
|
||||
property_node.set("name_upper", property_name.upper().replace("-", "_"))
|
||||
|
||||
dbg("> > > > > create node")
|
||||
|
||||
x = node_get_attr(properties_attrs, "format")
|
||||
if x:
|
||||
property_node.set("type", x)
|
||||
|
Reference in New Issue
Block a user