From: Rusty Russell Date: Tue, 1 Nov 2011 23:06:29 +0000 (+1030) Subject: strset: set errno to ENOENT even if we return NULL. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=532cd74d55b89872211b34756d5ad59870dd012e strset: set errno to ENOENT even if we return NULL. It seems redundant: strset_test() and strset_clear() can only return NULL when the string is not a member. However, it became clear in writing ccan/tsort that it's much more convenient for callers if we set errno in this case too, so they can pass it up. --- diff --git a/ccan/strset/strset.c b/ccan/strset/strset.c index 7c64b0cd..a5441d44 100644 --- a/ccan/strset/strset.c +++ b/ccan/strset/strset.c @@ -61,12 +61,13 @@ char *strset_test(const struct strset *set, const char *member) { const char *str; - /* Empty set? */ - if (!set->u.n) - return NULL; - str = closest(*set, member); - if (streq(member, str)) - return (char *)str; + /* Non-empty set? */ + if (set->u.n) { + str = closest(*set, member); + if (streq(member, str)) + return (char *)str; + } + errno = ENOENT; return NULL; } @@ -171,8 +172,10 @@ char *strset_clear(struct strset *set, const char *member) u8 direction = 0; /* prevent bogus gcc warning. */ /* Empty set? */ - if (!set->u.n) + if (!set->u.n) { + errno = ENOENT; return NULL; + } /* Find closest, but keep track of parent. */ n = set; @@ -184,8 +187,10 @@ char *strset_clear(struct strset *set, const char *member) if (unlikely(n->u.n->byte_num == (size_t)-1)) { const char *empty_str = n->u.n->child[0].u.s; - if (member[0]) + if (member[0]) { + errno = ENOENT; return NULL; + } /* Sew empty string back so remaining logic works */ free(n->u.n); @@ -203,8 +208,10 @@ char *strset_clear(struct strset *set, const char *member) } /* Did we find it? */ - if (!streq(member, n->u.s)) + if (!streq(member, n->u.s)) { + errno = ENOENT; return NULL; + } ret = n->u.s; diff --git a/ccan/strset/strset.h b/ccan/strset/strset.h index b8116c35..250ce718 100644 --- a/ccan/strset/strset.h +++ b/ccan/strset/strset.h @@ -52,7 +52,8 @@ static inline bool strset_empty(const struct strset *set) * @set: the set. * @member: the string to search for. * - * Returns the member, or NULL if it isn't in the set. + * Returns the member, or NULL if it isn't in the set (and sets errno + * = ENOENT). * * Example: * if (strset_test(&set, "hello")) @@ -82,7 +83,9 @@ bool strset_set(struct strset *set, const char *member); * @set: the set. * @member: the string to remove from the set. * - * This returns the string which was passed to strset_set(), or NULL. + * This returns the string which was passed to strset_set(), or NULL if + * the string was not in the map (in which case it sets errno = ENOENT). + * * This means that if you allocated a string (eg. using strdup()), you can * free it here. * diff --git a/ccan/strset/test/run.c b/ccan/strset/test/run.c index cfda0ee3..412a1fdf 100644 --- a/ccan/strset/test/run.c +++ b/ccan/strset/test/run.c @@ -10,20 +10,25 @@ int main(void) char *dup = strdup(str); /* This is how many tests you plan to run */ - plan_tests(26); + plan_tests(36); strset_init(&set); ok1(!strset_test(&set, str)); + ok1(errno == ENOENT); ok1(!strset_test(&set, none)); + ok1(errno == ENOENT); ok1(!strset_clear(&set, str)); + ok1(errno == ENOENT); ok1(!strset_clear(&set, none)); + ok1(errno == ENOENT); ok1(strset_set(&set, str)); ok1(strset_test(&set, str)); /* We compare the string, not the pointer. */ ok1(strset_test(&set, dup)); ok1(!strset_test(&set, none)); + ok1(errno == ENOENT); /* Add of duplicate should fail. */ ok1(!strset_set(&set, dup)); @@ -32,17 +37,22 @@ int main(void) /* Delete should return original string. */ ok1(strset_clear(&set, dup) == str); ok1(!strset_test(&set, str)); + ok1(errno == ENOENT); ok1(!strset_test(&set, none)); + ok1(errno == ENOENT); /* Try insert and delete of empty string. */ ok1(strset_set(&set, none)); ok1(strset_test(&set, none)); ok1(!strset_test(&set, str)); + ok1(errno == ENOENT); /* Delete should return original string. */ ok1(strset_clear(&set, "") == none); ok1(!strset_test(&set, str)); + ok1(errno == ENOENT); ok1(!strset_test(&set, none)); + ok1(errno == ENOENT); /* Both at once... */ ok1(strset_set(&set, none));