mirror of
https://github.com/weechat/weechat.git
synced 2026-06-29 06:16:40 +02:00
core: remove "wee-" prefix from source files in src/core and src/core/hook
This commit is contained in:
@@ -0,0 +1,727 @@
|
||||
/*
|
||||
* core-arraylist.c - array lists management
|
||||
*
|
||||
* Copyright (C) 2014-2024 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "weechat.h"
|
||||
#include "core-arraylist.h"
|
||||
#include "core-log.h"
|
||||
#include "core-string.h"
|
||||
|
||||
|
||||
/*
|
||||
* Compares two arraylist entries (default comparator).
|
||||
* It just compares pointers.
|
||||
*
|
||||
* Returns:
|
||||
* -1: pointer1 < pointer2
|
||||
* 0: pointer1 == pointer2
|
||||
* 1: pointer1 > pointer2
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_cmp_default_cb (void *data, struct t_arraylist *arraylist,
|
||||
void *pointer1, void *pointer2)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) arraylist;
|
||||
|
||||
if (pointer1 < pointer2)
|
||||
return -1;
|
||||
if (pointer1 > pointer2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new arraylist.
|
||||
*
|
||||
* Returns pointer to arraylist, NULL if error.
|
||||
*/
|
||||
|
||||
struct t_arraylist *
|
||||
arraylist_new (int initial_size,
|
||||
int sorted,
|
||||
int allow_duplicates,
|
||||
t_arraylist_cmp *callback_cmp, void *callback_cmp_data,
|
||||
t_arraylist_free *callback_free, void *callback_free_data)
|
||||
{
|
||||
struct t_arraylist *new_arraylist;
|
||||
|
||||
/* check arguments */
|
||||
if (initial_size < 0)
|
||||
return NULL;
|
||||
|
||||
new_arraylist = malloc (sizeof (*new_arraylist));
|
||||
if (!new_arraylist)
|
||||
return NULL;
|
||||
|
||||
new_arraylist->size = 0;
|
||||
if (initial_size > 0)
|
||||
{
|
||||
new_arraylist->size_alloc = initial_size;
|
||||
new_arraylist->size_alloc_min = initial_size;
|
||||
new_arraylist->data = calloc (initial_size,
|
||||
sizeof (*new_arraylist->data));
|
||||
if (!new_arraylist->data)
|
||||
{
|
||||
free (new_arraylist);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_arraylist->size_alloc = 0;
|
||||
new_arraylist->size_alloc_min = 0;
|
||||
new_arraylist->data = NULL;
|
||||
}
|
||||
new_arraylist->sorted = sorted;
|
||||
new_arraylist->allow_duplicates = allow_duplicates;
|
||||
new_arraylist->callback_cmp = (callback_cmp) ?
|
||||
callback_cmp : &arraylist_cmp_default_cb;
|
||||
new_arraylist->callback_cmp_data = (callback_cmp) ?
|
||||
callback_cmp_data : NULL;
|
||||
new_arraylist->callback_free = callback_free;
|
||||
new_arraylist->callback_free_data = callback_free_data;
|
||||
|
||||
return new_arraylist;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the size of an arraylist (number of elements).
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_size (struct t_arraylist *arraylist)
|
||||
{
|
||||
if (!arraylist)
|
||||
return 0;
|
||||
|
||||
return arraylist->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the pointer to an arraylist element, by index.
|
||||
*/
|
||||
|
||||
void *
|
||||
arraylist_get (struct t_arraylist *arraylist, int index)
|
||||
{
|
||||
if (!arraylist || (index < 0) || (index >= arraylist->size))
|
||||
return NULL;
|
||||
|
||||
return arraylist->data[index];
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjusts the allocated size of arraylist to add one element (if needed),
|
||||
* so that the list has enough allocated data to store (current_size + 1)
|
||||
* elements.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_grow (struct t_arraylist *arraylist)
|
||||
{
|
||||
int new_size_alloc;
|
||||
void **data;
|
||||
|
||||
if (!arraylist)
|
||||
return 0;
|
||||
|
||||
/* if we have enough space allocated, do nothing */
|
||||
if (arraylist->size + 1 <= arraylist->size_alloc)
|
||||
return 1;
|
||||
|
||||
new_size_alloc = (arraylist->size_alloc < 2) ?
|
||||
2 : arraylist->size_alloc + (arraylist->size_alloc / 2);
|
||||
|
||||
data = realloc (arraylist->data,
|
||||
new_size_alloc * sizeof (*arraylist->data));
|
||||
if (!data)
|
||||
return 0;
|
||||
arraylist->data = data;
|
||||
memset (&arraylist->data[arraylist->size_alloc],
|
||||
0,
|
||||
(new_size_alloc - arraylist->size_alloc) *
|
||||
sizeof (*arraylist->data));
|
||||
arraylist->size_alloc = new_size_alloc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjusts the allocated size of arraylist to remove one element (if needed),
|
||||
* so that the list has enough allocated data to store (current size - 1)
|
||||
* elements.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_shrink (struct t_arraylist *arraylist)
|
||||
{
|
||||
int new_size_alloc;
|
||||
void **data;
|
||||
|
||||
if (!arraylist)
|
||||
return 0;
|
||||
|
||||
/* we don't shrink if we are below the min allocated size */
|
||||
if ((arraylist->size_alloc == 0)
|
||||
|| (arraylist->size_alloc <= arraylist->size_alloc_min))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* clear the arraylist if current allocated size is 1 */
|
||||
if (arraylist->size_alloc == 1)
|
||||
{
|
||||
free (arraylist->data);
|
||||
arraylist->data = NULL;
|
||||
arraylist->size_alloc = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
new_size_alloc = arraylist->size_alloc - (arraylist->size_alloc / 2);
|
||||
|
||||
if (arraylist->size - 1 >= new_size_alloc)
|
||||
return 1;
|
||||
|
||||
data = realloc (arraylist->data,
|
||||
new_size_alloc * sizeof (*arraylist->data));
|
||||
if (!data)
|
||||
return 0;
|
||||
arraylist->data = data;
|
||||
arraylist->size_alloc = new_size_alloc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs a binary search in the arraylist to find an element
|
||||
* (this function must be called only if the arraylist is sorted).
|
||||
*
|
||||
* If "index" is not NULL, it is set with the index of element found (or -1 if
|
||||
* element was not found).
|
||||
*
|
||||
* If "index_insert" is not NULL, it is set with the index that must be used to
|
||||
* insert the element in the arraylist (to keep arraylist sorted).
|
||||
*
|
||||
* Returns pointer to element found, NULL if not found.
|
||||
*/
|
||||
|
||||
void *
|
||||
arraylist_binary_search (struct t_arraylist *arraylist, void *pointer,
|
||||
int *index, int *index_insert)
|
||||
{
|
||||
int ret_index, ret_index_insert, start, end, middle, rc;
|
||||
void *ret_pointer;
|
||||
|
||||
ret_index = -1;
|
||||
ret_index_insert = -1;
|
||||
ret_pointer = NULL;
|
||||
|
||||
if (!arraylist)
|
||||
goto end;
|
||||
|
||||
start = 0;
|
||||
end = arraylist->size - 1;
|
||||
|
||||
/*
|
||||
* statistically we often add at the end, or before first element, so
|
||||
* first check these cases (for performance), before doing the binary
|
||||
* search
|
||||
*/
|
||||
rc = (arraylist->callback_cmp) (arraylist->callback_cmp_data,
|
||||
arraylist,
|
||||
pointer,
|
||||
arraylist->data[end]);
|
||||
if (rc == 0)
|
||||
{
|
||||
ret_index = end;
|
||||
/* by convention, add an element with same value after the last one */
|
||||
ret_index_insert = end + 1;
|
||||
ret_pointer = arraylist->data[end];
|
||||
goto end;
|
||||
}
|
||||
if (rc > 0)
|
||||
{
|
||||
ret_index = -1;
|
||||
ret_index_insert = -1;
|
||||
ret_pointer = NULL;
|
||||
goto end;
|
||||
}
|
||||
if (arraylist->size == 1)
|
||||
{
|
||||
ret_index = -1;
|
||||
ret_index_insert = 0;
|
||||
ret_pointer = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = (arraylist->callback_cmp) (arraylist->callback_cmp_data,
|
||||
arraylist,
|
||||
pointer,
|
||||
arraylist->data[start]);
|
||||
if (rc == 0)
|
||||
{
|
||||
ret_index = start;
|
||||
ret_index_insert = start + 1;
|
||||
ret_pointer = arraylist->data[start];
|
||||
goto end;
|
||||
}
|
||||
if (rc < 0)
|
||||
{
|
||||
ret_index = -1;
|
||||
ret_index_insert = start;
|
||||
ret_pointer = NULL;
|
||||
goto end;
|
||||
}
|
||||
if (arraylist->size == 2)
|
||||
{
|
||||
ret_index = -1;
|
||||
ret_index_insert = end;
|
||||
ret_pointer = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
start++;
|
||||
end--;
|
||||
|
||||
/* perform a binary search to find the index */
|
||||
while (start <= end)
|
||||
{
|
||||
middle = (start + end) / 2;
|
||||
|
||||
rc = (arraylist->callback_cmp) (arraylist->callback_cmp_data,
|
||||
arraylist,
|
||||
pointer,
|
||||
arraylist->data[middle]);
|
||||
if (rc == 0)
|
||||
{
|
||||
ret_index = middle;
|
||||
ret_index_insert = middle + 1;
|
||||
ret_pointer = arraylist->data[middle];
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
end = middle - 1;
|
||||
else
|
||||
start = middle + 1;
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
ret_index = -1;
|
||||
ret_index_insert = (rc < 0) ? middle : middle + 1;
|
||||
ret_pointer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if ((ret_index >= 0) && arraylist->allow_duplicates)
|
||||
{
|
||||
/*
|
||||
* in case of duplicates in table, the index of element found
|
||||
* is the first element with the value, and the index for
|
||||
* insert is the last element with the value + 1
|
||||
*/
|
||||
start = ret_index - 1;
|
||||
while (start >= 0)
|
||||
{
|
||||
rc = (arraylist->callback_cmp) (
|
||||
arraylist->callback_cmp_data,
|
||||
arraylist,
|
||||
pointer,
|
||||
arraylist->data[start]);
|
||||
if (rc != 0)
|
||||
break;
|
||||
start--;
|
||||
}
|
||||
start++;
|
||||
end = ret_index + 1;
|
||||
while (end < arraylist->size)
|
||||
{
|
||||
rc = (arraylist->callback_cmp) (
|
||||
arraylist->callback_cmp_data,
|
||||
arraylist,
|
||||
pointer,
|
||||
arraylist->data[end]);
|
||||
if (rc != 0)
|
||||
break;
|
||||
end++;
|
||||
}
|
||||
end--;
|
||||
ret_index = start;
|
||||
ret_index_insert = end + 1;
|
||||
ret_pointer = arraylist->data[start];
|
||||
}
|
||||
|
||||
if (index)
|
||||
*index = ret_index;
|
||||
if (index_insert)
|
||||
*index_insert = ret_index_insert;
|
||||
|
||||
return ret_pointer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs a standard search in the arraylist to find an element
|
||||
* (this function must be called only if the arraylist is NOT sorted).
|
||||
*
|
||||
* If "index" is not NULL, it is set with the index of element found (or -1 if
|
||||
* element was not found).
|
||||
*
|
||||
* If "index_insert" is not NULL, it is set to -1 (elements are always added
|
||||
* at the end of list when it is not sorted).
|
||||
*
|
||||
* Returns pointer to element found, NULL if not found.
|
||||
*/
|
||||
|
||||
void *
|
||||
arraylist_standard_search (struct t_arraylist *arraylist, void *pointer,
|
||||
int *index, int *index_insert)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!arraylist)
|
||||
goto end;
|
||||
|
||||
for (i = 0; i < arraylist->size; i++)
|
||||
{
|
||||
if ((arraylist->callback_cmp) (arraylist->callback_cmp_data,
|
||||
arraylist, arraylist->data[i],
|
||||
pointer) == 0)
|
||||
{
|
||||
if (index)
|
||||
*index = i;
|
||||
if (index_insert)
|
||||
*index_insert = -1;
|
||||
return arraylist->data[i];
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (index)
|
||||
*index = -1;
|
||||
if (index_insert)
|
||||
*index_insert = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches an element in the arraylist.
|
||||
*
|
||||
* If "index" is not NULL, it is set with the index of element found (or -1 if
|
||||
* element was not found).
|
||||
*
|
||||
* If "index_insert" is not NULL, it is set with the index that must be used to
|
||||
* insert the element in the arraylist (to keep arraylist sorted).
|
||||
*
|
||||
* Returns pointer to element found, NULL if not found.
|
||||
*/
|
||||
|
||||
void *
|
||||
arraylist_search (struct t_arraylist *arraylist, void *pointer,
|
||||
int *index, int *index_insert)
|
||||
{
|
||||
if (index)
|
||||
*index = -1;
|
||||
if (index_insert)
|
||||
*index_insert = -1;
|
||||
|
||||
if (!arraylist || (arraylist->size == 0))
|
||||
return NULL;
|
||||
|
||||
if (arraylist->sorted)
|
||||
{
|
||||
return arraylist_binary_search (arraylist, pointer,
|
||||
index, index_insert);
|
||||
}
|
||||
else
|
||||
{
|
||||
return arraylist_standard_search (arraylist, pointer,
|
||||
index, index_insert);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts an element at a given index (and shifts next elements by one
|
||||
* position), or at automatic index if the arraylist is sorted.
|
||||
*
|
||||
* If the index is negative and that the arraylist is not sorted, the element
|
||||
* is added at the end of arraylist.
|
||||
*
|
||||
* If the arraylist is sorted, the argument "index" is ignored (the element
|
||||
* will be inserted at appropriate position, to keep arraylist sorted).
|
||||
*
|
||||
* Returns the index of the new element (>= 0) or -1 if error.
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_insert (struct t_arraylist *arraylist, int index, void *pointer)
|
||||
{
|
||||
int index_insert, i;
|
||||
|
||||
if (!arraylist)
|
||||
return -1;
|
||||
|
||||
if (arraylist->sorted)
|
||||
{
|
||||
(void) arraylist_search (arraylist, pointer, &index, &index_insert);
|
||||
if ((index >= 0) && !arraylist->allow_duplicates)
|
||||
{
|
||||
while ((index < arraylist->size)
|
||||
&& (((arraylist->callback_cmp) (
|
||||
arraylist->callback_cmp_data,
|
||||
arraylist, arraylist->data[index],
|
||||
pointer)) == 0))
|
||||
{
|
||||
arraylist_remove (arraylist, index);
|
||||
}
|
||||
}
|
||||
else
|
||||
index = index_insert;
|
||||
}
|
||||
else if (!arraylist->allow_duplicates)
|
||||
{
|
||||
/*
|
||||
* arraylist is not sorted and does not allow duplicates, then we
|
||||
* remove any element with the same value
|
||||
*/
|
||||
i = 0;
|
||||
while (i < arraylist->size)
|
||||
{
|
||||
if ((arraylist->callback_cmp) (arraylist->callback_cmp_data,
|
||||
arraylist, arraylist->data[i],
|
||||
pointer) == 0)
|
||||
{
|
||||
arraylist_remove (arraylist, i);
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if index is negative or too big, add at the end */
|
||||
if ((index < 0) || (index > arraylist->size))
|
||||
index = arraylist->size;
|
||||
|
||||
if (!arraylist_grow (arraylist))
|
||||
return -1;
|
||||
|
||||
/* shift next elements by one position */
|
||||
if (index < arraylist->size)
|
||||
{
|
||||
memmove (&arraylist->data[index + 1],
|
||||
&arraylist->data[index],
|
||||
(arraylist->size - index) * sizeof (*arraylist->data));
|
||||
}
|
||||
|
||||
/* set element */
|
||||
arraylist->data[index] = pointer;
|
||||
|
||||
(arraylist->size)++;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds an element at the end of arraylist (or in the middle if the arraylist
|
||||
* is sorted).
|
||||
*
|
||||
* Returns the index of the new element (>= 0) or -1 if error.
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_add (struct t_arraylist *arraylist, void *pointer)
|
||||
{
|
||||
if (!arraylist)
|
||||
return -1;
|
||||
|
||||
return arraylist_insert (arraylist, -1, pointer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes one element from the arraylist.
|
||||
*
|
||||
* Returns the index removed or -1 if error.
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_remove (struct t_arraylist *arraylist, int index)
|
||||
{
|
||||
if (!arraylist || (index < 0) || (index >= arraylist->size))
|
||||
return -1;
|
||||
|
||||
if (arraylist->callback_free)
|
||||
{
|
||||
(arraylist->callback_free) (arraylist->callback_free_data,
|
||||
arraylist,
|
||||
arraylist->data[index]);
|
||||
}
|
||||
|
||||
if (index < arraylist->size - 1)
|
||||
{
|
||||
memmove (&arraylist->data[index],
|
||||
&arraylist->data[index + 1],
|
||||
(arraylist->size - index - 1) * sizeof (*arraylist->data));
|
||||
memset (&arraylist->data[arraylist->size - 1], 0,
|
||||
sizeof (*arraylist->data));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (&arraylist->data[index], 0, sizeof (*arraylist->data));
|
||||
}
|
||||
|
||||
arraylist_shrink (arraylist);
|
||||
|
||||
(arraylist->size)--;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes all elements in the arraylist.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
arraylist_clear (struct t_arraylist *arraylist)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!arraylist)
|
||||
return 0;
|
||||
|
||||
if (arraylist->callback_free)
|
||||
{
|
||||
for (i = 0; i < arraylist->size; i++)
|
||||
{
|
||||
(arraylist->callback_free) (arraylist->callback_free_data,
|
||||
arraylist,
|
||||
arraylist->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (arraylist->data)
|
||||
{
|
||||
if (arraylist->size_alloc != arraylist->size_alloc_min)
|
||||
{
|
||||
free (arraylist->data);
|
||||
arraylist->data = NULL;
|
||||
arraylist->size_alloc = 0;
|
||||
if (arraylist->size_alloc_min > 0)
|
||||
{
|
||||
arraylist->data = calloc (arraylist->size_alloc_min,
|
||||
sizeof (*arraylist->data));
|
||||
if (!arraylist->data)
|
||||
return 0;
|
||||
arraylist->size_alloc = arraylist->size_alloc_min;
|
||||
}
|
||||
}
|
||||
else if (arraylist->size_alloc > 0)
|
||||
{
|
||||
memset (arraylist->data,
|
||||
0,
|
||||
arraylist->size_alloc * sizeof (*arraylist->data));
|
||||
}
|
||||
}
|
||||
|
||||
arraylist->size = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees an arraylist.
|
||||
*/
|
||||
|
||||
void
|
||||
arraylist_free (struct t_arraylist *arraylist)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!arraylist)
|
||||
return;
|
||||
|
||||
if (arraylist->callback_free)
|
||||
{
|
||||
for (i = 0; i < arraylist->size; i++)
|
||||
{
|
||||
(arraylist->callback_free) (arraylist->callback_free_data,
|
||||
arraylist,
|
||||
arraylist->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (arraylist->data)
|
||||
free (arraylist->data);
|
||||
|
||||
free (arraylist);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints an arraylist in WeeChat log file (usually for crash dump).
|
||||
*/
|
||||
|
||||
void
|
||||
arraylist_print_log (struct t_arraylist *arraylist, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
log_printf ("[arraylist %s (addr:0x%lx)]", name, arraylist);
|
||||
log_printf (" size . . . . . . . . . : %d", arraylist->size);
|
||||
log_printf (" size_alloc . . . . . . : %d", arraylist->size_alloc);
|
||||
log_printf (" size_alloc_min . . . . : %d", arraylist->size_alloc_min);
|
||||
log_printf (" sorted . . . . . . . . : %d", arraylist->sorted);
|
||||
log_printf (" allow_duplicates . . . : %d", arraylist->allow_duplicates);
|
||||
log_printf (" data . . . . . . . . . : 0x%lx", arraylist->data);
|
||||
if (arraylist->data)
|
||||
{
|
||||
for (i = 0; i < arraylist->size_alloc; i++)
|
||||
{
|
||||
log_printf (" data[%08d] . . . : 0x%lx",
|
||||
i, arraylist->data[i]);
|
||||
}
|
||||
}
|
||||
log_printf (" callback_cmp . . . . . : 0x%lx", arraylist->callback_cmp);
|
||||
log_printf (" callback_cmp_data. . . : 0x%lx",
|
||||
arraylist->callback_cmp_data);
|
||||
log_printf (" callback_free. . . . . : 0x%lx", arraylist->callback_free);
|
||||
log_printf (" callback_free_data . . : 0x%lx",
|
||||
arraylist->callback_free_data);
|
||||
}
|
||||
Reference in New Issue
Block a user