Commit 532cd74d authored by Rusty Russell's avatar Rusty Russell

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.
parent 8bb0697b
...@@ -61,12 +61,13 @@ char *strset_test(const struct strset *set, const char *member) ...@@ -61,12 +61,13 @@ char *strset_test(const struct strset *set, const char *member)
{ {
const char *str; const char *str;
/* Empty set? */ /* Non-empty set? */
if (!set->u.n) if (set->u.n) {
return NULL; str = closest(*set, member);
str = closest(*set, member); if (streq(member, str))
if (streq(member, str)) return (char *)str;
return (char *)str; }
errno = ENOENT;
return NULL; return NULL;
} }
...@@ -171,8 +172,10 @@ char *strset_clear(struct strset *set, const char *member) ...@@ -171,8 +172,10 @@ char *strset_clear(struct strset *set, const char *member)
u8 direction = 0; /* prevent bogus gcc warning. */ u8 direction = 0; /* prevent bogus gcc warning. */
/* Empty set? */ /* Empty set? */
if (!set->u.n) if (!set->u.n) {
errno = ENOENT;
return NULL; return NULL;
}
/* Find closest, but keep track of parent. */ /* Find closest, but keep track of parent. */
n = set; n = set;
...@@ -184,8 +187,10 @@ char *strset_clear(struct strset *set, const char *member) ...@@ -184,8 +187,10 @@ char *strset_clear(struct strset *set, const char *member)
if (unlikely(n->u.n->byte_num == (size_t)-1)) { if (unlikely(n->u.n->byte_num == (size_t)-1)) {
const char *empty_str = n->u.n->child[0].u.s; const char *empty_str = n->u.n->child[0].u.s;
if (member[0]) if (member[0]) {
errno = ENOENT;
return NULL; return NULL;
}
/* Sew empty string back so remaining logic works */ /* Sew empty string back so remaining logic works */
free(n->u.n); free(n->u.n);
...@@ -203,8 +208,10 @@ char *strset_clear(struct strset *set, const char *member) ...@@ -203,8 +208,10 @@ char *strset_clear(struct strset *set, const char *member)
} }
/* Did we find it? */ /* Did we find it? */
if (!streq(member, n->u.s)) if (!streq(member, n->u.s)) {
errno = ENOENT;
return NULL; return NULL;
}
ret = n->u.s; ret = n->u.s;
......
...@@ -52,7 +52,8 @@ static inline bool strset_empty(const struct strset *set) ...@@ -52,7 +52,8 @@ static inline bool strset_empty(const struct strset *set)
* @set: the set. * @set: the set.
* @member: the string to search for. * @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: * Example:
* if (strset_test(&set, "hello")) * if (strset_test(&set, "hello"))
...@@ -82,7 +83,9 @@ bool strset_set(struct strset *set, const char *member); ...@@ -82,7 +83,9 @@ bool strset_set(struct strset *set, const char *member);
* @set: the set. * @set: the set.
* @member: the string to remove from 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 * This means that if you allocated a string (eg. using strdup()), you can
* free it here. * free it here.
* *
......
...@@ -10,20 +10,25 @@ int main(void) ...@@ -10,20 +10,25 @@ int main(void)
char *dup = strdup(str); char *dup = strdup(str);
/* This is how many tests you plan to run */ /* This is how many tests you plan to run */
plan_tests(26); plan_tests(36);
strset_init(&set); strset_init(&set);
ok1(!strset_test(&set, str)); ok1(!strset_test(&set, str));
ok1(errno == ENOENT);
ok1(!strset_test(&set, none)); ok1(!strset_test(&set, none));
ok1(errno == ENOENT);
ok1(!strset_clear(&set, str)); ok1(!strset_clear(&set, str));
ok1(errno == ENOENT);
ok1(!strset_clear(&set, none)); ok1(!strset_clear(&set, none));
ok1(errno == ENOENT);
ok1(strset_set(&set, str)); ok1(strset_set(&set, str));
ok1(strset_test(&set, str)); ok1(strset_test(&set, str));
/* We compare the string, not the pointer. */ /* We compare the string, not the pointer. */
ok1(strset_test(&set, dup)); ok1(strset_test(&set, dup));
ok1(!strset_test(&set, none)); ok1(!strset_test(&set, none));
ok1(errno == ENOENT);
/* Add of duplicate should fail. */ /* Add of duplicate should fail. */
ok1(!strset_set(&set, dup)); ok1(!strset_set(&set, dup));
...@@ -32,17 +37,22 @@ int main(void) ...@@ -32,17 +37,22 @@ int main(void)
/* Delete should return original string. */ /* Delete should return original string. */
ok1(strset_clear(&set, dup) == str); ok1(strset_clear(&set, dup) == str);
ok1(!strset_test(&set, str)); ok1(!strset_test(&set, str));
ok1(errno == ENOENT);
ok1(!strset_test(&set, none)); ok1(!strset_test(&set, none));
ok1(errno == ENOENT);
/* Try insert and delete of empty string. */ /* Try insert and delete of empty string. */
ok1(strset_set(&set, none)); ok1(strset_set(&set, none));
ok1(strset_test(&set, none)); ok1(strset_test(&set, none));
ok1(!strset_test(&set, str)); ok1(!strset_test(&set, str));
ok1(errno == ENOENT);
/* Delete should return original string. */ /* Delete should return original string. */
ok1(strset_clear(&set, "") == none); ok1(strset_clear(&set, "") == none);
ok1(!strset_test(&set, str)); ok1(!strset_test(&set, str));
ok1(errno == ENOENT);
ok1(!strset_test(&set, none)); ok1(!strset_test(&set, none));
ok1(errno == ENOENT);
/* Both at once... */ /* Both at once... */
ok1(strset_set(&set, none)); ok1(strset_set(&set, none));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment