зеркало из https://github.com/nextcloud/desktop.git
CSync: Remove c_list
This commit is contained in:
Родитель
af9daaeff7
Коммит
6708c959d9
|
@ -128,8 +128,6 @@ int csync_create(CSYNC **csync, const char *local, const char *remote) {
|
|||
|
||||
ctx->status_code = CSYNC_STATUS_OK;
|
||||
|
||||
ctx->local.list = 0;
|
||||
ctx->remote.list = 0;
|
||||
ctx->current_fs = NULL;
|
||||
|
||||
ctx->abort = false;
|
||||
|
@ -557,12 +555,7 @@ static void _csync_clean_ctx(CSYNC *ctx)
|
|||
|
||||
/* free memory */
|
||||
c_rbtree_free(ctx->local.tree);
|
||||
c_list_free(ctx->local.list);
|
||||
c_rbtree_free(ctx->remote.tree);
|
||||
c_list_free(ctx->remote.list);
|
||||
|
||||
ctx->remote.list = 0;
|
||||
ctx->local.list = 0;
|
||||
|
||||
SAFE_FREE(ctx->statedb.file);
|
||||
SAFE_FREE(ctx->remote.root_perms);
|
||||
|
|
|
@ -111,14 +111,12 @@ struct csync_s {
|
|||
struct {
|
||||
char *uri;
|
||||
c_rbtree_t *tree;
|
||||
c_list_t *list;
|
||||
enum csync_replica_e type;
|
||||
} local;
|
||||
|
||||
struct {
|
||||
char *uri;
|
||||
c_rbtree_t *tree;
|
||||
c_list_t *list;
|
||||
enum csync_replica_e type;
|
||||
int read_from_db;
|
||||
const char *root_perms; /* Permission of the root folder. (Since the root folder is not in the db tree, we need to keep a separate entry.) */
|
||||
|
|
|
@ -20,7 +20,6 @@ set(CSTDLIB_LINK_LIBRARIES
|
|||
|
||||
set(cstdlib_SRCS
|
||||
c_alloc.c
|
||||
c_list.c
|
||||
c_path.c
|
||||
c_rbtree.c
|
||||
c_string.c
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "c_macro.h"
|
||||
#include "c_alloc.h"
|
||||
#include "c_list.h"
|
||||
#include "c_path.h"
|
||||
#include "c_rbtree.h"
|
||||
#include "c_string.h"
|
||||
|
|
|
@ -1,456 +0,0 @@
|
|||
/*
|
||||
* csync list -- a doubly-linked list
|
||||
*
|
||||
* This code is based on glist.{h,c} from glib
|
||||
* ftp://ftp.gtk.org/pub/gtk/
|
||||
* Copyright (c) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (c) 2006-2013 Andreas Schneider <mail@csyncapses.org>
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "c_alloc.h"
|
||||
#include "c_list.h"
|
||||
|
||||
/*
|
||||
* Adds a new element on to the end of the list.
|
||||
*/
|
||||
c_list_t *c_list_append(c_list_t *list, void *data) {
|
||||
c_list_t *new;
|
||||
c_list_t *last;
|
||||
|
||||
new = c_list_alloc();
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->data = data;
|
||||
|
||||
if (list == NULL) {
|
||||
return new;
|
||||
}
|
||||
|
||||
last = c_list_last(list);
|
||||
|
||||
last->next = new;
|
||||
new->prev = last;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a new element on at the beginning of the list.
|
||||
*/
|
||||
c_list_t *c_list_prepend(c_list_t *list, void *data) {
|
||||
c_list_t *new;
|
||||
c_list_t *first;
|
||||
|
||||
new = c_list_alloc();
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->data = data;
|
||||
|
||||
if (list != NULL) {
|
||||
first = c_list_first(list);
|
||||
|
||||
first->prev = new;
|
||||
new->next = first;
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts a new element into the list at the given position.
|
||||
*/
|
||||
c_list_t *c_list_insert(c_list_t *list, void *data, long position) {
|
||||
c_list_t *new;
|
||||
c_list_t *temp;
|
||||
|
||||
/* Handle wrong values for position */
|
||||
if (position < 0) {
|
||||
return c_list_append (list, data);
|
||||
} else if (position == 0) {
|
||||
return c_list_prepend (list, data);
|
||||
}
|
||||
|
||||
temp = c_list_position(list, position);
|
||||
|
||||
if (temp == NULL) {
|
||||
return c_list_append(list, data);
|
||||
}
|
||||
|
||||
new = c_list_alloc();
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->data = data;
|
||||
|
||||
/* List is not empty */
|
||||
if (temp->prev) {
|
||||
temp->prev->next = new;
|
||||
new->prev = temp->prev;
|
||||
}
|
||||
|
||||
new->next = temp;
|
||||
temp->prev = new;
|
||||
|
||||
/* */
|
||||
if (temp == list) {
|
||||
return new;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts a new element into the list, using the given comparison function to
|
||||
* determine its position.
|
||||
*/
|
||||
c_list_t *c_list_insert_sorted(c_list_t *list, void *data,
|
||||
c_list_compare_fn fn) {
|
||||
c_list_t *new;
|
||||
c_list_t *temp;
|
||||
int cmp;
|
||||
|
||||
new = c_list_alloc();
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new->data = data;
|
||||
|
||||
/* list is empty */
|
||||
if (list == NULL) {
|
||||
return new;
|
||||
}
|
||||
|
||||
temp = list;
|
||||
cmp = (fn)(data, temp->data);
|
||||
|
||||
while ((temp->next) && (cmp > 0)) {
|
||||
temp = temp->next;
|
||||
|
||||
cmp = (fn)(data, temp->data);
|
||||
}
|
||||
|
||||
/* last element */
|
||||
if ((temp->next == NULL) && (cmp > 0)) {
|
||||
temp->next = new;
|
||||
new->prev = temp;
|
||||
return list;
|
||||
}
|
||||
|
||||
/* first element */
|
||||
if (temp->prev) {
|
||||
temp->prev->next = new;
|
||||
new->prev = temp->prev;
|
||||
}
|
||||
|
||||
new->next = temp;
|
||||
temp->prev = new;
|
||||
|
||||
/* inserted before first */
|
||||
if (temp == list) {
|
||||
return new;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates space for one c_list_t element.
|
||||
*/
|
||||
c_list_t *c_list_alloc(void) {
|
||||
c_list_t *list = NULL;
|
||||
|
||||
list = c_malloc(sizeof(c_list_t));
|
||||
|
||||
list->data = NULL;
|
||||
|
||||
list->prev = NULL;
|
||||
list->next = NULL;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes an element from a c_list. If two elements contain the same data,
|
||||
* only the first is removed.
|
||||
*/
|
||||
c_list_t *c_list_remove(c_list_t *list, void *data) {
|
||||
c_list_t *temp;
|
||||
|
||||
if (list == NULL || data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
temp = list;
|
||||
|
||||
while (temp != NULL) {
|
||||
if (temp->data != data) {
|
||||
temp = temp->next;
|
||||
} else {
|
||||
/* not at first element */
|
||||
if (temp->prev) {
|
||||
temp->prev->next = temp->next;
|
||||
}
|
||||
|
||||
/* not at last element */
|
||||
if (temp->next) {
|
||||
temp->next->prev = temp->prev;
|
||||
}
|
||||
|
||||
/* first element */
|
||||
if (list == temp) {
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
SAFE_FREE(temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees all elements from a c_list.
|
||||
*/
|
||||
void c_list_free(c_list_t *list) {
|
||||
c_list_t *temp = NULL;
|
||||
|
||||
if (list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
list = c_list_last(list);
|
||||
|
||||
while (list->prev != NULL) {
|
||||
temp = list;
|
||||
list = list->prev;
|
||||
|
||||
SAFE_FREE(temp);
|
||||
}
|
||||
SAFE_FREE(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the next element in a c_list.
|
||||
*/
|
||||
c_list_t *c_list_next(c_list_t *list) {
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return list->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the previous element in a c_list.
|
||||
*/
|
||||
c_list_t *c_list_prev(c_list_t *list) {
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return list->prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the number of elements in a c_list
|
||||
*/
|
||||
unsigned long c_list_length(c_list_t *list) {
|
||||
unsigned long length = 1;
|
||||
|
||||
if (list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (list->next) {
|
||||
length++;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the first element in a c_list
|
||||
*/
|
||||
c_list_t *c_list_first(c_list_t *list) {
|
||||
if (list != NULL) {
|
||||
while (list->prev) {
|
||||
list = list->prev;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the last element in a c_list
|
||||
*/
|
||||
c_list_t *c_list_last(c_list_t *list) {
|
||||
if (list != NULL) {
|
||||
while (list->next) {
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the element at the given positon in a c_list
|
||||
*/
|
||||
c_list_t *c_list_position(c_list_t *list, long position) {
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((position-- > 0) && list != NULL) {
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the element in a c_list_t which contains the given data.
|
||||
*/
|
||||
c_list_t *c_list_find(c_list_t *list, const void *data) {
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (list != NULL) {
|
||||
if (list->data == data) {
|
||||
break;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds an element, using a supplied function to find the desired
|
||||
* element.
|
||||
*/
|
||||
c_list_t *c_list_find_custom(c_list_t *list, const void *data,
|
||||
c_list_compare_fn fn) {
|
||||
int cmp;
|
||||
|
||||
if (list != NULL && fn != NULL) {
|
||||
while (list != NULL) {
|
||||
cmp = (*fn)(list->data, data);
|
||||
if (cmp == 0) {
|
||||
return list;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal used function to merge 2 lists using a compare function
|
||||
*/
|
||||
static c_list_t *_c_list_merge(c_list_t *list1, c_list_t *list2,
|
||||
c_list_compare_fn func) {
|
||||
int cmp;
|
||||
|
||||
/* lists are emty */
|
||||
if (list1 == NULL) {
|
||||
return list2;
|
||||
} else if (list2 == NULL) {
|
||||
return list1;
|
||||
}
|
||||
|
||||
cmp = ((c_list_compare_fn) func)(list1->data, list2->data);
|
||||
/* compare if it is smaller */
|
||||
if (cmp <= 0) {
|
||||
list1->next = _c_list_merge(list1->next, list2, func);
|
||||
if (list1->next) {
|
||||
list1->next->prev = list1;
|
||||
}return list1;
|
||||
} else {
|
||||
list2->next = _c_list_merge(list1, list2->next, func);
|
||||
if (list2->next) {
|
||||
list2->next->prev = list2;
|
||||
}
|
||||
return list2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Internally used function to split 2 lists.
|
||||
*/
|
||||
static c_list_t *_c_list_split(c_list_t *list) {
|
||||
c_list_t *second = NULL;
|
||||
|
||||
/* list is empty */
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
} else if (list->next == NULL) {
|
||||
/* list has only 1 element */
|
||||
return NULL;
|
||||
} else {
|
||||
/* split */
|
||||
second = list->next;
|
||||
list->next = second->next;
|
||||
/* is last element */
|
||||
if (list->next) {
|
||||
list->next->prev = list;
|
||||
}
|
||||
|
||||
second->prev = NULL;
|
||||
second->next = _c_list_split(second->next);
|
||||
/* is last element */
|
||||
if (second->next) {
|
||||
second->next->prev = second;
|
||||
}
|
||||
|
||||
return second;
|
||||
}
|
||||
|
||||
/* never reached */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sorts the elements of a c_list. This is a merge sort.
|
||||
*/
|
||||
c_list_t *c_list_sort(c_list_t *list, c_list_compare_fn func) {
|
||||
c_list_t *second;
|
||||
|
||||
/* list is empty */
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
} else if (list->next == NULL) {
|
||||
/* list has only one element */
|
||||
return list;
|
||||
} else {
|
||||
/* split list */
|
||||
second = _c_list_split(list);
|
||||
}
|
||||
|
||||
return _c_list_merge(c_list_sort(list, func), c_list_sort(second, func),
|
||||
func);
|
||||
}
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
/*
|
||||
* csync list -- a doubly-linked list
|
||||
*
|
||||
* This code is based on glist.{h,c} from glib
|
||||
* ftp://ftp.gtk.org/pub/gtk/
|
||||
* Copyright (c) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (c) 2006-2013 Andreas Schneider <mail@csyncapses.org>
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _C_LIST_H
|
||||
#define _C_LIST_H
|
||||
|
||||
/**
|
||||
* c_list -- a doubly-linked list.
|
||||
*
|
||||
* The c_list_t structure and its associated functions provide a standard
|
||||
* doubly-linked list data structure. Each node has two links: one points to
|
||||
* the previous node, or points to a null value or empty list if it is the
|
||||
* first node; and one points to the next, or points to a null value or empty
|
||||
* list if it is the final node.
|
||||
*
|
||||
* The data contained in each element can be simply pointers to any type of
|
||||
* data. You are the owner of the data, this means you have to free the memory
|
||||
* you have allocated for the data.
|
||||
*
|
||||
* @file c_list.h
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef c_list_t
|
||||
* Creates a type name for c_list_s
|
||||
*/
|
||||
typedef struct c_list_s c_list_t;
|
||||
/**
|
||||
* @struct c_list_s
|
||||
*
|
||||
* Used for each element in a doubly-linked list. The list can hold
|
||||
* any kind of data.
|
||||
*/
|
||||
struct c_list_s {
|
||||
/** Link to the next element in the list */
|
||||
struct c_list_s *next;
|
||||
/** Link to the previous element in the list */
|
||||
struct c_list_s *prev;
|
||||
|
||||
/**
|
||||
* Holds the element's data, which can be a pointer to any kind of
|
||||
* data.
|
||||
*/
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies the type of a comparison function used to compare two values. The
|
||||
* value which should be returned depends on the context in which the
|
||||
* c_list_compare_fn is used.
|
||||
*
|
||||
* @param a First parameter to compare with.
|
||||
*
|
||||
* @param b Second parameter to compare with.
|
||||
*
|
||||
* @return The function should return a number > 0 if the first
|
||||
* parameter comes after the second parameter in the sort
|
||||
* order.
|
||||
*/
|
||||
typedef int (*c_list_compare_fn) (const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* Adds a new element on to the end of the list.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param data The data for the new element.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_append(c_list_t *list, void *data);
|
||||
|
||||
/**
|
||||
* Adds a new element on at the beginning of the list.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param data The data for the new element.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_prepend(c_list_t *list, void *data);
|
||||
|
||||
/**
|
||||
* Inserts a new element into the list at the given position. If the position
|
||||
* is lesser than 0, the new element gets appended to the list, if the position
|
||||
* is 0, we prepend the element and if the given position is greater than the
|
||||
* length of the list, the element gets appended too.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param data The data for the new element.
|
||||
*
|
||||
* @param position The position to insert the element.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_insert(c_list_t *list, void *data, long position);
|
||||
|
||||
/**
|
||||
* Inserts a new element into the list, using the given comparison function to
|
||||
* determine its position.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param data The data for the new element.
|
||||
*
|
||||
* @param fn The function to compare elements in the list. It
|
||||
* should return a number > 0 if the first parameter comes
|
||||
* after the second parameter in the sort order.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_insert_sorted(c_list_t *list, void *data,
|
||||
c_list_compare_fn fn);
|
||||
|
||||
/**
|
||||
* Allocates space for one c_list_t element.
|
||||
*
|
||||
* @return A pointer to the newly-allocated element.
|
||||
*/
|
||||
c_list_t *c_list_alloc(void);
|
||||
|
||||
/**
|
||||
* Removes an element from a c_list. If two elements contain the same data,
|
||||
* only the first is removed.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param data The data of the element to remove.
|
||||
*
|
||||
* @return The first element of the list, NULL on error.
|
||||
*/
|
||||
c_list_t *c_list_remove(c_list_t *list, void *data);
|
||||
|
||||
/**
|
||||
* Frees all elements from a c_list.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*/
|
||||
void c_list_free(c_list_t *list);
|
||||
|
||||
/**
|
||||
* Gets the next element in a c_list.
|
||||
*
|
||||
* @param An element in a c_list.
|
||||
*
|
||||
* @return The next element, or NULL if there are no more
|
||||
* elements.
|
||||
*/
|
||||
c_list_t *c_list_next(c_list_t *list);
|
||||
|
||||
/**
|
||||
* Gets the previous element in a c_list.
|
||||
*
|
||||
* @param An element in a c_list.
|
||||
*
|
||||
* @return The previous element, or NULL if there are no more
|
||||
* elements.
|
||||
*/
|
||||
c_list_t *c_list_prev(c_list_t *list);
|
||||
|
||||
/**
|
||||
* Gets the number of elements in a c_list
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @return The number of elements
|
||||
*/
|
||||
unsigned long c_list_length(c_list_t *list);
|
||||
|
||||
/**
|
||||
* Gets the first element in a c_list
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_first(c_list_t *list);
|
||||
|
||||
/**
|
||||
* Gets the last element in a c_list
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_last(c_list_t *list);
|
||||
|
||||
/**
|
||||
* Gets the element at the given positon in a c_list.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param position The position of the element, counting from 0.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_position(c_list_t *list, long position);
|
||||
|
||||
/**
|
||||
* Finds the element in a c_list_t which contains the given data.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param data The data of the element to remove.
|
||||
*
|
||||
* @return The found element or NULL if it is not found.
|
||||
*/
|
||||
c_list_t *c_list_find(c_list_t *list, const void *data);
|
||||
|
||||
/**
|
||||
* Finds an element, using a supplied function to find the desired
|
||||
* element.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param data The data of the element to remove.
|
||||
*
|
||||
* @param func The function to call for each element. It should
|
||||
* return 0 when the desired element is found.
|
||||
*
|
||||
* @return The found element or NULL if it is not found.
|
||||
*/
|
||||
c_list_t *c_list_find_custom(c_list_t *list, const void *data,
|
||||
c_list_compare_fn fn);
|
||||
|
||||
/**
|
||||
* Sorts the elements of a c_list.
|
||||
* The algorithm used is Mergesort, because that works really well
|
||||
* on linked lists, without requiring the O(N) extra space it needs
|
||||
* when you do it on arrays.
|
||||
*
|
||||
* @param list A pointer to c_list.
|
||||
*
|
||||
* @param func The comparison function used to sort the c_list. This
|
||||
* function is passed 2 elements of the GList and should
|
||||
* return 0 if they are equal, a negative value if the
|
||||
* first element comes before the second, or a positive
|
||||
* value if the first element comes after the second.
|
||||
*
|
||||
* @return New start of the list, which may have changed, so make
|
||||
* sure you store the new value.
|
||||
*/
|
||||
c_list_t *c_list_sort(c_list_t *list, c_list_compare_fn func);
|
||||
|
||||
#endif /* _C_LIST_H */
|
||||
|
|
@ -22,7 +22,6 @@ set(TEST_TARGET_LIBRARIES ${TORTURE_LIBRARY})
|
|||
# std
|
||||
add_cmocka_test(check_std_c_alloc std_tests/check_std_c_alloc.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_std_c_jhash std_tests/check_std_c_jhash.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_std_c_list std_tests/check_std_c_list.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_std_c_path std_tests/check_std_c_path.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_std_c_rbtree std_tests/check_std_c_rbtree.c ${TEST_TARGET_LIBRARIES})
|
||||
add_cmocka_test(check_std_c_str std_tests/check_std_c_str.c ${TEST_TARGET_LIBRARIES})
|
||||
|
|
|
@ -1,354 +0,0 @@
|
|||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "torture.h"
|
||||
|
||||
#include "std/c_list.h"
|
||||
|
||||
typedef struct test_s {
|
||||
int key;
|
||||
int number;
|
||||
} test_t;
|
||||
|
||||
/* compare function for sorting */
|
||||
static int list_cmp(const void *key, const void *data) {
|
||||
test_t *a, *b;
|
||||
|
||||
a = (test_t *) key;
|
||||
b = (test_t *) data;
|
||||
|
||||
if (a->key < b->key) {
|
||||
return -1;
|
||||
} else if (a->key > b->key) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_complete_list(void **state) {
|
||||
c_list_t *list = NULL;
|
||||
int i = 0;
|
||||
srand(1);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
test_t *testdata = NULL;
|
||||
|
||||
testdata = malloc(sizeof(test_t));
|
||||
assert_non_null(testdata);
|
||||
|
||||
testdata->key = i;
|
||||
testdata->number = rand() % 100;
|
||||
|
||||
list = c_list_append(list, (void *) testdata);
|
||||
assert_non_null(list);
|
||||
}
|
||||
|
||||
*state = list;
|
||||
}
|
||||
|
||||
static void setup_random_list(void **state) {
|
||||
c_list_t *list = NULL;
|
||||
int i = 0;
|
||||
srand(1);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
test_t *testdata;
|
||||
|
||||
testdata = malloc(sizeof(test_t));
|
||||
assert_non_null(testdata);
|
||||
|
||||
testdata->key = i;
|
||||
testdata->number = rand() % 100;
|
||||
|
||||
/* random insert */
|
||||
if (testdata->number > 49) {
|
||||
list = c_list_prepend(list, (void *) testdata);
|
||||
} else {
|
||||
list = c_list_append(list, (void *) testdata);
|
||||
}
|
||||
|
||||
assert_non_null(list);
|
||||
}
|
||||
|
||||
*state = list;
|
||||
}
|
||||
|
||||
static void teardown_destroy_list(void **state) {
|
||||
c_list_t *list = *state;
|
||||
c_list_t *walk = NULL;
|
||||
|
||||
for (walk = c_list_first(list); walk != NULL; walk = c_list_next(walk)) {
|
||||
test_t *data;
|
||||
|
||||
data = (test_t *) walk->data;
|
||||
free(data);
|
||||
}
|
||||
c_list_free(list);
|
||||
*state = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start tests
|
||||
*/
|
||||
static void check_c_list_alloc(void **state)
|
||||
{
|
||||
c_list_t *new = NULL;
|
||||
|
||||
(void) state; /* unused */
|
||||
|
||||
new = c_list_alloc();
|
||||
assert_non_null(new);
|
||||
|
||||
free(new);
|
||||
}
|
||||
|
||||
static void check_c_list_remove_null(void **state)
|
||||
{
|
||||
(void) state; /* unused */
|
||||
|
||||
assert_null(c_list_remove(NULL, NULL));
|
||||
}
|
||||
|
||||
static void check_c_list_append(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
|
||||
list = c_list_append(list, (void *) 5);
|
||||
assert_non_null(list);
|
||||
|
||||
list = c_list_remove(list, (void *) 5);
|
||||
assert_null(list);
|
||||
}
|
||||
|
||||
static void check_c_list_prepend(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
|
||||
list = c_list_prepend(list, (void *) 5);
|
||||
assert_non_null(list);
|
||||
|
||||
list = c_list_remove(list, (void *) 5);
|
||||
assert_null(list);
|
||||
}
|
||||
|
||||
static void check_c_list_first(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
|
||||
c_list_t *first = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
first = c_list_first(list);
|
||||
assert_non_null(first);
|
||||
|
||||
data = first->data;
|
||||
assert_int_equal(data->key, 0);
|
||||
}
|
||||
|
||||
static void check_c_list_last(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
c_list_t *last = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
last = c_list_last(list);
|
||||
assert_non_null(list);
|
||||
|
||||
data = last->data;
|
||||
assert_int_equal(data->key, 99);
|
||||
}
|
||||
|
||||
static void check_c_list_next(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
c_list_t *first = NULL;
|
||||
c_list_t *next = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
first = c_list_first(list);
|
||||
assert_non_null(first);
|
||||
next = c_list_next(first);
|
||||
assert_non_null(next);
|
||||
|
||||
data = next->data;
|
||||
assert_int_equal(data->key, 1);
|
||||
}
|
||||
|
||||
static void check_c_list_prev(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
c_list_t *last = NULL;
|
||||
c_list_t *prev = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
last = c_list_last(list);
|
||||
assert_non_null(last);
|
||||
prev = c_list_prev(last);
|
||||
assert_non_null(prev);
|
||||
|
||||
data = prev->data;
|
||||
assert_int_equal(data->key, 98);
|
||||
}
|
||||
|
||||
static void check_c_list_length(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
unsigned long len = 0;
|
||||
|
||||
len = c_list_length(list);
|
||||
assert_int_equal(len, 100);
|
||||
}
|
||||
|
||||
static void check_c_list_position(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
c_list_t *pos = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
pos = c_list_position(list, 50);
|
||||
assert_non_null(pos);
|
||||
|
||||
data = pos->data;
|
||||
assert_int_equal(data->key, 50);
|
||||
}
|
||||
|
||||
static void check_c_list_insert(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
c_list_t *pos = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
data = malloc(sizeof(test_t));
|
||||
assert_non_null(data);
|
||||
|
||||
data->key = data->number = 123;
|
||||
|
||||
list = c_list_insert(list, (void *) data, 50);
|
||||
data = NULL;
|
||||
|
||||
pos = c_list_position(list, 50);
|
||||
assert_non_null(pos);
|
||||
|
||||
data = pos->data;
|
||||
assert_int_equal(data->key, 123);
|
||||
}
|
||||
|
||||
static void check_c_list_find(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
c_list_t *find = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
data = malloc(sizeof(test_t));
|
||||
assert_non_null(data);
|
||||
|
||||
data->key = data->number = 123;
|
||||
|
||||
list = c_list_insert(list, (void *) data, 50);
|
||||
|
||||
find = c_list_find(list, data);
|
||||
assert_memory_equal(data, find->data, sizeof(test_t));
|
||||
}
|
||||
|
||||
static void check_c_list_find_custom(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
c_list_t *find = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
data = malloc(sizeof(test_t));
|
||||
assert_non_null(data);
|
||||
|
||||
data->key = data->number = 123;
|
||||
|
||||
list = c_list_insert(list, (void *) data, 50);
|
||||
|
||||
find = c_list_find_custom(list, data, list_cmp);
|
||||
assert_memory_equal(data, find->data, sizeof(test_t));
|
||||
}
|
||||
|
||||
static void check_c_list_insert_sorted(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
int i = 0;
|
||||
c_list_t *walk = NULL;
|
||||
c_list_t *new = NULL;
|
||||
test_t *data = NULL;
|
||||
|
||||
/* create the list */
|
||||
for (walk = c_list_first(list); walk != NULL; walk = c_list_next(walk)) {
|
||||
new = c_list_insert_sorted(new, walk->data, list_cmp);
|
||||
}
|
||||
|
||||
/* check the list */
|
||||
for (walk = c_list_first(new); walk != NULL; walk = c_list_next(walk)) {
|
||||
data = (test_t *) walk->data;
|
||||
assert_int_equal(data->key, i);
|
||||
i++;
|
||||
}
|
||||
|
||||
c_list_free(new);
|
||||
}
|
||||
|
||||
static void check_c_list_sort(void **state)
|
||||
{
|
||||
c_list_t *list = *state;
|
||||
int i = 0;
|
||||
test_t *data = NULL;
|
||||
c_list_t *walk = NULL;
|
||||
|
||||
/* sort list */
|
||||
list = c_list_sort(list, list_cmp);
|
||||
assert_non_null(list);
|
||||
|
||||
/* check the list */
|
||||
for (walk = c_list_first(list); walk != NULL; walk = c_list_next(walk)) {
|
||||
data = (test_t *) walk->data;
|
||||
assert_int_equal(data->key, i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
const UnitTest tests[] = {
|
||||
unit_test(check_c_list_alloc),
|
||||
unit_test(check_c_list_remove_null),
|
||||
unit_test(check_c_list_append),
|
||||
unit_test(check_c_list_prepend),
|
||||
unit_test_setup_teardown(check_c_list_first, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_last, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_next, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_prev, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_length, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_position, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_find, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_find_custom, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_insert, setup_complete_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_insert_sorted, setup_random_list, teardown_destroy_list),
|
||||
unit_test_setup_teardown(check_c_list_sort, setup_random_list, teardown_destroy_list),
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче