Moriyoshi Koizumi
moriy****@users*****
2002年 12月 29日 (日) 15:41:50 JST
moriyoshi 02/12/29 15:41:50 Modified: . configure.in Added: . acinclude.m4 mbfl mbfl_collection.c mbfl_collection.h mbfl_mutex.c mbfl_mutex.h mbfl_arraylist.c mbfl_arraylist.h mbfl_list.c mbfl_list.h Log: Added list / collection facilities Revision Changes Path 1.4 +41 -4 libmbfl/configure.in Index: configure.in =================================================================== RCS file: /cvsroot/php-i18n/libmbfl/configure.in,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- configure.in 24 Dec 2002 18:00:11 -0000 1.3 +++ configure.in 29 Dec 2002 06:41:49 -0000 1.4 @@ -10,11 +10,14 @@ AC_PROG_LIBTOOL AC_PROG_RANLIB -# Checks for libraries. - # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([stdlib.h stddef.h assert.h]) +AC_CHECK_HEADERS([stdlib.h stddef.h assert.h errno.h]) + +AC_ARG_ENABLE([threads], + [ --enable-threads enable threading support], + [enable_threads="$enableval"], + [enable_threads="autodetect"]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -23,7 +26,41 @@ # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC -AC_CHECK_FUNCS([strcasecmp strchr]) +AC_FUNC_MEMCMP +AC_CHECK_FUNCS([strcasecmp strchr memmove]) + +if test "$enable_threads" != "no"; then + MBFL_PTHREADS([ + avail_pthread="yes" + ],[ + avail_pthread="no" + ]) + + MBFL_WIN32_NATIVE_THREADS([ + avail_win32_native_thread="yes" + ],[ + avail_win32_native_thread="no" + ]) + + if test "$enable_threads" == "autodetect"; then + enable_threads="no" + if test "$avail_pthread" != "no"; then + enable_threads="pthread" + fi + fi +fi + +if test "$enable_threads" != "no"; then + CFLAGS="$CFLAGS -D_REENTRANT" + case "$enable_threads" in + "pthread" [)] + AC_DEFINE([USE_PTHREAD],[1],[Define to 1 if pthread is adopted for threading]) + ;; + "win32native" [)] + AC_DEFINE([USE_WIN32_NATIVE_THREAD],[1],[Define to 1 if win32 native thread is adopted for threading]) + esac +fi + AC_CONFIG_FILES([Makefile mbfl/Makefile filters/Makefile nls/Makefile]) AC_OUTPUT 1.1 libmbfl/acinclude.m4 Index: acinclude.m4 =================================================================== AC_DEFUN([MBFL_PTHREADS],[ AC_CHECK_HEADER([pthread.h], [ avail_pthread_funcs=1 AC_CHECK_FUNC([pthread_mutex_init], [], [avail_pthread_funcs=0]) AC_CHECK_FUNC([pthread_mutex_destroy], [], [avail_pthread_funcs=0]) AC_CHECK_FUNC([pthread_mutex_lock], [], [avail_pthread_funcs=0]) AC_CHECK_FUNC([pthread_mutex_unlock], [], [vail_pthread_funcs=0]) if test "$avail_pthread_funcs"; then AC_DEFINE([HAVE_PTHREAD], [1], [Define to 1 if pthread is available]) $1 fi ],[$2]) ]) AC_DEFUN([MBFL_WIN32_NATIVE_THREADS],[ AC_CHECK_HEADER([windows.h], [ avail_win32_native_thread_funcs=1 AC_CHECK_FUNC([EnterCriticalSection], [], [avail_win32_native_thread_funcs=0]) AC_CHECK_FUNC([LeaveCriticalSection], [], [avail_win32_native_thread_funcs=0]) AC_CHECK_FUNC([InitializeCriticalSection], [], [avail_win32_native_thread_funcs=0]) AC_CHECK_FUNC([DeleteCriticalSection], [], [avail_win32_native_thread_funcs=0]) if test "$avail_win32_native_thread_funcs"; then AC_DEFINE([HAVE_WIN32_NATIVE_THREAD], [1], [Define to 1 if win32 native thread is available]) $1 fi ],[$2]) ]) 1.1 libmbfl/mbfl/mbfl_collection.c Index: mbfl_collection.c =================================================================== /* * "streamable kanji code filter and converter" * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved. * * LICENSE NOTICES * * This file is part of "streamable kanji code filter and converter", * which is distributed under the terms of GNU Lesser General Public * License (version 2) as published by the Free Software Foundation. * * This software 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with "streamable kanji code filter and converter"; * if not, write to the Free Software Foundation, Inc., 59 Temple Place, * Suite 330, Boston, MA 02111-1307 USA * * The author of this file: Moriyoshi Koizumi <moriy****@php*****> * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <assert.h> #include "mbfl_defs.h" #include "mbfl_consts.h" #include "mbfl_collection.h" MBFLAPI int mbfl_collection_ctor(mbfl_collection *col_d) { assert(col_d != NULL); col_d->add_item_op = NULL; col_d->remove_item_op = NULL; col_d->contains_op = NULL; col_d->create_iter_op = NULL; col_d->dtor = _mbfl_collection_dtor; col_d->num_items = 0; return 0; } MBFLAPI void _mbfl_collection_dtor(mbfl_collection *col_d) { assert(col_d != NULL); /* do nothing */ } 1.1 libmbfl/mbfl/mbfl_collection.h Index: mbfl_collection.h =================================================================== #ifndef MBFL_COLLECTION_H #define MBFL_COLLECTION_H #include "mbfl_defs.h" #include "mbfl_iterator.h" struct _mbfl_collection; typedef void (*mbfl_collection_item_dtor_func)(void *); typedef int (*mbfl_collection_add_item_func)(struct _mbfl_collection *, void *, unsigned int, mbfl_collection_item_dtor_func); typedef int (*mbfl_collection_remove_item_func)(struct _mbfl_collection *, void *, unsigned int); typedef int (*mbfl_collection_contains_func)(struct _mbfl_collection *, void *, unsigned int); typedef mbfl_iterator *(*mbfl_collection_create_iter_func)(struct _mbfl_collection *); typedef void (*mbfl_collection_dtor_func)(struct _mbfl_collection *); typedef struct _mbfl_collection { mbfl_collection_add_item_func add_item_op; mbfl_collection_remove_item_func remove_item_op; mbfl_collection_contains_func contains_op; mbfl_collection_create_iter_func create_iter_op; mbfl_collection_dtor_func dtor; int num_items; } mbfl_collection; #define mbfl_collection_add_item(a, b, c, d) (a)->add_item_op((a), (b), (c), (d)) #define mbfl_collection_remove_item(a, b, c) (a)->remove_item_op((a), (b), (c)) #define mbfl_collection_contains(a, b, c) (a)->contains_op((a), (b), (c)) #define mbfl_collection_create_iter(a) (a)->create_iter_op((a)) #define mbfl_collection_dtor(a) (a)->dtor(a) MBFLAPI int mbfl_collection_ctor(mbfl_collection *); MBFLAPI void _mbfl_collection_dtor(mbfl_collection *); #endif /* MBFL_COLLECTION_H */ 1.1 libmbfl/mbfl/mbfl_mutex.c Index: mbfl_mutex.c =================================================================== #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STDDEF_H #include <stddef.h> #endif #ifdef HAVE_ERRNO_H #include <errno.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #if defined(USE_PTHREAD) #if defined(HAVE_PTHREAD) #include <pthread.h> #else #error "pthread is not available" #endif #elif defined(USE_WIN32_NATIVE_THREAD) #if defined(__WIN32__) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #else #error "You can't enable win32 native thread support in this build" #endif #endif #include <assert.h> #include "mbfl_allocators.h" #include "mbfl_mutex.h" #ifdef _REENTRANT MBFLAPI mbfl_mutex *mbfl_mutex_new(void) { #if defined(USE_PTHREAD) pthread_mutex_t *mutex = NULL; pthread_mutexattr_t mattr; if ((mutex = mbfl_malloc(sizeof(pthread_mutex_t))) == NULL) { return NULL; } pthread_mutexattr_init(&mattr); pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_PRIVATE); pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE_NP); pthread_mutex_init(mutex, &mattr); pthread_mutexattr_destroy(&mattr); #elif defined(USE_WIN32_NATIVE_THREAD) CRITICAL_SECTION *mutex; if ((mutex = mbfl_malloc(sizeof(CRITICAL_SECTION))) == NULL) { return NULL; } InitializeCriticalSection(mutex); #endif return (mbfl_mutex *)mutex; } MBFLAPI int mbfl_mutex_lock(mbfl_mutex *mutex) { #if defined(USE_PTHREAD) switch (pthread_mutex_lock((pthread_mutex_t *)mutex)) { case EINVAL: case EDEADLK: return -1; } #elif defined(USE_WIN32_NATIVE_THREAD) EnterCriticalSection((CRITICAL_SECTION *)mutex); if (GetLastError() == STATUS_INVALID_HANDLE) { return -1; } #endif return 0; } MBFLAPI int mbfl_mutex_unlock(mbfl_mutex *mutex) { #if defined(USE_PTHREAD) switch (pthread_mutex_unlock((pthread_mutex_t *)mutex)) { case EINVAL: case EFAULT: return -1; case EPERM: return 1; } #elif defined(USE_WIN32_NATIVE_THREAD) LeaveCriticalSection((CRITICAL_SECTION *)mutex); if (GetLastError() == STATUS_INVALID_HANDLE) { return -1; } #endif return 0; } MBFLAPI void mbfl_mutex_free(mbfl_mutex *mutex) { #if defined(USE_PTHREAD) pthread_mutex_destroy((pthread_mutex_t *)mutex); #elif defined(USE_WIN32_NATIVE_THREAD) DeleteCriticalSection((CRITICAL_SECTION *)mutex); #endif mbfl_free(mutex); } #endif /* _REENTRANT */ 1.1 libmbfl/mbfl/mbfl_mutex.h Index: mbfl_mutex.h =================================================================== #ifndef MBFL_MUTEX_H #define MBFL_MUTEX_H #include "mbfl_defs.h" #define mbfl_mutex void MBFLAPI mbfl_mutex *mbfl_mutex_new(void); MBFLAPI int mbfl_mutex_lock(mbfl_mutex *mutex); MBFLAPI int mbfl_mutex_unlock(mbfl_mutex *mutex); MBFLAPI void mbfl_mutex_free(mbfl_mutex *mutex); #endif /* MBFL_MUTEX_H */ 1.1 libmbfl/mbfl/mbfl_arraylist.c Index: mbfl_arraylist.c =================================================================== /* * "streamable kanji code filter and converter" * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved. * * LICENSE NOTICES * * This file is part of "streamable kanji code filter and converter", * which is distributed under the terms of GNU Lesser General Public * License (version 2) as published by the Free Software Foundation. * * This software 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with "streamable kanji code filter and converter"; * if not, write to the Free Software Foundation, Inc., 59 Temple Place, * Suite 330, Boston, MA 02111-1307 USA * * The author of this file: Moriyoshi Koizumi <moriy****@php*****> * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STDDEF_H #include <stddef.h> #endif #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_MEMORY_H #include <memory.h> #endif #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_STRINGS_H #include <strings.h> #endif #include <assert.h> #include "mbfl_defs.h" #include "mbfl_consts.h" #include "mbfl_allocators.h" #include "mbfl_arraylist.h" typedef struct _mbfl_arraylist_iterator { mbfl_iterator _super; mbfl_arraylist *al_d; int idx; } mbfl_arraylist_iterator; typedef struct _mbfl_arraylist_entry { unsigned int size; mbfl_collection_item_dtor_func item_dtor; char obj[4]; /* this doesn't represent actual object size */ } mbfl_arraylist_entry; #define MBFL_AL_ENT_SIZE(objsize) ((sizeof(mbfl_arraylist_entry)-sizeof(((mbfl_arraylist_entry*)0)->obj))+objsize) static int _mbfl_arraylist_insert_item_at(mbfl_arraylist *al_d, void *obj, unsigned int size, mbfl_collection_item_dtor_func item_dtor, int idx); static int _mbfl_arraylist_get_item_at(mbfl_arraylist *al_d, void **pobj, unsigned int *pobj_size, int idx); static int _mbfl_arraylist_remove_item_at(mbfl_arraylist *al_d, int idx); static int _mbfl_arraylist_index_of(mbfl_arraylist *al_d, int *pretval, void *obj, unsigned int size); static mbfl_iterator *_mbfl_arraylist_create_iter(mbfl_arraylist *al_d); MBFLAPI int mbfl_arraylist_ctor(mbfl_arraylist *al_d) { int err; assert(al_d != NULL); if ((err = mbfl_list_ctor(&(al_d->_super))) != 0) { return err; } #ifdef _REENTRANT if ((al_d->mutex = mbfl_mutex_new()) == NULL) { return -1; } #endif al_d->entries_size = 0; al_d->allocated_size = 0; al_d->max_obj_size = 0; al_d->entries = NULL; al_d->_super._super.create_iter_op = (mbfl_collection_create_iter_func)_mbfl_arraylist_create_iter; al_d->_super._super.dtor = (mbfl_collection_dtor_func)_mbfl_arraylist_dtor; al_d->_super.insert_item_at_op = (mbfl_list_insert_item_at_func)_mbfl_arraylist_insert_item_at; al_d->_super.get_item_at_op = (mbfl_list_get_item_at_func)_mbfl_arraylist_get_item_at; al_d->_super.remove_item_at_op = (mbfl_list_remove_item_at_func)_mbfl_arraylist_remove_item_at; al_d->_super.index_of_op = (mbfl_list_index_of_func)_mbfl_arraylist_index_of; return 0; } MBFLAPI void _mbfl_arraylist_dtor(mbfl_arraylist *al_d) { assert(al_d != NULL); #ifdef _REENTRANT assert(al_d->mutex != NULL); mbfl_mutex_free(al_d->mutex); #endif if (al_d->entries != NULL) { mbfl_free(al_d->entries); } _mbfl_list_dtor(&(al_d->_super)); } static int _mbfl_arraylist_insert_item_at(mbfl_arraylist *al_d, void *obj, unsigned int size, mbfl_collection_item_dtor_func item_dtor, int idx) { unsigned int aligned_size; unsigned int ent_size; int err = 0; mbfl_arraylist_entry *new_entry; #ifdef _REENTRANT int mutex_locked = 0; #endif assert(al_d != NULL); #ifdef _REENTRANT assert(al_d->mutex != NULL); #endif aligned_size = (size + 7) & ~7; ent_size = MBFL_AL_ENT_SIZE(al_d->max_obj_size); if (aligned_size > al_d->max_obj_size) { unsigned int i; unsigned int new_ent_size; unsigned int required_size; #ifdef _REENTRANT if (mbfl_mutex_lock(al_d->mutex) != 0) { err = -1; goto out; } mutex_locked = 1; #endif required_size = MBFL_AL_ENT_SIZE(aligned_size) * (al_d->_super._super.num_items+1); if (required_size > al_d->allocated_size) { unsigned int new_size = (al_d->allocated_size == 0 ? MBFL_AL_ENT_SIZE(aligned_size): al_d->allocated_size); void *new_entries; while (new_size < required_size) { new_size *= 2; } if ((new_entries = mbfl_realloc(al_d->entries, new_size)) == NULL) { err = -1; goto out; } al_d->entries = new_entries; al_d->allocated_size = new_size; } new_ent_size = MBFL_AL_ENT_SIZE(aligned_size); i = al_d->_super._super.num_items; while (i-- > 0) { memmove(((char *)al_d->entries + i * new_ent_size), ((char *)al_d->entries + i * ent_size), ent_size); } ent_size = new_ent_size; al_d->max_obj_size = aligned_size; } al_d->entries_size = ent_size * al_d->_super._super.num_items; if (al_d->entries_size >= al_d->allocated_size) { unsigned int new_size; void *new_entries; #ifdef _REENTRANT if (!mutex_locked) { if (mbfl_mutex_lock(al_d->mutex) != 0) { err = -1; goto out; } mutex_locked = 1; } #endif new_size = al_d->entries_size; new_size = (new_size == 0 ? ent_size: new_size * 2); if ((new_entries = mbfl_realloc(al_d->entries, new_size)) == NULL) { err = -1; goto out; } al_d->entries = new_entries; al_d->allocated_size = new_size; } #ifdef _REENTRANT if (!mutex_locked) { if (mbfl_mutex_lock(al_d->mutex) != 0) { return -1; } mutex_locked = 1; } #endif new_entry = ((mbfl_arraylist_entry *)((char *)al_d->entries + al_d->entries_size)); new_entry->size = size; new_entry->item_dtor = item_dtor; memcpy(new_entry->obj, obj, size); al_d->entries_size += ent_size; al_d->_super._super.num_items++; out: #ifdef _REENTRANT if (mutex_locked && mbfl_mutex_unlock(al_d->mutex) != 0) { return -1; } #endif return err; } static int _mbfl_arraylist_remove_item_at(mbfl_arraylist *al_d, int idx) { mbfl_arraylist_entry *entry; unsigned int ent_size; #ifdef _REENTRANT if (mbfl_mutex_lock(al_d->mutex) != 0) { return -1; } #endif ent_size = MBFL_AL_ENT_SIZE(al_d->max_obj_size); entry = (mbfl_arraylist_entry *)((((char *)al_d->entries) + ent_size * idx)); if (entry->item_dtor != NULL) { entry->item_dtor((void *)entry->obj); } memmove(entry, ((char *)entry + ent_size), al_d->entries_size - ent_size * idx - ent_size); al_d->entries_size -= ent_size; al_d->_super._super.num_items--; #ifdef _REENTRANT if (mbfl_mutex_unlock(al_d->mutex) != 0) { return -1; } #endif return 0; } static int _mbfl_arraylist_get_item_at(mbfl_arraylist *al_d, void **pobj, unsigned int *pobj_size, int idx) { mbfl_arraylist_entry *entry; int err = 0; assert(al_d != NULL); assert(pobj != NULL); assert(pobj_size != NULL); if (idx < 0) { return 1; } #ifdef _REENTRANT if (mbfl_mutex_lock(al_d->mutex) != 0) { return -1; } #endif if (idx >= al_d->_super._super.num_items) { err = 1; goto out; } entry = (mbfl_arraylist_entry *)(((char *)al_d->entries) + MBFL_AL_ENT_SIZE(al_d->max_obj_size) * idx); *pobj = entry->obj; *pobj_size = entry->size; out: #ifdef _REENTRANT if (mbfl_mutex_unlock(al_d->mutex) != 0) { return -1; } #endif return err; } static int _mbfl_arraylist_index_of(mbfl_arraylist *al_d, int *pretval, void *obj, unsigned int size) { int i; int retval; mbfl_arraylist_entry *entry; assert(al_d != NULL); assert(pretval != NULL); #ifdef _REENTRANT assert(al_d->mutex != NULL); #endif entry = (mbfl_arraylist_entry *)al_d->entries; #ifdef _REENTRANT if (mbfl_mutex_lock(al_d->mutex) != 0) { return -1; } #endif retval = 1; for (i = 0; i < al_d->_super._super.num_items; ++i) { if (entry->size == size && memcmp(entry->obj, obj, size) == 0) { *pretval = i; retval = 0; break; } ((char *)entry) += MBFL_AL_ENT_SIZE(al_d->max_obj_size); } #ifdef _REENTRANT if (mbfl_mutex_unlock(al_d->mutex) != 0) { return -1; } #endif return retval; } static int _mbfl_arraylist_iterator_next_func(mbfl_arraylist_iterator *iter, void **pobj, unsigned int *psize) { int err; assert(iter != NULL); assert(pobj != NULL); assert(psize != NULL); if (iter->_super.has_next == 0) { return -1; } if ((err = mbfl_arraylist_get_item_at(iter->al_d, pobj, psize, iter->idx)) != 0) { return err; } if (++iter->idx >= (unsigned int)iter->al_d->_super._super.num_items) { iter->_super.has_next = 0; } return 0; } static mbfl_iterator *_mbfl_arraylist_create_iter(mbfl_arraylist *al_d) { mbfl_arraylist_iterator *iter; assert(al_d != NULL); if ((iter = mbfl_malloc(sizeof(mbfl_arraylist_iterator))) == NULL) { return NULL; } iter->_super.has_next = (al_d->_super._super.num_items > 0 ? 1: 0); iter->_super.next_op = (mbfl_iterator_next_func)_mbfl_arraylist_iterator_next_func; iter->idx = 0; iter->al_d = al_d; return (mbfl_iterator *)iter; } 1.1 libmbfl/mbfl/mbfl_arraylist.h Index: mbfl_arraylist.h =================================================================== #ifndef MBFL_ARRAYLIST_H #define MBFL_ARRAYLIST_H #include "mbfl_defs.h" #include "mbfl_list.h" #include "mbfl_mutex.h" struct _mbfl_arraylist; typedef struct _mbfl_arraylist { mbfl_list _super; unsigned int entries_size; unsigned int allocated_size; unsigned int max_obj_size; void *entries; mbfl_mutex *mutex; } mbfl_arraylist; MBFLAPI int mbfl_arraylist_ctor(mbfl_arraylist *); MBFLAPI void _mbfl_arraylist_dtor(mbfl_arraylist *); #define mbfl_arraylist_add_item(a, b, c, d) mbfl_list_add_item(&((a)->_super),(b), (c), (d)) #define mbfl_arraylist_remove(a, b, c) mbfl_list_remove(&((a)->_super),(b), (c)) #define mbfl_arraylist_contains(a, b, c) mbfl_list_contains(&((a)->_super),(b), (c)) #define mbfl_arraylist_create_iter(a) mbfl_list_create_iter(&((a)->_super)) #define mbfl_arraylist_insert_item_at(a, b, c, d, e) mbfl_list_insert_item(&((a)->_super), (b), (c), (d), (e)) #define mbfl_arraylist_get_item_at(a, b, c, d) mbfl_list_get_item_at(&((a)->_super), (b), (c), (d)) #define mbfl_arraylist_remove_item_at(a, b) mbfl_list_remove_item_at(&((a)->_super), (b)) #define mbfl_arraylist_index_of(a, b, c, d) mbfl_list_index_of(&((a)->_super), (b), (c), (d)) #define mbfl_arraylist_dtor(a) mbfl_list_dtor((mbfl_list *)&((a)->_super)) #endif /* MBFL_ARRAYLIST_H */ 1.1 libmbfl/mbfl/mbfl_list.c Index: mbfl_list.c =================================================================== #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_STDDEF_H #include <stddef.h> #endif #include <assert.h> #include "mbfl_list.h" #include "mbfl_allocators.h" static int _mbfl_list_add_item(mbfl_list *, void *, unsigned int, mbfl_collection_item_dtor_func); static int _mbfl_list_contains(mbfl_list *, void *, unsigned int); static int _mbfl_list_remove_item(mbfl_list *, void *, unsigned int); MBFLAPI int mbfl_list_ctor(mbfl_list *listd) { int err; assert(listd != NULL); if ((err = mbfl_collection_ctor(&(listd->_super))) != 0) { return err; } listd->insert_item_at_op = NULL; listd->get_item_at_op = NULL; listd->index_of_op = NULL; listd->_super.add_item_op = (mbfl_collection_add_item_func)_mbfl_list_add_item; listd->_super.remove_item_op = (mbfl_collection_remove_item_func)_mbfl_list_remove_item; listd->_super.contains_op = (mbfl_collection_contains_func)_mbfl_list_contains; listd->_super.dtor = (mbfl_collection_dtor_func)_mbfl_list_dtor; return 0; } MBFLAPI void _mbfl_list_dtor(mbfl_list *listd) { assert(listd != NULL); _mbfl_collection_dtor(&(listd->_super)); /* do nothing */ } static int _mbfl_list_add_item(mbfl_list *listd, void *obj, unsigned int size, mbfl_collection_item_dtor_func item_dtor) { mbfl_list_insert_item_at(listd, obj, size, item_dtor, -1); } static int _mbfl_list_contains(mbfl_list *listd, void *obj, unsigned int size) { int dummy; if (mbfl_list_index_of(listd, &dummy, obj, size) == 0) { return 1; } return 0; } static int _mbfl_list_remove_item(mbfl_list *listd, void *obj, unsigned int size) { int idx; int err; if ((err = mbfl_list_index_of(listd, &idx, obj, size)) != 0) { return err; } if ((err = mbfl_list_remove_item_at(listd, idx)) != 0) { return err; } return 0; } 1.1 libmbfl/mbfl/mbfl_list.h Index: mbfl_list.h =================================================================== #ifndef MBFL_LIST_H #define MBFL_LIST_H #include "mbfl_collection.h" struct _mbfl_list; typedef int (*mbfl_list_insert_item_at_func)(struct _mbfl_list *, void *, unsigned int, mbfl_collection_item_dtor_func item_dtor, int); typedef int (*mbfl_list_remove_item_at_func)(struct _mbfl_list *, int); typedef int (*mbfl_list_get_item_at_func)(struct _mbfl_list *, void **, unsigned int *, int); typedef int (*mbfl_list_index_of_func)(struct _mbfl_list *, int *, void *, unsigned int); typedef struct _mbfl_list { mbfl_collection _super; mbfl_list_insert_item_at_func insert_item_at_op; mbfl_list_get_item_at_func get_item_at_op; mbfl_list_remove_item_at_func remove_item_at_op; mbfl_list_index_of_func index_of_op; } mbfl_list; #define mbfl_list_add_item(a, b, c, d) mbfl_collection_add_item(&((a)->_super),(b), (c), (d)) #define mbfl_list_remove_item(a, b, c) mbfl_collection_remove_item(&((a)->_super),(b), (c)) #define mbfl_list_contains(a, b, c) mbfl_collection_contains(&((a)->_super),(b), (c)) #define mbfl_list_create_iter(a) mbfl_collection_create_iter(&((a)->_super)) #define mbfl_list_insert_item_at(a, b, c, d, e) (a)->insert_item_at_op((a), (b), (c), (d), (e)) #define mbfl_list_get_item_at(a, b, c, d) (a)->get_item_at_op((a), (b), (c), (d)) #define mbfl_list_remove_item_at(a, b) (a)->remove_item_at_op((a), (b)) #define mbfl_list_index_of(a, b, c, d) (a)->index_of_op((a), (b), (c), (d)) #define mbfl_list_dtor(a) mbfl_collection_dtor((mbfl_collection *)&((a)->_super)) MBFLAPI int mbfl_list_ctor(mbfl_list *); MBFLAPI void _mbfl_list_dtor(mbfl_list *); #endif /* MBFL_LIST_H */