1    	#ifndef __OSI_RBTREE_DOT_H__
2    	#define __OSI_RBTREE_DOT_H__
3    	
4    	#include <stdlib.h>
5    	#include <stddef.h>
6    	#include <assert.h>
7    	
8    	/* Adapted from the kernel's rbtree.c */
9    	struct osi_node {
10   		unsigned long  osi_parent_color;
11   	#define	OSI_RED		0
12   	#define	OSI_BLACK	1
13   		struct osi_node *osi_left;
14   		struct osi_node *osi_right;
15   	};
16   	
17   	#define osi_parent(r)   ((struct osi_node *)((r)->osi_parent_color & ~3))
18   	#define osi_color(r)   ((r)->osi_parent_color & 1)
19   	#define osi_is_red(r)   (!osi_color(r))
20   	#define osi_is_black(r) osi_color(r)
21   	#define osi_set_red(r)  do { (r)->osi_parent_color &= ~1; } while (0)
22   	#define osi_set_black(r)  do { (r)->osi_parent_color |= 1; } while (0)
23   	#define OSI_EMPTY_NODE(node) (osi_parent(node) == node)
24   	
25   	struct osi_root
26   	{
27   		struct osi_node *osi_node;
28   	};
29   	
30   	#define OSI_EMPTY_ROOT(root)  ((root)->osi_node == NULL)
31   	
32   	static inline void osi_set_parent(struct osi_node *rb, struct osi_node *p)
33   	{
34   	        rb->osi_parent_color = (rb->osi_parent_color & 3) | (unsigned long)p;
35   	}
36   	
37   	static inline void osi_set_color(struct osi_node *rb, int color)
38   	{
39   		rb->osi_parent_color = (rb->osi_parent_color & ~1) | color;
40   	}
41   	
42   	static inline void osi_link_node(struct osi_node *node,
43   					 struct osi_node *parent,
44   					 struct osi_node **osi_link)
45   	{
46   		node->osi_parent_color = (unsigned long )parent;
47   		node->osi_left = node->osi_right = NULL;
48   	
49   		*osi_link = node;
50   	}
51   	
52   	static inline void __osi_rotate_left(struct osi_node *node,
53   					     struct osi_root *root)
54   	{
55   		struct osi_node *right = node->osi_right;
56   		struct osi_node *parent = osi_parent(node);
57   	
58   		if ((node->osi_right = right->osi_left))
59   			osi_set_parent(right->osi_left, node);
60   		right->osi_left = node;
61   	
62   		osi_set_parent(right, parent);
63   	
64   		if (parent) {
65   			if (node == parent->osi_left)
66   				parent->osi_left = right;
67   			else
68   				parent->osi_right = right;
69   		}
70   		else
71   			root->osi_node = right;
72   		osi_set_parent(node, right);
73   	}
74   	
75   	static inline void __osi_rotate_right(struct osi_node *node,
76   					      struct osi_root *root)
77   	{
78   		struct osi_node *left = node->osi_left;
79   		struct osi_node *parent = osi_parent(node);
80   	
81   		if ((node->osi_left = left->osi_right))
82   			osi_set_parent(left->osi_right, node);
83   		left->osi_right = node;
84   	
85   		osi_set_parent(left, parent);
86   	
87   		if (parent) {
88   			if (node == parent->osi_right)
89   				parent->osi_right = left;
90   			else
91   				parent->osi_left = left;
92   		} else
93   			root->osi_node = left;
94   		osi_set_parent(node, left);
95   	}
96   	
97   	static inline void osi_insert_color(struct osi_node *node,
98   					    struct osi_root *root)
99   	{
100  		struct osi_node *parent, *gparent;
101  	
(1) Event cond_true: Condition "parent = (struct osi_node *)(node->osi_parent_color & 18446744073709551612UL /* ~3 */)", taking true branch.
(2) Event cond_true: Condition "!(parent->osi_parent_color & 1)", taking true branch.
(8) Event cond_true: Condition "parent = (struct osi_node *)(node->osi_parent_color & 18446744073709551612UL /* ~3 */)", taking true branch.
(9) Event cond_true: Condition "!(parent->osi_parent_color & 1)", taking true branch.
(18) Event loop_begin: Jumped back to beginning of loop.
(19) Event cond_true: Condition "parent = (struct osi_node *)(node->osi_parent_color & 18446744073709551612UL /* ~3 */)", taking true branch.
(20) Event cond_true: Condition "!(parent->osi_parent_color & 1)", taking true branch.
(29) Event loop_begin: Jumped back to beginning of loop.
(30) Event cond_true: Condition "parent = (struct osi_node *)(node->osi_parent_color & 18446744073709551612UL /* ~3 */)", taking true branch.
(31) Event cond_true: Condition "!(parent->osi_parent_color & 1)", taking true branch.
(39) Event loop_begin: Jumped back to beginning of loop.
(40) Event cond_true: Condition "parent = (struct osi_node *)(node->osi_parent_color & 18446744073709551612UL /* ~3 */)", taking true branch.
(41) Event cond_true: Condition "!(parent->osi_parent_color & 1)", taking true branch.
(50) Event loop_begin: Jumped back to beginning of loop.
(51) Event cond_true: Condition "parent = (struct osi_node *)(node->osi_parent_color & 18446744073709551612UL /* ~3 */)", taking true branch.
(52) Event cond_true: Condition "!(parent->osi_parent_color & 1)", taking true branch.
(59) Event cond_true: Condition "parent = (struct osi_node *)(node->osi_parent_color & 18446744073709551612UL /* ~3 */)", taking true branch.
(60) Event cond_false: Condition "!(parent->osi_parent_color & 1)", taking false branch.
102  		while ((parent = osi_parent(node)) && osi_is_red(parent)) {
103  			gparent = osi_parent(parent);
104  	
(3) Event cond_true: Condition "parent == gparent->osi_left", taking true branch.
(10) Event cond_true: Condition "parent == gparent->osi_left", taking true branch.
(21) Event cond_true: Condition "parent == gparent->osi_left", taking true branch.
(32) Event cond_true: Condition "parent == gparent->osi_left", taking true branch.
(42) Event cond_true: Condition "parent == gparent->osi_left", taking true branch.
(53) Event cond_false: Condition "parent == gparent->osi_left", taking false branch.
105  			if (parent == gparent->osi_left) {
106  				{
107  					struct osi_node *uncle = gparent->osi_right;
(4) Event cond_true: Condition "uncle", taking true branch.
(5) Event cond_true: Condition "!(uncle->osi_parent_color & 1)", taking true branch.
(11) Event cond_true: Condition "uncle", taking true branch.
(12) Event cond_false: Condition "!(uncle->osi_parent_color & 1)", taking false branch.
(22) Event cond_true: Condition "uncle", taking true branch.
(23) Event cond_false: Condition "!(uncle->osi_parent_color & 1)", taking false branch.
(33) Event cond_false: Condition "uncle", taking false branch.
(43) Event cond_true: Condition "uncle", taking true branch.
(44) Event cond_false: Condition "!(uncle->osi_parent_color & 1)", taking false branch.
108  					if (uncle && osi_is_red(uncle)) {
109  						osi_set_black(uncle);
110  						osi_set_black(parent);
111  						osi_set_red(gparent);
112  						node = gparent;
(6) Event continue: Continuing loop.
113  						continue;
(13) Event if_end: End of if statement.
(24) Event if_end: End of if statement.
(34) Event if_end: End of if statement.
(45) Event if_end: End of if statement.
114  					}
115  				}
116  	
(14) Event cond_true: Condition "parent->osi_right == node", taking true branch.
(25) Event cond_true: Condition "parent->osi_right == node", taking true branch.
(35) Event cond_true: Condition "parent->osi_right == node", taking true branch.
(46) Event cond_true: Condition "parent->osi_right == node", taking true branch.
117  				if (parent->osi_right == node) {
118  					struct osi_node *tmp;
119  	
120  					__osi_rotate_left(parent, root);
121  					tmp = parent;
122  					parent = node;
123  					node = tmp;
124  				}
125  	
126  				osi_set_black(parent);
127  				osi_set_red(gparent);
128  				__osi_rotate_right(gparent, root);
(15) Event if_fallthrough: Falling through to end of if statement.
(26) Event if_fallthrough: Falling through to end of if statement.
(36) Event if_fallthrough: Falling through to end of if statement.
(47) Event if_fallthrough: Falling through to end of if statement.
(54) Event else_branch: Reached else branch.
129  			} else {
130  				{
131  					struct osi_node *uncle = gparent->osi_left;
(55) Event cond_true: Condition "uncle", taking true branch.
(56) Event cond_true: Condition "!(uncle->osi_parent_color & 1)", taking true branch.
132  					if (uncle && osi_is_red(uncle)) {
133  						osi_set_black(uncle);
134  						osi_set_black(parent);
135  						osi_set_red(gparent);
136  						node = gparent;
(57) Event continue: Continuing loop.
137  						continue;
138  					}
139  				}
140  	
141  				if (parent->osi_left == node) {
142  					struct osi_node *tmp;
143  					__osi_rotate_right(parent, root);
144  					tmp = parent;
145  					parent = node;
146  					node = tmp;
147  				}
148  	
149  				osi_set_black(parent);
150  				osi_set_red(gparent);
151  				__osi_rotate_left(gparent, root);
(16) Event if_end: End of if statement.
(27) Event if_end: End of if statement.
(37) Event if_end: End of if statement.
(48) Event if_end: End of if statement.
152  			}
(7) Event loop: Looping back.
(17) Event loop: Jumping back to the beginning of the loop.
(28) Event loop: Jumping back to the beginning of the loop.
(38) Event loop: Jumping back to the beginning of the loop.
(49) Event loop: Jumping back to the beginning of the loop.
(58) Event loop: Looping back.
(61) Event loop_end: Reached end of loop.
153  		}
154  	
(62) Event null_field: Reading field "osi_node", which is expected to possibly be "NULL" in "root->osi_node" (checked 12 out of 13 times).
(68) Event dereference: Dereferencing "root->osi_node", which is known to be "NULL".
Also see events: [example_checked][example_checked][example_checked][example_checked][example_checked]
155  		osi_set_black(root->osi_node);
156  	}
157  	
158  	static inline void __osi_erase_color(struct osi_node *node,
159  					     struct osi_node *parent,
160  					     struct osi_root *root)
161  	{
162  		struct osi_node *other;
163  	
164  		while ((!node || osi_is_black(node)) && node != root->osi_node) {
165  			if (parent->osi_left == node) {
166  				other = parent->osi_right;
167  				if (osi_is_red(other)) {
168  					osi_set_black(other);
169  					osi_set_red(parent);
170  					__osi_rotate_left(parent, root);
171  					other = parent->osi_right;
172  				}
173  				if ((!other->osi_left || osi_is_black(other->osi_left)) &&
174  				    (!other->osi_right || osi_is_black(other->osi_right)))
175  				{
176  					osi_set_red(other);
177  					node = parent;
178  					parent = osi_parent(node);
179  				} else {
180  					if (!other->osi_right || osi_is_black(other->osi_right))
181  					{
182  						struct osi_node *o_left;
183  						if ((o_left = other->osi_left))
184  							osi_set_black(o_left);
185  						osi_set_red(other);
186  						__osi_rotate_right(other, root);
187  						other = parent->osi_right;
188  					}
189  					osi_set_color(other, osi_color(parent));
190  					osi_set_black(parent);
191  					if (other->osi_right)
192  						osi_set_black(other->osi_right);
193  					__osi_rotate_left(parent, root);
194  					node = root->osi_node;
195  					break;
196  				}
197  			} else {
198  				other = parent->osi_left;
199  				if (osi_is_red(other)) {
200  					osi_set_black(other);
201  					osi_set_red(parent);
202  					__osi_rotate_right(parent, root);
203  					other = parent->osi_left;
204  				}
205  				if ((!other->osi_left || osi_is_black(other->osi_left)) &&
206  				    (!other->osi_right || osi_is_black(other->osi_right)))
207  				{
208  					osi_set_red(other);
209  					node = parent;
210  					parent = osi_parent(node);
211  				} else {
212  					if (!other->osi_left || osi_is_black(other->osi_left))
213  					{
214  						struct osi_node *o_right;
215  						if ((o_right = other->osi_right))
216  							osi_set_black(o_right);
217  						osi_set_red(other);
218  						__osi_rotate_left(other, root);
219  						other = parent->osi_left;
220  					}
221  					osi_set_color(other, osi_color(parent));
222  					osi_set_black(parent);
223  					if (other->osi_left)
224  						osi_set_black(other->osi_left);
225  					__osi_rotate_right(parent, root);
226  					node = root->osi_node;
227  					break;
228  				}
229  			}
230  		}
(65) Event example_checked: Example 3: "root->osi_node" has its value checked in "node".
Also see events: [null_field][example_checked][example_checked][example_checked][example_checked][dereference]
231  		if (node)
232  			osi_set_black(node);
233  	}
234  	
235  	static inline void osi_erase(struct osi_node *node, struct osi_root *root)
236  	{
237  		struct osi_node *child, *parent;
238  		int color;
239  	
240  		if (!node->osi_left)
241  			child = node->osi_right;
242  		else if (!node->osi_right)
243  			child = node->osi_left;
244  		else {
245  			struct osi_node *old = node, *left;
246  	
247  			node = node->osi_right;
248  			while ((left = node->osi_left) != NULL)
249  				node = left;
250  	
251  			if (osi_parent(old)) {
252  				if (osi_parent(old)->osi_left == old)
253  					osi_parent(old)->osi_left = node;
254  				else
255  					osi_parent(old)->osi_right = node;
256  			} else
257  				root->osi_node = node;
258  	
259  			child = node->osi_right;
260  			parent = osi_parent(node);
261  			color = osi_color(node);
262  	
263  			if (parent == old) {
264  				parent = node;
265  			} else {
266  				if (child)
267  					osi_set_parent(child, parent);
268  				parent->osi_left = child;
269  	
270  				node->osi_right = old->osi_right;
271  				osi_set_parent(old->osi_right, node);
272  			}
273  	
274  			node->osi_parent_color = old->osi_parent_color;
275  			node->osi_left = old->osi_left;
276  			osi_set_parent(old->osi_left, node);
277  	
278  			goto color;
279  		}
280  	
281  		parent = osi_parent(node);
282  		color = osi_color(node);
283  	
284  		if (child)
285  			osi_set_parent(child, parent);
286  		if (parent)
287  		{
288  			if (parent->osi_left == node)
289  				parent->osi_left = child;
290  			else
291  				parent->osi_right = child;
292  		}
293  		else
294  			root->osi_node = child;
295  	
296  	 color:
297  		if (color == OSI_BLACK)
298  			/* coverity[var_deref_model:SUPPRESS] */
299  			__osi_erase_color(child, parent, root);
300  	}
301  	
302  	/*
303  	 * This function returns the first node (in sort order) of the tree.
304  	 */
305  	static inline struct osi_node *osi_first(struct osi_root *root)
306  	{
307  		struct osi_node	*n;
308  	
309  		n = root->osi_node;
(63) Event example_checked: Example 1: "root->osi_node" has its value checked in "n".
Also see events: [null_field][example_checked][example_checked][example_checked][example_checked][dereference]
310  		if (!n)
311  			return NULL;
312  		while (n->osi_left)
313  			n = n->osi_left;
314  		return n;
315  	}
316  	
317  	static inline struct osi_node *osi_last(struct osi_root *root)
318  	{
319  		struct osi_node	*n;
320  	
321  		n = root->osi_node;
322  		if (!n)
323  			return NULL;
324  		while (n->osi_right)
325  			n = n->osi_right;
326  		return n;
327  	}
328  	
329  	static inline struct osi_node *osi_next(struct osi_node *node)
330  	{
331  		struct osi_node *parent;
332  	
333  		if (OSI_EMPTY_NODE(node))
334  			return NULL;
335  	
336  		/* If we have a right-hand child, go down and then left as far
337  		   as we can. */
338  		if (node->osi_right) {
339  			node = node->osi_right;
340  			while (node->osi_left)
341  				node=node->osi_left;
342  			return node;
343  		}
344  	
345  		/* No right-hand children.  Everything down and left is
346  		   smaller than us, so any 'next' node must be in the general
347  		   direction of our parent. Go up the tree; any time the
348  		   ancestor is a right-hand child of its parent, keep going
349  		   up. First time it's a left-hand child of its parent, said
350  		   parent is our 'next' node. */
351  		while ((parent = osi_parent(node)) && node == parent->osi_right)
352  			node = parent;
353  	
354  		return parent;
355  	}
356  	
357  	static inline struct osi_node *osi_prev(struct osi_node *node)
358  	{
359  		struct osi_node *parent;
360  	
361  		if (OSI_EMPTY_NODE(node))
362  			return NULL;
363  	
364  		/* If we have a left-hand child, go down and then right as far
365  		   as we can. */
366  		if (node->osi_left) {
367  			node = node->osi_left;
368  			while (node->osi_right)
369  				node=node->osi_right;
370  			return node;
371  		}
372  	
373  		/* No left-hand children. Go up till we find an ancestor which
374  		   is a right-hand child of its parent */
375  		while ((parent = osi_parent(node)) && node == parent->osi_left)
376  			node = parent;
377  	
378  		return parent;
379  	}
380  	
381  	static inline void osi_replace_node(struct osi_node *victim,
382  					    struct osi_node *newn,
383  					    struct osi_root *root)
384  	{
385  		struct osi_node *parent = osi_parent(victim);
386  	
387  		/* Set the surrounding nodes to point to the replacement */
388  		if (parent) {
389  			if (victim == parent->osi_left)
390  				parent->osi_left = newn;
391  			else
392  				parent->osi_right = newn;
393  		} else {
394  			root->osi_node = newn;
395  		}
396  		if (victim->osi_left)
397  			osi_set_parent(victim->osi_left, newn);
398  		if (victim->osi_right)
399  			osi_set_parent(victim->osi_right, newn);
400  	
401  		/* Copy the pointers/colour from the victim to the replacement */
402  		*newn = *victim;
403  	}
404  	
405  	#endif
406