nsq: update new_nsq_reader() function call 745/head
authorEmmanuel Schmidbauer <emmanuel@getweave.com>
Fri, 12 Aug 2016 19:40:42 +0000 (15:40 -0400)
committerEmmanuel Schmidbauer <emmanuel@getweave.com>
Fri, 12 Aug 2016 19:40:42 +0000 (15:40 -0400)
-remove local libnsq files
-pass NULL for NSQReaderCfg to new_nsq_reader()

modules/nsq/http.h [deleted file]
modules/nsq/nsq.h [deleted file]
modules/nsq/nsq_mod.c
modules/nsq/reader.c [deleted file]
modules/nsq/utlist.h [deleted file]

diff --git a/modules/nsq/http.h b/modules/nsq/http.h
deleted file mode 100644 (file)
index a8bc40c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __http_h
-#define __http_h
-
-#include <ev.h>
-#include <curl/curl.h>
-
-struct HttpClient {
-    CURLM *multi;
-    struct ev_loop *loop;
-    struct ev_timer timer_event;
-    int still_running;
-};
-
-struct HttpResponse {
-    int status_code;
-    struct Buffer *data;
-};
-
-struct HttpRequest {
-    CURL *easy;
-    char *url;
-    struct HttpClient *httpc;
-    char error[CURL_ERROR_SIZE];
-    struct Buffer *data;
-    void (*callback)(struct HttpRequest *req, struct HttpResponse *resp, void *arg);
-    void *cb_arg;
-};
-
-struct HttpSocket {
-    curl_socket_t sockfd;
-    CURL *easy;
-    int action;
-    long timeout;
-    struct ev_io ev;
-    int evset;
-    struct HttpClient *httpc;
-};
-
-struct HttpClient *new_http_client(struct ev_loop *loop);
-void free_http_client(struct HttpClient *httpc);
-struct HttpRequest *new_http_request(const char *url,
-    void (*callback)(struct HttpRequest *req, struct HttpResponse *resp, void *arg), void *cb_arg, char *data);
-void free_http_request(struct HttpRequest *req);
-struct HttpResponse *new_http_response(int status_code, void *data);
-void free_http_response(struct HttpResponse *resp);
-int http_client_get(struct HttpClient *httpc, struct HttpRequest *req);
-
-#endif
diff --git a/modules/nsq/nsq.h b/modules/nsq/nsq.h
deleted file mode 100644 (file)
index 8473d36..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef __nsq_h
-#define __nsq_h
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <time.h>
-#include <ev.h>
-#include <evbuffsock.h>
-
-#include "utlist.h"
-
-typedef enum {NSQ_FRAME_TYPE_RESPONSE, NSQ_FRAME_TYPE_ERROR, NSQ_FRAME_TYPE_MESSAGE} frame_type;
-struct NSQDConnection;
-struct NSQMessage;
-
-struct NSQReader {
-    char *topic;
-    char *channel;
-    void *ctx; //context for call back
-    int max_in_flight;
-    struct NSQDConnection *conns;
-    struct NSQLookupdEndpoint *lookupd;
-    struct ev_timer lookupd_poll_timer;
-    struct ev_loop *loop;
-    void *httpc;
-    void (*connect_callback)(struct NSQReader *rdr, struct NSQDConnection *conn);
-    void (*close_callback)(struct NSQReader *rdr, struct NSQDConnection *conn);
-    void (*msg_callback)(struct NSQReader *rdr, struct NSQDConnection *conn, struct NSQMessage *msg, void *ctx);
-};
-
-struct NSQReader *new_nsq_reader(struct ev_loop *loop, const char *topic, const char *channel, void *ctx,
-    void (*connect_callback)(struct NSQReader *rdr, struct NSQDConnection *conn),
-    void (*close_callback)(struct NSQReader *rdr, struct NSQDConnection *conn),
-    void (*msg_callback)(struct NSQReader *rdr, struct NSQDConnection *conn, struct NSQMessage *msg, void *ctx));
-void free_nsq_reader(struct NSQReader *rdr);
-int nsq_reader_connect_to_nsqd(struct NSQReader *rdr, const char *address, int port);
-int nsq_reader_add_nsqlookupd_endpoint(struct NSQReader *rdr, const char *address, int port);
-void nsq_reader_set_loop(struct NSQReader *rdr, struct ev_loop *loop);
-void nsq_run(struct ev_loop *loop);
-
-struct NSQDConnection {
-    struct BufferedSocket *bs;
-    struct Buffer *command_buf;
-    uint32_t current_msg_size;
-    uint32_t current_frame_type;
-    char *current_data;
-    struct ev_loop *loop;
-    void (*connect_callback)(struct NSQDConnection *conn, void *arg);
-    void (*close_callback)(struct NSQDConnection *conn, void *arg);
-    void (*msg_callback)(struct NSQDConnection *conn, struct NSQMessage *msg, void *arg);
-    void *arg;
-    struct NSQDConnection *next;
-};
-
-struct NSQDConnection *new_nsqd_connection(struct ev_loop *loop, const char *address, int port,
-    void (*connect_callback)(struct NSQDConnection *conn, void *arg),
-    void (*close_callback)(struct NSQDConnection *conn, void *arg),
-    void (*msg_callback)(struct NSQDConnection *conn, struct NSQMessage *msg, void *arg),
-    void *arg);
-void free_nsqd_connection(struct NSQDConnection *conn);
-int nsqd_connection_connect(struct NSQDConnection *conn);
-void nsqd_connection_disconnect(struct NSQDConnection *conn);
-
-void nsq_subscribe(struct Buffer *buf, const char *topic, const char *channel);
-void nsq_ready(struct Buffer *buf, int count);
-void nsq_finish(struct Buffer *buf, const char *id);
-void nsq_requeue(struct Buffer *buf, const char *id, int timeout_ms);
-void nsq_nop(struct Buffer *buf);
-
-struct NSQMessage {
-    int64_t timestamp;
-    uint16_t attempts;
-    char id[16+1];
-    size_t body_length;
-    char *body;
-};
-
-struct NSQMessage *nsq_decode_message(const char *data, size_t data_length);
-void free_nsq_message(struct NSQMessage *msg);
-
-struct NSQLookupdEndpoint {
-    char *address;
-    int port;
-    struct NSQLookupdEndpoint *next;
-};
-
-struct NSQLookupdEndpoint *new_nsqlookupd_endpoint(const char *address, int port);
-void free_nsqlookupd_endpoint(struct NSQLookupdEndpoint *nsqlookupd_endpoint);
-
-#endif
index 37c749a..3dd4b08 100644 (file)
@@ -273,7 +273,7 @@ int nsq_consumer_worker_proc(int cmd_pipe, char *topic, char *channel)
 
        LM_DBG("NSQ Worker connecting to NSQ Topic [%s] and NSQ Channel [%s]\n", topic, channel);
        // setup the reader
-       rdr = new_nsq_reader(loop, topic, channel, (void *)ctx, NULL, NULL, nsq_message_handler);
+       rdr = new_nsq_reader(loop, topic, channel, (void *)ctx, NULL, NULL, NULL, nsq_message_handler);
 
        if (consumer_use_nsqd == 0) {
                snprintf(address, 128, "%.*s", nsq_lookupd_address.len, nsq_lookupd_address.s);
diff --git a/modules/nsq/reader.c b/modules/nsq/reader.c
deleted file mode 100644 (file)
index 337576d..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "nsq.h"
-#include "utlist.h"
-#include "http.h"
-#include "../../dprint.h"
-#include "../../rand/kam_rand.h"
-
-extern int nsq_max_in_flight;
-
-static void nsq_reader_connect_cb(struct NSQDConnection *conn, void *arg)
-{
-    struct NSQReader *rdr = (struct NSQReader *)arg;
-
-    if (rdr->connect_callback) {
-        rdr->connect_callback(rdr, conn);
-    }
-
-    // subscribe
-    buffer_reset(conn->command_buf);
-    nsq_subscribe(conn->command_buf, rdr->topic, rdr->channel);
-    buffered_socket_write_buffer(conn->bs, conn->command_buf);
-
-    // send initial RDY
-    buffer_reset(conn->command_buf);
-    nsq_ready(conn->command_buf, rdr->max_in_flight);
-    buffered_socket_write_buffer(conn->bs, conn->command_buf);
-}
-
-static void nsq_reader_msg_cb(struct NSQDConnection *conn, struct NSQMessage *msg, void *arg)
-{
-    struct NSQReader *rdr = (struct NSQReader *)arg;
-
-       //LM_ERR("nsq_reader_msg_cb()!\n");
-    if (rdr->msg_callback) {
-        msg->id[sizeof(msg->id)-1] = '\0';
-        rdr->msg_callback(rdr, conn, msg, rdr->ctx);
-    }
-}
-
-static void nsq_reader_close_cb(struct NSQDConnection *conn, void *arg)
-{
-    struct NSQReader *rdr = (struct NSQReader *)arg;
-
-       //LM_ERR("nsq_reader_close_cb()!\n");
-
-    if (rdr->close_callback) {
-        rdr->close_callback(rdr, conn);
-    }
-
-    LL_DELETE(rdr->conns, conn);
-
-    free_nsqd_connection(conn);
-}
-
-void nsq_lookupd_request_cb(struct HttpRequest *req, struct HttpResponse *resp, void *arg);
-
-static void nsq_reader_lookupd_poll_cb(EV_P_ struct ev_timer *w, int revents)
-{
-    struct NSQReader *rdr = (struct NSQReader *)w->data;
-    struct NSQLookupdEndpoint *nsqlookupd_endpoint;
-    struct HttpRequest *req;
-    int i, idx, count = 0;
-    char buf[256];
-
-       //LM_ERR("nsq_reader_lookupd_poll_cb()!\n");
-
-    LL_FOREACH(rdr->lookupd, nsqlookupd_endpoint) {
-        count++;
-    }
-    if (count == 0)
-       idx = 0;
-    else
-       idx = kam_rand() % count;
-
-
-    i = 0;
-    LL_FOREACH(rdr->lookupd, nsqlookupd_endpoint) {
-        if (i++ == idx) {
-            sprintf(buf, "http://%s:%d/lookup?topic=%s", nsqlookupd_endpoint->address,
-                nsqlookupd_endpoint->port, rdr->topic);
-                       //LM_ERR("buf %s\n", buf);
-            req = new_http_request(buf, nsq_lookupd_request_cb, rdr, NULL);
-            http_client_get((struct HttpClient *)rdr->httpc, req);
-            break;
-        }
-    }
-
-    ev_timer_again(rdr->loop, &rdr->lookupd_poll_timer);
-}
-
-struct NSQReader* new_nsq_reader(struct ev_loop *loop, const char *topic, const char *channel, void *ctx,
-    void (*connect_callback)(struct NSQReader *rdr, struct NSQDConnection *conn),
-    void (*close_callback)(struct NSQReader *rdr, struct NSQDConnection *conn),
-    void (*msg_callback)(struct NSQReader *rdr, struct NSQDConnection *conn, struct NSQMessage *msg, void *ctx))
-{
-    struct NSQReader *rdr;
-
-    rdr = (struct NSQReader *)malloc(sizeof(struct NSQReader));
-    rdr->topic = strdup(topic);
-    rdr->channel = strdup(channel);
-    rdr->max_in_flight = nsq_max_in_flight;
-    rdr->connect_callback = connect_callback;
-    rdr->close_callback = close_callback;
-    rdr->msg_callback = msg_callback;
-    rdr->ctx = ctx;
-    rdr->conns = NULL;
-    rdr->lookupd = NULL;
-    rdr->loop = loop;
-
-    rdr->httpc = new_http_client(rdr->loop);
-
-       //LM_ERR("new_nsq_reader(), nsq_max_in_flight = %d!\n", nsq_max_in_flight);
-
-    // TODO: configurable interval
-    ev_timer_init(&rdr->lookupd_poll_timer, nsq_reader_lookupd_poll_cb, 0., 5.);
-    rdr->lookupd_poll_timer.data = rdr;
-    ev_timer_again(rdr->loop, &rdr->lookupd_poll_timer);
-
-    return rdr;
-}
-
-void free_nsq_reader(struct NSQReader *rdr)
-{
-    struct NSQDConnection *conn;
-    struct NSQLookupdEndpoint *nsqlookupd_endpoint;
-
-       //LM_ERR("free_nsq_reader()!\n");
-
-    if (rdr) {
-        // TODO: this should probably trigger disconnections and then keep
-        // trying to clean up until everything upstream is finished
-        LL_FOREACH(rdr->conns, conn) {
-            nsqd_connection_disconnect(conn);
-        }
-        LL_FOREACH(rdr->lookupd, nsqlookupd_endpoint) {
-            free_nsqlookupd_endpoint(nsqlookupd_endpoint);
-        }
-        free(rdr->topic);
-        free(rdr->channel);
-        free(rdr);
-    }
-}
-
-int nsq_reader_add_nsqlookupd_endpoint(struct NSQReader *rdr, const char *address, int port)
-{
-    struct NSQLookupdEndpoint *nsqlookupd_endpoint;
-
-       //LM_ERR("nsq_reader_add_nsqlookupd_endpoint(address = %s, port = %d)!\n", address, port);
-    nsqlookupd_endpoint = new_nsqlookupd_endpoint(address, port);
-    LL_APPEND(rdr->lookupd, nsqlookupd_endpoint);
-
-    return 1;
-}
-
-int nsq_reader_connect_to_nsqd(struct NSQReader *rdr, const char *address, int port)
-{
-    struct NSQDConnection *conn;
-    int rc;
-
-       //LM_ERR("nsq_reader_connect_to_nsqd()!\n");
-    conn = new_nsqd_connection(rdr->loop, address, port, nsq_reader_connect_cb, nsq_reader_close_cb, nsq_reader_msg_cb, rdr);
-    rc = nsqd_connection_connect(conn);
-    if (rc > 0) {
-        LL_APPEND(rdr->conns, conn);
-    }
-    return rc;
-}
-
-void nsq_run(struct ev_loop *loop)
-{
-       //LM_ERR("nsq_run()!\n");
-    kam_srand(time(NULL));
-    ev_loop(loop, 0);
-}
diff --git a/modules/nsq/utlist.h b/modules/nsq/utlist.h
deleted file mode 100644 (file)
index 6bccec7..0000000
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
-Copyright (c) 2007-2013, Troy D. Hanson   http://troydhanson.github.com/uthash/
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
-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.
-*/
-
-#ifndef UTLIST_H
-#define UTLIST_H
-
-#define UTLIST_VERSION 1.9.8
-
-#include <assert.h>
-
-/* 
- * This file contains macros to manipulate singly and doubly-linked lists.
- *
- * 1. LL_ macros:  singly-linked lists.
- * 2. DL_ macros:  doubly-linked lists.
- * 3. CDL_ macros: circular doubly-linked lists.
- *
- * To use singly-linked lists, your structure must have a "next" pointer.
- * To use doubly-linked lists, your structure must "prev" and "next" pointers.
- * Either way, the pointer to the head of the list must be initialized to NULL.
- * 
- * ----------------.EXAMPLE -------------------------
- * struct item {
- *      int id;
- *      struct item *prev, *next;
- * }
- *
- * struct item *list = NULL:
- *
- * int main() {
- *      struct item *item;
- *      ... allocate and populate item ...
- *      DL_APPEND(list, item);
- * }
- * --------------------------------------------------
- *
- * For doubly-linked lists, the append and delete macros are O(1)
- * For singly-linked lists, append and delete are O(n) but prepend is O(1)
- * The sort macro is O(n log(n)) for all types of single/double/circular lists.
- */
-
-/* These macros use decltype or the earlier __typeof GNU extension.
-   As decltype is only available in newer compilers (VS2010 or gcc 4.3+
-   when compiling c++ code), this code uses whatever method is needed
-   or, for VS2008 where neither is available, uses casting workarounds. */
-#ifdef _MSC_VER            /* MS compiler */
-#if _MSC_VER >= 1600 && defined(__cplusplus)  /* VS2010 or newer in C++ mode */
-#define LDECLTYPE(x) decltype(x)
-#else                     /* VS2008 or older (or VS2010 in C mode) */
-#define NO_DECLTYPE
-#define LDECLTYPE(x) char*
-#endif
-#else                      /* GNU, Sun and other compilers */
-#define LDECLTYPE(x) __typeof(x)
-#endif
-
-/* for VS2008 we use some workarounds to get around the lack of decltype,
- * namely, we always reassign our tmp variable to the list head if we need
- * to dereference its prev/next pointers, and save/restore the real head.*/
-#ifdef NO_DECLTYPE
-#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); }
-#define _NEXT(elt,list,next) ((char*)((list)->next))
-#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); }
-/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */
-#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
-#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
-#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
-#else 
-#define _SV(elt,list)
-#define _NEXT(elt,list,next) ((elt)->next)
-#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to)
-/* #define _PREV(elt,list,prev) ((elt)->prev) */
-#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to)
-#define _RS(list)
-#define _CASTASGN(a,b) (a)=(b)
-#endif
-
-/******************************************************************************
- * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort    *
- * Unwieldy variable names used here to avoid shadowing passed-in variables.  *
- *****************************************************************************/
-#define LL_SORT(list, cmp)                                                                     \
-    LL_SORT2(list, cmp, next)
-
-#define LL_SORT2(list, cmp, next)                                                              \
-do {                                                                                           \
-  LDECLTYPE(list) _ls_p;                                                                       \
-  LDECLTYPE(list) _ls_q;                                                                       \
-  LDECLTYPE(list) _ls_e;                                                                       \
-  LDECLTYPE(list) _ls_tail;                                                                    \
-  int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping;                       \
-  if (list) {                                                                                  \
-    _ls_insize = 1;                                                                            \
-    _ls_looping = 1;                                                                           \
-    while (_ls_looping) {                                                                      \
-      _CASTASGN(_ls_p,list);                                                                   \
-      list = NULL;                                                                             \
-      _ls_tail = NULL;                                                                         \
-      _ls_nmerges = 0;                                                                         \
-      while (_ls_p) {                                                                          \
-        _ls_nmerges++;                                                                         \
-        _ls_q = _ls_p;                                                                         \
-        _ls_psize = 0;                                                                         \
-        for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) {                                         \
-          _ls_psize++;                                                                         \
-          _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list);                          \
-          if (!_ls_q) break;                                                                   \
-        }                                                                                      \
-        _ls_qsize = _ls_insize;                                                                \
-        while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) {                                    \
-          if (_ls_psize == 0) {                                                                \
-            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
-              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
-          } else if (_ls_qsize == 0 || !_ls_q) {                                               \
-            _ls_e = _ls_p; _SV(_ls_p,list); _ls_p =                                            \
-              _NEXT(_ls_p,list,next); _RS(list); _ls_psize--;                                  \
-          } else if (cmp(_ls_p,_ls_q) <= 0) {                                                  \
-            _ls_e = _ls_p; _SV(_ls_p,list); _ls_p =                                            \
-              _NEXT(_ls_p,list,next); _RS(list); _ls_psize--;                                  \
-          } else {                                                                             \
-            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
-              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
-          }                                                                                    \
-          if (_ls_tail) {                                                                      \
-            _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list);                \
-          } else {                                                                             \
-            _CASTASGN(list,_ls_e);                                                             \
-          }                                                                                    \
-          _ls_tail = _ls_e;                                                                    \
-        }                                                                                      \
-        _ls_p = _ls_q;                                                                         \
-      }                                                                                        \
-      if (_ls_tail) {                                                                          \
-        _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list);                     \
-      }                                                                                        \
-      if (_ls_nmerges <= 1) {                                                                  \
-        _ls_looping=0;                                                                         \
-      }                                                                                        \
-      _ls_insize *= 2;                                                                         \
-    }                                                                                          \
-  }                                                                                            \
-} while (0)
-
-
-#define DL_SORT(list, cmp)                                                                     \
-    DL_SORT2(list, cmp, prev, next)
-
-#define DL_SORT2(list, cmp, prev, next)                                                        \
-do {                                                                                           \
-  LDECLTYPE(list) _ls_p;                                                                       \
-  LDECLTYPE(list) _ls_q;                                                                       \
-  LDECLTYPE(list) _ls_e;                                                                       \
-  LDECLTYPE(list) _ls_tail;                                                                    \
-  int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping;                       \
-  if (list) {                                                                                  \
-    _ls_insize = 1;                                                                            \
-    _ls_looping = 1;                                                                           \
-    while (_ls_looping) {                                                                      \
-      _CASTASGN(_ls_p,list);                                                                   \
-      list = NULL;                                                                             \
-      _ls_tail = NULL;                                                                         \
-      _ls_nmerges = 0;                                                                         \
-      while (_ls_p) {                                                                          \
-        _ls_nmerges++;                                                                         \
-        _ls_q = _ls_p;                                                                         \
-        _ls_psize = 0;                                                                         \
-        for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) {                                         \
-          _ls_psize++;                                                                         \
-          _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list);                          \
-          if (!_ls_q) break;                                                                   \
-        }                                                                                      \
-        _ls_qsize = _ls_insize;                                                                \
-        while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) {                                    \
-          if (_ls_psize == 0) {                                                                \
-            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
-              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
-          } else if (_ls_qsize == 0 || !_ls_q) {                                               \
-            _ls_e = _ls_p; _SV(_ls_p,list); _ls_p =                                            \
-              _NEXT(_ls_p,list,next); _RS(list); _ls_psize--;                                  \
-          } else if (cmp(_ls_p,_ls_q) <= 0) {                                                  \
-            _ls_e = _ls_p; _SV(_ls_p,list); _ls_p =                                            \
-              _NEXT(_ls_p,list,next); _RS(list); _ls_psize--;                                  \
-          } else {                                                                             \
-            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
-              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
-          }                                                                                    \
-          if (_ls_tail) {                                                                      \
-            _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list);                \
-          } else {                                                                             \
-            _CASTASGN(list,_ls_e);                                                             \
-          }                                                                                    \
-          _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list);                     \
-          _ls_tail = _ls_e;                                                                    \
-        }                                                                                      \
-        _ls_p = _ls_q;                                                                         \
-      }                                                                                        \
-      _CASTASGN(list->prev, _ls_tail);                                                         \
-      _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list);                       \
-      if (_ls_nmerges <= 1) {                                                                  \
-        _ls_looping=0;                                                                         \
-      }                                                                                        \
-      _ls_insize *= 2;                                                                         \
-    }                                                                                          \
-  }                                                                                            \
-} while (0)
-
-#define CDL_SORT(list, cmp)                                                                    \
-    CDL_SORT2(list, cmp, prev, next)
-
-#define CDL_SORT2(list, cmp, prev, next)                                                       \
-do {                                                                                           \
-  LDECLTYPE(list) _ls_p;                                                                       \
-  LDECLTYPE(list) _ls_q;                                                                       \
-  LDECLTYPE(list) _ls_e;                                                                       \
-  LDECLTYPE(list) _ls_tail;                                                                    \
-  LDECLTYPE(list) _ls_oldhead;                                                                 \
-  LDECLTYPE(list) _tmp;                                                                        \
-  int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping;                       \
-  if (list) {                                                                                  \
-    _ls_insize = 1;                                                                            \
-    _ls_looping = 1;                                                                           \
-    while (_ls_looping) {                                                                      \
-      _CASTASGN(_ls_p,list);                                                                   \
-      _CASTASGN(_ls_oldhead,list);                                                             \
-      list = NULL;                                                                             \
-      _ls_tail = NULL;                                                                         \
-      _ls_nmerges = 0;                                                                         \
-      while (_ls_p) {                                                                          \
-        _ls_nmerges++;                                                                         \
-        _ls_q = _ls_p;                                                                         \
-        _ls_psize = 0;                                                                         \
-        for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) {                                         \
-          _ls_psize++;                                                                         \
-          _SV(_ls_q,list);                                                                     \
-          if (_NEXT(_ls_q,list,next) == _ls_oldhead) {                                         \
-            _ls_q = NULL;                                                                      \
-          } else {                                                                             \
-            _ls_q = _NEXT(_ls_q,list,next);                                                    \
-          }                                                                                    \
-          _RS(list);                                                                           \
-          if (!_ls_q) break;                                                                   \
-        }                                                                                      \
-        _ls_qsize = _ls_insize;                                                                \
-        while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) {                                    \
-          if (_ls_psize == 0) {                                                                \
-            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
-              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
-            if (_ls_q == _ls_oldhead) { _ls_q = NULL; }                                        \
-          } else if (_ls_qsize == 0 || !_ls_q) {                                               \
-            _ls_e = _ls_p; _SV(_ls_p,list); _ls_p =                                            \
-              _NEXT(_ls_p,list,next); _RS(list); _ls_psize--;                                  \
-            if (_ls_p == _ls_oldhead) { _ls_p = NULL; }                                        \
-          } else if (cmp(_ls_p,_ls_q) <= 0) {                                                  \
-            _ls_e = _ls_p; _SV(_ls_p,list); _ls_p =                                            \
-              _NEXT(_ls_p,list,next); _RS(list); _ls_psize--;                                  \
-            if (_ls_p == _ls_oldhead) { _ls_p = NULL; }                                        \
-          } else {                                                                             \
-            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
-              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
-            if (_ls_q == _ls_oldhead) { _ls_q = NULL; }                                        \
-          }                                                                                    \
-          if (_ls_tail) {                                                                      \
-            _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list);                \
-          } else {                                                                             \
-            _CASTASGN(list,_ls_e);                                                             \
-          }                                                                                    \
-          _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list);                     \
-          _ls_tail = _ls_e;                                                                    \
-        }                                                                                      \
-        _ls_p = _ls_q;                                                                         \
-      }                                                                                        \
-      _CASTASGN(list->prev,_ls_tail);                                                          \
-      _CASTASGN(_tmp,list);                                                                    \
-      _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list);                       \
-      if (_ls_nmerges <= 1) {                                                                  \
-        _ls_looping=0;                                                                         \
-      }                                                                                        \
-      _ls_insize *= 2;                                                                         \
-    }                                                                                          \
-  }                                                                                            \
-} while (0)
-
-/******************************************************************************
- * singly linked list macros (non-circular)                                   *
- *****************************************************************************/
-#define LL_PREPEND(head,add)                                                                   \
-    LL_PREPEND2(head,add,next)
-
-#define LL_PREPEND2(head,add,next)                                                             \
-do {                                                                                           \
-  (add)->next = head;                                                                          \
-  head = add;                                                                                  \
-} while (0)
-
-#define LL_CONCAT(head1,head2)                                                                 \
-    LL_CONCAT2(head1,head2,next)
-
-#define LL_CONCAT2(head1,head2,next)                                                           \
-do {                                                                                           \
-  LDECLTYPE(head1) _tmp;                                                                       \
-  if (head1) {                                                                                 \
-    _tmp = head1;                                                                              \
-    while (_tmp->next) { _tmp = _tmp->next; }                                                  \
-    _tmp->next=(head2);                                                                        \
-  } else {                                                                                     \
-    (head1)=(head2);                                                                           \
-  }                                                                                            \
-} while (0)
-
-#define LL_APPEND(head,add)                                                                    \
-    LL_APPEND2(head,add,next)
-
-#define LL_APPEND2(head,add,next)                                                              \
-do {                                                                                           \
-  LDECLTYPE(head) _tmp;                                                                        \
-  (add)->next=NULL;                                                                            \
-  if (head) {                                                                                  \
-    _tmp = head;                                                                               \
-    while (_tmp->next) { _tmp = _tmp->next; }                                                  \
-    _tmp->next=(add);                                                                          \
-  } else {                                                                                     \
-    (head)=(add);                                                                              \
-  }                                                                                            \
-} while (0)
-
-#define LL_DELETE(head,del)                                                                    \
-    LL_DELETE2(head,del,next)
-
-#define LL_DELETE2(head,del,next)                                                              \
-do {                                                                                           \
-  LDECLTYPE(head) _tmp;                                                                        \
-  if ((head) == (del)) {                                                                       \
-    (head)=(head)->next;                                                                       \
-  } else {                                                                                     \
-    _tmp = head;                                                                               \
-    while (_tmp->next && (_tmp->next != (del))) {                                              \
-      _tmp = _tmp->next;                                                                       \
-    }                                                                                          \
-    if (_tmp->next) {                                                                          \
-      _tmp->next = ((del)->next);                                                              \
-    }                                                                                          \
-  }                                                                                            \
-} while (0)
-
-/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */
-#define LL_APPEND_VS2008(head,add)                                                             \
-    LL_APPEND2_VS2008(head,add,next)
-
-#define LL_APPEND2_VS2008(head,add,next)                                                       \
-do {                                                                                           \
-  if (head) {                                                                                  \
-    (add)->next = head;     /* use add->next as a temp variable */                             \
-    while ((add)->next->next) { (add)->next = (add)->next->next; }                             \
-    (add)->next->next=(add);                                                                   \
-  } else {                                                                                     \
-    (head)=(add);                                                                              \
-  }                                                                                            \
-  (add)->next=NULL;                                                                            \
-} while (0)
-
-#define LL_DELETE_VS2008(head,del)                                                             \
-    LL_DELETE2_VS2008(head,del,next)
-
-#define LL_DELETE2_VS2008(head,del,next)                                                       \
-do {                                                                                           \
-  if ((head) == (del)) {                                                                       \
-    (head)=(head)->next;                                                                       \
-  } else {                                                                                     \
-    char *_tmp = (char*)(head);                                                                \
-    while ((head)->next && ((head)->next != (del))) {                                          \
-      head = (head)->next;                                                                     \
-    }                                                                                          \
-    if ((head)->next) {                                                                        \
-      (head)->next = ((del)->next);                                                            \
-    }                                                                                          \
-    {                                                                                          \
-      char **_head_alias = (char**)&(head);                                                    \
-      *_head_alias = _tmp;                                                                     \
-    }                                                                                          \
-  }                                                                                            \
-} while (0)
-#ifdef NO_DECLTYPE
-#undef LL_APPEND
-#define LL_APPEND LL_APPEND_VS2008
-#undef LL_DELETE
-#define LL_DELETE LL_DELETE_VS2008
-#undef LL_DELETE2
-#define LL_DELETE2_VS2008
-#undef LL_APPEND2
-#define LL_APPEND2 LL_APPEND2_VS2008
-#undef LL_CONCAT /* no LL_CONCAT_VS2008 */
-#undef DL_CONCAT /* no DL_CONCAT_VS2008 */
-#endif
-/* end VS2008 replacements */
-
-#define LL_FOREACH(head,el)                                                                    \
-    LL_FOREACH2(head,el,next)
-
-#define LL_FOREACH2(head,el,next)                                                              \
-    for(el=head;el;el=(el)->next)
-
-#define LL_FOREACH_SAFE(head,el,tmp)                                                           \
-    LL_FOREACH_SAFE2(head,el,tmp,next)
-
-#define LL_FOREACH_SAFE2(head,el,tmp,next)                                                     \
-  for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
-
-#define LL_SEARCH_SCALAR(head,out,field,val)                                                   \
-    LL_SEARCH_SCALAR2(head,out,field,val,next)
-
-#define LL_SEARCH_SCALAR2(head,out,field,val,next)                                             \
-do {                                                                                           \
-    LL_FOREACH2(head,out,next) {                                                               \
-      if ((out)->field == (val)) break;                                                        \
-    }                                                                                          \
-} while(0) 
-
-#define LL_SEARCH(head,out,elt,cmp)                                                            \
-    LL_SEARCH2(head,out,elt,cmp,next)
-
-#define LL_SEARCH2(head,out,elt,cmp,next)                                                      \
-do {                                                                                           \
-    LL_FOREACH2(head,out,next) {                                                               \
-      if ((cmp(out,elt))==0) break;                                                            \
-    }                                                                                          \
-} while(0) 
-
-#define LL_REPLACE_ELEM(head, el, add)                                                         \
-do {                                                                                           \
- LDECLTYPE(head) _tmp;                                                                         \
- assert(head != NULL);                                                                         \
- assert(el != NULL);                                                                           \
- assert(add != NULL);                                                                          \
- (add)->next = (el)->next;                                                                     \
- if ((head) == (el)) {                                                                         \
-  (head) = (add);                                                                              \
- } else {                                                                                      \
-  _tmp = head;                                                                                 \
-  while (_tmp->next && (_tmp->next != (el))) {                                                 \
-   _tmp = _tmp->next;                                                                          \
-  }                                                                                            \
-  if (_tmp->next) {                                                                            \
-    _tmp->next = (add);                                                                        \
-  }                                                                                            \
- }                                                                                             \
-} while (0)
-
-#define LL_PREPEND_ELEM(head, el, add)                                                         \
-do {                                                                                           \
- LDECLTYPE(head) _tmp;                                                                         \
- assert(head != NULL);                                                                         \
- assert(el != NULL);                                                                           \
- assert(add != NULL);                                                                          \
- (add)->next = (el);                                                                           \
- if ((head) == (el)) {                                                                         \
-  (head) = (add);                                                                              \
- } else {                                                                                      \
-  _tmp = head;                                                                                 \
-  while (_tmp->next && (_tmp->next != (el))) {                                                 \
-   _tmp = _tmp->next;                                                                          \
-  }                                                                                            \
-  if (_tmp->next) {                                                                            \
-    _tmp->next = (add);                                                                        \
-  }                                                                                            \
- }                                                                                             \
-} while (0)                                                                                    \
-
-
-/******************************************************************************
- * doubly linked list macros (non-circular)                                   *
- *****************************************************************************/
-#define DL_PREPEND(head,add)                                                                   \
-    DL_PREPEND2(head,add,prev,next)
-
-#define DL_PREPEND2(head,add,prev,next)                                                        \
-do {                                                                                           \
- (add)->next = head;                                                                           \
- if (head) {                                                                                   \
-   (add)->prev = (head)->prev;                                                                 \
-   (head)->prev = (add);                                                                       \
- } else {                                                                                      \
-   (add)->prev = (add);                                                                        \
- }                                                                                             \
- (head) = (add);                                                                               \
-} while (0)
-
-#define DL_APPEND(head,add)                                                                    \
-    DL_APPEND2(head,add,prev,next)
-
-#define DL_APPEND2(head,add,prev,next)                                                         \
-do {                                                                                           \
-  if (head) {                                                                                  \
-      (add)->prev = (head)->prev;                                                              \
-      (head)->prev->next = (add);                                                              \
-      (head)->prev = (add);                                                                    \
-      (add)->next = NULL;                                                                      \
-  } else {                                                                                     \
-      (head)=(add);                                                                            \
-      (head)->prev = (head);                                                                   \
-      (head)->next = NULL;                                                                     \
-  }                                                                                            \
-} while (0) 
-
-#define DL_CONCAT(head1,head2)                                                                 \
-    DL_CONCAT2(head1,head2,prev,next)
-
-#define DL_CONCAT2(head1,head2,prev,next)                                                      \
-do {                                                                                           \
-  LDECLTYPE(head1) _tmp;                                                                       \
-  if (head2) {                                                                                 \
-    if (head1) {                                                                               \
-        _tmp = (head2)->prev;                                                                  \
-        (head2)->prev = (head1)->prev;                                                         \
-        (head1)->prev->next = (head2);                                                         \
-        (head1)->prev = _tmp;                                                                  \
-    } else {                                                                                   \
-        (head1)=(head2);                                                                       \
-    }                                                                                          \
-  }                                                                                            \
-} while (0) 
-
-#define DL_DELETE(head,del)                                                                    \
-    DL_DELETE2(head,del,prev,next)
-
-#define DL_DELETE2(head,del,prev,next)                                                         \
-do {                                                                                           \
-  assert((del)->prev != NULL);                                                                 \
-  if ((del)->prev == (del)) {                                                                  \
-      (head)=NULL;                                                                             \
-  } else if ((del)==(head)) {                                                                  \
-      (del)->next->prev = (del)->prev;                                                         \
-      (head) = (del)->next;                                                                    \
-  } else {                                                                                     \
-      (del)->prev->next = (del)->next;                                                         \
-      if ((del)->next) {                                                                       \
-          (del)->next->prev = (del)->prev;                                                     \
-      } else {                                                                                 \
-          (head)->prev = (del)->prev;                                                          \
-      }                                                                                        \
-  }                                                                                            \
-} while (0) 
-
-
-#define DL_FOREACH(head,el)                                                                    \
-    DL_FOREACH2(head,el,next)
-
-#define DL_FOREACH2(head,el,next)                                                              \
-    for(el=head;el;el=(el)->next)
-
-/* this version is safe for deleting the elements during iteration */
-#define DL_FOREACH_SAFE(head,el,tmp)                                                           \
-    DL_FOREACH_SAFE2(head,el,tmp,next)
-
-#define DL_FOREACH_SAFE2(head,el,tmp,next)                                                     \
-  for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
-
-/* these are identical to their singly-linked list counterparts */
-#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR
-#define DL_SEARCH LL_SEARCH
-#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2
-#define DL_SEARCH2 LL_SEARCH2
-
-#define DL_REPLACE_ELEM(head, el, add)                                                         \
-do {                                                                                           \
- assert(head != NULL);                                                                         \
- assert(el != NULL);                                                                           \
- assert(add != NULL);                                                                          \
- if ((head) == (el)) {                                                                         \
-  (head) = (add);                                                                              \
-  (add)->next = (el)->next;                                                                    \
-  if ((el)->next == NULL) {                                                                    \
-   (add)->prev = (add);                                                                        \
-  } else {                                                                                     \
-   (add)->prev = (el)->prev;                                                                   \
-   (add)->next->prev = (add);                                                                  \
-  }                                                                                            \
- } else {                                                                                      \
-  (add)->next = (el)->next;                                                                    \
-  (add)->prev = (el)->prev;                                                                    \
-  (add)->prev->next = (add);                                                                   \
-  if ((el)->next == NULL) {                                                                    \
-   (head)->prev = (add);                                                                       \
-  } else {                                                                                     \
-   (add)->next->prev = (add);                                                                  \
-  }                                                                                            \
- }                                                                                             \
-} while (0)
-
-#define DL_PREPEND_ELEM(head, el, add)                                                         \
-do {                                                                                           \
- assert(head != NULL);                                                                         \
- assert(el != NULL);                                                                           \
- assert(add != NULL);                                                                          \
- (add)->next = (el);                                                                           \
- (add)->prev = (el)->prev;                                                                     \
- (el)->prev = (add);                                                                           \
- if ((head) == (el)) {                                                                         \
-  (head) = (add);                                                                              \
- } else {                                                                                      \
-  (add)->prev->next = (add);                                                                   \
- }                                                                                             \
-} while (0)                                                                                    \
-
-
-/******************************************************************************
- * circular doubly linked list macros                                         *
- *****************************************************************************/
-#define CDL_PREPEND(head,add)                                                                  \
-    CDL_PREPEND2(head,add,prev,next)
-
-#define CDL_PREPEND2(head,add,prev,next)                                                       \
-do {                                                                                           \
- if (head) {                                                                                   \
-   (add)->prev = (head)->prev;                                                                 \
-   (add)->next = (head);                                                                       \
-   (head)->prev = (add);                                                                       \
-   (add)->prev->next = (add);                                                                  \
- } else {                                                                                      \
-   (add)->prev = (add);                                                                        \
-   (add)->next = (add);                                                                        \
- }                                                                                             \
-(head)=(add);                                                                                  \
-} while (0)
-
-#define CDL_DELETE(head,del)                                                                   \
-    CDL_DELETE2(head,del,prev,next)
-
-#define CDL_DELETE2(head,del,prev,next)                                                        \
-do {                                                                                           \
-  if ( ((head)==(del)) && ((head)->next == (head))) {                                          \
-      (head) = 0L;                                                                             \
-  } else {                                                                                     \
-     (del)->next->prev = (del)->prev;                                                          \
-     (del)->prev->next = (del)->next;                                                          \
-     if ((del) == (head)) (head)=(del)->next;                                                  \
-  }                                                                                            \
-} while (0) 
-
-#define CDL_FOREACH(head,el)                                                                   \
-    CDL_FOREACH2(head,el,next)
-
-#define CDL_FOREACH2(head,el,next)                                                             \
-    for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) 
-
-#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2)                                                    \
-    CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)
-
-#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)                                         \
-  for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL);                                        \
-      (el) && ((tmp2)=(el)->next, 1);                                                          \
-      ((el) = (((el)==(tmp1)) ? 0L : (tmp2))))
-
-#define CDL_SEARCH_SCALAR(head,out,field,val)                                                  \
-    CDL_SEARCH_SCALAR2(head,out,field,val,next)
-
-#define CDL_SEARCH_SCALAR2(head,out,field,val,next)                                            \
-do {                                                                                           \
-    CDL_FOREACH2(head,out,next) {                                                              \
-      if ((out)->field == (val)) break;                                                        \
-    }                                                                                          \
-} while(0) 
-
-#define CDL_SEARCH(head,out,elt,cmp)                                                           \
-    CDL_SEARCH2(head,out,elt,cmp,next)
-
-#define CDL_SEARCH2(head,out,elt,cmp,next)                                                     \
-do {                                                                                           \
-    CDL_FOREACH2(head,out,next) {                                                              \
-      if ((cmp(out,elt))==0) break;                                                            \
-    }                                                                                          \
-} while(0) 
-
-#define CDL_REPLACE_ELEM(head, el, add)                                                        \
-do {                                                                                           \
- assert(head != NULL);                                                                         \
- assert(el != NULL);                                                                           \
- assert(add != NULL);                                                                          \
- if ((el)->next == (el)) {                                                                     \
-  (add)->next = (add);                                                                         \
-  (add)->prev = (add);                                                                         \
-  (head) = (add);                                                                              \
- } else {                                                                                      \
-  (add)->next = (el)->next;                                                                    \
-  (add)->prev = (el)->prev;                                                                    \
-  (add)->next->prev = (add);                                                                   \
-  (add)->prev->next = (add);                                                                   \
-  if ((head) == (el)) {                                                                        \
-   (head) = (add);                                                                             \
-  }                                                                                            \
- }                                                                                             \
-} while (0)
-
-#define CDL_PREPEND_ELEM(head, el, add)                                                        \
-do {                                                                                           \
- assert(head != NULL);                                                                         \
- assert(el != NULL);                                                                           \
- assert(add != NULL);                                                                          \
- (add)->next = (el);                                                                           \
- (add)->prev = (el)->prev;                                                                     \
- (el)->prev = (add);                                                                           \
- (add)->prev->next = (add);                                                                    \
- if ((head) == (el)) {                                                                         \
-  (head) = (add);                                                                              \
- }                                                                                             \
-} while (0)                                                                                    \
-
-#endif /* UTLIST_H */
-