xref: /dragonfly/lib/libc/citrus/citrus_none.c (revision 49781055)
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 }
517