Skip to content

Commit

Permalink
Merge pull request #206 from sippy/master
Browse files Browse the repository at this point in the history
Document ucl_object_iter_chk_excpn() and add it into test scenario.
  • Loading branch information
vstakhov committed Apr 3, 2019
2 parents d611533 + d373c3b commit 23d99f3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
13 changes: 12 additions & 1 deletion doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ UCL defines the following functions to manage safe iterators:

- `ucl_object_iterate_new` - creates new safe iterator
- `ucl_object_iterate_reset` - resets iterator to a new object
- `ucl_object_iterate_safe` - safely iterate the object inside iterator
- `ucl_object_iterate_safe` - safely iterate the object inside iterator. Note: function may allocate and free memory during its operation. Therefore it returns `NULL` either while trying to access item after the last one or when exception (such as memory allocation failure) happens.
- `ucl_object_iter_chk_excpn` - check if the last call to `ucl_object_iterate_safe` ended up in unrecoverable exception (e.g. `ENOMEM`).
- `ucl_object_iterate_free` - free memory associated with the safe iterator

Please note that unlike unsafe iterators, safe iterators *must* be explicitly initialized and freed.
Expand All @@ -447,13 +448,23 @@ it = ucl_object_iterate_new (obj);
while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
/* Do something */
}
/* Check error condition */
if (ucl_object_iter_chk_excpn (it)) {
ucl_object_iterate_free (it);
exit (1);
}

/* Switch to another object */
it = ucl_object_iterate_reset (it, another_obj);

while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
/* Do something else */
}
/* Check error condition */
if (ucl_object_iter_chk_excpn (it)) {
ucl_object_iterate_free (it);
exit (1);
}

ucl_object_iterate_free (it);
~~~
Expand Down
26 changes: 22 additions & 4 deletions doc/libucl.3
Original file line number Diff line number Diff line change
Expand Up @@ -612,15 +612,23 @@ Iteration\ without\ expansion:
.PP
UCL defines the following functions to manage safe iterators:
.IP \[bu] 2
\f[C]ucl_object_iterate_new\f[] \- creates new safe iterator
\f[C]ucl_object_iterate_new\f[] \- creates new safe iterator.
.IP \[bu] 2
\f[C]ucl_object_iterate_reset\f[] \- resets iterator to a new object
\f[C]ucl_object_iterate_reset\f[] \- resets iterator to a new object.
.IP \[bu] 2
\f[C]ucl_object_iterate_safe\f[] \- safely iterate the object inside
iterator
iterator.
Note: function may allocate and free memory during its operation.
Therefore it returns \f[C]NULL\f[] either while trying to access item
after the last one or when exception (such as memory allocation
failure) happens.
.IP \[bu] 2
\f[C]ucl_object_iter_chk_excpn\f[] \- check if the last call to
\f[C]ucl_object_iterate_safe\f[] ended up in unrecoverable exception
(e.g. \f[C]ENOMEM\f[]).
.IP \[bu] 2
\f[C]ucl_object_iterate_free\f[] \- free memory associated with the safe
iterator
iterator.
.PP
Please note that unlike unsafe iterators, safe iterators \f[I]must\f[]
be explicitly initialized and freed.
Expand All @@ -637,13 +645,23 @@ it\ =\ ucl_object_iterate_new\ (obj);
while\ ((cur\ =\ ucl_object_iterate_safe\ (it,\ true))\ !=\ NULL)\ {
\ \ \ \ /*\ Do\ something\ */
}
/*\ Check\ error\ condition\ */
if\ (ucl_object_iter_chk_excpn\ (it))\ {
\ \ \ \ ucl_object_iterate_free\ (it);
\ \ \ \ exit\ (1);
}

/*\ Switch\ to\ another\ object\ */
it\ =\ ucl_object_iterate_reset\ (it,\ another_obj);

while\ ((cur\ =\ ucl_object_iterate_safe\ (it,\ true))\ !=\ NULL)\ {
\ \ \ \ /*\ Do\ something\ else\ */
}
/*\ Check\ error\ condition\ */
if\ (ucl_object_iter_chk_excpn\ (it))\ {
\ \ \ \ ucl_object_iterate_free\ (it);
\ \ \ \ exit\ (1);
}

ucl_object_iterate_free\ (it);
\f[]
Expand Down
9 changes: 9 additions & 0 deletions tests/test_generate.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,27 +240,36 @@ main (int argc, char **argv)
/* Test iteration */
it = ucl_object_iterate_new (obj);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
/* key0 = 0.1 */
assert (ucl_object_type (it_obj) == UCL_FLOAT);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
/* key1 = "" */
assert (ucl_object_type (it_obj) == UCL_STRING);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
/* key2 = "" */
assert (ucl_object_type (it_obj) == UCL_STRING);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
/* key3 = "" */
assert (ucl_object_type (it_obj) == UCL_STRING);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
/* key4 = ([float, int, float], boolean) */
ucl_object_iterate_reset (it, it_obj);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
assert (ucl_object_type (it_obj) == UCL_FLOAT);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
assert (ucl_object_type (it_obj) == UCL_INT);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
assert (ucl_object_type (it_obj) == UCL_FLOAT);
it_obj = ucl_object_iterate_safe (it, true);
assert (!ucl_object_iter_chk_excpn (it));
assert (ucl_object_type (it_obj) == UCL_BOOLEAN);
ucl_object_iterate_free (it);

Expand Down

0 comments on commit 23d99f3

Please sign in to comment.