Re: question of uListSearch
Brandon Long <[email protected]> Thu, 30 Apr 2009 14:56:39 -0700
| Newsgroups | gmane.text.clearsilver.general |
|---|---|
| Organization | Fiction L Networks |
| Message-ID | <20090430215639.GE19144@bl1> |
forgot ulist_test.c, now attached. Brandon On 04/30/09 Brandon Long uttered the following other thing: > On 04/30/09 [email protected] uttered the following other thing: > > > > Hi, my process core dump when I using uListSearch, i found that the > > 2st parameter for bsearch SHOULD BE ul->items[0], or *ul->items in > > line 225 of ulist.c > > > > return bsearch(key, ul->items, ul->num, sizeof(void *), compareFunc); > > No, its correct as is. The usage of uList and the compareFunc's isn't > very obvious. In fact, its possible that the "bug" is that the above > should be: > > return bsearch(&key, ul->items, ul->num, sizeof(void *), compareFunc); > > With the current code, you need to pass in the pointer to what you want, > which isn't very obvious. See the attached expanded ulist_test.c code > for an example usage. > > I feel like I should fix the code, but that would break anyone currently > using it, so no dice with that. > > > BTW, string_array_split() should judge doese strduped string is empty, > > > > e.g. string_array_split(&list, "/home/bigmaliang", "/") will strdup a empty > > string in line 235 of neo_str.c > > > > n = strdup(f); > > You're asking that it doesn't include the empty string? The above > behavior does match python split, for instance: > > # python -c 'print "/home/bigmaliang".split("/")' > ['', 'home', 'bigmaliang'] > > Brandon > -- > "The meek shall inherit the earth; now let's check out who gets heaven." > -- J. Neil Shulman > http://www.fiction.net/blong/ -- "video killed the radio star ... then the Spice Girls killed the rest." -- Alan Braverman http://www.fiction.net/blong/
ulist_test.c
(text/plain, 4.8 KB)
/*
* Copyright 2001-2004 Brandon Long
* All Rights Reserved.
*
* ClearSilver Templating System
*
* This code is made available under the terms of the ClearSilver License.
* http://www.clearsilver.net/license.hdf
*
*/
/*
* Tests for ulist library
*/
#include "util/neo_misc.h"
#include "util/neo_err.h"
#include "util/neo_rand.h"
#include "util/ulist.h"
#include <string.h>
int integerCompare(const void *a, const void *b) {
if (a == NULL) return -1;
if (b == NULL) return 1;
int ax = *(int *)a;
int bx = *(int *)b;
return ax - bx;
}
NEOERR *TestIntegerStorage() {
NEOERR *err;
ULIST *arr;
int x;
ne_warn("TestIntegerStorage");
// Simple append test
err = uListInit(&arr, 100, 0);
if (err) return nerr_pass(err);
for (x = 0; x < 1000; x++) {
err = uListAppend(arr, (void *)x);
if (err) return nerr_pass(err);
}
// Simple get test
for (x = 0; x < 1000; x++) {
int y;
err = uListGet(arr, x, (void *)&y);
if (err) return nerr_pass(err);
if (x != y) {
return nerr_raise(NERR_ASSERT,
"Value returned didn't match value stored: Got %d, Expected %d",
y, x);
}
}
// Sort shouldn't do anything
//err = uListSort(arr, integerCompare);
if (err) return nerr_pass(err);
for (x = 0; x < 1000; x++) {
int y;
err = uListGet(arr, x, (void *)&y);
if (err) return nerr_pass(err);
if (x != y) {
return nerr_raise(NERR_ASSERT,
"Value returned didn't match value stored: Got %d, Expected %d",
y, x);
}
}
// Simple search test
for (x = 0; x < 1000; x++) {
int y = *(int *) uListSearch(arr, (void *)&x, integerCompare);
if (x != y) {
return nerr_raise(NERR_ASSERT,
"Value returned didn't match value stored: Got %d, Expected %d",
y, x);
}
}
// Simple in test
for (x = 0; x < 1000; x++) {
int y = *(int *) uListIn(arr, (void *)&x, integerCompare);
if (x != y) {
return nerr_raise(NERR_ASSERT,
"Value returned didn't match value stored: Got %d, Expected %d",
y, x);
}
}
err = uListDestroy(&arr, 0);
return nerr_pass(err);
}
int stringCompare(const void *a, const void *b) {
if (a == NULL) return -1;
if (b == NULL) return 1;
const char *sa = *(char **)a;
const char *sb = *(char **)b;
return strcmp(sa, sb);
}
NEOERR *TestStringStorage() {
NEOERR *err;
ULIST *arr;
char word[4096];
int x;
ne_warn("TestStringStorage");
// Simple append test
err = uListInit(&arr, 100, 0);
if (err) return nerr_pass(err);
for (x = 0; x < 1000; x++) {
char *word_dup;
neo_rand_word(word, sizeof(word));
word_dup = strdup(word);
if (word_dup == NULL)
return nerr_raise(NERR_NOMEM, "Unable to dup word: %s", word);
err = uListAppend(arr, word_dup);
if (err) return nerr_pass(err);
}
char *a, *b;
#ifdef DEBUG_DUMP
for (x = 0; x < 1000; x++) {
err = uListGet(arr, x, (void *)&a);
if (err) return nerr_pass(err);
ne_warn("%d = %s", x, a);
}
#endif
// Sort 'em
err = uListSort(arr, stringCompare);
if (err) return nerr_pass(err);
#ifdef DEBUG_DUMP
for (x = 0; x < 1000; x++) {
err = uListGet(arr, x, (void *)&a);
if (err) return nerr_pass(err);
ne_warn("%d = %s", x, a);
}
#endif
err = uListGet(arr, 0, (void *)&a);
if (err) return nerr_pass(err);
for (x = 1; x < 1000; x++) {
err = uListGet(arr, x, (void *)&b);
if (err) return nerr_pass(err);
if (strcmp(a, b) > 0) {
return nerr_raise(NERR_ASSERT,
"Expect word %s to come after %s after sort", b, a);
}
}
// Simple search test
for (x = 0; x < 1000; x++) {
err = uListGet(arr, x, (void *)&a);
if (err) return nerr_pass(err);
b = uListSearch(arr, &a, stringCompare);
if (b == NULL) {
return nerr_raise(NERR_ASSERT, "Unable to find %s", a);
}
if (!strcmp(a, b)) {
return nerr_raise(NERR_ASSERT, "Expected to find %s, found %s", a, b);
}
}
// Simple index test
for (x = 0; x < 1000; x++) {
err = uListGet(arr, x, (void *)&a);
if (err) return nerr_pass(err);
int y = uListIndex(arr, &a, stringCompare);
err = uListGet(arr, y, (void *)&b);
if (x != y) {
err = uListGet(arr, y, (void *)&b);
if (err) return nerr_pass(err);
if (strcmp(a, b)) {
return nerr_raise(NERR_ASSERT, "Index returned didn't match index "
"expected: Got %d, Expected %d", y, x);
}
}
}
err = uListDestroy(&arr, 0);
return nerr_pass(err);
}
int main(int argc, char *argv[]) {
NEOERR *err;
nerr_init();
err = TestStringStorage();
if (err) {
nerr_log_error(err);
printf("FAIL\n");
return -1;
}
err = TestIntegerStorage();
if (err) {
nerr_log_error(err);
printf("FAIL\n");
return -1;
}
printf("PASS\n");
return 0;
}