xref: /illumos-gate/usr/src/lib/libcurses/screen/mbtowc.c (revision e8031f0a8ed0e45c6d8847c5e09424e66fd34a4b)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*  Copyright (c) 1988 AT&T */
24 /*    All Rights Reserved   */
25 
26 /*
27  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 /*LINTLIBRARY*/
34 
35 #include "c_synonyms.h"
36 #include <widec.h>
37 #include <ctype.h>
38 #include <sys/types.h>
39 #include "curses_wchar.h"
40 
41 int
42 _curs_mbtowc(wchar_t *wchar, const char *s, size_t n)
43 {
44 	int length, c;
45 	wchar_t intcode;
46 	char *olds = (char *)s;
47 	wchar_t mask;
48 
49 	if (s == (char *)0)
50 		return (0);
51 	if (n == 0)
52 		return (-1);
53 	c = (unsigned char)*s++;
54 	if (c < 0200) {
55 		if (wchar)
56 			*wchar = c;
57 		return (c ? 1 : 0);
58 	}
59 	intcode = 0;
60 	if (c == SS2) {
61 		if ((length = eucw2) == 0)
62 			goto lab1;
63 		mask = P01;
64 		goto lab2;
65 	} else if (c == SS3) {
66 		if ((length = eucw3) == 0)
67 			goto lab1;
68 		mask = P10;
69 		goto lab2;
70 	}
71 lab1:
72 	if (iscntrl(c)) {
73 		if (wchar)
74 			*wchar = c;
75 		return (1);
76 	}
77 	length = eucw1 - 1;
78 	mask = P11;
79 	intcode = c & 0177;
80 lab2:
81 	if (length + 1 > n || length < 0)
82 		return (-1);
83 	while (length--) {
84 		if ((c = (unsigned char)*s++) < 0200 || iscntrl(c))
85 			return (-1);
86 		intcode = (intcode << 7) | (c & 0x7F);
87 	}
88 	if (wchar)
89 		*wchar = intcode | mask;
90 	/*LINTED*/
91 	return ((int)(s - olds));
92 }
93