From 0c387b8ee04811f10eb638a40c0ca5befd3059ef Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 26 Jun 2012 20:34:02 +0200
Subject: [PATCH 2/3] Rework the newly added ilist interface to be usable on
 systems without USE_INLINE

I find doing such magick is ugly but...

 2 files changed, 72 insertions(+), 39 deletions(-)

diff --git a/src/backend/lib/ilist.c b/src/backend/lib/ilist.c
index 72de7a3..d1dccdb 100644
--- a/src/backend/lib/ilist.c
+++ b/src/backend/lib/ilist.c
@@ -20,7 +20,15 @@
 
 #include "postgres.h"
 
+/*
+ * If inlines aren't available include the function as defined in the header,
+ * but without 'static inline' defined. That way we do not have to duplicate
+ * their functionality.
+ */
+#ifndef USE_INLINE
+#define USE_DECLARATION
 #include "lib/ilist.h"
+#endif
 
 #ifdef ILIST_DEBUG
 void ilist_d_check(ilist_d_head* head)
@@ -76,4 +84,5 @@ void ilist_s_check(ilist_s_head* head)
 	    }
     }
 }
-#endif
+
+#endif /* ILIST_DEBUG */
diff --git a/src/include/lib/ilist.h b/src/include/lib/ilist.h
index cb1de99..91419a4 100644
--- a/src/include/lib/ilist.h
+++ b/src/include/lib/ilist.h
@@ -56,7 +56,6 @@
  * default even with --enable-cassert
 */
 /* #define ILIST_DEBUG */
-
 /*
  * gcc warns about unused parameters if -Wunused-parameter is specified (part
  * of -Wextra ). In the cases below its perfectly fine not to use those
@@ -70,12 +69,6 @@
 #define unused_attr
 #endif
 
-#ifndef USE_INLINE
-#error "a compiler supporting static inlines is required"
-#endif
-
-#include <assert.h>
-
 /*
  * struct to embed in other structs that need to be part of a double linked
  * list.
@@ -116,29 +109,56 @@ typedef struct
 } ilist_s_head;
 
 
+#ifdef USE_INLINE
+#define INLINE_IF_POSSIBLE static inline
+#define USE_DECLARATION
+#else
+#define INLINE_IF_POSSIBLE
+#endif
 
-#ifdef ILIST_DEBUG
+#ifndef USE_INLINE
+extern void ilist_d_check(unused_attr ilist_d_head* head);
+extern void ilist_d_init(ilist_d_head *head);
+extern void ilist_d_push_front(ilist_d_head *head, ilist_d_node *node);
+extern void ilist_d_push_back(ilist_d_head *head, ilist_d_node *node);
+extern void ilist_d_add_after(unused_attr ilist_d_head *head, ilist_d_node *after, ilist_d_node *node);
+extern void ilist_d_add_before(unused_attr ilist_d_head *head, ilist_d_node *before, ilist_d_node *node);
+extern void ilist_d_remove(unused_attr ilist_d_head *head, ilist_d_node *node);
+extern ilist_d_node* ilist_d_pop_front(ilist_d_head *head);
+extern void ilist_d_move_front(ilist_d_head *head, ilist_d_node *node);
+extern bool ilist_d_has_next(ilist_d_head *head, ilist_d_node *node);
+extern bool ilist_d_has_prev(ilist_d_head *head, ilist_d_node *node);
+extern bool ilist_d_is_empty(ilist_d_head *head);
+extern void ilist_d_check(ilist_d_head* head);
+
+extern void ilist_s_init(ilist_s_head *head);
+extern void ilist_s_push_front(ilist_s_head *head, ilist_s_node *node);
+extern ilist_s_node* ilist_s_pop_front(ilist_s_head *head);
+extern void ilist_s_remove(ilist_s_head *head, ilist_s_node *node);
+extern void ilist_s_add_after(unused_attr ilist_s_head *head,
+	                              ilist_s_node *after, ilist_s_node *node);
+extern bool ilist_s_is_empty(ilist_s_head *head);
+extern bool ilist_s_has_next(unused_attr ilist_s_head* head,
+	                             ilist_s_node *node);
+
+#endif /* USE_INLINE */
 
-void ilist_d_check(ilist_d_head* head);
-void ilist_s_check(ilist_s_head* head);
 
+#ifdef ILIST_DEBUG
+extern void ilist_d_check(ilist_d_head* head);
+extern void ilist_s_check(ilist_s_head* head);
 #else
+#define ilist_d_check(head)
+#define ilist_s_check(head)
+#endif /*ILIST_DEBUG*/
 
-static inline void ilist_d_check(unused_attr ilist_d_head* head)
-{
-}
-
-static inline void ilist_s_check(unused_attr ilist_s_head* head)
-{
-}
-
-#endif /* ILIST_DEBUG */
+#ifdef USE_DECLARATION
 
 /*
  * Initialize the head of a list. Previous state will be thrown away without
  * any cleanup.
  */
-static inline void ilist_d_init(ilist_d_head *head)
+INLINE_IF_POSSIBLE void ilist_d_init(ilist_d_head *head)
 {
 	head->head.next = head->head.prev = &head->head;
 	ilist_d_check(head);
@@ -147,7 +167,7 @@ static inline void ilist_d_init(ilist_d_head *head)
 /*
  * adds a node at the beginning of the list
  */
-static inline void ilist_d_push_front(ilist_d_head *head, ilist_d_node *node)
+INLINE_IF_POSSIBLE void ilist_d_push_front(ilist_d_head *head, ilist_d_node *node)
 {
 	node->next = head->head.next;
 	node->prev = &head->head;
@@ -160,7 +180,7 @@ static inline void ilist_d_push_front(ilist_d_head *head, ilist_d_node *node)
 /*
  * adds a node at the end of the list
  */
-static inline void ilist_d_push_back(ilist_d_head *head, ilist_d_node *node)
+INLINE_IF_POSSIBLE void ilist_d_push_back(ilist_d_head *head, ilist_d_node *node)
 {
 	node->next = &head->head;
 	node->prev = head->head.prev;
@@ -173,7 +193,7 @@ static inline void ilist_d_push_back(ilist_d_head *head, ilist_d_node *node)
 /*
  * adds a node after another *in the same list*
  */
-static inline void ilist_d_add_after(unused_attr ilist_d_head *head, ilist_d_node *after, ilist_d_node *node)
+INLINE_IF_POSSIBLE void ilist_d_add_after(unused_attr ilist_d_head *head, ilist_d_node *after, ilist_d_node *node)
 {
 	ilist_d_check(head);
 	node->prev = after;
@@ -186,7 +206,7 @@ static inline void ilist_d_add_after(unused_attr ilist_d_head *head, ilist_d_nod
 /*
  * adds a node after another *in the same list*
  */
-static inline void ilist_d_add_before(unused_attr ilist_d_head *head, ilist_d_node *before, ilist_d_node *node)
+INLINE_IF_POSSIBLE void ilist_d_add_before(unused_attr ilist_d_head *head, ilist_d_node *before, ilist_d_node *node)
 {
 	ilist_d_check(head);
 	node->prev = before->prev;
@@ -200,7 +220,7 @@ static inline void ilist_d_add_before(unused_attr ilist_d_head *head, ilist_d_no
 /*
  * removes a node from a list
  */
-static inline void ilist_d_remove(unused_attr ilist_d_head *head, ilist_d_node *node)
+INLINE_IF_POSSIBLE void ilist_d_remove(unused_attr ilist_d_head *head, ilist_d_node *node)
 {
 	ilist_d_check(head);
 	node->prev->next = node->next;
@@ -211,7 +231,7 @@ static inline void ilist_d_remove(unused_attr ilist_d_head *head, ilist_d_node *
 /*
  * removes the first node from a list or returns NULL
  */
-static inline ilist_d_node* ilist_d_pop_front(ilist_d_head *head)
+INLINE_IF_POSSIBLE ilist_d_node* ilist_d_pop_front(ilist_d_head *head)
 {
 	ilist_d_node* ret;
 
@@ -226,7 +246,7 @@ static inline ilist_d_node* ilist_d_pop_front(ilist_d_head *head)
 /*
  * moves an element that has to be in the list to the front of the list
  */
-static inline void ilist_d_move_front(ilist_d_head *head, ilist_d_node *node)
+INLINE_IF_POSSIBLE void ilist_d_move_front(ilist_d_head *head, ilist_d_node *node)
 {
 	/* fast path if its already at the front */
 	if(&head->head == node)
@@ -239,7 +259,7 @@ static inline void ilist_d_move_front(ilist_d_head *head, ilist_d_node *node)
 /*
  * Check whether the passed node is the last element in the list
  */
-static inline bool ilist_d_has_next(ilist_d_head *head, ilist_d_node *node)
+INLINE_IF_POSSIBLE bool ilist_d_has_next(ilist_d_head *head, ilist_d_node *node)
 {
 	return node->next != &head->head;
 }
@@ -247,7 +267,7 @@ static inline bool ilist_d_has_next(ilist_d_head *head, ilist_d_node *node)
 /*
  * Check whether the passed node is the first element in the list
  */
-static inline bool ilist_d_has_prev(ilist_d_head *head, ilist_d_node *node)
+INLINE_IF_POSSIBLE bool ilist_d_has_prev(ilist_d_head *head, ilist_d_node *node)
 {
 	return node->prev != &head->head;
 }
@@ -255,11 +275,13 @@ static inline bool ilist_d_has_prev(ilist_d_head *head, ilist_d_node *node)
 /*
  * Check whether the list is empty.
  */
-static inline bool ilist_d_is_empty(ilist_d_head *head)
+INLINE_IF_POSSIBLE bool ilist_d_is_empty(ilist_d_head *head)
 {
 	return head->head.next == head->head.prev;
 }
 
+#endif /*USE_DECLARATION*/
+
 /*
  * Return the value of first element in the list if there is one, return NULL
  * otherwise.
@@ -325,16 +347,18 @@ static inline bool ilist_d_is_empty(ilist_d_head *head)
                                                name = name->prev)
 
 
+#ifdef USE_DECLARATION
+
 /*
  * Initialize a single linked list element.
  */
-static inline void ilist_s_init(ilist_s_head *head)
+INLINE_IF_POSSIBLE void ilist_s_init(ilist_s_head *head)
 {
 	head->head.next = NULL;
 	ilist_s_check(head);
 }
 
-static inline void ilist_s_push_front(ilist_s_head *head, ilist_s_node *node)
+INLINE_IF_POSSIBLE void ilist_s_push_front(ilist_s_head *head, ilist_s_node *node)
 {
 	node->next = head->head.next;
 	head->head.next = node;
@@ -344,7 +368,7 @@ static inline void ilist_s_push_front(ilist_s_head *head, ilist_s_node *node)
 /*
  * fails if the list is empty
  */
-static inline ilist_s_node* ilist_s_pop_front(ilist_s_head *head)
+INLINE_IF_POSSIBLE ilist_s_node* ilist_s_pop_front(ilist_s_head *head)
 {
 	ilist_s_node* front = head->head.next;
 	head->head.next = head->head.next->next;
@@ -359,7 +383,7 @@ static inline ilist_s_node* ilist_s_pop_front(ilist_s_head *head)
  *
  * XXX: This function possibly should be out-of-line?
  */
-static inline void ilist_s_remove(ilist_s_head *head,
+INLINE_IF_POSSIBLE void ilist_s_remove(ilist_s_head *head,
                                   ilist_s_node *node)
 {
 	ilist_s_node *last = &head->head;
@@ -384,12 +408,11 @@ static inline void ilist_s_remove(ilist_s_head *head,
 #ifdef ILIST_DEBUG
    if(!found)
 	   elog(ERROR, "tried to remove nonexisting node");
-	assert(found);
 #endif
 }
 
 
-static inline void ilist_s_add_after(unused_attr ilist_s_head *head,
+INLINE_IF_POSSIBLE void ilist_s_add_after(unused_attr ilist_s_head *head,
                                      ilist_s_node *after, ilist_s_node *node)
 {
 	node->next = after->next;
@@ -398,17 +421,18 @@ static inline void ilist_s_add_after(unused_attr ilist_s_head *head,
 }
 
 
-static inline bool ilist_s_is_empty(ilist_s_head *head)
+INLINE_IF_POSSIBLE bool ilist_s_is_empty(ilist_s_head *head)
 {
 	return head->head.next == NULL;
 }
 
-static inline bool ilist_s_has_next(unused_attr ilist_s_head* head,
+INLINE_IF_POSSIBLE bool ilist_s_has_next(unused_attr ilist_s_head* head,
                                     ilist_s_node *node)
 {
 	return node->next != NULL;
 }
 
+#endif /* USE_DECLARATION */
 
 #define ilist_s_front(type, membername, ptr) (ilist_s_is_empty(ptr) ? \
 	ilist_container(type, membername, (ptr).next) : NULL
-- 
1.7.10.rc3.3.g19a6c.dirty

