1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 #include <stdlib.h>
22 #include <mailutils/errno.h>
23 #include <mailutils/sys/list.h>
24
25 struct map_closure
26 {
27 mu_list_mapper_t map;
28 void *data;
29 mu_list_t list;
30 int status;
31 };
32
33 static int
_list_mapper(void ** itmv,size_t itmc,void * data)34 _list_mapper (void **itmv, size_t itmc, void *data)
35 {
36 struct map_closure *clos = data;
37 int rc, status;
38
39 if (!clos->list)
40 {
41 status = mu_list_create (&clos->list);
42 if (status)
43 {
44 clos->status = status;
45 return MU_ERR_FAILURE;
46 }
47 }
48
49 rc = clos->map (itmv, itmc, clos->data);
50 if (!(rc & MU_LIST_MAP_SKIP))
51 {
52 status = mu_list_append (clos->list, itmv[0]);
53 if (status)
54 {
55 clos->status = status;
56 return MU_ERR_FAILURE;
57 }
58 }
59 if (rc & MU_LIST_MAP_STOP)
60 return MU_ERR_CANCELED;
61 return 0;
62 }
63
64 int
mu_list_map(mu_list_t list,mu_list_mapper_t map,void * data,size_t nelem,mu_list_t * res)65 mu_list_map (mu_list_t list, mu_list_mapper_t map, void *data, size_t nelem,
66 mu_list_t *res)
67 {
68 int rc;
69 struct map_closure cl;
70
71 if (!res)
72 return MU_ERR_OUT_PTR_NULL;
73
74 cl.map = map;
75 cl.data = data;
76 cl.list = NULL;
77 cl.status = 0;
78
79 rc = mu_list_gmap (list, _list_mapper, nelem, &cl);
80
81 *res = cl.list;
82 if (rc == MU_ERR_FAILURE)
83 return cl.status;
84 return 0;
85 }
86