1 /*
2  *	Doubly linked list primitives
3  *	Copyright
4  *		(C) 1992 Joseph H. Allen
5  *
6  *	This file is part of JOE (Joe's Own Editor)
7  */
8 #ifndef _JOE_QUEUE
9 #define _JOE_QUEUE 1
10 
11 #ifdef EXTERN_B_C
12 __IDSTRING(rcsid_queue_h, "$MirOS: contrib/code/jupp/queue.h,v 1.7 2018/11/11 18:15:37 tg Exp $");
13 #endif
14 
15 extern void *ITEM;
16 extern void *QUEUE;
17 extern void *LAST;
18 
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; \
23 	} while(0)
24 
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; \
29 	} while(0)
30 
31 #define deque_f(type,member,item) \
32 	( \
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, \
36 	(type *)ITEM \
37 	)
38 
39 #define qempty(type,member,item) \
40 	( \
41 	QUEUE=(void *)(item), \
42 	(type *)QUEUE==((type *)QUEUE)->member.next \
43 	)
44 
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; \
52 	} while(0)
53 
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; \
61 	} while(0)
62 
63 #define enqueb_f(type,member,queue,item) \
64 	( \
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, \
71 	(type *)ITEM \
72 	)
73 
74 #define promote(type,member,queue,item) \
75 	enquef(type,member,(queue),deque_f(type,member,(item)))
76 
77 #define demote(type,member,queue,item) \
78 	enqueb(type,member,(queue),deque_f(type,member,(item)))
79 
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; \
88 	} while(0)
89 
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; \
98 	} while(0)
99 
100 #define spliceb_f(type,member,queue,chain) \
101 	( \
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, \
109 	(type *)ITEM \
110 	)
111 
112 #define snip(type,member,first,last) \
113 	( \
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, \
120 	(type *)ITEM \
121 	)
122 
123 void *alitem(void *list, size_t itemsize);
124 void frchn(void *list, void *ch);
125 
126 #endif
127