Adding this too under skygateway
This commit is contained in:
@ -18,8 +18,8 @@ clean:
|
|||||||
all: utils lib
|
all: utils lib
|
||||||
|
|
||||||
utils:
|
utils:
|
||||||
make -C $(ROOT_PATH)/utils clean all
|
make -C $(QUERY_CLASSIFIER_PATH)/utils clean all
|
||||||
$(COPY) $(ROOT_PATH)/utils/skygw_utils.o ./
|
$(COPY) $(QUERY_CLASSIFIER_PATH)/utils/skygw_utils.o ./
|
||||||
|
|
||||||
lib: libcomp liblink
|
lib: libcomp liblink
|
||||||
|
|
||||||
|
18
utils/makefile
Normal file
18
utils/makefile
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
include ../build_gateway.inc
|
||||||
|
include ../makefile.inc
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CPP = g++
|
||||||
|
|
||||||
|
makeall: clean all
|
||||||
|
|
||||||
|
clean:
|
||||||
|
- $(DEL) *.o
|
||||||
|
- $(DEL) *.so
|
||||||
|
- $(DEL) *.a
|
||||||
|
- $(DEL) *~
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(CPP) -c $(CFLAGS) \
|
||||||
|
-fPIC skygw_utils.cc -o skygw_utils.o
|
||||||
|
|
126
utils/skygw_debug.h
Normal file
126
utils/skygw_debug.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if !defined(SKYGW_DEBUG_H)
|
||||||
|
#define SKYGW_DEBUG_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXTERN_C_BLOCK_BEGIN extern "C" {
|
||||||
|
#define EXTERN_C_BLOCK_END }
|
||||||
|
#define EXTERN_C_FUNC extern "C"
|
||||||
|
#else
|
||||||
|
#define EXTERN_C_BLOCK_BEGIN
|
||||||
|
#define EXTERN_C_BLOCK_END
|
||||||
|
#define EXTERN_C_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SS_DEBUG)
|
||||||
|
|
||||||
|
# define STRBOOL(b) ((b) ? "TRUE" : "FALSE")
|
||||||
|
# define STRQTYPE(t) ((t) == QUERY_TYPE_WRITE ? "QUERY_TYPE_WRITE" : \
|
||||||
|
((t) == QUERY_TYPE_READ ? "QUERY_TYPE_READ" : \
|
||||||
|
((t) == QUERY_TYPE_SESSION_WRITE ? "QUERY_TYPE_SESSION_WRITE" : \
|
||||||
|
"QUERY_TYPE_UNKNOWN")))
|
||||||
|
# define ss_dfprintf fprintf
|
||||||
|
# define ss_dfflush fflush
|
||||||
|
# define ss_dfwrite fwrite
|
||||||
|
|
||||||
|
# define ss_dassert(exp) \
|
||||||
|
{ \
|
||||||
|
if (!(exp)) { \
|
||||||
|
ss_dfprintf(stderr, \
|
||||||
|
"debug assert %s:%d\n", \
|
||||||
|
(char*)__FILE__, \
|
||||||
|
__LINE__); \
|
||||||
|
ss_dfflush(stderr); \
|
||||||
|
assert(exp); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
# define ss_info_dassert(exp, info) \
|
||||||
|
{ \
|
||||||
|
if (!(exp)) { \
|
||||||
|
ss_dfprintf(stderr, "debug assert %s:%d, %s\n", \
|
||||||
|
(char *)__FILE__, \
|
||||||
|
__LINE__, \
|
||||||
|
info); \
|
||||||
|
ss_dfflush(stderr); \
|
||||||
|
assert((exp)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* SS_DEBUG */
|
||||||
|
|
||||||
|
# define STRBOOL(b)
|
||||||
|
# define ss_dfprintf(a, b, ...)
|
||||||
|
# define ss_dfflush
|
||||||
|
# define ss_dfwrite
|
||||||
|
# define ss_dassert
|
||||||
|
# define ss_info_dassert(exp, info)
|
||||||
|
|
||||||
|
#endif /* SS_DEBUG */
|
||||||
|
|
||||||
|
#define CHK_NUM_BASE 101
|
||||||
|
|
||||||
|
typedef enum skygw_chk_t {
|
||||||
|
CHK_NUM_SLIST = CHK_NUM_BASE,
|
||||||
|
CHK_NUM_SLIST_NODE,
|
||||||
|
CHK_NUM_SLIST_CURSOR,
|
||||||
|
CHK_NUM_QUERY_TEST,
|
||||||
|
CHK_NUM_LOGFILE
|
||||||
|
} skygw_chk_t;
|
||||||
|
|
||||||
|
#define CHK_SLIST(l) { \
|
||||||
|
ss_info_dassert((l->slist_chk_top == CHK_NUM_SLIST && \
|
||||||
|
l->slist_chk_tail == CHK_NUM_SLIST), \
|
||||||
|
"Single-linked list structure under- or overflow"); \
|
||||||
|
if (l->slist_head == NULL) { \
|
||||||
|
ss_info_dassert(l->slist_nelems == 0, \
|
||||||
|
"List head is NULL but element counter is not zero."); \
|
||||||
|
ss_info_dassert(l->slist_tail == NULL, \
|
||||||
|
"List head is NULL but tail has node"); \
|
||||||
|
} else { \
|
||||||
|
ss_info_dassert(l->slist_nelems > 0, \
|
||||||
|
"List head has node but element counter is not " \
|
||||||
|
"positive."); \
|
||||||
|
CHK_SLIST_NODE(l->slist_head); \
|
||||||
|
CHK_SLIST_NODE(l->slist_tail); \
|
||||||
|
} \
|
||||||
|
if (l->slist_nelems == 0) { \
|
||||||
|
ss_info_dassert(l->slist_head == NULL, \
|
||||||
|
"Element counter is zero but head has node"); \
|
||||||
|
ss_info_dassert(l->slist_tail == NULL, \
|
||||||
|
"Element counter is zero but tail has node"); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHK_SLIST_NODE(n) { \
|
||||||
|
ss_info_dassert((n->slnode_chk_top == CHK_NUM_SLIST_NODE && \
|
||||||
|
n->slnode_chk_tail == CHK_NUM_SLIST_NODE), \
|
||||||
|
"Single-linked list node under- or overflow"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHK_SLIST_CURSOR(c) { \
|
||||||
|
ss_info_dassert(c->slcursor_chk_top == CHK_NUM_SLIST_CURSOR && \
|
||||||
|
c->slcursor_chk_tail == CHK_NUM_SLIST_CURSOR, \
|
||||||
|
"List cursor under- or overflow"); \
|
||||||
|
ss_info_dassert(c->slcursor_list != NULL, \
|
||||||
|
"List cursor doesn't have list"); \
|
||||||
|
ss_info_dassert(c->slcursor_pos != NULL || \
|
||||||
|
(c->slcursor_pos == NULL && \
|
||||||
|
c->slcursor_list->slist_head == NULL), \
|
||||||
|
"List cursor doesn't have position"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHK_QUERY_TEST(q) { \
|
||||||
|
ss_info_dassert(q->qt_chk_top == CHK_NUM_QUERY_TEST && \
|
||||||
|
q->qt_chk_tail == CHK_NUM_QUERY_TEST, \
|
||||||
|
"Query test under- or overflow."); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHK_LOGFILE(lf) { \
|
||||||
|
ss_info_assert(lf->lf_chk_top == CHK_NUM_LOGFILE && \
|
||||||
|
lf->lf_chk_tail == CHK_NUM_LOGFILE, \
|
||||||
|
"Logfile struct under- or overflow"); \
|
||||||
|
}
|
||||||
|
#endif /* SKYGW_DEBUG_H */
|
49
utils/skygw_types.h
Normal file
49
utils/skygw_types.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* @section LICENCE
|
||||||
|
*
|
||||||
|
* This file is distributed as part of the SkySQL Gateway. It is
|
||||||
|
* free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright SkySQL Ab
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(SKYGW_TYPES_H)
|
||||||
|
#define SKYGW_TYPES_H
|
||||||
|
|
||||||
|
#define SECOND_USEC (1024*1024L)
|
||||||
|
#define MSEC_USEC (1024L)
|
||||||
|
|
||||||
|
#define KILOBYTE_BYTE (1024L)
|
||||||
|
#define MEGABYTE_BYTE (1024*1024L)
|
||||||
|
#define GIGABYTE_BYTE (1024*1024*1024L)
|
||||||
|
|
||||||
|
#define KB KILOBYTE_BYTE
|
||||||
|
#define MB MEGABYTE_BYTE
|
||||||
|
#define GB GIGABYTE_BYTE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define TRUE true
|
||||||
|
#define FALSE false
|
||||||
|
#else
|
||||||
|
typedef enum {FALSE=0, TRUE} bool;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SKYGW_TYPES_H */
|
354
utils/skygw_utils.cc
Normal file
354
utils/skygw_utils.cc
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "skygw_debug.h"
|
||||||
|
#include "skygw_types.h"
|
||||||
|
#include "skygw_utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Single-linked list for storing test cases */
|
||||||
|
typedef struct slist_node_st slist_node_t;
|
||||||
|
typedef struct slist_st slist_t;
|
||||||
|
typedef struct slist_cursor_st slist_cursor_t;
|
||||||
|
|
||||||
|
struct slist_node_st {
|
||||||
|
skygw_chk_t slnode_chk_top;
|
||||||
|
slist_t* slnode_list;
|
||||||
|
slist_node_t* slnode_next;
|
||||||
|
void* slnode_data;
|
||||||
|
size_t slnode_cursor_refcount;
|
||||||
|
skygw_chk_t slnode_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slist_st {
|
||||||
|
skygw_chk_t slist_chk_top;
|
||||||
|
slist_node_t* slist_head;
|
||||||
|
slist_node_t* slist_tail;
|
||||||
|
size_t slist_nelems;
|
||||||
|
slist_t* slist_cursors_list;
|
||||||
|
skygw_chk_t slist_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slist_cursor_st {
|
||||||
|
skygw_chk_t slcursor_chk_top;
|
||||||
|
slist_t* slcursor_list;
|
||||||
|
slist_node_t* slcursor_pos;
|
||||||
|
skygw_chk_t slcursor_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** End of structs and types */
|
||||||
|
|
||||||
|
|
||||||
|
static slist_cursor_t* slist_cursor_init(
|
||||||
|
slist_t* list);
|
||||||
|
|
||||||
|
static slist_t* slist_init_ex(
|
||||||
|
bool create_cursors);
|
||||||
|
|
||||||
|
static slist_node_t* slist_node_init(
|
||||||
|
void* data,
|
||||||
|
slist_cursor_t* cursor);
|
||||||
|
|
||||||
|
static void slist_add_node(
|
||||||
|
slist_t* list,
|
||||||
|
slist_node_t* node);
|
||||||
|
|
||||||
|
static slist_node_t* slist_node_get_next(
|
||||||
|
slist_node_t* curr_node);
|
||||||
|
|
||||||
|
static slist_node_t* slist_get_first(
|
||||||
|
slist_t* list);
|
||||||
|
|
||||||
|
static slist_cursor_t* slist_get_cursor(
|
||||||
|
slist_t* list);
|
||||||
|
|
||||||
|
/** End of static function declarations */
|
||||||
|
|
||||||
|
|
||||||
|
static slist_t* slist_init_ex(
|
||||||
|
bool create_cursors)
|
||||||
|
{
|
||||||
|
slist_t* list;
|
||||||
|
|
||||||
|
list = (slist_t*)calloc(1, sizeof(slist_t));
|
||||||
|
list->slist_chk_top = CHK_NUM_SLIST;
|
||||||
|
list->slist_chk_tail = CHK_NUM_SLIST;
|
||||||
|
|
||||||
|
if (create_cursors) {
|
||||||
|
list->slist_cursors_list = slist_init_ex(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slist_node_t* slist_node_init(
|
||||||
|
void* data,
|
||||||
|
slist_cursor_t* cursor)
|
||||||
|
{
|
||||||
|
slist_node_t* node;
|
||||||
|
|
||||||
|
node = (slist_node_t*)calloc(1, sizeof(slist_node_t));
|
||||||
|
node->slnode_chk_top = CHK_NUM_SLIST_NODE;
|
||||||
|
node->slnode_chk_tail = CHK_NUM_SLIST_NODE;
|
||||||
|
node->slnode_data = data;
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
|
||||||
|
if (cursor != NULL) {
|
||||||
|
node->slnode_cursor_refcount += 1;
|
||||||
|
cursor->slcursor_pos = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void slist_add_node(
|
||||||
|
slist_t* list,
|
||||||
|
slist_node_t* node)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
|
||||||
|
if (list->slist_tail != NULL) {
|
||||||
|
CHK_SLIST_NODE(list->slist_tail);
|
||||||
|
CHK_SLIST_NODE(list->slist_head);
|
||||||
|
ss_dassert(list->slist_tail->slnode_next == NULL);
|
||||||
|
list->slist_tail->slnode_next = node;
|
||||||
|
} else {
|
||||||
|
list->slist_head = node;
|
||||||
|
}
|
||||||
|
list->slist_tail = node;
|
||||||
|
node->slnode_list = list;
|
||||||
|
list->slist_nelems += 1;
|
||||||
|
CHK_SLIST(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static slist_node_t* slist_node_get_next(
|
||||||
|
slist_node_t* curr_node)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(curr_node);
|
||||||
|
|
||||||
|
if (curr_node->slnode_next != NULL) {
|
||||||
|
CHK_SLIST_NODE(curr_node->slnode_next);
|
||||||
|
return (curr_node->slnode_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slist_node_t* slist_get_first(
|
||||||
|
slist_t* list)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
|
||||||
|
if (list->slist_head != NULL) {
|
||||||
|
CHK_SLIST_NODE(list->slist_head);
|
||||||
|
return list->slist_head;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slist_cursor_t* slist_cursor_init(
|
||||||
|
slist_t* list)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
slist_cursor_t* c;
|
||||||
|
|
||||||
|
c = (slist_cursor_t *)calloc(1, sizeof(slist_cursor_t));
|
||||||
|
c->slcursor_chk_top = CHK_NUM_SLIST_CURSOR;
|
||||||
|
c->slcursor_chk_tail = CHK_NUM_SLIST_CURSOR;
|
||||||
|
c->slcursor_list = list;
|
||||||
|
|
||||||
|
/** Set cursor position is list is not empty */
|
||||||
|
if (list->slist_head != NULL) {
|
||||||
|
list->slist_head->slnode_cursor_refcount += 1;
|
||||||
|
c->slcursor_pos = list->slist_head;
|
||||||
|
}
|
||||||
|
/** Add cursor to cursor list */
|
||||||
|
slist_add_node(list->slist_cursors_list, slist_node_init(c, NULL));
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slist_cursor_t* slist_get_cursor(
|
||||||
|
slist_t* list)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
|
||||||
|
slist_cursor_t* c;
|
||||||
|
|
||||||
|
c = slist_cursor_init(list);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node Create a cursor and a list with cursors supported
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param void - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return returns a pointer to cursor, which is not positioned
|
||||||
|
* because the list is empty.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
slist_cursor_t* slist_init(void)
|
||||||
|
{
|
||||||
|
slist_t* list;
|
||||||
|
slist_cursor_t* slc;
|
||||||
|
|
||||||
|
list = slist_init_ex(TRUE);
|
||||||
|
CHK_SLIST(list);
|
||||||
|
slc = slist_cursor_init(list);
|
||||||
|
CHK_SLIST_CURSOR(slc);
|
||||||
|
|
||||||
|
return slc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node moves cursor to the first node of list.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param c - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return TRUE if there is first node in the list
|
||||||
|
* FALSE is the list is empty.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool slcursor_move_to_begin(
|
||||||
|
slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
bool succp = TRUE;
|
||||||
|
slist_t* list;
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
list = c->slcursor_list;
|
||||||
|
CHK_SLIST(list);
|
||||||
|
c->slcursor_pos = list->slist_head;
|
||||||
|
if (c->slcursor_pos == NULL) {
|
||||||
|
succp = FALSE;
|
||||||
|
}
|
||||||
|
return succp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node moves cursor to next node
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param c - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return TRUE in success, FALSE is there is no next node on the list.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool slcursor_step_ahead(
|
||||||
|
slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
bool succp = FALSE;
|
||||||
|
slist_node_t* node;
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
CHK_SLIST_NODE(c->slcursor_pos);
|
||||||
|
|
||||||
|
node = c->slcursor_pos->slnode_next;
|
||||||
|
|
||||||
|
if (node != NULL) {
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
c->slcursor_pos = node;
|
||||||
|
succp = TRUE;
|
||||||
|
}
|
||||||
|
return succp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* slcursor_get_data(
|
||||||
|
slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
slist_node_t* node;
|
||||||
|
void* data = NULL;
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
node = c->slcursor_pos;
|
||||||
|
|
||||||
|
if (node != NULL) {
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
data = node->slnode_data;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node Add data to the list by using cursor.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param c - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @param data - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void slcursor_add_data(
|
||||||
|
slist_cursor_t* c,
|
||||||
|
void* data)
|
||||||
|
{
|
||||||
|
slist_t* list;
|
||||||
|
slist_node_t* pos;
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
list = c->slcursor_list;
|
||||||
|
CHK_SLIST(list);
|
||||||
|
pos = c->slcursor_pos;
|
||||||
|
|
||||||
|
if (pos != NULL) {
|
||||||
|
CHK_SLIST_NODE(pos);
|
||||||
|
pos = list->slist_tail->slnode_next;
|
||||||
|
}
|
||||||
|
ss_dassert(pos == NULL);
|
||||||
|
pos = slist_node_init(data, c);
|
||||||
|
slist_add_node(list, pos);
|
||||||
|
CHK_SLIST(list);
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void slist_done(
|
||||||
|
slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
bool succp;
|
||||||
|
void* data;
|
||||||
|
|
||||||
|
succp = slcursor_move_to_begin(c);
|
||||||
|
|
||||||
|
while (succp) {
|
||||||
|
data = slcursor_get_data(c);
|
||||||
|
free(data);
|
||||||
|
succp = slcursor_step_ahead(c);
|
||||||
|
}
|
||||||
|
free(c->slcursor_list);
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** End of list implementation */
|
26
utils/skygw_utils.h
Normal file
26
utils/skygw_utils.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#if !defined(SKYGW_UTILS_H)
|
||||||
|
#define SKYGW_UTILS_H
|
||||||
|
|
||||||
|
#include "skygw_types.h"
|
||||||
|
#include "skygw_debug.h"
|
||||||
|
|
||||||
|
EXTERN_C_BLOCK_BEGIN
|
||||||
|
|
||||||
|
typedef struct slist_node_st slist_node_t;
|
||||||
|
typedef struct slist_st slist_t;
|
||||||
|
typedef struct slist_cursor_st slist_cursor_t;
|
||||||
|
|
||||||
|
slist_cursor_t* slist_init(void);
|
||||||
|
void slist_done(slist_cursor_t* c);
|
||||||
|
|
||||||
|
void slcursor_add_data(slist_cursor_t* c, void* data);
|
||||||
|
void* slcursor_get_data(slist_cursor_t* c);
|
||||||
|
|
||||||
|
bool slcursor_move_to_begin(slist_cursor_t* c);
|
||||||
|
bool slcursor_step_ahead(slist_cursor_t* c);
|
||||||
|
|
||||||
|
EXTERN_C_BLOCK_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SKYGW_UTILS_H */
|
Reference in New Issue
Block a user