enhanced dll
This commit is contained in:
@ -2,7 +2,7 @@ pkgincludedir = $(includedir)/qse/cmn
|
||||
|
||||
pkginclude_HEADERS = \
|
||||
mem.h xma.h fma.h chr.h str.h lda.h htb.h rbt.h \
|
||||
rex.h sll.h dll.h opt.h tio.h \
|
||||
rex.h sll.h gdl.h dll.h opt.h tio.h \
|
||||
fio.h pio.h sio.h time.h misc.h main.h stdio.h
|
||||
|
||||
if ENABLE_CXX
|
||||
|
@ -52,8 +52,9 @@ CONFIG_CLEAN_VPATH_FILES =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__pkginclude_HEADERS_DIST = mem.h xma.h fma.h chr.h str.h lda.h \
|
||||
htb.h rbt.h rex.h sll.h dll.h opt.h tio.h fio.h pio.h sio.h \
|
||||
time.h misc.h main.h stdio.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
||||
htb.h rbt.h rex.h sll.h gdl.h dll.h opt.h tio.h fio.h pio.h \
|
||||
sio.h time.h misc.h main.h stdio.h Mmgr.hpp StdMmgr.hpp \
|
||||
Mmged.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
@ -221,8 +222,8 @@ top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
pkginclude_HEADERS = mem.h xma.h fma.h chr.h str.h lda.h htb.h rbt.h \
|
||||
rex.h sll.h dll.h opt.h tio.h fio.h pio.h sio.h time.h misc.h \
|
||||
main.h stdio.h $(am__append_1)
|
||||
rex.h sll.h gdl.h dll.h opt.h tio.h fio.h pio.h sio.h time.h \
|
||||
misc.h main.h stdio.h $(am__append_1)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: dll.h 352 2010-08-31 13:20:34Z hyunghwan.chung $
|
||||
* $Id: dll.h 354 2010-09-03 12:50:08Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -21,162 +21,216 @@
|
||||
#ifndef _QSE_CMN_DLL_H_
|
||||
#define _QSE_CMN_DLL_H_
|
||||
|
||||
/** @file
|
||||
* This file defines a doubly linked list interface.
|
||||
*/
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
#include <qse/cmn/gdl.h>
|
||||
|
||||
/**
|
||||
* The qse_dll_nhdr_t type defines a common node header fields used internally.
|
||||
*/
|
||||
typedef struct qse_dll_nhdr_t qse_dll_nhdr_t;
|
||||
struct qse_dll_nhdr_t
|
||||
{
|
||||
qse_dll_nhdr_t* next;
|
||||
qse_dll_nhdr_t* prev;
|
||||
};
|
||||
|
||||
#define __QSE_DLL_WRAP(x) do { x } while(0)
|
||||
#define QSE_DLL_DEFINE(list_type,node_type,data_define,manage_define) \
|
||||
typedef struct list_type list_type; \
|
||||
typedef struct node_type node_type; \
|
||||
struct node_type \
|
||||
{ \
|
||||
node_type* prev; \
|
||||
node_type* next; \
|
||||
data_define \
|
||||
}; \
|
||||
struct list_type \
|
||||
{ \
|
||||
node_type gdl; \
|
||||
qse_size_t size; \
|
||||
manage_define \
|
||||
}
|
||||
|
||||
#define QSE_DLL_TYPE(data_type) qse_dll_ ## data_type ## _t
|
||||
#define QSE_DLL_NODE_TYPE(data_type) qse_dll_ ## data_type ## _node_t
|
||||
|
||||
/**
|
||||
* The QSE_DLL_DEFINE macro defines a new doubly-linked list type for data
|
||||
* The QSE_DLL_DEFINE_SIMPLE macro defines a doubly-linked list type for data
|
||||
* of the @a data_type type.
|
||||
*/
|
||||
#define QSE_DLL_DEFINE(data_type) \
|
||||
typedef struct QSE_DLL_TYPE(data_type) QSE_DLL_TYPE(data_type); \
|
||||
typedef struct QSE_DLL_NODE_TYPE(data_type) QSE_DLL_NODE_TYPE(data_type); \
|
||||
struct QSE_DLL_NODE_TYPE(data_type) \
|
||||
{ \
|
||||
QSE_DLL_NODE_TYPE(data_type)* next; \
|
||||
QSE_DLL_NODE_TYPE(data_type)* prev; \
|
||||
data_type data; \
|
||||
}; \
|
||||
struct QSE_DLL_TYPE(data_type) \
|
||||
{ \
|
||||
QSE_DLL_NODE_TYPE(data_type) link; \
|
||||
}
|
||||
#define QSE_DLL_DEFINE_SIMPLE(data_type) \
|
||||
QSE_DLL_DEFINE ( \
|
||||
QSE_DLL_TYPE(data_type), \
|
||||
QSE_DLL_NODE_TYPE(data_type), \
|
||||
data_type data;, \
|
||||
)
|
||||
|
||||
/**
|
||||
* The QSE_DLL_DEFINE macro defines a new doubly-linked list type for data
|
||||
* The QSE_DLL_DEFINE_MANAGED macro defines a doubly-linked list type for data
|
||||
* of the @a data_type type.
|
||||
*/
|
||||
#define QSE_DLL_DEFINE_MANAGED(data_type,manage_type) \
|
||||
typedef struct QSE_DLL_TYPE(data_type) QSE_DLL_TYPE(data_type); \
|
||||
typedef struct QSE_DLL_NODE_TYPE(data_type) QSE_DLL_NODE_TYPE(data_type); \
|
||||
struct QSE_DLL_NODE_TYPE(data_type) \
|
||||
{ \
|
||||
QSE_DLL_NODE_TYPE(data_type)* next; \
|
||||
QSE_DLL_NODE_TYPE(data_type)* prev; \
|
||||
data_type data; \
|
||||
}; \
|
||||
struct QSE_DLL_TYPE(data_type) \
|
||||
{ \
|
||||
QSE_DLL_NODE_TYPE(data_type) link; \
|
||||
QSE_DLL_DEFINE ( \
|
||||
QSE_DLL_TYPE(data_type), \
|
||||
QSE_DLL_NODE_TYPE(data_type), \
|
||||
data_type data;, \
|
||||
manage_type data; \
|
||||
}
|
||||
)
|
||||
|
||||
#define QSE_DLL_INIT(dll) __QSE_DLL_WRAP ( \
|
||||
(dll)->link.next = &(dll)->link; \
|
||||
(dll)->link.prev = &(dll)->link; \
|
||||
)
|
||||
#define QSE_DLL_INIT(dll) \
|
||||
QSE_BLOCK ( \
|
||||
QSE_GDL_INIT(&(dll)->gdl); \
|
||||
(dll)->size = 0; \
|
||||
)
|
||||
|
||||
#define QSE_DLL_FINI(dll) __QSE_DLL_WRAP ( \
|
||||
while (!QSE_DLL_ISEMPTY(dll)) QSE_DLL_DELHEAD(dll); \
|
||||
)
|
||||
#define QSE_DLL_FINI(dll) QSE_DLL_CLEAR(dll)
|
||||
|
||||
#define QSE_DLL_CHAIN(dll,p,x,n) __QSE_DLL_WRAP ( \
|
||||
register qse_dll_nhdr_t* __qse_dll_chain_prev = (qse_dll_nhdr_t*)(p); \
|
||||
register qse_dll_nhdr_t* __qse_dll_chain_next = (qse_dll_nhdr_t*)(n); \
|
||||
(x)->prev = (void*)__qse_dll_chain_prev; \
|
||||
(x)->next = (void*)__qse_dll_chain_next; \
|
||||
__qse_dll_chain_next->prev = (void*)(x); \
|
||||
__qse_dll_chain_prev->next = (void*)(x); \
|
||||
)
|
||||
#define QSE_DLL_CHAIN(dll,p,x,n) \
|
||||
QSE_BLOCK ( \
|
||||
QSE_GDL_CHAIN ((qse_gdl_t*)p, (qse_gdl_t*)x, (qse_gdl_t*)n); \
|
||||
(dll)->size++; \
|
||||
)
|
||||
|
||||
#define QSE_DLL_UNCHAIN(dll,x) __QSE_DLL_WRAP ( \
|
||||
register qse_dll_nhdr_t* __qse_dll_unchain_prev = \
|
||||
(qse_dll_nhdr_t*)((x)->prev); \
|
||||
register qse_dll_nhdr_t* __qse_dll_unchain_next = \
|
||||
(qse_dll_nhdr_t*)((x)->next); \
|
||||
__qse_dll_unchain_next->prev = __qse_dll_unchain_prev; \
|
||||
__qse_dll_unchain_prev->next = __qse_dll_unchain_next; \
|
||||
)
|
||||
#define QSE_DLL_UNCHAIN(dll,x) \
|
||||
QSE_BLOCK ( \
|
||||
QSE_GDL_UNCHAIN ((qse_gdl_t*)x); \
|
||||
(dll)->size--; \
|
||||
)
|
||||
|
||||
#define QSE_DLL_HEADNODE(dll) ((dll)->link.next)
|
||||
#define QSE_DLL_TAILNODE(dll) ((dll)->link.prev)
|
||||
#define QSE_DLL_NEXTNODE(dll,p) ((p)->next)
|
||||
#define QSE_DLL_PREVNODE(dll,p) ((p)->prev)
|
||||
#define QSE_DLL_ISVALIDNODE(dll,p) ((p) != &(dll)->link)
|
||||
#define QSE_DLL_CLEAR(dll) \
|
||||
QSE_BLOCK ( \
|
||||
while (!QSE_DLL_ISEMPTY(dll)) QSE_DLL_DELHEAD(dll); \
|
||||
)
|
||||
|
||||
#define QSE_DLL_ISEMPTY(dll) (QSE_DLL_HEADNODE(dll) == &(dll)->link)
|
||||
#define QSE_DLL_ADDHEAD(dll,x) QSE_DLL_CHAIN(dll,&(dll)->link,x,QSE_DLL_HEADNODE(dll))
|
||||
#define QSE_DLL_ADDTAIL(dll,x) QSE_DLL_CHAIN(dll,QSE_DLL_TAILNODE(dll),x,&(dll)->link)
|
||||
#define QSE_DLL_DELHEAD(dll) QSE_DLL_UNCHAIN(dll,QSE_DLL_HEADNODE(dll))
|
||||
#define QSE_DLL_DELTAIL(dll) QSE_DLL_UNCHAIN(dll,QSE_DLL_TAILNODE(dll))
|
||||
|
||||
/*
|
||||
* Doubly Linked List
|
||||
/**
|
||||
* The QSE_DLL_ISEMPTY macro determines if a list @a dll is empty
|
||||
*/
|
||||
#define QSE_DLL_ISEMPTY(dll) QSE_GDL_ISEMPTY(&(dll)->gdl)
|
||||
|
||||
/**
|
||||
* The QSE_DLL_ISMEMBER macro determines if a node @a x is a member
|
||||
* of a list @a dll.
|
||||
*/
|
||||
#define QSE_DLL_ISMEMBER(dll,x) ((x) != &(dll)->gdl)
|
||||
|
||||
#define QSE_DLL_HEAD(dll) QSE_GDL_HEAD(&(dll)->gdl)
|
||||
#define QSE_DLL_TAIL(dll) QSE_GDL_TAIL(&(dll)->gdl)
|
||||
#define QSE_DLL_SIZE(dll) ((dll)->size)
|
||||
|
||||
/**
|
||||
* The QSE_DLL_ADDHEAD macro add a member node @a x to the head of
|
||||
* the list @a dll.
|
||||
*/
|
||||
#define QSE_DLL_ADDHEAD(dll,x) \
|
||||
QSE_DLL_CHAIN(dll,&(dll)->gdl,x,QSE_DLL_HEAD(dll))
|
||||
|
||||
/**
|
||||
* The QSE_DLL_ADDHEAD macro add a member node @a x to the tail of
|
||||
* the list @a dll.
|
||||
*/
|
||||
#define QSE_DLL_ADDTAIL(dll,x) \
|
||||
QSE_DLL_CHAIN(dll,QSE_DLL_TAIL(dll),x,&(dll)->gdl)
|
||||
|
||||
/**
|
||||
* The QSE_DLL_DELHEAD macro deletes the head node.
|
||||
*/
|
||||
#define QSE_DLL_DELHEAD(dll) \
|
||||
QSE_DLL_UNCHAIN(dll,QSE_DLL_HEAD(dll))
|
||||
|
||||
/**
|
||||
* The QSE_DLL_DELTAIL macro deletes the tail node.
|
||||
*/
|
||||
#define QSE_DLL_DELTAIL(dll) \
|
||||
QSE_DLL_UNCHAIN(dll,QSE_DLL_TAIL(dll))
|
||||
|
||||
|
||||
/* ----------- more general implementation below ----------------- */
|
||||
enum qse_dll_walk_t
|
||||
{
|
||||
QSE_DLL_WALK_STOP = 0,
|
||||
QSE_DLL_WALK_FORWARD = 1,
|
||||
QSE_DLL_WALK_BACKWARD = 2
|
||||
};
|
||||
typedef enum qse_dll_walk_t qse_dll_walk_t;
|
||||
|
||||
typedef struct qse_dll_t qse_dll_t;
|
||||
typedef struct qse_dll_node_t qse_dll_node_t;
|
||||
|
||||
/* data copier */
|
||||
typedef void* (*qse_dll_copier_t) (qse_dll_t* dll, void* dptr, qse_size_t dlen);
|
||||
typedef void* (*qse_dll_copier_t) (
|
||||
qse_dll_t* dll,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
/* data freeer */
|
||||
typedef void (*qse_dll_freeer_t) (qse_dll_t* dll, void* dptr, qse_size_t dlen);
|
||||
typedef void (*qse_dll_freeer_t) (
|
||||
qse_dll_t* dll,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_comper_t type defines a key comparator that is called when
|
||||
* the list needs to compare data. A doubly linked list is created with a
|
||||
* default comparator that performs bitwise comparison.
|
||||
*
|
||||
* The comparator must return 0 if the data are the same and a non-zero
|
||||
* integer otherwise.
|
||||
*/
|
||||
typedef int (*qse_dll_comper_t) (
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
const void* dptr1, /**< data pointer */
|
||||
qse_size_t dlen1, /**< data length */
|
||||
const void* dptr2, /**< data pointer */
|
||||
qse_size_t dlen2 /**< data length */
|
||||
);
|
||||
|
||||
/* node visitor */
|
||||
typedef int (*qse_dll_walker_t) (
|
||||
qse_dll_t* dll, qse_dll_node_t* node, void* arg);
|
||||
|
||||
struct qse_dll_t
|
||||
{
|
||||
qse_mmgr_t* mmgr;
|
||||
|
||||
qse_dll_copier_t copier;
|
||||
qse_dll_freeer_t freeer;
|
||||
|
||||
qse_size_t size;
|
||||
qse_dll_node_t* head;
|
||||
qse_dll_node_t* tail;
|
||||
};
|
||||
typedef qse_dll_walk_t (*qse_dll_walker_t) (
|
||||
qse_dll_t* dll,
|
||||
qse_dll_node_t* node,
|
||||
void* ctx
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_node_t type defines a doubly linked list node.
|
||||
*/
|
||||
struct qse_dll_node_t
|
||||
{
|
||||
void* dptr; /* pointer to the beginning of data */
|
||||
qse_size_t dlen; /* length of data in bytes */
|
||||
qse_dll_node_t* next; /* pointer to the next node */
|
||||
qse_dll_node_t* prev; /* pointer to the prev node */
|
||||
/* the first two fields in sync with qse_gdl_t */
|
||||
qse_dll_node_t* prev;
|
||||
qse_dll_node_t* next;
|
||||
|
||||
void* dptr; /**< data pointer */
|
||||
qse_size_t dlen; /**< data length */
|
||||
};
|
||||
|
||||
|
||||
enum qse_dll_walk_t
|
||||
/**
|
||||
* The qse_dll_t type defines a doubly linked list.
|
||||
*/
|
||||
struct qse_dll_t
|
||||
{
|
||||
QSE_DLL_WALK_STOP = 0,
|
||||
QSE_DLL_WALK_FORWARD = 1
|
||||
QSE_DEFINE_COMMON_FIELDS (dll)
|
||||
|
||||
qse_dll_node_t gdl;
|
||||
qse_size_t size;
|
||||
|
||||
qse_byte_t scale;
|
||||
qse_dll_copier_t copier;
|
||||
qse_dll_freeer_t freeer;
|
||||
qse_dll_comper_t comper;
|
||||
};
|
||||
|
||||
#define QSE_DLL_COPIER_INLINE qse_dll_copyinline
|
||||
#define QSE_DLL_COPIER_SIMPLE ((qse_dll_copier_t)1)
|
||||
#define QSE_DLL_COPIER_INLINE ((qse_dll_copier_t)2)
|
||||
|
||||
#define QSE_DLL_HEAD(dll) ((dll)->head)
|
||||
#define QSE_DLL_TAIL(dll) ((dll)->tail)
|
||||
#define QSE_DLL_SIZE(dll) ((dll)->size)
|
||||
#define QSE_DLL_SCALE(dll) ((dll)->scale)
|
||||
#define QSE_DLL_DPTR(node) ((node)->dptr)
|
||||
#define QSE_DLL_DLEN(node) ((node)->dlen)
|
||||
|
||||
#define QSE_DLL_DPTR(n) ((n)->dptr)
|
||||
#define QSE_DLL_DLEN(n) ((n)->dlen)
|
||||
#define QSE_DLL_NEXT(n) ((n)->next)
|
||||
#define QSE_DLL_PREV(n) ((n)->prev)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NAME: creates a doubly linked list with extension area
|
||||
*
|
||||
* DESCRIPTION:
|
||||
QSE_DEFINE_COMMON_FUNCTIONS (dll)
|
||||
|
||||
/**
|
||||
* The qse_dll_open() function creates an empty doubly linked list.
|
||||
* If the memory manager mmgr is QSE_NULL, the function gets the default
|
||||
* memory manager with QSE_MMGR_GETMMGR() and uses it if it is not QSE_NULL.
|
||||
@ -185,141 +239,175 @@ extern "C" {
|
||||
* after initializing the main area. The extension initializer is passed
|
||||
* the pointer to the doubly linked list created.
|
||||
*
|
||||
* RETURNS:
|
||||
* @return
|
||||
* the pointer to a newly created doubly linked list on success.
|
||||
* QSE_NULL on failure.
|
||||
*
|
||||
* WARNING:
|
||||
* In the debug build, it fails the assertion if QSE_MMGR_SETMMGR() returns
|
||||
* QSE_NULL when QSE_NULL is passed as the first parameter. In the release
|
||||
* build, it returns QSE_NULL if such a thing happens.
|
||||
*/
|
||||
|
||||
qse_dll_t* qse_dll_open (
|
||||
qse_mmgr_t* mmgr /* memory manager */ ,
|
||||
qse_size_t ext /* size of extension area in bytes */
|
||||
qse_mmgr_t* mmgr, /**< memory manager */
|
||||
qse_size_t xtnsize /**< size of extension area in bytes */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME destroys a singly linked list
|
||||
/**
|
||||
* The qse_dll_close() function destroys a doubly linked list.
|
||||
*/
|
||||
void qse_dll_close (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
qse_dll_t* dll /** doubly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME deletes all elements of a singly linked list
|
||||
/**
|
||||
* The qse_dll_init() function initializes a statically declared list.
|
||||
*/
|
||||
void qse_dll_clear (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
qse_dll_t* qse_dll_init (
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_mmgr_t* mmgr /**< memory manager */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME specifies how to clone an element
|
||||
*
|
||||
* DESCRIPTION
|
||||
* A special copier QSE_DLL_COPIER_INLINE is provided. This copier enables
|
||||
* you to copy the data inline to the internal node. No freeer is invoked
|
||||
* when the node is freeed.
|
||||
*
|
||||
* You may set the copier to QSE_NULL to perform no special operation
|
||||
* when the data pointer is rememebered.
|
||||
/**
|
||||
* The qse_dll_fini() function finalizes a statically initialized list.
|
||||
*/
|
||||
void qse_dll_fini (
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_getscale() function gets the scale factor
|
||||
*/
|
||||
int qse_dll_getscale (
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_setscale() function sets the scale factor of the data length.
|
||||
* A scale factor determines the actual length of data in bytes. A doubly
|
||||
* linked list created with a scale factor of 1. The scale factor should be
|
||||
* larger than 0 and less than 256.
|
||||
*/
|
||||
void qse_dll_setscale (
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
int scale /**< scale factor */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_setcopier() function changes the element copier.
|
||||
* A special copier QSE_DLL_COPIER_INLINE is provided. This copier enables
|
||||
* you to copy the data inline to the internal node. No freeer is invoked
|
||||
* when the node is freeed. You may set the copier to QSE_NULL to perform
|
||||
* no special operation when the data pointer is rememebered.
|
||||
*/
|
||||
void qse_dll_setcopier (
|
||||
qse_dll_t* dll /* a singly linked list */,
|
||||
qse_dll_copier_t copier /* a element copier */
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_dll_copier_t copier /**< element copier */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_getcopier() function returns the element copier.
|
||||
*/
|
||||
qse_dll_copier_t qse_dll_getcopier (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME specifies how to destroy an element
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The freeer is called when a node containing the element is destroyed.
|
||||
/**
|
||||
* The qse_dll_setfreeer() function changes the element freeer.
|
||||
* The freeer is called when a node containing the element is destroyed.
|
||||
*/
|
||||
void qse_dll_setfreeer (
|
||||
qse_dll_t* dll /* a singly linked list */,
|
||||
qse_dll_freeer_t freeer /* a element freeer */
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_dll_freeer_t freeer /**< element freeer */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_getfreeer() function returns the element freeer.
|
||||
*/
|
||||
qse_dll_freeer_t qse_dll_getfreeer (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Gets the pointer to the extension area
|
||||
* RETURN the pointer to the extension area
|
||||
*/
|
||||
void* qse_dll_getxtn (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME: get the pointer to the memory manager in use
|
||||
*/
|
||||
qse_mmgr_t* qse_dll_getmmgr (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
);
|
||||
|
||||
void qse_dll_setmmgr (qse_dll_t* dll, qse_mmgr_t* mmgr);
|
||||
|
||||
/*
|
||||
* NAME Gets the number of elements held in a singly linked list
|
||||
* RETURN the number of elements the list holds
|
||||
/**
|
||||
* The qse_dll_getsize() function returns the number of the data nodes held
|
||||
* in a doubly linked list.
|
||||
*/
|
||||
qse_size_t qse_dll_getsize (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Gets the head(first) node
|
||||
* RETURN the tail node of a singly linked list
|
||||
/**
|
||||
* The qse_dll_gethead() function gets the head node. You may use the
|
||||
* #QSE_DLL_HEAD macro instead.
|
||||
*/
|
||||
qse_dll_node_t* qse_dll_gethead (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Gets the tail(last) node
|
||||
* RETURN the tail node of a singly linked list
|
||||
/**
|
||||
* The qse_dll_gettail() function gets the head node. You may use the
|
||||
* #QSE_DLL_TAIL macro instead.
|
||||
*/
|
||||
qse_dll_node_t* qse_dll_gettail (
|
||||
qse_dll_t* dll /* a singly linked list */
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Inserts data before a positional node given
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Inserts data.
|
||||
|
||||
qse_dll_node_t* qse_dll_search (
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_dll_node_t* pos, /**< positional node */
|
||||
const void* dptr, /**< data pointer */
|
||||
qse_size_t dlen /**< data length */
|
||||
);
|
||||
|
||||
qse_dll_node_t* qse_dll_rsearch (
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_dll_node_t* pos, /**< positional node */
|
||||
const void* dptr, /**< data pointer */
|
||||
qse_size_t dlen /**< data length */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_insert() function insert an element into a list
|
||||
*/
|
||||
qse_dll_node_t* qse_dll_insert (
|
||||
qse_dll_t* dll /* a singly linked list */,
|
||||
qse_dll_node_t* pos /* a node before which a new node is inserted */,
|
||||
void* dptr /* the pointer to the data */ ,
|
||||
qse_size_t dlen /* the length of the data in bytes */
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_dll_node_t* pos, /**< node before which a new node is inserted */
|
||||
void* dptr, /**< data pointer */
|
||||
qse_size_t dlen /**< data length */
|
||||
);
|
||||
|
||||
void qse_dll_delete (
|
||||
qse_dll_t* dll,
|
||||
qse_dll_node_t* pos
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_dll_clear() functions deletes all elements of a list
|
||||
*/
|
||||
void qse_dll_clear (
|
||||
qse_dll_t* dll /**< doubly linked list */
|
||||
);
|
||||
|
||||
void qse_dll_walk (
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_dll_walker_t walker, /**< user-defined walker function */
|
||||
void* ctx /**< pointer to user-defined data */
|
||||
);
|
||||
|
||||
void qse_dll_rwalk (
|
||||
qse_dll_t* dll, /**< doubly linked list */
|
||||
qse_dll_walker_t walker, /**< user-defined walker function */
|
||||
void* ctx /**< pointer to user-defined data */
|
||||
);
|
||||
|
||||
qse_dll_node_t* qse_dll_pushhead (
|
||||
qse_dll_t* dll /* a singly linked list */,
|
||||
void* dptr,
|
||||
qse_dll_t* dll, /* doubly linked list */
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
qse_dll_node_t* qse_dll_pushtail (
|
||||
qse_dll_t* dll /* a singly linked list */,
|
||||
void* dptr,
|
||||
qse_dll_t* dll, /* doubly linked list */
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
void qse_dll_delete (
|
||||
qse_dll_t* dll,
|
||||
qse_dll_node_t* pos
|
||||
);
|
||||
|
||||
void qse_dll_pophead (
|
||||
qse_dll_t* dll
|
||||
);
|
||||
@ -328,36 +416,6 @@ void qse_dll_poptail (
|
||||
qse_dll_t* dll
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Traverses s singly linked list
|
||||
*
|
||||
* DESCRIPTION
|
||||
* A singly linked list allows uni-directional in-order traversal.
|
||||
* The qse_dll_walk() function traverses a singly linkked list from its
|
||||
* head node down to its tail node as long as the walker function returns
|
||||
* QSE_DLL_WALK_FORWARD. A walker can return QSE_DLL_WALK_STOP to cause
|
||||
* immediate stop of traversal.
|
||||
* For each node, the walker function is called and it is passed three
|
||||
* parameters: the singly linked list, the visiting node, and the
|
||||
* user-defined data passed as the third parameter in a call to the
|
||||
* qse_dll_walk() function.
|
||||
*/
|
||||
void qse_dll_walk (
|
||||
qse_dll_t* dll /* a singly linked list */,
|
||||
qse_dll_walker_t walker /* a user-defined walker function */,
|
||||
void* arg /* pointer to user-defined data */
|
||||
);
|
||||
|
||||
/*
|
||||
* Causes a singly linked list to copy in data to a node.
|
||||
* Use QSE_DLL_COPIER_INLINE instead.
|
||||
*/
|
||||
void* qse_dll_copyinline (
|
||||
qse_dll_t* dll /* a singly linked list */,
|
||||
void* data /* pointer to data to copy */ ,
|
||||
qse_size_t len /* length of data in bytes */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
70
qse/include/qse/cmn/gdl.h
Normal file
70
qse/include/qse/cmn/gdl.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _QSE_CMN_GDL_H_
|
||||
#define _QSE_CMN_GDL_H_
|
||||
|
||||
/** @file
|
||||
* This file defins a generic double link and provides basic macros to
|
||||
* manipulate a chain of links.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The qse_gdl_t type defines a structure to contain forward and
|
||||
* backward links.
|
||||
*/
|
||||
typedef struct qse_gdl_t qse_gdl_t;
|
||||
struct qse_gdl_t
|
||||
{
|
||||
qse_gdl_t* prev;
|
||||
qse_gdl_t* next;
|
||||
};
|
||||
|
||||
/**
|
||||
* The QSE_GDL_INIT macro initializes a host link to be used for internal
|
||||
* management.
|
||||
*/
|
||||
#define QSE_GDL_INIT(host) QSE_BLOCK ( \
|
||||
(host)->next = (host); (host)->prev = (host); \
|
||||
)
|
||||
|
||||
/**
|
||||
* The QSE_GDL_CHAIN macro chains a new member node @a x between
|
||||
* two nodes @a p and @a n.
|
||||
*/
|
||||
#define QSE_GDL_CHAIN(p,x,n) qse_gdl_chain(p,x,n)
|
||||
|
||||
/**
|
||||
* The QSE_GDL_UNCHAIN macro unchains a member node @a x.
|
||||
*/
|
||||
#define QSE_GDL_UNCHAIN(x) qse_gdl_unchain(x)
|
||||
|
||||
/**
|
||||
* The QSE_GDL_ISEMPTY macro checks if the chain is empty.
|
||||
*/
|
||||
#define QSE_GDL_ISEMPTY(host) ((host)->next == (host))
|
||||
|
||||
/**
|
||||
* The QSE_GDL_HEAD macro get the first node in the chain.
|
||||
*/
|
||||
#define QSE_GDL_HEAD(host) ((host)->next)
|
||||
|
||||
/**
|
||||
* The QSE_GDL_TAIL macro gets the last node in the chain.
|
||||
*/
|
||||
#define QSE_GDL_TAIL(host) ((host)->prev)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void qse_gdl_chain (qse_gdl_t* p, qse_gdl_t* x, qse_gdl_t* n);
|
||||
void qse_gdl_unchain (qse_gdl_t* x);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: htb.h 341 2010-08-04 07:25:48Z hyunghwan.chung $
|
||||
* $Id: htb.h 354 2010-09-03 12:50:08Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -38,7 +38,7 @@ typedef struct qse_htb_pair_t qse_htb_pair_t;
|
||||
*/
|
||||
enum qse_htb_walk_t
|
||||
{
|
||||
QSE_HTB_WALK_STOP = 0,
|
||||
QSE_HTB_WALK_STOP = 0,
|
||||
QSE_HTB_WALK_FORWARD = 1
|
||||
};
|
||||
typedef enum qse_htb_walk_t qse_htb_walk_t;
|
||||
|
@ -58,7 +58,7 @@
|
||||
# define qse_map_clear(map) qse_htb_clear(map)
|
||||
# define qse_map_walk(map,walker,ctx) qse_htb_walk(map,walker,ctx)
|
||||
# define QSE_MAP_WALK_STOP QSE_HTB_WALK_STOP
|
||||
# define QSE_MAP_WALK_FORWARD QSE_HTB_WALK_FORWARD
|
||||
# define QSE_MAP_WALK_FORWARD QSE_HTB_WALK_FORWARD
|
||||
# define qse_map_walk_t qse_htb_walk_t
|
||||
# define QSE_MAP_KEY QSE_HTB_KEY
|
||||
# define QSE_MAP_VAL QSE_HTB_VAL
|
||||
@ -111,7 +111,7 @@
|
||||
# define qse_map_clear(map) qse_rbt_clear(map)
|
||||
# define qse_map_walk(map,walker,ctx) qse_rbt_walk(map,walker,ctx)
|
||||
# define QSE_MAP_WALK_STOP QSE_RBT_WALK_STOP
|
||||
# define QSE_MAP_WALK_FORWARD QSE_RBT_WALK_FORWARD
|
||||
# define QSE_MAP_WALK_FORWARD QSE_RBT_WALK_FORWARD
|
||||
# define qse_map_walk_t qse_rbt_walk_t
|
||||
# define QSE_MAP_KEY QSE_RBT_KEY
|
||||
# define QSE_MAP_VAL QSE_RBT_VAL
|
||||
|
@ -37,7 +37,7 @@ typedef struct qse_rbt_pair_t qse_rbt_pair_t;
|
||||
*/
|
||||
enum qse_rbt_walk_t
|
||||
{
|
||||
QSE_RBT_WALK_STOP = 0,
|
||||
QSE_RBT_WALK_STOP = 0,
|
||||
QSE_RBT_WALK_FORWARD = 1
|
||||
};
|
||||
typedef enum qse_rbt_walk_t qse_rbt_walk_t;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sll.h 328 2010-07-08 06:58:44Z hyunghwan.chung $
|
||||
* $Id: sll.h 354 2010-09-03 12:50:08Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -25,7 +25,7 @@
|
||||
#include <qse/macros.h>
|
||||
|
||||
/** @file
|
||||
* Singly linked list
|
||||
* This file provides a singly linked list interface.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -33,13 +33,14 @@
|
||||
*/
|
||||
enum qse_sll_walk_t
|
||||
{
|
||||
QSE_SLL_WALK_STOP = 0, /**< stop traversal */
|
||||
QSE_SLL_WALK_FORWARD = 1 /**< traverse to the next node */
|
||||
QSE_SLL_WALK_STOP = 0, /**< stop traversal */
|
||||
QSE_SLL_WALK_FORWARD = 1 /**< traverse to the next node */
|
||||
};
|
||||
typedef enum qse_sll_walk_t qse_sll_walk_t;
|
||||
|
||||
|
||||
typedef struct qse_sll_t qse_sll_t;
|
||||
typedef struct qse_sll_node_t qse_sll_node_t;
|
||||
typedef enum qse_sll_walk_t qse_sll_walk_t;
|
||||
|
||||
/**
|
||||
* The qse_sll_copier_t type defines a callback function for node construction.
|
||||
@ -89,16 +90,15 @@ typedef int (*qse_sll_comper_t) (
|
||||
* The qse_sll_walker_t type defines a list traversal callback for each node.
|
||||
* The qse_sll_walk() calls a callback function of the type qse_sll_walker_t
|
||||
* for each node until it returns QSE_SLL_WALK_STOP. The walker should return
|
||||
* QSE_SLL_WALK_FORWARD to let qse_sll_walk() continue visiting the next node.
|
||||
* QSE_SLL_WALK_FORWARD to let qse_sll_walk() continue visiting the next node.
|
||||
* The third parameter to qse_sll_walk() is passed to the walker as the third
|
||||
* parameter.
|
||||
*/
|
||||
typedef qse_sll_walk_t (*qse_sll_walker_t) (
|
||||
qse_sll_t* sll, /* singly linked list */
|
||||
qse_sll_node_t* node, /* visited node */
|
||||
void* arg /* user-defined data */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
qse_sll_node_t* node, /**< visited node */
|
||||
void* ctx /**< user-defined data */
|
||||
);
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_sll_t type defines a singly lnked list.
|
||||
@ -183,203 +183,128 @@ qse_sll_t* qse_sll_open (
|
||||
qse_size_t ext /* size of extension area in bytes */
|
||||
);
|
||||
|
||||
/****f* Common/qse_sll_close
|
||||
* NAME
|
||||
* qse_sll_close - destroy a singly linked list
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The qse_sll_close() function destroys a singly linked list freeing up
|
||||
* the memory.
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_close() function destroys a singly linked list freeing up
|
||||
* the memory.
|
||||
*/
|
||||
void qse_sll_close (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_init
|
||||
* NAME
|
||||
* qse_sll_init - initialize a singly linked list
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The qse_sll_init() function initializes a singly linked list. The memory
|
||||
* should be allocated by a caller and be passed to it. The caller may declare
|
||||
* a static variable of the qse_sll_t type and pass its address. A memory
|
||||
* manager still needs to be passed for node manipulation later.
|
||||
/**
|
||||
* The qse_sll_init() function initializes a statically declared singly
|
||||
* linked list. The memory should be allocated by a caller and be passed
|
||||
* to it. The caller may declare a static variable of the qse_sll_t type
|
||||
* and pass its address. A memory manager still needs to be passed for
|
||||
* node manipulation later.
|
||||
*
|
||||
* RETURN
|
||||
* @return
|
||||
* The qse_sll_init() function returns the first parameter on success and
|
||||
* QSE_NULL on failure.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_sll_t* qse_sll_init (
|
||||
qse_sll_t* sll /* an uninitialized singly linked list */,
|
||||
qse_mmgr_t* mmgr /* a memory manager */
|
||||
qse_sll_t* sll, /* singly linked list */
|
||||
qse_mmgr_t* mmgr /* memory manager */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_fini
|
||||
* NAME
|
||||
* qse_sll_init - deinitialize a singly linked list
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_fini() function finalizes a statically initialized list.
|
||||
*/
|
||||
void qse_sll_fini (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_getsize
|
||||
* NAME
|
||||
* qse_sll_getsize - get the number of nodes
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The qse_sll_getsize() function returns the number of the data nodes held
|
||||
* in a singly linked list.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
qse_size_t qse_sll_getsize (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
|
||||
/****f* Common/qse_sll_getscale
|
||||
* NAME
|
||||
* qse_sll_getscale - get the scale factor
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_getscale() function gets the scale factor
|
||||
*/
|
||||
int qse_sll_getscale (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_setscale
|
||||
* NAME
|
||||
* qse_sll_setscale - set the scale factor
|
||||
*
|
||||
* DESCRIPTION
|
||||
/**
|
||||
* The qse_sll_setscale() function sets the scale factor of the data length.
|
||||
* A scale factor determines the actual length of data in bytes. A singly
|
||||
* linked list created with a scale factor of 1. The scale factor should be
|
||||
* larger than 0 and less than 256.
|
||||
*
|
||||
* NOTES
|
||||
* It is a bad idea to change the scale factor when a sll is not empty.
|
||||
*
|
||||
* SYNOPSIS
|
||||
*/
|
||||
void qse_sll_setscale (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
int scale /* a scale factor */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
int scale /**< scale factor */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_getcopier
|
||||
* NAME
|
||||
* qse_sll_getfreeer - get the data copier
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_getfreeer() function gets the data copier.
|
||||
*/
|
||||
qse_sll_copier_t qse_sll_getcopier (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /* singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_setcopier
|
||||
* NAME
|
||||
* qse_sll_setcopier - set a data copier
|
||||
*
|
||||
* DESCRIPTION
|
||||
* A special copier QSE_SLL_COPIER_INLINE is provided. This copier enables
|
||||
* you to copy the data inline to the internal node. No freeer is invoked
|
||||
* when the node is freeed.
|
||||
*
|
||||
* You may set the copier to QSE_NULL to perform no special operation
|
||||
* when the data pointer is rememebered.
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_setcopier() function changes the element copier.
|
||||
* A special copier QSE_SLL_COPIER_INLINE is provided. This copier enables
|
||||
* you to copy the data inline to the internal node. No freeer is invoked
|
||||
* when the node is freeed. You may set the copier to QSE_NULL to perform
|
||||
* no special operation when the data pointer is rememebered.
|
||||
*/
|
||||
void qse_sll_setcopier (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_copier_t copier /* a data copier */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
qse_sll_copier_t copier /**< data copier */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_getfreeer
|
||||
* NAME
|
||||
* qse_sll_getfreeer - get the data freeer
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_getfreeer() function returns the element freeer.
|
||||
*/
|
||||
qse_sll_freeer_t qse_sll_getfreeer (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_setfreeer
|
||||
* NAME
|
||||
* qse_sll_setfreeer - set a data freeer
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The freeer is called when a node containing the element is destroyed.
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_setfreeer() function changes the element freeer.
|
||||
* The freeer is called when a node containing the element is destroyed.
|
||||
*/
|
||||
void qse_sll_setfreeer (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_freeer_t freeer /* a data freeer */
|
||||
qse_sll_t* sll, /**< singly linked list */
|
||||
qse_sll_freeer_t freeer /**< data freeer */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_getcomper
|
||||
* NAME
|
||||
* qse_sll_getcomper - get the data comparator
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_getcomper() function returns the data comparator.
|
||||
*/
|
||||
qse_sll_comper_t qse_sll_getcomper (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_setcomper
|
||||
* NAME
|
||||
* qse_sll_setcomper - set the data comparator
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_setcomper() function changes the data comparator
|
||||
*/
|
||||
void qse_sll_setcomper (
|
||||
qse_sll_t* sll /* a singly linked list */,
|
||||
qse_sll_comper_t comper /* a comparator */
|
||||
qse_sll_t* sll /**< singly linked list */,
|
||||
qse_sll_comper_t comper /**< comparator */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_gethead
|
||||
* NAME
|
||||
* qse_sll_gethead - get the head node
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_getsize() function returns the number of the data nodes held
|
||||
* in a singly linked list.
|
||||
*/
|
||||
qse_size_t qse_sll_getsize (
|
||||
qse_sll_t* sll /** singly linked list */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_sll_gethead() function gets the head node. You may use the
|
||||
* #QSE_SLL_HEAD macro instead.
|
||||
*/
|
||||
qse_sll_node_t* qse_sll_gethead (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< a singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* Common/qse_sll_gettail
|
||||
* NAME
|
||||
* qse_sll_gettail - get the tail node
|
||||
*
|
||||
* SYNOPSIS
|
||||
/**
|
||||
* The qse_sll_gettail() function gets the head node. You may use the
|
||||
* #QSE_SLL_TAIL macro instead.
|
||||
*/
|
||||
qse_sll_node_t* qse_sll_gettail (
|
||||
qse_sll_t* sll /* a singly linked list */
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_sll_search() function traverses a list to find a node containing
|
||||
@ -387,8 +312,8 @@ qse_sll_node_t* qse_sll_gettail (
|
||||
* from the next node of the positional node. If the positional node is
|
||||
* QSE_NULL, the traversal begins from the head node.
|
||||
*
|
||||
* Note that no reverse search is provided because a reverse traversal can not be
|
||||
* achieved efficiently.
|
||||
* Note that no reverse search is provided because a reverse traversal can not
|
||||
* be achieved efficiently.
|
||||
*
|
||||
* @return pointer to the node found. QSE_NULL if no match is found
|
||||
*/
|
||||
@ -430,31 +355,10 @@ void qse_sll_clear (
|
||||
qse_sll_t* sll /**< singly linked list */
|
||||
);
|
||||
|
||||
qse_sll_node_t* qse_sll_pushhead (
|
||||
qse_sll_t* sll /**< singly linked list */,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
qse_sll_node_t* qse_sll_pushtail (
|
||||
qse_sll_t* sll /**< singly linked list */,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
|
||||
void qse_sll_pophead (
|
||||
qse_sll_t* sll
|
||||
);
|
||||
|
||||
void qse_sll_poptail (
|
||||
qse_sll_t* sll
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_sll_walk() function traverses a singly linkked list from its
|
||||
* head node down to its tail node as long as the walker function returns
|
||||
* QSE_SLL_WALK_FORWARD. A walker can return QSE_SLL_WALK_STOP to cause
|
||||
* QSE_SLL_WALK_FORWARD . A walker can return QSE_SLL_WALK_STOP to cause
|
||||
* immediate stop of traversal.
|
||||
*
|
||||
* For each node, the walker function is called and it is passed three
|
||||
@ -468,6 +372,26 @@ void qse_sll_walk (
|
||||
void* ctx /**< the pointer to user-defined data */
|
||||
);
|
||||
|
||||
qse_sll_node_t* qse_sll_pushhead (
|
||||
qse_sll_t* sll /**< singly linked list */,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
qse_sll_node_t* qse_sll_pushtail (
|
||||
qse_sll_t* sll /**< singly linked list */,
|
||||
void* dptr,
|
||||
qse_size_t dlen
|
||||
);
|
||||
|
||||
void qse_sll_pophead (
|
||||
qse_sll_t* sll
|
||||
);
|
||||
|
||||
void qse_sll_poptail (
|
||||
qse_sll_t* sll
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: str.h 353 2010-09-01 13:19:59Z hyunghwan.chung $
|
||||
* $Id: str.h 354 2010-09-03 12:50:08Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -25,10 +25,11 @@
|
||||
#include <qse/macros.h>
|
||||
|
||||
/** @file
|
||||
* Various functions, types, macros for string manipulation.
|
||||
* This file provides various functions, types, macros for string manipulation.
|
||||
*
|
||||
* The #qse_cstr_t type and the #qse_xstr_t defined in <qse/types.h> help you
|
||||
* deal with a string pointer and length in a structure.
|
||||
*
|
||||
* The qse_cstr_t type and the qse_xstr_t defined in <qse/types.h> helps you
|
||||
* dealing with a string pointer and length.
|
||||
*/
|
||||
|
||||
#define QSE_STR_LEN(s) ((s)->len) /**< string length */
|
||||
@ -170,17 +171,25 @@ qse_size_t qse_strxcpy (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strycpy() function copies a length-bounded string into
|
||||
* a buffer with unknown size.
|
||||
*/
|
||||
qse_size_t qse_strncpy (
|
||||
qse_char_t* buf,
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
qse_char_t* buf, /**< buffer with unknown length */
|
||||
const qse_char_t* str, /**< length-bounded string */
|
||||
qse_size_t len /**< string length */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strycpy() function copies a length-bounded string into
|
||||
* a length-bounded buffer.
|
||||
*/
|
||||
qse_size_t qse_strxncpy (
|
||||
qse_char_t* buf,
|
||||
qse_size_t bsz,
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
qse_char_t* buf, /**< length-bounded buffer */
|
||||
qse_size_t bsz, /**< buffer length */
|
||||
const qse_char_t* str, /**< length-bounded string */
|
||||
qse_size_t len /**< string length */
|
||||
);
|
||||
|
||||
/**
|
||||
@ -189,13 +198,13 @@ qse_size_t qse_strxncpy (
|
||||
* buffer.
|
||||
*/
|
||||
qse_size_t qse_strxput (
|
||||
qse_char_t* buf,
|
||||
qse_char_t* buf,
|
||||
qse_size_t bsz,
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
qse_size_t qse_strxnput (
|
||||
qse_char_t* buf,
|
||||
qse_char_t* buf,
|
||||
qse_size_t bsz,
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
@ -226,8 +235,8 @@ qse_size_t qse_strfcpy (
|
||||
* @sa qse_strfcpy, qse_strxfcpy, qse_strxfncpy
|
||||
*/
|
||||
qse_size_t qse_strfncpy (
|
||||
qse_char_t* buf,
|
||||
const qse_char_t* fmt,
|
||||
qse_char_t* buf,
|
||||
const qse_char_t* fmt,
|
||||
const qse_cstr_t str[]
|
||||
);
|
||||
|
||||
@ -256,9 +265,9 @@ qse_size_t qse_strxfcpy (
|
||||
* @sa qse_strfcpy, qse_strfncpy, qse_strxfcpy
|
||||
*/
|
||||
qse_size_t qse_strxfncpy (
|
||||
qse_char_t* buf,
|
||||
qse_char_t* buf,
|
||||
qse_size_t bsz,
|
||||
const qse_char_t* fmt,
|
||||
const qse_char_t* fmt,
|
||||
const qse_cstr_t str[]
|
||||
);
|
||||
|
||||
@ -281,11 +290,11 @@ qse_size_t qse_strxfncpy (
|
||||
* @endcode
|
||||
*/
|
||||
qse_size_t qse_strxsubst (
|
||||
qse_char_t* buf,
|
||||
qse_char_t* buf,
|
||||
qse_size_t bsz,
|
||||
const qse_char_t* fmt,
|
||||
qse_strxsubst_subst_t subst,
|
||||
void* ctx
|
||||
void* ctx
|
||||
);
|
||||
|
||||
qse_size_t qse_strxcat (
|
||||
@ -308,15 +317,15 @@ int qse_strcmp (
|
||||
|
||||
int qse_strxcmp (
|
||||
const qse_char_t* s1,
|
||||
qse_size_t len1,
|
||||
qse_size_t len1,
|
||||
const qse_char_t* s2
|
||||
);
|
||||
|
||||
int qse_strxncmp (
|
||||
const qse_char_t* s1,
|
||||
qse_size_t len1,
|
||||
qse_size_t len1,
|
||||
const qse_char_t* s2,
|
||||
qse_size_t len2
|
||||
qse_size_t len2
|
||||
);
|
||||
|
||||
int qse_strcasecmp (
|
||||
@ -505,17 +514,25 @@ qse_char_t* qse_strxbeg (
|
||||
const qse_char_t* sub)
|
||||
;
|
||||
|
||||
/*
|
||||
* The qse_strbeg() function checks if the a string begins with a substring.
|
||||
* @return @a str on match, QSE_NULL on no match
|
||||
*/
|
||||
qse_char_t* qse_strnbeg (
|
||||
const qse_char_t* str,
|
||||
const qse_char_t* sub,
|
||||
qse_size_t len
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
/*
|
||||
* The qse_strbeg() function checks if the a string begins with a substring.
|
||||
* @return @a str on match, QSE_NULL on no match
|
||||
*/
|
||||
qse_char_t* qse_strxnbeg (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len1,
|
||||
qse_size_t len1,
|
||||
const qse_char_t* sub,
|
||||
qse_size_t len2
|
||||
qse_size_t len2
|
||||
);
|
||||
|
||||
/**
|
||||
@ -565,25 +582,76 @@ qse_char_t* qse_strxnend (
|
||||
/*
|
||||
* string conversion
|
||||
*/
|
||||
int qse_strtoi (const qse_char_t* str);
|
||||
long qse_strtol (const qse_char_t* str);
|
||||
unsigned int qse_strtoui (const qse_char_t* str);
|
||||
unsigned long qse_strtoul (const qse_char_t* str);
|
||||
int qse_strtoi (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
int qse_strxtoi (const qse_char_t* str, qse_size_t len);
|
||||
long qse_strxtol (const qse_char_t* str, qse_size_t len);
|
||||
unsigned int qse_strxtoui (const qse_char_t* str, qse_size_t len);
|
||||
unsigned long qse_strxtoul (const qse_char_t* str, qse_size_t len);
|
||||
long qse_strtol (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
qse_int_t qse_strtoint (const qse_char_t* str);
|
||||
qse_long_t qse_strtolong (const qse_char_t* str);
|
||||
qse_uint_t qse_strtouint (const qse_char_t* str);
|
||||
qse_ulong_t qse_strtoulong (const qse_char_t* str);
|
||||
unsigned int qse_strtoui (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
qse_int_t qse_strxtoint (const qse_char_t* str, qse_size_t len);
|
||||
qse_long_t qse_strxtolong (const qse_char_t* str, qse_size_t len);
|
||||
qse_uint_t qse_strxtouint (const qse_char_t* str, qse_size_t len);
|
||||
qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len);
|
||||
unsigned long qse_strtoul (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
int qse_strxtoi (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
long qse_strxtol (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
unsigned int qse_strxtoui (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
unsigned long qse_strxtoul (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
qse_int_t qse_strtoint (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
qse_long_t qse_strtolong (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
qse_uint_t qse_strtouint (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
qse_ulong_t qse_strtoulong (
|
||||
const qse_char_t* str
|
||||
);
|
||||
|
||||
qse_int_t qse_strxtoint (
|
||||
const qse_char_t* str, qse_size_t len
|
||||
);
|
||||
|
||||
qse_long_t qse_strxtolong (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
qse_uint_t qse_strxtouint (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
qse_ulong_t qse_strxtoulong (
|
||||
const qse_char_t* str,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_strspl() function splits a string into fields.
|
||||
@ -595,7 +663,6 @@ int qse_strspl (
|
||||
qse_char_t rquote,
|
||||
qse_char_t escape
|
||||
);
|
||||
/******/
|
||||
|
||||
/**
|
||||
* The qse_strspltrn() function splits a string translating special
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: macros.h 348 2010-08-26 06:26:28Z hyunghwan.chung $
|
||||
* $Id: macros.h 354 2010-09-03 12:50:08Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -29,26 +29,35 @@
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
|
||||
# define QSE_INLINE inline
|
||||
# define QSE_HAVE_INLINE
|
||||
#elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__)
|
||||
# define QSE_INLINE /*extern*/ inline
|
||||
# define QSE_HAVE_INLINE
|
||||
#else
|
||||
# define QSE_INLINE
|
||||
# undef QSE_HAVE_INLINE
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define QSE_INLINE_ALWAYS inline __attribute__((__always_inline__))
|
||||
# define QSE_HAVE_INLINE_ALWAYS
|
||||
#elif defined(_MSC_VER) || (defined(__CC_ARM) || defined(__ARMCC__))
|
||||
# define QSE_INLINE_ALWAYS __forceinline
|
||||
# define QSE_HAVE_INLINE_ALWAYS
|
||||
#else
|
||||
# define QSE_INLINE_ALWAYS QSE_INLINE
|
||||
# undef QSE_HAVE_INLINE_ALWAYS
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define QSE_INLINE_NEVER inline __attribute__((__noinline__))
|
||||
# define QSE_HAVE_INLINE_NEVER
|
||||
#elif (defined(__CC_ARM) || defined(__ARMCC__))
|
||||
# define QSE_INLINE_NEVER __declspec(noinline)
|
||||
# define QSE_HAVE_INLINE_NEVER
|
||||
#else
|
||||
# define QSE_INLINE_NEVER
|
||||
# undef QSE_HAVE_INLINE_NEVER
|
||||
#endif
|
||||
|
||||
|
||||
@ -142,14 +151,20 @@
|
||||
#define QSE_TYPE_MIN(type) \
|
||||
((QSE_TYPE_IS_SIGNED(type)? QSE_TYPE_SIGNED_MIN(type): QSE_TYPE_UNSIGNED_MIN(type)))
|
||||
|
||||
/**
|
||||
* The QSE_BLOCK macro encloses one or more statements in a block with
|
||||
* no side-effect.
|
||||
*/
|
||||
#define QSE_BLOCK(code) do { code } while(0)
|
||||
|
||||
#define QSE_IS_POWOF2(x) (((x) & ((x) - 1)) == 0)
|
||||
|
||||
#define QSE_SWAP(x,y,original_type,casting_type) \
|
||||
do { \
|
||||
QSE_BLOCK ( \
|
||||
x = (original_type)((casting_type)(x) ^ (casting_type)(y)); \
|
||||
y = (original_type)((casting_type)(y) ^ (casting_type)(x)); \
|
||||
x = (original_type)((casting_type)(x) ^ (casting_type)(y)); \
|
||||
} while (0)
|
||||
)
|
||||
|
||||
#define QSE_ABS(x) ((x) < 0? -(x): (x))
|
||||
|
||||
@ -162,7 +177,7 @@
|
||||
#define QSE_END_LOOP(id) QSE_LOOP_CONTINUE(id) } __loop_ ## id ## _end__:
|
||||
|
||||
#define QSE_REPEAT(n,blk) \
|
||||
do { \
|
||||
QSE_BLOCK ( \
|
||||
qse_size_t __qse_repeat_x1__ = (qse_size_t)(n); \
|
||||
qse_size_t __qse_repeat_x2__ = __qse_repeat_x1__ >> 4; \
|
||||
__qse_repeat_x1__ &= 15; \
|
||||
@ -171,7 +186,8 @@
|
||||
blk; blk; blk; blk; blk; blk; blk; blk; \
|
||||
blk; blk; blk; blk; blk; blk; blk; blk; \
|
||||
} \
|
||||
} while (0);
|
||||
)
|
||||
|
||||
|
||||
/* number of characters to number of bytes */
|
||||
#define QSE_NCTONB(x) ((x)*sizeof(qse_char_t))
|
||||
|
Reference in New Issue
Block a user