keylogin(1): Fix a warning and raise WARNS to 6.
[dragonfly.git] / lib / libc / citrus / modules / citrus_mapper_serial.c
1 /* $NetBSD: src/lib/libc/citrus/modules/citrus_mapper_serial.c,v 1.2 2003/07/12 15:39:20 tshiozak Exp $ */
2
3 /*-
4  * Copyright (c)2003 Citrus Project,
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/types.h>
30 #include <sys/queue.h>
31 #include <assert.h>
32 #include <errno.h>
33 #include <limits.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "citrus_namespace.h"
39 #include "citrus_types.h"
40 #include "citrus_bcs.h"
41 #include "citrus_module.h"
42 #include "citrus_region.h"
43 #include "citrus_memstream.h"
44 #include "citrus_mmap.h"
45 #include "citrus_hash.h"
46 #include "citrus_mapper.h"
47 #include "citrus_mapper_serial.h"
48
49 /* ---------------------------------------------------------------------- */
50
51 _CITRUS_MAPPER_DECLS(mapper_serial);
52 _CITRUS_MAPPER_DEF_OPS(mapper_serial);
53
54 #define _citrus_mapper_parallel_mapper_init             \
55         _citrus_mapper_serial_mapper_init
56 #define _citrus_mapper_parallel_mapper_uninit           \
57         _citrus_mapper_serial_mapper_uninit
58 #define _citrus_mapper_parallel_mapper_init_state       \
59         _citrus_mapper_serial_mapper_init_state
60 static int      _citrus_mapper_parallel_mapper_convert(
61         struct _citrus_mapper * __restrict, _index_t * __restrict, _index_t,
62         void * __restrict);
63
64 CITRUS_MODULE(mapper_parallel, mapper, _citrus_mapper_parallel_mapper_getops)
65 _CITRUS_MAPPER_DEF_OPS(mapper_parallel);
66 #undef _citrus_mapper_parallel_mapper_init
67 #undef _citrus_mapper_parallel_mapper_uninit
68 #undef _citrus_mapper_parallel_mapper_init_state
69
70
71 /* ---------------------------------------------------------------------- */
72
73 struct maplink {
74         STAILQ_ENTRY(maplink)   ml_entry;
75         struct _mapper          *ml_mapper;
76 };
77 STAILQ_HEAD(maplist, maplink);
78
79 struct _citrus_mapper_serial {
80         struct maplist  sr_mappers;
81 };
82
83 int
84 _citrus_mapper_serial_mapper_getops(struct _citrus_mapper_ops *ops,
85                                     size_t lenops, uint32_t expected_version)
86 {
87         if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
88                 return EINVAL;
89
90         memcpy(ops, &_citrus_mapper_serial_mapper_ops,
91                sizeof(_citrus_mapper_serial_mapper_ops));
92
93         return 0;
94 }
95
96 int
97 _citrus_mapper_parallel_mapper_getops(struct _citrus_mapper_ops *ops,
98                                       size_t lenops, uint32_t expected_version)
99 {
100         if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
101                 return EINVAL;
102
103         memcpy(ops, &_citrus_mapper_parallel_mapper_ops,
104                sizeof(_citrus_mapper_parallel_mapper_ops));
105
106         return 0;
107 }
108
109 static void
110 uninit(struct _citrus_mapper_serial *sr)
111 {
112         struct maplink *ml;
113
114         while ((ml = STAILQ_FIRST(&sr->sr_mappers)) != NULL) {
115                 STAILQ_REMOVE_HEAD(&sr->sr_mappers, ml_entry);
116                 _mapper_close(ml->ml_mapper);
117                 free(ml);
118         }
119 }
120
121 static int
122 parse_var(struct _citrus_mapper_area *__restrict ma,
123           struct _citrus_mapper_serial *sr, struct _memstream *ms)
124 {
125         int ret;
126         struct _region r;
127         char mapname[PATH_MAX];
128         struct maplink *ml;
129
130         STAILQ_INIT(&sr->sr_mappers);
131         while (1) {
132                 /* remove beginning white spaces */
133                 _memstream_skip_ws(ms);
134                 if (_memstream_iseof(ms))
135                         break;
136                 /* cut down a mapper name */
137                 _memstream_chr(ms, &r, ',');
138                 snprintf(mapname, sizeof(mapname), "%.*s",
139                          (int)_region_size(&r), (char *)_region_head(&r));
140                 /* remove trailing white spaces */
141                 mapname[_bcs_skip_nonws(mapname)-mapname] = '\0';
142                 /* create a new mapper record */
143                 ml = malloc(sizeof(*ml));
144                 if (ml == NULL)
145                         return errno;
146                 ret = _mapper_open(ma, &ml->ml_mapper, mapname);
147                 if (ret) {
148                         free(ml);
149                         return ret;
150                 }
151                 /* support only 1:1 and stateless converter */
152                 if (_mapper_get_src_max(ml->ml_mapper) != 1 ||
153                     _mapper_get_dst_max(ml->ml_mapper) != 1 ||
154                     _mapper_get_state_size(ml->ml_mapper) != 0) {
155                         free(ml);
156                         return EINVAL;
157                 }
158                 STAILQ_INSERT_TAIL(&sr->sr_mappers, ml, ml_entry);
159         }
160         return 0;
161 }
162
163 static int
164 /*ARGSUSED*/
165 _citrus_mapper_serial_mapper_init(struct _citrus_mapper_area *__restrict ma,
166                                   struct _citrus_mapper * __restrict cm,
167                                   const char * __restrict dir __unused,
168                                   const void * __restrict var, size_t lenvar,
169                                   struct _citrus_mapper_traits * __restrict mt,
170                                   size_t lenmt)
171 {
172         struct _citrus_mapper_serial *sr;
173         struct _memstream ms;
174         struct _region r;
175
176         _DIAGASSERT(cm && dir && mt);
177
178         if (lenmt<sizeof(*mt))
179                 return EINVAL;
180
181         sr = malloc(sizeof(*sr));
182         if (sr == NULL)
183                 return errno;
184
185         _region_init(&r, (void *)var, lenvar);
186         _memstream_bind(&ms, &r);
187         if (parse_var(ma, sr, &ms)) {
188                 uninit(sr);
189                 free(sr);
190                 return EINVAL;
191         }
192         cm->cm_closure = sr;
193         mt->mt_src_max = mt->mt_dst_max = 1;    /* 1:1 converter */
194         mt->mt_state_size = 0;                  /* stateless */
195
196         return 0;
197 }
198
199 static void
200 /*ARGSUSED*/
201 _citrus_mapper_serial_mapper_uninit(struct _citrus_mapper *cm)
202 {
203         if (cm && cm->cm_closure) {
204                 uninit(cm->cm_closure);
205                 free(cm->cm_closure);
206         }
207 }
208
209 static int
210 /*ARGSUSED*/
211 _citrus_mapper_serial_mapper_convert(struct _citrus_mapper * __restrict cm,
212                                      _index_t * __restrict dst, _index_t src,
213                                      void * __restrict ps __unused)
214 {
215         int ret;
216         struct _citrus_mapper_serial *sr;
217         struct maplink *ml;
218
219         _DIAGASSERT(cm && cm->cm_closure);
220
221         sr = cm->cm_closure;
222         STAILQ_FOREACH(ml, &sr->sr_mappers, ml_entry) {
223                 ret = _mapper_convert(ml->ml_mapper, &src, src, NULL);
224                 if (ret != _MAPPER_CONVERT_SUCCESS)
225                         return ret;
226         }
227         *dst = src;
228         return _MAPPER_CONVERT_SUCCESS;
229 }
230
231 static int
232 /*ARGSUSED*/
233 _citrus_mapper_parallel_mapper_convert(struct _citrus_mapper * __restrict cm,
234                                        _index_t * __restrict dst, _index_t src,
235                                        void * __restrict ps __unused)
236 {
237         int ret;
238         struct _citrus_mapper_serial *sr;
239         struct maplink *ml;
240         _index_t tmp;
241
242         _DIAGASSERT(cm && cm->cm_closure);
243
244         sr = cm->cm_closure;
245         STAILQ_FOREACH(ml, &sr->sr_mappers, ml_entry) {
246                 ret = _mapper_convert(ml->ml_mapper, &tmp, src, NULL);
247                 if (ret == _MAPPER_CONVERT_SUCCESS) {
248                         *dst = tmp;
249                         return _MAPPER_CONVERT_SUCCESS;
250                 } else if (ret == _MAPPER_CONVERT_ILSEQ)
251                         return _MAPPER_CONVERT_ILSEQ;
252         }
253         return _MAPPER_CONVERT_NONIDENTICAL;
254 }
255
256 static void
257 /*ARGSUSED*/
258 _citrus_mapper_serial_mapper_init_state(struct _citrus_mapper * __restrict cm __unused,
259                                         void * __restrict ps __unused)
260 {
261 }