2 * Doubly linked list primitives
4 * (C) 1992 Joseph H. Allen
6 * This file is part of JOE (Joe's Own Editor)
12 __RCSID("$MirOS: contrib/code/jupp/queue.h,v 1.3 2017/12/02 02:07:30 tg Exp $");
19 #define izque(type,member,item) do { \
20 QUEUE = (void *)(item); \
21 ((type *)QUEUE)->member.prev = (type *)QUEUE; \
22 ((type *)QUEUE)->member.next = (type *)QUEUE; \
25 #define deque(type,member,item) do { \
26 ITEM = (void *)(item); \
27 ((type *)ITEM)->member.prev->member.next = ((type *)ITEM)->member.next; \
28 ((type *)ITEM)->member.next->member.prev = ((type *)ITEM)->member.prev; \
31 #define deque_f(type,member,item) \
33 ITEM=(void *)(item), \
34 ((type *)ITEM)->member.prev->member.next=((type *)ITEM)->member.next, \
35 ((type *)ITEM)->member.next->member.prev=((type *)ITEM)->member.prev, \
39 #define qempty(type,member,item) \
41 QUEUE=(void *)(item), \
42 (type *)QUEUE==((type *)QUEUE)->member.next \
45 #define enquef(type,member,queue,item) do { \
46 ITEM = (void *)(item); \
47 QUEUE = (void *)(queue); \
48 ((type *)ITEM)->member.next = ((type *)QUEUE)->member.next; \
49 ((type *)ITEM)->member.prev = (type *)QUEUE; \
50 ((type *)QUEUE)->member.next->member.prev = (type *)ITEM; \
51 ((type *)QUEUE)->member.next = (type *)ITEM; \
54 #define enqueb(type,member,queue,item) do { \
55 ITEM = (void *)(item); \
56 QUEUE = (void *)(queue); \
57 ((type *)ITEM)->member.next = (type *)QUEUE; \
58 ((type *)ITEM)->member.prev = ((type *)QUEUE)->member.prev; \
59 ((type *)QUEUE)->member.prev->member.next = (type *)ITEM; \
60 ((type *)QUEUE)->member.prev = (type *)ITEM; \
63 #define enqueb_f(type,member,queue,item) \
65 ITEM=(void *)(item), \
66 QUEUE=(void *)(queue), \
67 ((type *)ITEM)->member.next=(type *)QUEUE, \
68 ((type *)ITEM)->member.prev=((type *)QUEUE)->member.prev, \
69 ((type *)QUEUE)->member.prev->member.next=(type *)ITEM, \
70 ((type *)QUEUE)->member.prev=(type *)ITEM, \
74 #define promote(type,member,queue,item) \
75 enquef(type,member,(queue),deque_f(type,member,(item)))
77 #define demote(type,member,queue,item) \
78 enqueb(type,member,(queue),deque_f(type,member,(item)))
80 #define splicef(type,member,queue,chain) do { \
81 ITEM = (void *)(chain); \
82 LAST = (void *)((type *)ITEM)->member.prev; \
83 QUEUE = (void *)(queue); \
84 ((type *)LAST)->member.next = ((type *)QUEUE)->member.next; \
85 ((type *)ITEM)->member.prev = (type *)QUEUE; \
86 ((type *)QUEUE)->member.next->member.prev = (type *)LAST; \
87 ((type *)QUEUE)->member.next = (type *)ITEM; \
90 #define spliceb(type,member,queue,chain) do { \
91 ITEM = (void *)(chain); \
92 LAST = (void *)((type *)ITEM)->member.prev; \
93 QUEUE = (void *)(queue); \
94 ((type *)LAST)->member.next = (type *)QUEUE; \
95 ((type *)ITEM)->member.prev = ((type *)QUEUE)->member.prev; \
96 ((type *)QUEUE)->member.prev->member.next = (type *)ITEM; \
97 ((type *)QUEUE)->member.prev = (type *)LAST; \
100 #define spliceb_f(type,member,queue,chain) \
102 ITEM=(void *)(chain), \
103 LAST=(void *)((type *)ITEM)->member.prev, \
104 QUEUE=(void *)(queue), \
105 ((type *)LAST)->member.next=(type *)QUEUE, \
106 ((type *)ITEM)->member.prev=((type *)QUEUE)->member.prev, \
107 ((type *)QUEUE)->member.prev->member.next=(type *)ITEM, \
108 ((type *)QUEUE)->member.prev=(type *)LAST, \
112 #define snip(type,member,first,last) \
114 ITEM=(void *)(first), \
115 LAST=(void *)(last), \
116 ((type *)LAST)->member.next->member.prev=((type *)ITEM)->member.prev, \
117 ((type *)ITEM)->member.prev->member.next=((type *)LAST)->member.next, \
118 ((type *)ITEM)->member.prev=(type *)LAST, \
119 ((type *)LAST)->member.next=(type *)ITEM, \
123 void *alitem PARAMS((void *list, int itemsize));
124 void frchn PARAMS((void *list, void *ch));