diff options
author | Florian Weimer <fweimer@redhat.com> | 2019-05-02 11:42:51 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2019-05-02 11:42:51 +0200 |
commit | 7b807a35a8dc63f9742cecf0fc3db46c30e28b0d (patch) | |
tree | 0dce83854245814394b46373b4c8316ab7610b0c /manual/examples | |
parent | 20aa5819586ac7ad11f711bab64feda307965191 (diff) | |
download | glibc-7b807a35a8dc63f9742cecf0fc3db46c30e28b0d.tar.gz glibc-7b807a35a8dc63f9742cecf0fc3db46c30e28b0d.tar.xz glibc-7b807a35a8dc63f9742cecf0fc3db46c30e28b0d.zip |
misc: Add twalk_r function
The twalk function is very difficult to use in a multi-threaded program because there is no way to pass external state to the iterator function. Reviewed-by: Carlos O'Donell <carlos@redhat.com> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'manual/examples')
-rw-r--r-- | manual/examples/twalk.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/manual/examples/twalk.c b/manual/examples/twalk.c new file mode 100644 index 0000000000..04e32731d6 --- /dev/null +++ b/manual/examples/twalk.c @@ -0,0 +1,56 @@ +/* Implement twalk using twalk_r. + Copyright (C) 2019 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <search.h> + +struct twalk_with_twalk_r_closure +{ + void (*action) (const void *, VISIT, int); + int depth; +}; + +static void +twalk_with_twalk_r_action (const void *nodep, VISIT which, void *closure0) +{ + struct twalk_with_twalk_r_closure *closure = closure0; + + switch (which) + { + case leaf: + closure->action (nodep, which, closure->depth); + break; + case preorder: + closure->action (nodep, which, closure->depth); + ++closure->depth; + break; + case postorder: + /* The preorder action incremented the depth. */ + closure->action (nodep, which, closure->depth - 1); + break; + case endorder: + --closure->depth; + closure->action (nodep, which, closure->depth); + break; + } +} + +void +twalk (const void *root, void (*action) (const void *, VISIT, int)) +{ + struct twalk_with_twalk_r_closure closure = { action, 0 }; + twalk_r (root, twalk_with_twalk_r_action, &closure); +} |