Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions include/dmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ DMOD_BUILTIN_API( dmlist, 1.0, void, _clear, ( dmlist_context_t* ctx ) );
*/
DMOD_BUILTIN_API( dmlist, 1.0, void*, _find, ( dmlist_context_t* ctx, const void* data, dmlist_compare_func_t compare_func ) );

/**
* @brief Find the next occurrence of an element in the list.
*
* @param ctx Pointer to the list context.
* @param last_found Pointer to the last found data (NULL to start from beginning).
* @param data Pointer to the data to find.
* @param compare_func Comparison function to use.
*
* @return Pointer to the found data, or NULL if not found.
*/
DMOD_BUILTIN_API( dmlist, 1.0, void*, _find_next, ( dmlist_context_t* ctx, const void* last_found, const void* data, dmlist_compare_func_t compare_func ) );

/**
* @brief Remove an element from the list.
*
Expand Down
31 changes: 31 additions & 0 deletions src/dmlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,44 @@ DMOD_INPUT_API_DECLARATION( dmlist, 1.0, void, _clear, ( dmlist_context_t* ctx )
}

DMOD_INPUT_API_DECLARATION( dmlist, 1.0, void*, _find, ( dmlist_context_t* ctx, const void* data, dmlist_compare_func_t compare_func ) )
{
return dmlist_find_next( ctx, NULL, data, compare_func );
}

DMOD_INPUT_API_DECLARATION( dmlist, 1.0, void*, _find_next, ( dmlist_context_t* ctx, const void* last_found, const void* data, dmlist_compare_func_t compare_func ) )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

przecież teraz zwykły find może być po prostu wrapperem na tę funkcję

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Masz rację! Zrefaktorowałem kod - teraz dmlist_find jest prostym wrapperem który wywołuje dmlist_find_next(ctx, NULL, data, compare_func). To eliminuje duplikację kodu. (ac66e8c)

{
if( ctx == NULL || compare_func == NULL )
{
return NULL;
}

dmlist_node_t* current = ctx->head;

// If last_found is not NULL, find the node containing it and start from the next one
if( last_found != NULL )
{
bool found_last = false;
// Find the node containing last_found
while( current != NULL )
{
if( current->data == last_found )
{
// Start from the next node
current = current->next;
found_last = true;
break;
}
current = current->next;
}

// If last_found was not in the list, return NULL
if( !found_last )
{
return NULL;
}
}

// Search for the data starting from current
while( current != NULL )
{
if( compare_func( current->data, data ) == 0 )
Expand Down
69 changes: 68 additions & 1 deletion tests/test_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
#define TEST_PASS() printf("PASS\n")
#define TEST_FAIL() printf("FAIL\n")

// Comparison function for integers
static int compare_int(const void* a, const void* b) {
const int* ia = (const int*)a;
const int* ib = (const int*)b;
return *ia - *ib;
}

int main(void) {
printf("=== Simple DMLIST Test ===\n");

Expand Down Expand Up @@ -97,7 +104,67 @@ int main(void) {
}
TEST_PASS();

// Test 10: Destroy
// Test 10: Find and find_next
printf("Find and Find Next: ");
// Add values with duplicates
int val4 = 10;
int val5 = 20;
int val6 = 10;
int val7 = 30;
int val8 = 10;
dmlist_push_back(list, &val4);
dmlist_push_back(list, &val5);
dmlist_push_back(list, &val6);
dmlist_push_back(list, &val7);
dmlist_push_back(list, &val8);

// Find first occurrence of 10
int search_val = 10;
int* found1 = (int*)dmlist_find_next(list, NULL, &search_val, compare_int);
if(found1 == NULL || *found1 != 10 || found1 != &val4) {
TEST_FAIL();
return 1;
}

// Find second occurrence of 10
int* found2 = (int*)dmlist_find_next(list, found1, &search_val, compare_int);
if(found2 == NULL || *found2 != 10 || found2 != &val6) {
TEST_FAIL();
return 1;
}

// Find third occurrence of 10
int* found3 = (int*)dmlist_find_next(list, found2, &search_val, compare_int);
if(found3 == NULL || *found3 != 10 || found3 != &val8) {
TEST_FAIL();
return 1;
}

// Try to find fourth occurrence (should return NULL)
int* found4 = (int*)dmlist_find_next(list, found3, &search_val, compare_int);
if(found4 != NULL) {
TEST_FAIL();
return 1;
}

// Test with NULL last_found should behave like find
int* found_from_start = (int*)dmlist_find_next(list, NULL, &search_val, compare_int);
if(found_from_start == NULL || found_from_start != &val4) {
TEST_FAIL();
return 1;
}

// Test with invalid last_found (not in list) should return NULL
int external_val = 99;
int* found_invalid = (int*)dmlist_find_next(list, &external_val, &search_val, compare_int);
if(found_invalid != NULL) {
TEST_FAIL();
return 1;
}

TEST_PASS();

// Test 11: Destroy
printf("Destroy: ");
dmlist_destroy(list);
TEST_PASS();
Expand Down