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