ports

morpheus ports
git clone git://git.2f30.org/ports.git
Log | Files | Refs | LICENSE

commit fb2d807ad3fdd7d0fc498c4c7870e382eef6800d
parent 49ecc50304f3c0a51129710024b0c73a137f68d7
Author: sin <sin@2f30.org>
Date:   Sat Jun 14 19:49:59 +0100

Add mg

Diffstat:
mg/mg.mk | 14++++++++++++++
mg/mkfile | 7+++++++
mg/musl-fixup.patch | 741+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 762 insertions(+), 0 deletions(-)
diff --git a/mg/mg.mk b/mg/mg.mk @@ -0,0 +1,14 @@ +TARG = mg +DEPS = ncurses +INSTALL_BIN = mg +INSTALL_MAN1 = mg.1 + +<$mkbuild/mk.common + +mg:QV: + export CFLAGS="$CFLAGS -I. -D_GNU_SOURCE -DFKEYS -DREGEX -DXKEYS $DEPS_CFLAGS" + export LDFLAGS="$LDFLAGS $DEPS_LDFLAGS" + CC="${CC} -static" make \ + PREFIX="$PREFIX" + CFLAGS="$CFLAGS" \ + LDFLAGS="$LDFLAGS" diff --git a/mg/mkfile b/mg/mkfile @@ -0,0 +1,7 @@ +<$mkbuild/mk.3rdparty + +src = mg-openbsd +git = git://github.com/scott-parker/mg-openbsd.git +mkfile = ../mg.mk +patches = \ + ../musl-fixup.patch diff --git a/mg/musl-fixup.patch b/mg/musl-fixup.patch @@ -0,0 +1,741 @@ +From 57dee7a87c40cd2210bd548013f67f4ad060ec7c Mon Sep 17 00:00:00 2001 +From: sin <sin@2f30.org> +Date: Sat, 14 Jun 2014 19:46:29 +0100 +Subject: [PATCH] Fix up patch to make it compile against musl + +--- + Makefile | 2 +- + def.h | 1 + + fileio.c | 4 +- + linux.c | 1 - + re_search.c | 1 + + sys/queue.h | 648 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 653 insertions(+), 4 deletions(-) + create mode 100644 sys/queue.h + +diff --git a/Makefile b/Makefile +index 9935033..04ce580 100644 +--- a/Makefile ++++ b/Makefile +@@ -5,7 +5,7 @@ DOCDIR?= $(PREFIX)/share/doc + + CC?= gcc + CFLAGS+= -O2 -Wall -D_GNU_SOURCE -DFKEYS -DREGEX -DXKEYS +-LDADD+= -lcurses ++LDADD+= -lncurses + + SRCS= $(shell ls *.c) + OBJS= $(SRCS:.c=.o) +diff --git a/def.h b/def.h +index 562516f..485c823 100644 +--- a/def.h ++++ b/def.h +@@ -10,6 +10,7 @@ + * per-terminal definitions are in special header files. + */ + ++#include <sys/types.h> + #include "sysdef.h" /* Order is critical. */ + #include "ttydef.h" + #include "chrdef.h" +diff --git a/fileio.c b/fileio.c +index 78bd876..e6eca16 100644 +--- a/fileio.c ++++ b/fileio.c +@@ -95,7 +95,7 @@ int + ffwopen(FILE ** ffp, const char *fn, struct buffer *bp) + { + int fd; +- mode_t fmode = DEFFILEMODE; ++ mode_t fmode = 0666; + + if (bp && bp->b_fi.fi_mode) + fmode = bp->b_fi.fi_mode & 07777; +@@ -361,7 +361,7 @@ copy(char *frname, char *toname) + { + int ifd, ofd; + char buf[BUFSIZ]; +- mode_t fmode = DEFFILEMODE; /* XXX?? */ ++ mode_t fmode = 0666; + struct stat orig; + ssize_t sr; + +diff --git a/linux.c b/linux.c +index ebceec4..6a41919 100644 +--- a/linux.c ++++ b/linux.c +@@ -1,5 +1,4 @@ + #include <sys/types.h> +-#include <sys/cdefs.h> + + #include <errno.h> + #include <limits.h> +diff --git a/re_search.c b/re_search.c +index d8d4008..1a64d5b 100644 +--- a/re_search.c ++++ b/re_search.c +@@ -28,6 +28,7 @@ + #define SRCH_ACCM (-4) + #define SRCH_MARK (-5) + ++#define REG_STARTEND (1 << 2) + #define RE_NMATCH 10 /* max number of matches */ + #define REPLEN 256 /* max length of replacement string */ + +diff --git a/sys/queue.h b/sys/queue.h +new file mode 100644 +index 0000000..f8f09bf +--- /dev/null ++++ b/sys/queue.h +@@ -0,0 +1,648 @@ ++/* $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $ */ ++/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ ++ ++/* ++ * Copyright (c) 1991, 1993 ++ * The Regents of the University of California. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * @(#)queue.h 8.5 (Berkeley) 8/20/94 ++ */ ++ ++#ifndef _SYS_QUEUE_H_ ++#define _SYS_QUEUE_H_ ++ ++/* ++ * This file defines five types of data structures: singly-linked lists, ++ * lists, simple queues, tail queues, and circular queues. ++ * ++ * ++ * A singly-linked list is headed by a single forward pointer. The elements ++ * are singly linked for minimum space and pointer manipulation overhead at ++ * the expense of O(n) removal for arbitrary elements. New elements can be ++ * added to the list after an existing element or at the head of the list. ++ * Elements being removed from the head of the list should use the explicit ++ * macro for this purpose for optimum efficiency. A singly-linked list may ++ * only be traversed in the forward direction. Singly-linked lists are ideal ++ * for applications with large datasets and few or no removals or for ++ * implementing a LIFO queue. ++ * ++ * A list is headed by a single forward pointer (or an array of forward ++ * pointers for a hash table header). The elements are doubly linked ++ * so that an arbitrary element can be removed without a need to ++ * traverse the list. New elements can be added to the list before ++ * or after an existing element or at the head of the list. A list ++ * may only be traversed in the forward direction. ++ * ++ * A simple queue is headed by a pair of pointers, one the head of the ++ * list and the other to the tail of the list. The elements are singly ++ * linked to save space, so elements can only be removed from the ++ * head of the list. New elements can be added to the list before or after ++ * an existing element, at the head of the list, or at the end of the ++ * list. A simple queue may only be traversed in the forward direction. ++ * ++ * A tail queue is headed by a pair of pointers, one to the head of the ++ * list and the other to the tail of the list. The elements are doubly ++ * linked so that an arbitrary element can be removed without a need to ++ * traverse the list. New elements can be added to the list before or ++ * after an existing element, at the head of the list, or at the end of ++ * the list. A tail queue may be traversed in either direction. ++ * ++ * A circle queue is headed by a pair of pointers, one to the head of the ++ * list and the other to the tail of the list. The elements are doubly ++ * linked so that an arbitrary element can be removed without a need to ++ * traverse the list. New elements can be added to the list before or after ++ * an existing element, at the head of the list, or at the end of the list. ++ * A circle queue may be traversed in either direction, but has a more ++ * complex end of list detection. ++ * ++ * For details on the use of these macros, see the queue(3) manual page. ++ */ ++ ++#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) ++#define _Q_INVALIDATE(a) (a) = ((void *)-1) ++#else ++#define _Q_INVALIDATE(a) ++#endif ++ ++/* ++ * Singly-linked List definitions. ++ */ ++#define SLIST_HEAD(name, type) \ ++struct name { \ ++ struct type *slh_first; /* first element */ \ ++} ++ ++#define SLIST_HEAD_INITIALIZER(head) \ ++ { NULL } ++ ++#define SLIST_ENTRY(type) \ ++struct { \ ++ struct type *sle_next; /* next element */ \ ++} ++ ++/* ++ * Singly-linked List access methods. ++ */ ++#define SLIST_FIRST(head) ((head)->slh_first) ++#define SLIST_END(head) NULL ++#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) ++#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) ++ ++#define SLIST_FOREACH(var, head, field) \ ++ for((var) = SLIST_FIRST(head); \ ++ (var) != SLIST_END(head); \ ++ (var) = SLIST_NEXT(var, field)) ++ ++#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ ++ for ((var) = SLIST_FIRST(head); \ ++ (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ ++ (var) = (tvar)) ++ ++/* ++ * Singly-linked List functions. ++ */ ++#define SLIST_INIT(head) { \ ++ SLIST_FIRST(head) = SLIST_END(head); \ ++} ++ ++#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ ++ (elm)->field.sle_next = (slistelm)->field.sle_next; \ ++ (slistelm)->field.sle_next = (elm); \ ++} while (0) ++ ++#define SLIST_INSERT_HEAD(head, elm, field) do { \ ++ (elm)->field.sle_next = (head)->slh_first; \ ++ (head)->slh_first = (elm); \ ++} while (0) ++ ++#define SLIST_REMOVE_AFTER(elm, field) do { \ ++ (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ ++} while (0) ++ ++#define SLIST_REMOVE_HEAD(head, field) do { \ ++ (head)->slh_first = (head)->slh_first->field.sle_next; \ ++} while (0) ++ ++#define SLIST_REMOVE(head, elm, type, field) do { \ ++ if ((head)->slh_first == (elm)) { \ ++ SLIST_REMOVE_HEAD((head), field); \ ++ } else { \ ++ struct type *curelm = (head)->slh_first; \ ++ \ ++ while (curelm->field.sle_next != (elm)) \ ++ curelm = curelm->field.sle_next; \ ++ curelm->field.sle_next = \ ++ curelm->field.sle_next->field.sle_next; \ ++ _Q_INVALIDATE((elm)->field.sle_next); \ ++ } \ ++} while (0) ++ ++/* ++ * List definitions. ++ */ ++#define LIST_HEAD(name, type) \ ++struct name { \ ++ struct type *lh_first; /* first element */ \ ++} ++ ++#define LIST_HEAD_INITIALIZER(head) \ ++ { NULL } ++ ++#define LIST_ENTRY(type) \ ++struct { \ ++ struct type *le_next; /* next element */ \ ++ struct type **le_prev; /* address of previous next element */ \ ++} ++ ++/* ++ * List access methods ++ */ ++#define LIST_FIRST(head) ((head)->lh_first) ++#define LIST_END(head) NULL ++#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) ++#define LIST_NEXT(elm, field) ((elm)->field.le_next) ++ ++#define LIST_FOREACH(var, head, field) \ ++ for((var) = LIST_FIRST(head); \ ++ (var)!= LIST_END(head); \ ++ (var) = LIST_NEXT(var, field)) ++ ++#define LIST_FOREACH_SAFE(var, head, field, tvar) \ ++ for ((var) = LIST_FIRST(head); \ ++ (var) && ((tvar) = LIST_NEXT(var, field), 1); \ ++ (var) = (tvar)) ++ ++/* ++ * List functions. ++ */ ++#define LIST_INIT(head) do { \ ++ LIST_FIRST(head) = LIST_END(head); \ ++} while (0) ++ ++#define LIST_INSERT_AFTER(listelm, elm, field) do { \ ++ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ ++ (listelm)->field.le_next->field.le_prev = \ ++ &(elm)->field.le_next; \ ++ (listelm)->field.le_next = (elm); \ ++ (elm)->field.le_prev = &(listelm)->field.le_next; \ ++} while (0) ++ ++#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ ++ (elm)->field.le_prev = (listelm)->field.le_prev; \ ++ (elm)->field.le_next = (listelm); \ ++ *(listelm)->field.le_prev = (elm); \ ++ (listelm)->field.le_prev = &(elm)->field.le_next; \ ++} while (0) ++ ++#define LIST_INSERT_HEAD(head, elm, field) do { \ ++ if (((elm)->field.le_next = (head)->lh_first) != NULL) \ ++ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ ++ (head)->lh_first = (elm); \ ++ (elm)->field.le_prev = &(head)->lh_first; \ ++} while (0) ++ ++#define LIST_REMOVE(elm, field) do { \ ++ if ((elm)->field.le_next != NULL) \ ++ (elm)->field.le_next->field.le_prev = \ ++ (elm)->field.le_prev; \ ++ *(elm)->field.le_prev = (elm)->field.le_next; \ ++ _Q_INVALIDATE((elm)->field.le_prev); \ ++ _Q_INVALIDATE((elm)->field.le_next); \ ++} while (0) ++ ++#define LIST_REPLACE(elm, elm2, field) do { \ ++ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ ++ (elm2)->field.le_next->field.le_prev = \ ++ &(elm2)->field.le_next; \ ++ (elm2)->field.le_prev = (elm)->field.le_prev; \ ++ *(elm2)->field.le_prev = (elm2); \ ++ _Q_INVALIDATE((elm)->field.le_prev); \ ++ _Q_INVALIDATE((elm)->field.le_next); \ ++} while (0) ++ ++/* ++ * Simple queue definitions. ++ */ ++#define SIMPLEQ_HEAD(name, type) \ ++struct name { \ ++ struct type *sqh_first; /* first element */ \ ++ struct type **sqh_last; /* addr of last next element */ \ ++} ++ ++#define SIMPLEQ_HEAD_INITIALIZER(head) \ ++ { NULL, &(head).sqh_first } ++ ++#define SIMPLEQ_ENTRY(type) \ ++struct { \ ++ struct type *sqe_next; /* next element */ \ ++} ++ ++/* ++ * Simple queue access methods. ++ */ ++#define SIMPLEQ_FIRST(head) ((head)->sqh_first) ++#define SIMPLEQ_END(head) NULL ++#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) ++#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) ++ ++#define SIMPLEQ_FOREACH(var, head, field) \ ++ for((var) = SIMPLEQ_FIRST(head); \ ++ (var) != SIMPLEQ_END(head); \ ++ (var) = SIMPLEQ_NEXT(var, field)) ++ ++#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ ++ for ((var) = SIMPLEQ_FIRST(head); \ ++ (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \ ++ (var) = (tvar)) ++ ++/* ++ * Simple queue functions. ++ */ ++#define SIMPLEQ_INIT(head) do { \ ++ (head)->sqh_first = NULL; \ ++ (head)->sqh_last = &(head)->sqh_first; \ ++} while (0) ++ ++#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ ++ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ ++ (head)->sqh_last = &(elm)->field.sqe_next; \ ++ (head)->sqh_first = (elm); \ ++} while (0) ++ ++#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ ++ (elm)->field.sqe_next = NULL; \ ++ *(head)->sqh_last = (elm); \ ++ (head)->sqh_last = &(elm)->field.sqe_next; \ ++} while (0) ++ ++#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ ++ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ ++ (head)->sqh_last = &(elm)->field.sqe_next; \ ++ (listelm)->field.sqe_next = (elm); \ ++} while (0) ++ ++#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ ++ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ ++ (head)->sqh_last = &(head)->sqh_first; \ ++} while (0) ++ ++#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ ++ if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ ++ == NULL) \ ++ (head)->sqh_last = &(elm)->field.sqe_next; \ ++} while (0) ++ ++/* ++ * XOR Simple queue definitions. ++ */ ++#define XSIMPLEQ_HEAD(name, type) \ ++struct name { \ ++ struct type *sqx_first; /* first element */ \ ++ struct type **sqx_last; /* addr of last next element */ \ ++ unsigned long sqx_cookie; \ ++} ++ ++#define XSIMPLEQ_ENTRY(type) \ ++struct { \ ++ struct type *sqx_next; /* next element */ \ ++} ++ ++/* ++ * XOR Simple queue access methods. ++ */ ++#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \ ++ (unsigned long)(ptr))) ++#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first)) ++#define XSIMPLEQ_END(head) NULL ++#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head)) ++#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next)) ++ ++ ++#define XSIMPLEQ_FOREACH(var, head, field) \ ++ for ((var) = XSIMPLEQ_FIRST(head); \ ++ (var) != XSIMPLEQ_END(head); \ ++ (var) = XSIMPLEQ_NEXT(head, var, field)) ++ ++#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ ++ for ((var) = XSIMPLEQ_FIRST(head); \ ++ (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \ ++ (var) = (tvar)) ++ ++/* ++ * XOR Simple queue functions. ++ */ ++#define XSIMPLEQ_INIT(head) do { \ ++ arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \ ++ (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \ ++ (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ ++} while (0) ++ ++#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ ++ if (((elm)->field.sqx_next = (head)->sqx_first) == \ ++ XSIMPLEQ_XOR(head, NULL)) \ ++ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ ++ (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \ ++} while (0) ++ ++#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ ++ (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \ ++ *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \ ++ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ ++} while (0) ++ ++#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ ++ if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \ ++ XSIMPLEQ_XOR(head, NULL)) \ ++ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ ++ (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \ ++} while (0) ++ ++#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \ ++ if (((head)->sqx_first = XSIMPLEQ_XOR(head, \ ++ (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \ ++ (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ ++} while (0) ++ ++#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ ++ if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \ ++ (elm)->field.sqx_next)->field.sqx_next) \ ++ == XSIMPLEQ_XOR(head, NULL)) \ ++ (head)->sqx_last = \ ++ XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ ++} while (0) ++ ++ ++/* ++ * Tail queue definitions. ++ */ ++#define TAILQ_HEAD(name, type) \ ++struct name { \ ++ struct type *tqh_first; /* first element */ \ ++ struct type **tqh_last; /* addr of last next element */ \ ++} ++ ++#define TAILQ_HEAD_INITIALIZER(head) \ ++ { NULL, &(head).tqh_first } ++ ++#define TAILQ_ENTRY(type) \ ++struct { \ ++ struct type *tqe_next; /* next element */ \ ++ struct type **tqe_prev; /* address of previous next element */ \ ++} ++ ++/* ++ * tail queue access methods ++ */ ++#define TAILQ_FIRST(head) ((head)->tqh_first) ++#define TAILQ_END(head) NULL ++#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) ++#define TAILQ_LAST(head, headname) \ ++ (*(((struct headname *)((head)->tqh_last))->tqh_last)) ++/* XXX */ ++#define TAILQ_PREV(elm, headname, field) \ ++ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) ++#define TAILQ_EMPTY(head) \ ++ (TAILQ_FIRST(head) == TAILQ_END(head)) ++ ++#define TAILQ_FOREACH(var, head, field) \ ++ for((var) = TAILQ_FIRST(head); \ ++ (var) != TAILQ_END(head); \ ++ (var) = TAILQ_NEXT(var, field)) ++ ++#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ ++ for ((var) = TAILQ_FIRST(head); \ ++ (var) != TAILQ_END(head) && \ ++ ((tvar) = TAILQ_NEXT(var, field), 1); \ ++ (var) = (tvar)) ++ ++ ++#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ ++ for((var) = TAILQ_LAST(head, headname); \ ++ (var) != TAILQ_END(head); \ ++ (var) = TAILQ_PREV(var, headname, field)) ++ ++#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ ++ for ((var) = TAILQ_LAST(head, headname); \ ++ (var) != TAILQ_END(head) && \ ++ ((tvar) = TAILQ_PREV(var, headname, field), 1); \ ++ (var) = (tvar)) ++ ++/* ++ * Tail queue functions. ++ */ ++#define TAILQ_INIT(head) do { \ ++ (head)->tqh_first = NULL; \ ++ (head)->tqh_last = &(head)->tqh_first; \ ++} while (0) ++ ++#define TAILQ_INSERT_HEAD(head, elm, field) do { \ ++ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ ++ (head)->tqh_first->field.tqe_prev = \ ++ &(elm)->field.tqe_next; \ ++ else \ ++ (head)->tqh_last = &(elm)->field.tqe_next; \ ++ (head)->tqh_first = (elm); \ ++ (elm)->field.tqe_prev = &(head)->tqh_first; \ ++} while (0) ++ ++#define TAILQ_INSERT_TAIL(head, elm, field) do { \ ++ (elm)->field.tqe_next = NULL; \ ++ (elm)->field.tqe_prev = (head)->tqh_last; \ ++ *(head)->tqh_last = (elm); \ ++ (head)->tqh_last = &(elm)->field.tqe_next; \ ++} while (0) ++ ++#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ ++ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ ++ (elm)->field.tqe_next->field.tqe_prev = \ ++ &(elm)->field.tqe_next; \ ++ else \ ++ (head)->tqh_last = &(elm)->field.tqe_next; \ ++ (listelm)->field.tqe_next = (elm); \ ++ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ ++} while (0) ++ ++#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ ++ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ ++ (elm)->field.tqe_next = (listelm); \ ++ *(listelm)->field.tqe_prev = (elm); \ ++ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ ++} while (0) ++ ++#define TAILQ_REMOVE(head, elm, field) do { \ ++ if (((elm)->field.tqe_next) != NULL) \ ++ (elm)->field.tqe_next->field.tqe_prev = \ ++ (elm)->field.tqe_prev; \ ++ else \ ++ (head)->tqh_last = (elm)->field.tqe_prev; \ ++ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ ++ _Q_INVALIDATE((elm)->field.tqe_prev); \ ++ _Q_INVALIDATE((elm)->field.tqe_next); \ ++} while (0) ++ ++#define TAILQ_REPLACE(head, elm, elm2, field) do { \ ++ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ ++ (elm2)->field.tqe_next->field.tqe_prev = \ ++ &(elm2)->field.tqe_next; \ ++ else \ ++ (head)->tqh_last = &(elm2)->field.tqe_next; \ ++ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ ++ *(elm2)->field.tqe_prev = (elm2); \ ++ _Q_INVALIDATE((elm)->field.tqe_prev); \ ++ _Q_INVALIDATE((elm)->field.tqe_next); \ ++} while (0) ++ ++/* ++ * Circular queue definitions. ++ */ ++#define CIRCLEQ_HEAD(name, type) \ ++struct name { \ ++ struct type *cqh_first; /* first element */ \ ++ struct type *cqh_last; /* last element */ \ ++} ++ ++#define CIRCLEQ_HEAD_INITIALIZER(head) \ ++ { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } ++ ++#define CIRCLEQ_ENTRY(type) \ ++struct { \ ++ struct type *cqe_next; /* next element */ \ ++ struct type *cqe_prev; /* previous element */ \ ++} ++ ++/* ++ * Circular queue access methods ++ */ ++#define CIRCLEQ_FIRST(head) ((head)->cqh_first) ++#define CIRCLEQ_LAST(head) ((head)->cqh_last) ++#define CIRCLEQ_END(head) ((void *)(head)) ++#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) ++#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) ++#define CIRCLEQ_EMPTY(head) \ ++ (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) ++ ++#define CIRCLEQ_FOREACH(var, head, field) \ ++ for((var) = CIRCLEQ_FIRST(head); \ ++ (var) != CIRCLEQ_END(head); \ ++ (var) = CIRCLEQ_NEXT(var, field)) ++ ++#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \ ++ for ((var) = CIRCLEQ_FIRST(head); \ ++ (var) != CIRCLEQ_END(head) && \ ++ ((tvar) = CIRCLEQ_NEXT(var, field), 1); \ ++ (var) = (tvar)) ++ ++#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ ++ for((var) = CIRCLEQ_LAST(head); \ ++ (var) != CIRCLEQ_END(head); \ ++ (var) = CIRCLEQ_PREV(var, field)) ++ ++#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ ++ for ((var) = CIRCLEQ_LAST(head, headname); \ ++ (var) != CIRCLEQ_END(head) && \ ++ ((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \ ++ (var) = (tvar)) ++ ++/* ++ * Circular queue functions. ++ */ ++#define CIRCLEQ_INIT(head) do { \ ++ (head)->cqh_first = CIRCLEQ_END(head); \ ++ (head)->cqh_last = CIRCLEQ_END(head); \ ++} while (0) ++ ++#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ ++ (elm)->field.cqe_next = (listelm)->field.cqe_next; \ ++ (elm)->field.cqe_prev = (listelm); \ ++ if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ ++ (head)->cqh_last = (elm); \ ++ else \ ++ (listelm)->field.cqe_next->field.cqe_prev = (elm); \ ++ (listelm)->field.cqe_next = (elm); \ ++} while (0) ++ ++#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ ++ (elm)->field.cqe_next = (listelm); \ ++ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ ++ if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ ++ (head)->cqh_first = (elm); \ ++ else \ ++ (listelm)->field.cqe_prev->field.cqe_next = (elm); \ ++ (listelm)->field.cqe_prev = (elm); \ ++} while (0) ++ ++#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ ++ (elm)->field.cqe_next = (head)->cqh_first; \ ++ (elm)->field.cqe_prev = CIRCLEQ_END(head); \ ++ if ((head)->cqh_last == CIRCLEQ_END(head)) \ ++ (head)->cqh_last = (elm); \ ++ else \ ++ (head)->cqh_first->field.cqe_prev = (elm); \ ++ (head)->cqh_first = (elm); \ ++} while (0) ++ ++#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ ++ (elm)->field.cqe_next = CIRCLEQ_END(head); \ ++ (elm)->field.cqe_prev = (head)->cqh_last; \ ++ if ((head)->cqh_first == CIRCLEQ_END(head)) \ ++ (head)->cqh_first = (elm); \ ++ else \ ++ (head)->cqh_last->field.cqe_next = (elm); \ ++ (head)->cqh_last = (elm); \ ++} while (0) ++ ++#define CIRCLEQ_REMOVE(head, elm, field) do { \ ++ if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ ++ (head)->cqh_last = (elm)->field.cqe_prev; \ ++ else \ ++ (elm)->field.cqe_next->field.cqe_prev = \ ++ (elm)->field.cqe_prev; \ ++ if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ ++ (head)->cqh_first = (elm)->field.cqe_next; \ ++ else \ ++ (elm)->field.cqe_prev->field.cqe_next = \ ++ (elm)->field.cqe_next; \ ++ _Q_INVALIDATE((elm)->field.cqe_prev); \ ++ _Q_INVALIDATE((elm)->field.cqe_next); \ ++} while (0) ++ ++#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ ++ if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ ++ CIRCLEQ_END(head)) \ ++ (head)->cqh_last = (elm2); \ ++ else \ ++ (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ ++ if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ ++ CIRCLEQ_END(head)) \ ++ (head)->cqh_first = (elm2); \ ++ else \ ++ (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ ++ _Q_INVALIDATE((elm)->field.cqe_prev); \ ++ _Q_INVALIDATE((elm)->field.cqe_next); \ ++} while (0) ++ ++#endif /* !_SYS_QUEUE_H_ */ +-- +2.0.0 +