summaryrefslogtreecommitdiff
path: root/shared/nm-utils
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-04-14 13:36:32 +0200
committerThomas Haller <thaller@redhat.com>2019-04-18 18:57:24 +0200
commitb434b9ec0794fc62a2469445d17debf645ba24cc (patch)
tree340dbfbce81b71903770f4a4a0d523efb6a7d595 /shared/nm-utils
parentdf3c7c3ff463a10a033fcc4bf516007d3c57bf92 (diff)
downloadNetworkManager-b434b9ec0794fc62a2469445d17debf645ba24cc.tar.gz
shared: split C-only helper "shared/nm-std-aux" utils out of "shared/nm-utils"
"shared/nm-utils" contains general purpose utility functions that only depend on glib (and extend glib with some helper functions). We will also add code that does not use glib, hence it would be good if the part of "shared/nm-utils" that does not depend on glib, could be used by these future projects. Also, we use the term "utils" everywhere. While that covers the purpose and content well, having everything called "nm-something-utils" is not great. Instead, call this "nm-std-aux", inspired by "c-util/c-stdaux".
Diffstat (limited to 'shared/nm-utils')
-rw-r--r--shared/nm-utils/c-list-util.c209
-rw-r--r--shared/nm-utils/c-list-util.h66
-rw-r--r--shared/nm-utils/nm-dedup-multi.h2
-rw-r--r--shared/nm-utils/tests/test-shared-general.c4
-rw-r--r--shared/nm-utils/unaligned.h99
5 files changed, 3 insertions, 377 deletions
diff --git a/shared/nm-utils/c-list-util.c b/shared/nm-utils/c-list-util.c
deleted file mode 100644
index 44ca26a558..0000000000
--- a/shared/nm-utils/c-list-util.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2017 Red Hat, Inc.
- */
-
-#include "c-list-util.h"
-
-/*****************************************************************************/
-
-/**
- * c_list_relink:
- * @lst: the head list entry
- *
- * Takes an invalid list, that has undefined prev pointers.
- * Only the next pointers are valid, and the tail's next
- * pointer points to %NULL instead of the head.
- *
- * c_list_relink() fixes the list by updating all prev pointers
- * and close the circular linking by pointing the tails' next
- * pointer to @lst.
- *
- * The use of this function is to do a bulk update, that lets the
- * list degredate by not updating the prev pointers. At the end,
- * the list can be fixed by c_list_relink().
- */
-void
-c_list_relink (CList *lst)
-{
- CList *ls, *ls_prev;
-
- ls_prev = lst;
- ls = lst->next;
- do {
- ls->prev = ls_prev;
- ls_prev = ls;
- ls = ls->next;
- } while (ls);
- ls_prev->next = lst;
- lst->prev = ls_prev;
-}
-
-/*****************************************************************************/
-
-static CList *
-_c_list_srt_split (CList *ls)
-{
- CList *ls2;
-
- ls2 = ls;
- ls = ls->next;
- if (!ls)
- return NULL;
- do {
- ls = ls->next;
- if (!ls)
- break;
- ls = ls->next;
- ls2 = ls2->next;
- } while (ls);
- ls = ls2->next;
- ls2->next = NULL;
- return ls;
-}
-
-static CList *
-_c_list_srt_merge (CList *ls1,
- CList *ls2,
- CListSortCmp cmp,
- const void *user_data)
-{
- CList *ls;
- CList head;
-
- ls = &head;
- for (;;) {
- /* while invoking the @cmp function, the list
- * elements are not properly linked. Don't try to access
- * their next/prev pointers. */
- if (cmp (ls1, ls2, user_data) <= 0) {
- ls->next = ls1;
- ls = ls1;
- ls1 = ls1->next;
- if (!ls1)
- break;
- } else {
- ls->next = ls2;
- ls = ls2;
- ls2 = ls2->next;
- if (!ls2)
- break;
- }
- }
- ls->next = ls1 ?: ls2;
-
- return head.next;
-}
-
-typedef struct {
- CList *ls1;
- CList *ls2;
- char ls1_sorted;
-} SortStack;
-
-static CList *
-_c_list_sort (CList *ls,
- CListSortCmp cmp,
- const void *user_data)
-{
- /* reserve a huge stack-size. We need roughly log2(n) entries, hence this
- * is much more we will ever need. We don't guard for stack-overflow either. */
- SortStack stack_arr[70];
- SortStack *stack_head = stack_arr;
-
- stack_arr[0].ls1 = ls;
-
- /* A simple top-down, non-recursive, stable merge-sort.
- *
- * Maybe natural merge-sort would be better, to do better for
- * partially sorted lists. */
-_split:
- stack_head[0].ls2 = _c_list_srt_split (stack_head[0].ls1);
- if (stack_head[0].ls2) {
- stack_head[0].ls1_sorted = 0;
- stack_head[1].ls1 = stack_head[0].ls1;
- stack_head++;
- goto _split;
- }
-
-_backtrack:
- if (stack_head == stack_arr)
- return stack_arr[0].ls1;
-
- stack_head--;
- if (!stack_head[0].ls1_sorted) {
- stack_head[0].ls1 = stack_head[1].ls1;
- stack_head[0].ls1_sorted = 1;
- stack_head[1].ls1 = stack_head[0].ls2;
- stack_head++;
- goto _split;
- }
-
- stack_head[0].ls1 = _c_list_srt_merge (stack_head[0].ls1, stack_head[1].ls1, cmp, user_data);
- goto _backtrack;
-}
-
-/**
- * c_list_sort_headless:
- * @lst: the list.
- * @cmp: compare function for sorting. While comparing two
- * CList elements, their next/prev pointers are in undefined
- * state.
- * @user_data: user data for @cmp.
- *
- * Sorts the list @lst according to @cmp. Contrary to
- * c_list_sort(), @lst is not the list head but a
- * valid entry as well. This function returns the new
- * list head.
- */
-CList *
-c_list_sort_headless (CList *lst,
- CListSortCmp cmp,
- const void *user_data)
-{
- if (!c_list_is_empty (lst)) {
- lst->prev->next = NULL;
- lst = _c_list_sort (lst, cmp, user_data);
- c_list_relink (lst);
- }
- return lst;
-}
-
-/**
- * c_list_sort:
- * @head: the list head.
- * @cmp: compare function for sorting. While comparing two
- * CList elements, their next/prev pointers are in undefined
- * state.
- * @user_data: user data for @cmp.
- *
- * Sorts the list @head according to @cmp.
- */
-void
-c_list_sort (CList *head,
- CListSortCmp cmp,
- const void *user_data)
-{
- if ( !c_list_is_empty (head)
- && head->next->next != head) {
- head->prev->next = NULL;
- head->next = _c_list_sort (head->next, cmp, user_data);
- c_list_relink (head);
- }
-}
diff --git a/shared/nm-utils/c-list-util.h b/shared/nm-utils/c-list-util.h
deleted file mode 100644
index 648bacc744..0000000000
--- a/shared/nm-utils/c-list-util.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2017 Red Hat, Inc.
- */
-
-#ifndef __C_LIST_UTIL_H__
-#define __C_LIST_UTIL_H__
-
-#include "c-list/src/c-list.h"
-
-/*****************************************************************************/
-
-void c_list_relink (CList *lst);
-
-typedef int (*CListSortCmp) (const CList *a,
- const CList *b,
- const void *user_data);
-
-CList *c_list_sort_headless (CList *lst,
- CListSortCmp cmp,
- const void *user_data);
-
-void c_list_sort (CList *head,
- CListSortCmp cmp,
- const void *user_data);
-
-/* c_list_length_is:
- * @list: the #CList list head
- * @check_len: the length to compare
- *
- * Returns: basically the same as (c_list_length (@list) == @check_len),
- * but does not require to iterate the entire list first. There is only
- * one real use: to find out whether there is exactly one element in the
- * list, by passing @check_len as 1.
- */
-static inline int
-c_list_length_is (const CList *list, unsigned long check_len) {
- unsigned long n = 0;
- const CList *iter;
-
- c_list_for_each (iter, list) {
- ++n;
- if (n > check_len)
- return 0;
- }
-
- return n == check_len;
-}
-
-#endif /* __C_LIST_UTIL_H__ */
diff --git a/shared/nm-utils/nm-dedup-multi.h b/shared/nm-utils/nm-dedup-multi.h
index 845b4c3ef5..82c6f1e955 100644
--- a/shared/nm-utils/nm-dedup-multi.h
+++ b/shared/nm-utils/nm-dedup-multi.h
@@ -23,7 +23,7 @@
#define __NM_DEDUP_MULTI_H__
#include "nm-obj.h"
-#include "c-list-util.h"
+#include "nm-std-aux/c-list-util.h"
/*****************************************************************************/
diff --git a/shared/nm-utils/tests/test-shared-general.c b/shared/nm-utils/tests/test-shared-general.c
index f56bd15e50..067e9f05d7 100644
--- a/shared/nm-utils/tests/test-shared-general.c
+++ b/shared/nm-utils/tests/test-shared-general.c
@@ -21,9 +21,9 @@
#include "nm-default.h"
-#include "nm-utils/nm-time-utils.h"
+#include "nm-std-aux/unaligned.h"
#include "nm-utils/nm-random-utils.h"
-#include "nm-utils/unaligned.h"
+#include "nm-utils/nm-time-utils.h"
#include "nm-utils/nm-test-utils.h"
diff --git a/shared/nm-utils/unaligned.h b/shared/nm-utils/unaligned.h
deleted file mode 100644
index 00c17f8769..0000000000
--- a/shared/nm-utils/unaligned.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <endian.h>
-#include <stdint.h>
-
-/* BE */
-
-static inline uint16_t unaligned_read_be16(const void *_u) {
- const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
-
- return be16toh(u->x);
-}
-
-static inline uint32_t unaligned_read_be32(const void *_u) {
- const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
-
- return be32toh(u->x);
-}
-
-static inline uint64_t unaligned_read_be64(const void *_u) {
- const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
-
- return be64toh(u->x);
-}
-
-static inline void unaligned_write_be16(void *_u, uint16_t a) {
- struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
-
- u->x = be16toh(a);
-}
-
-static inline void unaligned_write_be32(void *_u, uint32_t a) {
- struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
-
- u->x = be32toh(a);
-}
-
-static inline void unaligned_write_be64(void *_u, uint64_t a) {
- struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
-
- u->x = be64toh(a);
-}
-
-/* LE */
-
-static inline uint16_t unaligned_read_le16(const void *_u) {
- const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
-
- return le16toh(u->x);
-}
-
-static inline uint32_t unaligned_read_le32(const void *_u) {
- const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
-
- return le32toh(u->x);
-}
-
-static inline uint64_t unaligned_read_le64(const void *_u) {
- const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
-
- return le64toh(u->x);
-}
-
-static inline void unaligned_write_le16(void *_u, uint16_t a) {
- struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u;
-
- u->x = le16toh(a);
-}
-
-static inline void unaligned_write_le32(void *_u, uint32_t a) {
- struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u;
-
- u->x = le32toh(a);
-}
-
-static inline void unaligned_write_le64(void *_u, uint64_t a) {
- struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u;
-
- u->x = le64toh(a);
-}
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define unaligned_read_ne16 unaligned_read_be16
-#define unaligned_read_ne32 unaligned_read_be32
-#define unaligned_read_ne64 unaligned_read_be64
-
-#define unaligned_write_ne16 unaligned_write_be16
-#define unaligned_write_ne32 unaligned_write_be32
-#define unaligned_write_ne64 unaligned_write_be64
-#else
-#define unaligned_read_ne16 unaligned_read_le16
-#define unaligned_read_ne32 unaligned_read_le32
-#define unaligned_read_ne64 unaligned_read_le64
-
-#define unaligned_write_ne16 unaligned_write_le16
-#define unaligned_write_ne32 unaligned_write_le32
-#define unaligned_write_ne64 unaligned_write_le64
-#endif