Allow inclusion of Citrus modules in statically linked binaries.
[dragonfly.git] / lib / libc / citrus / citrus_none.c
1 /*      $NetBSD: src/lib/libc/citrus/citrus_none.c,v 1.12 2004/01/18 03:57:30 yamt Exp $        */
2 /*      $DragonFly: src/lib/libc/citrus/citrus_none.c,v 1.4 2005/07/04 08:02:43 joerg Exp $ */
3
4 /*-
5  * Copyright (c)2002 Citrus Project,
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <assert.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <stddef.h>
36 #include <locale.h>
37 #include <wchar.h>
38 #include <sys/types.h>
39
40 #include "citrus_namespace.h"
41 #include "citrus_types.h"
42 #include "citrus_module.h"
43 #include "citrus_ctype.h"
44 #include "citrus_none.h"
45 #include "citrus_stdenc.h"
46
47 /* ---------------------------------------------------------------------- */
48 static int
49 _citrus_NONE_ctype_getops(_citrus_ctype_ops_rec_t *, size_t, uint32_t);
50 static int
51 _citrus_NONE_stdenc_getops(struct _citrus_stdenc_ops *, size_t, uint32_t);
52
53 _CITRUS_CTYPE_DECLS(NONE);
54 _CITRUS_CTYPE_DEF_OPS(NONE);
55
56
57 /* ---------------------------------------------------------------------- */
58
59 static int
60 _citrus_NONE_ctype_getops(_citrus_ctype_ops_rec_t *ops, size_t lenops,
61                         uint32_t expected_version)
62 {
63         if (expected_version<_CITRUS_CTYPE_ABI_VERSION || lenops<sizeof(*ops))
64                 return (EINVAL);
65
66         memcpy(ops, &_citrus_NONE_ctype_ops, sizeof(_citrus_NONE_ctype_ops));
67
68         return (0);
69 }
70
71 static int
72 _citrus_NONE_stdenc_getops(struct _citrus_stdenc_ops *ops, size_t lenops,
73                          uint32_t expected_version)
74 {
75         if (expected_version<_CITRUS_STDENC_ABI_VERSION || lenops<sizeof(*ops))
76                 return (EINVAL);
77
78         memcpy(ops, &_citrus_NONE_stdenc_ops, sizeof(_citrus_NONE_stdenc_ops));
79
80         return (0);
81 }
82
83 static int
84 /*ARGSUSED*/
85 _citrus_NONE_ctype_init(void ** __restrict cl, void * __restrict var __unused,
86                         size_t lenvar __unused, size_t lenps __unused)
87 {
88         *cl = NULL;
89         return (0);
90 }
91
92 static void
93 /*ARGSUSED*/
94 _citrus_NONE_ctype_uninit(void *cl __unused)
95 {
96 }
97
98 static unsigned
99 /*ARGSUSED*/
100 _citrus_NONE_ctype_get_mb_cur_max(void *cl __unused)
101 {
102         return (1);
103 }
104
105 static int
106 /*ARGSUSED*/
107 _citrus_NONE_ctype_mblen(void * __restrict cl __unused,
108                          const char * __restrict s, size_t n,
109                          int * __restrict nresult)
110 {
111         if (!s) {
112                 *nresult = 0; /* state independent */
113                 return (0);
114         }
115         if (n==0) {
116                 *nresult = -1;
117                 return (EILSEQ);
118         }
119         *nresult = (*s == 0) ? 0 : 1;
120         return (0);
121 }
122
123 static int
124 /*ARGSUSED*/
125 _citrus_NONE_ctype_mbrlen(void * __restrict cl __unused,
126                           const char * __restrict s, size_t n,
127                           void * __restrict pspriv __unused,
128                           size_t * __restrict nresult)
129 {
130         if (!s) {
131                 *nresult = 0;
132                 return (0);
133         }
134         if (n==0) {
135                 *nresult = (size_t)-2;
136                 return (0);
137         }
138         *nresult = (*s == 0) ? 0 : 1;
139         return (0);
140 }
141
142 static int
143 /*ARGSUSED*/
144 _citrus_NONE_ctype_mbrtowc(void * __restrict cl __unused,
145                            wchar_t * __restrict pwc,
146                            const char * __restrict s, size_t n,
147                            void * __restrict pspriv __unused,
148                            size_t * __restrict nresult)
149 {
150         if (s == NULL) {
151                 *nresult = 0;
152                 return (0);
153         }
154         if (n == 0) {
155                 *nresult = (size_t)-2;
156                 return (0);
157         }
158
159         if (pwc != NULL)
160                 *pwc = (wchar_t)(unsigned char) *s;
161
162         *nresult = *s == '\0' ? 0 : 1;
163         return (0);
164 }
165
166 static int
167 /*ARGSUSED*/
168 _citrus_NONE_ctype_mbsinit(void * __restrict cl __unused,
169                            const void * __restrict pspriv __unused,
170                            int * __restrict nresult)
171 {
172         *nresult = 1;  /* always initial state */
173         return (0);
174 }
175
176 static int
177 /*ARGSUSED*/
178 _citrus_NONE_ctype_mbsrtowcs(void * __restrict cl __unused,
179                              wchar_t * __restrict pwcs,
180                              const char ** __restrict s, size_t n,
181                              void * __restrict pspriv __unused,
182                              size_t * __restrict nresult)
183 {
184         int cnt;
185         const char *s0;
186
187         /* if pwcs is NULL, ignore n */
188         if (pwcs == NULL)
189                 n = 1; /* arbitrary >0 value */
190
191         cnt = 0;
192         s0 = *s; /* to keep *s unchanged for now, use copy instead. */
193         while (n > 0) {
194                 if (pwcs != NULL) {
195                         *pwcs = (wchar_t)(unsigned char)*s0;
196                 }
197                 if (*s0 == '\0') {
198                         s0 = NULL;
199                         break;
200                 }
201                 s0++;
202                 if (pwcs != NULL) {
203                         pwcs++;
204                         n--;
205                 }
206                 cnt++;
207         }
208         if (pwcs)
209                 *s = s0;
210
211         *nresult = (size_t)cnt;
212
213         return (0);
214 }
215
216 static int
217 _citrus_NONE_ctype_mbstowcs(void * __restrict cl, wchar_t * __restrict wcs,
218                             const char * __restrict s, size_t n,
219                             size_t * __restrict nresult)
220 {
221         const char *tmp_s = __DEQUALIFY(const char *, s);
222
223         return (_citrus_NONE_ctype_mbsrtowcs(cl, wcs, &tmp_s, n, NULL, nresult));
224 }
225
226 static int
227 /*ARGSUSED*/
228 _citrus_NONE_ctype_mbtowc(void * __restrict cl __unused,
229                           wchar_t * __restrict pwc,
230                           const char * __restrict s, size_t n,
231                           int * __restrict nresult)
232 {
233
234         if (s == NULL) {
235                 *nresult = 0; /* state independent */
236                 return (0);
237         }
238         if (n == 0) {
239                 return (EILSEQ);
240         }
241         if (pwc == NULL) {
242                 if (*s == '\0') {
243                         *nresult = 0;
244                 } else {
245                         *nresult = 1;
246                 }
247                 return (0);
248         }
249
250         *pwc = (wchar_t)*s;
251         *nresult = *s == '\0' ? 0 : 1;
252
253         return (0);
254 }
255
256 static int
257 /*ARGSUSED*/
258 _citrus_NONE_ctype_wcrtomb(void * __restrict cl __unused,
259                            char * __restrict s, wchar_t wc,
260                            void * __restrict pspriv __unused,
261                            size_t * __restrict nresult)
262 {
263         if ((wc&~0xFFU) != 0) {
264                 *nresult = (size_t)-1;
265                 return (EILSEQ);
266         }
267
268         *nresult = 1;
269         if (s!=NULL)
270                 *s = (char)wc;
271
272         return (0);
273 }
274
275 static int
276 /*ARGSUSED*/
277 _citrus_NONE_ctype_wcsrtombs(void * __restrict cl __unused,
278                              char * __restrict s,
279                              const wchar_t ** __restrict pwcs, size_t n,
280                              void * __restrict pspriv __unused,
281                              size_t * __restrict nresult)
282 {
283         size_t count;
284         const wchar_t *pwcs0;
285
286         pwcs0 = *pwcs;
287         count = 0;
288
289         if (s == NULL)
290                 n = 1;
291
292         while (n > 0) {
293                 if ((*pwcs0 & ~0xFFU) != 0) {
294                         *nresult = (size_t)-1;
295                         return (EILSEQ);
296                 }
297                 if (s != NULL) {
298                         *s++ = (char)*pwcs0;
299                         n--;
300                 }
301                 if (*pwcs0 == L'\0') {
302                         pwcs0 = NULL;
303                         break;
304                 }
305                 count++;
306                 pwcs0++;
307         }
308         if (s != NULL)
309                 *pwcs = pwcs0;
310
311         *nresult = count;
312
313         return (0);
314 }
315
316 static int
317 _citrus_NONE_ctype_wcstombs(void * __restrict cl, char * __restrict s,
318                             const wchar_t * __restrict pwcs, size_t n,
319                             size_t * __restrict nresult)
320 {
321         const wchar_t *tmp_pwcs = __DEQUALIFY(const wchar_t *, pwcs);
322
323         return (_citrus_NONE_ctype_wcsrtombs(cl, s, &tmp_pwcs, n, NULL, nresult));
324 }
325
326 static int
327 _citrus_NONE_ctype_wctomb(void * __restrict cl, char * __restrict s,
328                           wchar_t wc, int * __restrict nresult)
329 {
330         int ret;
331         size_t nr;
332
333         if (s == 0) {
334                 /*
335                  * initialize state here.
336                  * (nothing to do for us.)
337                  */
338                 *nresult = 0; /* we're state independent */
339                 return (0);
340         }
341
342         ret = _citrus_NONE_ctype_wcrtomb(cl, s, wc, NULL, &nr);
343         *nresult = (int)nr;
344
345         return (ret);
346 }
347
348 static int
349 /*ARGSUSED*/
350 _citrus_NONE_ctype_btowc(_citrus_ctype_rec_t * __restrict cc __unused,
351                          int c, wint_t * __restrict wcresult)
352 {
353         if (c == EOF || c & ~0xFF)
354                 *wcresult = WEOF;
355         else
356                 *wcresult = (wint_t)c;
357         return (0);
358 }
359
360 static int
361 /*ARGSUSED*/
362 _citrus_NONE_ctype_wctob(_citrus_ctype_rec_t * __restrict cc __unused,
363                          wint_t wc, int * __restrict cresult)
364 {
365         if (wc == WEOF || wc & ~0xFF)
366                 *cresult = EOF;
367         else
368                 *cresult = (int)wc;
369         return (0);
370 }
371
372 /* ---------------------------------------------------------------------- */
373
374 _CITRUS_STDENC_DECLS(NONE);
375 _CITRUS_STDENC_DEF_OPS(NONE);
376 struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = {
377         0,      /* et_state_size */
378         1,      /* mb_cur_max */
379 };
380
381 static int
382 /*ARGSUSED*/
383 _citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce,
384                          const void *var __unused, size_t lenvar __unused,
385                          struct _citrus_stdenc_traits * __restrict et)
386 {
387
388         et->et_state_size = 0;
389         et->et_mb_cur_max = 1;
390
391         ce->ce_closure = NULL;
392
393         return (0);
394 }
395
396 static void
397 /*ARGSUSED*/
398 _citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce __unused)
399 {
400 }
401
402 static int
403 /*ARGSUSED*/
404 _citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce __unused,
405                                void * __restrict ps __unused)
406 {
407         return (0);
408 }
409
410 static int
411 /*ARGSUSED*/
412 _citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce __unused,
413                            _csid_t *csid, _index_t *idx,
414                            const char **s, size_t n,
415                            void *ps __unused, size_t *nresult)
416 {
417
418         _DIAGASSERT(csid != NULL && idx != NULL);
419
420         if (n<1) {
421                 *nresult = (size_t)-2;
422                 return (0);
423         }
424
425         *csid = 0;
426         *idx = (_index_t)(unsigned char)*(*s)++;
427         *nresult = *idx == 0 ? 0 : 1;
428
429         return (0);
430 }
431
432 static int
433 /*ARGSUSED*/
434 _citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce __unused,
435                            char *s, size_t n,
436                            _csid_t csid, _index_t idx,
437                            void *ps __unused, size_t *nresult)
438 {
439
440         if (csid == _CITRUS_CSID_INVALID) {
441                 *nresult = 0;
442                 return (0);
443         }
444         if (n<1) {
445                 *nresult = (size_t)-1;
446                 return (E2BIG);
447         }
448         if (csid != 0 || (idx&0xFF) != idx)
449                 return (EILSEQ);
450
451         *s = (char)idx;
452         *nresult = 1;
453
454         return (0);
455 }
456
457 static int
458 /*ARGSUSED*/
459 _citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce __unused,
460                            _wc_t * __restrict pwc,
461                            const char ** __restrict s, size_t n,
462                            void * __restrict pspriv __unused,
463                            size_t * __restrict nresult)
464 {
465         if (s == NULL) {
466                 *nresult = 0;
467                 return (0);
468         }
469         if (n == 0) {
470                 *nresult = (size_t)-2;
471                 return (0);
472         }
473
474         if (pwc != NULL)
475                 *pwc = (_wc_t)(unsigned char) **s;
476
477         *nresult = *s == '\0' ? 0 : 1;
478         return (0);
479 }
480
481 static int
482 /*ARGSUSED*/
483 _citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce __unused,
484                            char * __restrict s, size_t n, _wc_t wc,
485                            void * __restrict pspriv __unused,
486                            size_t * __restrict nresult)
487 {
488         if ((wc&~0xFFU) != 0) {
489                 *nresult = (size_t)-1;
490                 return (EILSEQ);
491         }
492         if (n==0) {
493                 *nresult = (size_t)-1;
494                 return (E2BIG);
495         }
496
497         *nresult = 1;
498         if (s!=NULL && n>0)
499                 *s = (char)wc;
500
501         return (0);
502 }
503
504 static int
505 /*ARGSUSED*/
506 _citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce __unused,
507                                     char * __restrict s __unused,
508                                     size_t n __unused,
509                                     void * __restrict pspriv __unused,
510                                     size_t * __restrict nresult)
511 {
512
513         *nresult = 0;
514
515         return (0);
516 }