Commit d2dd1303 authored by jehan's avatar jehan

add list api

add map api
add traces api
add tests
parent 8ce30a84
......@@ -196,6 +196,7 @@ add_compile_options(${STRICT_OPTIONS_CPP} ${STRICT_OPTIONS_C})
add_subdirectory(include)
add_subdirectory(src)
add_subdirectory(tester)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
......
......@@ -20,7 +20,7 @@
#
############################################################################
set(HEADER_FILES crypto.h)
set(HEADER_FILES crypto.h port.h logging.h list.h map.h)
if (ENABLE_TESTS)
list(APPEND HEADER_FILES tester.h)
endif()
......
/*
bctoolbox
Copyright (C) 2016 Belledonne Communications SARL
This program 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, either version 2 of the License, or
(at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
*/
#ifndef BCTOOLBOX_LIST_H_
#define BCTOOLBOX_LIST_H_
#include "bctoolbox/port.h"
#ifdef __cplusplus
extern "C"{
#endif
typedef struct _bctoolbox_list bctoolbox_list_t;
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_append(bctoolbox_list_t * elem, void * data);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_prepend(bctoolbox_list_t * elem, void * data);
BCTOOLBOX_PUBLIC bctoolbox_list_t* bctoolbox_list_prepend_link(bctoolbox_list_t* elem, bctoolbox_list_t *new_elem);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_last_elem(const bctoolbox_list_t *l);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_first_elem(const bctoolbox_list_t *l);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_free(bctoolbox_list_t * elem);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_concat(bctoolbox_list_t * first, bctoolbox_list_t * second);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_remove(bctoolbox_list_t * first, void *data);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_pop_front(bctoolbox_list_t *list, void **front_data);
BCTOOLBOX_PUBLIC int bctoolbox_list_size(const bctoolbox_list_t * first);
BCTOOLBOX_PUBLIC void bctoolbox_list_for_each(const bctoolbox_list_t * list, void (*func)(void *));
BCTOOLBOX_PUBLIC void bctoolbox_list_for_each2(const bctoolbox_list_t * list, void (*func)(void *, void *), void *user_data);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_remove_link(bctoolbox_list_t * list, bctoolbox_list_t * elem);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_delete_link(bctoolbox_list_t * list, bctoolbox_list_t * elem);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_find(bctoolbox_list_t * list, void *data);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_free(bctoolbox_list_t *list);
/*frees list elements and associated data, using the supplied function pointer*/
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_free_with_data(bctoolbox_list_t *list, void (*freefunc)(void*));
typedef int (*bctoolbox_compare_func)(const void *, const void*);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_find_custom(const bctoolbox_list_t * list, bctoolbox_compare_func cmp, const void *user_data);
BCTOOLBOX_PUBLIC void * bctoolbox_list_nth_data(const bctoolbox_list_t * list, int index);
BCTOOLBOX_PUBLIC int bctoolbox_list_position(const bctoolbox_list_t * list, bctoolbox_list_t * elem);
BCTOOLBOX_PUBLIC int bctoolbox_list_index(const bctoolbox_list_t * list, void *data);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_insert_sorted(bctoolbox_list_t * list, void *data, bctoolbox_compare_func cmp);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_insert(bctoolbox_list_t * list, bctoolbox_list_t * before, void *data);
BCTOOLBOX_PUBLIC bctoolbox_list_t * bctoolbox_list_copy(const bctoolbox_list_t * list);
/*copy list elements and associated data, using the supplied function pointer*/
BCTOOLBOX_PUBLIC bctoolbox_list_t* bctoolbox_list_copy_with_data(const bctoolbox_list_t* list, void* (*copyfunc)(void*));
BCTOOLBOX_PUBLIC bctoolbox_list_t* bctoolbox_list_next(const bctoolbox_list_t *elem);
BCTOOLBOX_PUBLIC void* bctoolbox_list_get_data(const bctoolbox_list_t *elem);
#ifdef __cplusplus
}
#endif
#endif /* BCTOOLBOX_LIST_H_ */
/*
bctoolobx
Copyright (C) 2016 Belledonne Communications, France, Grenoble
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* \file logging.h
* \brief Logging API.
*
**/
#ifndef BCTOOLBOX_LOGGING_H
#define BCTOOLBOX_LOGGING_H
#include <bctoolbox/port.h>
#ifndef BCTOOLBOX_LOG_DOMAIN
#define BCTOOLBOX_LOG_DOMAIN NULL
#endif
#ifdef __cplusplus
extern "C"
{
#endif
typedef enum {
BCTOOLBOX_DEBUG=1,
BCTOOLBOX_TRACE=1<<1,
BCTOOLBOX_MESSAGE=1<<2,
BCTOOLBOX_WARNING=1<<3,
BCTOOLBOX_ERROR=1<<4,
BCTOOLBOX_FATAL=1<<5,
BCTOOLBOX_LOGLEV_END=1<<6
} BctoolboxLogLevel;
typedef void (*BctoolboxLogFunc)(const char *domain, BctoolboxLogLevel lev, const char *fmt, va_list args);
BCTOOLBOX_PUBLIC void bctoolbox_set_log_file(FILE *file);
BCTOOLBOX_PUBLIC void bctoolbox_set_log_handler(BctoolboxLogFunc func);
BCTOOLBOX_PUBLIC BctoolboxLogFunc bctoolbox_get_log_handler(void);
BCTOOLBOX_PUBLIC void bctoolbox_logv_out(const char *domain, BctoolboxLogLevel level, const char *fmt, va_list args);
#define bctoolbox_log_level_enabled(domain, level) (bctoolbox_get_log_level_mask(domain) & (level))
BCTOOLBOX_PUBLIC void bctoolbox_logv(const char *domain, BctoolboxLogLevel level, const char *fmt, va_list args);
/**
* Flushes the log output queue.
* WARNING: Must be called from the thread that has been defined with bctoolbox_set_log_thread_id().
*/
BCTOOLBOX_PUBLIC void bctoolbox_logv_flush(void);
/**
* Activate all log level greater or equal than specified level argument.
**/
BCTOOLBOX_PUBLIC void bctoolbox_set_log_level(const char *domain, BctoolboxLogLevel level);
BCTOOLBOX_PUBLIC void bctoolbox_set_log_level_mask(const char *domain, int levelmask);
BCTOOLBOX_PUBLIC unsigned int bctoolbox_get_log_level_mask(const char *domain);
/**
* Tell oRTP the id of the thread used to output the logs.
* This is meant to output all the logs from the same thread to prevent deadlock problems at the application level.
* @param[in] thread_id The id of the thread that will output the logs (can be obtained using bctoolbox_thread_self()).
*/
BCTOOLBOX_PUBLIC void bctoolbox_set_log_thread_id(unsigned long thread_id);
#ifdef __GNUC__
#define CHECK_FORMAT_ARGS(m,n) __attribute__((format(printf,m,n)))
#else
#define CHECK_FORMAT_ARGS(m,n)
#endif
#ifdef __clang__
/*in case of compile with -g static inline can produce this type of warning*/
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
#ifdef BCTOOLBOX_DEBUG_MODE
static BCTOOLBOX_INLINE void CHECK_FORMAT_ARGS(1,2) bctoolbox_debug(const char *fmt,...)
{
va_list args;
va_start (args, fmt);
bctoolbox_logv(BCTOOLBOX_LOG_DOMAIN, BCTOOLBOX_DEBUG, fmt, args);
va_end (args);
}
#else
#define bctoolbox_debug(...)
#endif
#ifdef BCTOOLBOX_NOMESSAGE_MODE
#define bctoolbox_log(...)
#define bctoolbox_message(...)
#define bctoolbox_warning(...)
#else
static BCTOOLBOX_INLINE void bctoolbox_log(const char* domain, BctoolboxLogLevel lev, const char *fmt,...) {
va_list args;
va_start (args, fmt);
bctoolbox_logv(domain, lev, fmt, args);
va_end (args);
}
static BCTOOLBOX_INLINE void CHECK_FORMAT_ARGS(1,2) bctoolbox_message(const char *fmt,...)
{
va_list args;
va_start (args, fmt);
bctoolbox_logv(BCTOOLBOX_LOG_DOMAIN, BCTOOLBOX_MESSAGE, fmt, args);
va_end (args);
}
static BCTOOLBOX_INLINE void CHECK_FORMAT_ARGS(1,2) bctoolbox_warning(const char *fmt,...)
{
va_list args;
va_start (args, fmt);
bctoolbox_logv(BCTOOLBOX_LOG_DOMAIN, BCTOOLBOX_WARNING, fmt, args);
va_end (args);
}
#endif
static BCTOOLBOX_INLINE void CHECK_FORMAT_ARGS(1,2) bctoolbox_error(const char *fmt,...)
{
va_list args;
va_start (args, fmt);
bctoolbox_logv(BCTOOLBOX_LOG_DOMAIN, BCTOOLBOX_ERROR, fmt, args);
va_end (args);
}
static BCTOOLBOX_INLINE void CHECK_FORMAT_ARGS(1,2) bctoolbox_fatal(const char *fmt,...)
{
va_list args;
va_start (args, fmt);
bctoolbox_logv(BCTOOLBOX_LOG_DOMAIN, BCTOOLBOX_FATAL, fmt, args);
va_end (args);
}
#ifdef __QNX__
void bctoolbox_qnx_log_handler(const char *domain, BctoolboxLogLevel lev, const char *fmt, va_list args);
#endif
#ifdef __cplusplus
}
#include <string>
#include <iostream>
#include <sstream>
#include <syslog.h>
namespace bctoolbox {
namespace log {
// Here we define our application severity levels.
enum level { normal, trace, debug, info, warning, error, fatal };
// The formatting logic for the severity level
template <typename CharT, typename TraitsT>
inline std::basic_ostream<CharT, TraitsT> &operator<<(std::basic_ostream<CharT, TraitsT> &strm,
const bctoolbox::log::level &lvl) {
static const char *const str[] = {"normal", "trace", "debug", "info", "warning", "error", "fatal"};
if (static_cast<std::size_t>(lvl) < (sizeof(str) / sizeof(*str)))
strm << str[lvl];
else
strm << static_cast<int>(lvl);
return strm;
}
template <typename CharT, typename TraitsT>
inline std::basic_istream<CharT, TraitsT> &operator>>(std::basic_istream<CharT, TraitsT> &strm,
bctoolbox::log::level &lvl) {
static const char *const str[] = {"normal", "trace", "debug", "info", "warning", "error", "fatal"};
std::string s;
strm >> s;
for (unsigned int n = 0; n < (sizeof(str) / sizeof(*str)); ++n) {
if (s == str[n]) {
lvl = static_cast<bctoolbox::log::level>(n);
return strm;
}
}
// Parse error
strm.setstate(std::ios_base::failbit);
return strm;
}
}
}
#include <ostream>
struct pumpstream : public std::ostringstream {
const std::string mDomain;
const BctoolboxLogLevel level;
pumpstream(std::string domain, BctoolboxLogLevel l) : mDomain(domain), level(l) {
}
~pumpstream() {
bctoolbox_log(mDomain.c_str(), level, "%s", str().c_str());
}
};
#if (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
template <typename _Tp> inline pumpstream &operator<<(pumpstream &&__os, const _Tp &__x) {
(static_cast<std::ostringstream &>(__os)) << __x;
return __os;
}
#endif
#define BCTOOLBOX_SLOG(domain, thelevel) \
\
if (bctoolbox_log_level_enabled((domain), (thelevel))) \
pumpstream((domain),(thelevel))
#define BCTOOLBOX_SLOGD(DOMAIN) BCTOOLBOX_SLOG(DOMAIN, BCTOOLBOX_DEBUG)
#define BCTOOLBOX_SLOGI(DOMAIN) BCTOOLBOX_SLOG((DOMAIN), (BCTOOLBOX_MESSAGE))
#define BCTOOLBOX_SLOGW(DOMAIN) BCTOOLBOX_SLOG(DOMAIN, BCTOOLBOX_WARNING)
#define BCTOOLBOX_SLOGE(DOMAIN) BCTOOLBOX_SLOG(DOMAIN, BCTOOLBOX_ERROR)
#endif
#endif
/*
bctoolbox mmap
Copyright (C) 2016 Belledonne Communications SARL
This program 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, either version 2 of the License, or
(at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
*/
#ifndef BCTOOLBOX_MMAP_H_
#define BCTOOLBOX_MMAP_H_
#include "bctoolbox/port.h"
#ifdef __cplusplus
extern "C"{
#endif
typedef struct _bctoolbox_map_t bctoolbox_map_t;
typedef struct _bctoolbox_pair_t bctoolbox_pair_t;
typedef struct _bctoolbox_iterator_t bctoolbox_iterator_t;
typedef struct _bctoolbox_mmap_long_t bctoolbox_mmap_long_t;
/*map*/
BCTOOLBOX_PUBLIC bctoolbox_map_t *bctoolbox_mmap_long_new(void);
BCTOOLBOX_PUBLIC void bctoolbox_mmap_long_delete(bctoolbox_map_t *mmap);
BCTOOLBOX_PUBLIC void bctoolbox_map_insert(bctoolbox_map_t *map,const bctoolbox_pair_t *pair);
/*same as insert, but also deleting pair*/
BCTOOLBOX_PUBLIC void bctoolbox_map_insert_and_delete(bctoolbox_map_t *map,bctoolbox_pair_t *pair);
BCTOOLBOX_PUBLIC void bctoolbox_map_erase(bctoolbox_map_t *map,bctoolbox_iterator_t *it);
/*return a new allocated iterator*/
BCTOOLBOX_PUBLIC bctoolbox_iterator_t *bctoolbox_map_begin(const bctoolbox_map_t *map);
/*return a new allocated iterator*/
BCTOOLBOX_PUBLIC bctoolbox_iterator_t *bctoolbox_map_end(const bctoolbox_map_t *map);
/*iterator*/
BCTOOLBOX_PUBLIC bctoolbox_pair_t *bctoolbox_iterator_get_pair(const bctoolbox_iterator_t *it);
/*return a new allocated iterator*/
BCTOOLBOX_PUBLIC bctoolbox_iterator_t *bctoolbox_iterator_get_next(const bctoolbox_iterator_t *it);
/* return a new allocated iterator and delete previous*/
BCTOOLBOX_PUBLIC bctoolbox_iterator_t *bctoolbox_iterator_get_next_and_delete(bctoolbox_iterator_t *it);
BCTOOLBOX_PUBLIC bool_t bctoolbox_iterator_equals(const bctoolbox_iterator_t *a,const bctoolbox_iterator_t *b);
BCTOOLBOX_PUBLIC void bctoolbox_iterator_delete(bctoolbox_iterator_t *it);
/*pair*/
typedef struct _bctoolbox_pair_long_t bctoolbox_pair_long_t; /*inherite from bctoolbox_pair_t*/
BCTOOLBOX_PUBLIC bctoolbox_pair_long_t * bctoolbox_pair_long_new(long key,void *value);
BCTOOLBOX_PUBLIC void* bctoolbox_pair_get_second(const bctoolbox_pair_t * pair);
BCTOOLBOX_PUBLIC const long bctoolbox_pair_long_get_first(const bctoolbox_pair_long_t * pair);
BCTOOLBOX_PUBLIC void bctoolbox_pair_delete(bctoolbox_pair_t * pair);
#ifdef __cplusplus
}
#endif
#endif /* BCTOOLBOX_LIST_H_ */
This diff is collapsed.
......@@ -21,6 +21,8 @@
############################################################################
set(BCTOOLBOX_SOURCE_FILES)
list(APPEND BCTOOLBOX_SOURCE_FILES utils/port.c logging/logging.c containers/list.c containers/map.cc)
if(MBEDTLS_FOUND)
list(APPEND BCTOOLBOX_SOURCE_FILES crypto/mbedtls.c)
endif()
......
/*
bctoolbox
Copyright (C) 2016 Belledonne Communications SARL
This program 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, either version 2 of the License, or
(at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
*/
#define _CRT_RAND_S
#include <stddef.h>
#include <stdlib.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <unistd.h>
#include <sys/time.h> /*for gettimeofday*/
#include <dirent.h> /* available on POSIX system only */
#else
#include <direct.h>
#endif
#include "bctoolbox/port.h"
#include "bctoolbox/logging.h"
#include "bctoolbox/list.h"
struct _bctoolbox_list {
struct _bctoolbox_list *next;
struct _bctoolbox_list *prev;
void *data;
};
bctoolbox_list_t* bctoolbox_list_new(void *data){
bctoolbox_list_t* new_elem=bctoolbox_new0(bctoolbox_list_t,1);
new_elem->data=data;
return new_elem;
}
bctoolbox_list_t* bctoolbox_list_next(const bctoolbox_list_t *elem) {
return elem->next;
}
void* bctoolbox_list_get_data(const bctoolbox_list_t *elem) {
return elem->data;
}
bctoolbox_list_t* bctoolbox_list_append_link(bctoolbox_list_t* elem,bctoolbox_list_t *new_elem){
bctoolbox_list_t* it=elem;
if (elem==NULL) return new_elem;
if (new_elem==NULL) return elem;
while (it->next!=NULL) it=bctoolbox_list_next(it);
it->next=new_elem;
new_elem->prev=it;
return elem;
}
bctoolbox_list_t* bctoolbox_list_append(bctoolbox_list_t* elem, void * data){
bctoolbox_list_t* new_elem=bctoolbox_list_new(data);
return bctoolbox_list_append_link(elem,new_elem);
}
bctoolbox_list_t* bctoolbox_list_prepend_link(bctoolbox_list_t* elem, bctoolbox_list_t *new_elem){
if (elem!=NULL) {
new_elem->next=elem;
elem->prev=new_elem;
}
return new_elem;
}
bctoolbox_list_t* bctoolbox_list_prepend(bctoolbox_list_t* elem, void *data){
return bctoolbox_list_prepend_link(elem,bctoolbox_list_new(data));
}
bctoolbox_list_t * bctoolbox_list_last_elem(const bctoolbox_list_t *l){
if (l==NULL) return NULL;
while(l->next){
l=l->next;
}
return (bctoolbox_list_t*)l;
}
bctoolbox_list_t * bctoolbox_list_first_elem(const bctoolbox_list_t *l){
if (l==NULL) return NULL;
while(l->prev){
l=l->prev;
}
return (bctoolbox_list_t*)l;
}
bctoolbox_list_t* bctoolbox_list_concat(bctoolbox_list_t* first, bctoolbox_list_t* second){
bctoolbox_list_t* it=first;
if (it==NULL) return second;
if (second==NULL) return first;
while(it->next!=NULL) it=bctoolbox_list_next(it);
it->next=second;
second->prev=it;
return first;
}
bctoolbox_list_t* bctoolbox_list_free(bctoolbox_list_t* list){
bctoolbox_list_t* elem = list;
bctoolbox_list_t* tmp;
if (list==NULL) return NULL;
while(elem->next!=NULL) {
tmp = elem;
elem = elem->next;
bctoolbox_free(tmp);
}
bctoolbox_free(elem);
return NULL;
}
bctoolbox_list_t * bctoolbox_list_free_with_data(bctoolbox_list_t *list, void (*freefunc)(void*)){
bctoolbox_list_t* elem = list;
bctoolbox_list_t* tmp;
if (list==NULL) return NULL;
while(elem->next!=NULL) {
tmp = elem;
elem = elem->next;
freefunc(tmp->data);
bctoolbox_free(tmp);
}
freefunc(elem->data);
bctoolbox_free(elem);
return NULL;
}
bctoolbox_list_t* _bctoolbox_list_remove(bctoolbox_list_t* first, void *data, int warn_if_not_found){
bctoolbox_list_t* it;
it=bctoolbox_list_find(first,data);
if (it) return bctoolbox_list_delete_link(first,it);
else if (warn_if_not_found){
bctoolbox_warning("bctoolbox_list_remove: no element with %p data was in the list", data);
}
return first;
}
bctoolbox_list_t* bctoolbox_list_remove(bctoolbox_list_t* first, void *data){
return _bctoolbox_list_remove(first, data, TRUE);
}
int bctoolbox_list_size(const bctoolbox_list_t* first){
int n=0;
while(first!=NULL){
++n;
first=first->next;
}
return n;
}
void bctoolbox_list_for_each(const bctoolbox_list_t* list, void (*func)(void *)){
for(;list!=NULL;list=list->next){
func(list->data);
}
}
void bctoolbox_list_for_each2(const bctoolbox_list_t* list, void (*func)(void *, void *), void *user_data){
for(;list!=NULL;list=list->next){
func(list->data,user_data);
}
}
bctoolbox_list_t * bctoolbox_list_pop_front(bctoolbox_list_t *list, void **front_data){
bctoolbox_list_t *front_elem=list;
if (front_elem==NULL){
*front_data=NULL;
return NULL;
}
*front_data=front_elem->data;
list=bctoolbox_list_remove_link(list,front_elem);
bctoolbox_free(front_elem);
return list;
}
bctoolbox_list_t* bctoolbox_list_remove_link(bctoolbox_list_t* list, bctoolbox_list_t* elem){
bctoolbox_list_t* ret;
if (elem==list){
ret=elem->next;
elem->prev=NULL;
elem->next=NULL;
if (ret!=NULL) ret->prev=NULL;
return ret;
}
elem->prev->next=elem->next;
if (elem->next!=NULL) elem->next->prev=elem->prev;
elem->next=NULL;
elem->prev=NULL;
return list;
}
bctoolbox_list_t * bctoolbox_list_delete_link(bctoolbox_list_t* list, bctoolbox_list_t* elem){
bctoolbox_list_t *ret=bctoolbox_list_remove_link(list,elem);
bctoolbox_free(elem);
return ret;
}
bctoolbox_list_t* bctoolbox_list_find(bctoolbox_list_t* list, void *data){
for(;list!=NULL;list=list->next){
if (list->data==data) return list;
}
return NULL;
}
bctoolbox_list_t* bctoolbox_list_find_custom(const bctoolbox_list_t* list, bctoolbox_compare_func compare_func, const void *user_data){
for(;list!=NULL;list=list->next){
if (compare_func(list->data,user_data)==0) return (bctoolbox_list_t *)list;
}
return NULL;
}
bctoolbox_list_t *bctoolbox_list_delete_custom(bctoolbox_list_t *list, bctoolbox_compare_func compare_func, const void *user_data){
bctoolbox_list_t *elem=bctoolbox_list_find_custom(list,compare_func,user_data);
if (elem!=NULL){
list=bctoolbox_list_delete_link(list,elem);
}
return list;
}
void * bctoolbox_list_nth_data(const bctoolbox_list_t* list, int index){
int i;
for(i=0;list!=NULL;list=list->next,++i){
if (i==index) return list->data;
}
bctoolbox_error("bctoolbox_list_nth_data: no such index in list.");
return NULL;
}
int bctoolbox_list_position(const bctoolbox_list_t* list, bctoolbox_list_t* elem){
int i;
for(i=0;list!=NULL;list=list->next,++i){
if (elem==list) return i;
}
bctoolbox_error("bctoolbox_list_position: no such element in list.");
return -1;
}
int bctoolbox_list_index(const bctoolbox_list_t* list, void *data){
int i;
for(i=0;list!=NULL;list=list->next,++i){
if (data==list->data) return i;
}
bctoolbox_error("bctoolbox_list_index: no such element in list.");
return -1;
}
bctoolbox_list_t* bctoolbox_list_insert_sorted(bctoolbox_list_t* list, void *data, int (*compare_func)(const void *, const void*)){
bctoolbox_list_t* it,*previt=NULL;
bctoolbox_list_t* nelem;
bctoolbox_list_t* ret=list;
if (list==NULL) return bctoolbox_list_append(list,data);
else{
nelem=bctoolbox_list_new(data);
for(it=list;it!=NULL;it=it->next){
previt=it;
if (compare_func(data,it->data)<=0){
nelem->prev=it->prev;
nelem->next=it;
if (it->prev!=NULL)
it->prev->next=nelem;
else{
ret=nelem;
}
it->prev=nelem;
return ret;
}
}
previt->next=nelem;
nelem->prev=previt;
}
return ret;
}
bctoolbox_list_t* bctoolbox_list_insert(bctoolbox_list_t* list, bctoolbox_list_t* before, void *data){
bctoolbox_list_t* elem;
if (list==NULL || before==NULL) return bctoolbox_list_append(list,data);
for(elem=list;elem!=NULL;elem=bctoolbox_list_next(elem)){
if (elem==before){
if (elem->prev==NULL)
return bctoolbox_list_prepend(list,data);
else{
bctoolbox_list_t* nelem=bctoolbox_list_new(data);
nelem->prev=elem->prev;
nelem->next=elem;
elem->prev->next=nelem;
elem->prev=nelem;
}
}
}
return list;
}
bctoolbox_list_t* bctoolbox_list_copy(const bctoolbox_list_t* list){
bctoolbox_list_t* copy=NULL;
const bctoolbox_list_t* iter;
for(iter=list;iter!=NULL;iter=bctoolbox_list_next(iter)){
copy=bctoolbox_list_append(copy,iter->data);
}
return copy;
}
bctoolbox_list_t* bctoolbox_list_copy_with_data(const bctoolbox_list_t* list, void* (*copyfunc)(void*)){
bctoolbox_list_t* copy=NULL;
const bctoolbox_list_t* iter;
for(iter=list;iter!=NULL;iter=bctoolbox_list_next(iter)){
copy=bctoolbox_list_append(copy,copyfunc(iter->data));
}
return copy;
}