xref: /titanic_51/usr/src/lib/libbc/libc/gen/common/iso.multibyte.c (revision 5d54f3d8999eac1762fe0a8c7177d20f1f201fae)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 1988 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include "codeset.h"
317c478bd9Sstevel@tonic-gate #include "mbextern.h"
327c478bd9Sstevel@tonic-gate #include "iso2022.h"
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #define TO_MULTI	2
357c478bd9Sstevel@tonic-gate #define TO_SINGLE	1
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #define BIT7ENV		7	/* 7bit enviornment */
387c478bd9Sstevel@tonic-gate #define BIT8ENV		8	/* 8bit environment */
397c478bd9Sstevel@tonic-gate #define NUM_OF_STATES	4	/* G0, G1, G2, G3 */
407c478bd9Sstevel@tonic-gate #define BIT8(_ch)	(_ch & 0x80)
417c478bd9Sstevel@tonic-gate #define MAXSIZE		100	/* ESC LOCK upper lower */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #define USE_STATE	0	/* use the actual _state info */
447c478bd9Sstevel@tonic-gate #define USE_CONTROL	1	/* use C0 or C1 */
457c478bd9Sstevel@tonic-gate #define USE_SS2		2	/* use Single shift 2 */
467c478bd9Sstevel@tonic-gate #define USE_SS3		3	/* use Single shift 3 */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate #define G0MASK	0x0000
497c478bd9Sstevel@tonic-gate #define G1MASK	0x0080
507c478bd9Sstevel@tonic-gate #define G2MASK	0x8000
517c478bd9Sstevel@tonic-gate #define G3MASK	0x8080
527c478bd9Sstevel@tonic-gate #define FINAL	0x33		/* Temporary final character */
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #define MMB_CUR_MAX 128
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate /*
577c478bd9Sstevel@tonic-gate  * Keep state informations
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate struct state {
607c478bd9Sstevel@tonic-gate 	char width;	/* 1 or 2 */
617c478bd9Sstevel@tonic-gate 	char final;	/* final character */
627c478bd9Sstevel@tonic-gate };
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate static char _my_env = BIT7ENV;	/* default 7bits environment */
657c478bd9Sstevel@tonic-gate static struct state Invoked_G0, Invoked_G1;
667c478bd9Sstevel@tonic-gate static char _currentG0 = G0;
677c478bd9Sstevel@tonic-gate static char _currentG1 = G1;
687c478bd9Sstevel@tonic-gate static struct state _des_states[NUM_OF_STATES] = {
697c478bd9Sstevel@tonic-gate 	{-1, 0}, {-1, 0}, {-1, 0}, {01, 0}
707c478bd9Sstevel@tonic-gate };
717c478bd9Sstevel@tonic-gate 
72*5d54f3d8Smuffin void _savestates(void);	/* save states */
73*5d54f3d8Smuffin void _restorestates(void);	/* restore states */
74*5d54f3d8Smuffin void _initializestates(void);/* Initialize states */
75*5d54f3d8Smuffin 
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * Variables for wc*tomb*()
797c478bd9Sstevel@tonic-gate  */
807c478bd9Sstevel@tonic-gate static char _currentOUT = G0; /* G0, G1, G2 or G3 */
81*5d54f3d8Smuffin static int	prevcsize = 1;
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate /*
847c478bd9Sstevel@tonic-gate  * mbtowc - subroutine for most iso codeset sequences
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate int
87*5d54f3d8Smuffin _mbtowc_iso(wchar_t *pwc, char *s, size_t n)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate 	unsigned char ch;
907c478bd9Sstevel@tonic-gate 	unsigned char tch;	/* temporary use */
917c478bd9Sstevel@tonic-gate 	unsigned char *us = (unsigned char *)s;
927c478bd9Sstevel@tonic-gate 	int gen_wide_state = USE_STATE; /* used in gen_wide: */
937c478bd9Sstevel@tonic-gate 	int length = 0;
947c478bd9Sstevel@tonic-gate 	int len = 0;
957c478bd9Sstevel@tonic-gate 	wchar_t wide;
967c478bd9Sstevel@tonic-gate 	int mask;
977c478bd9Sstevel@tonic-gate 	int i;
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	/*
1027c478bd9Sstevel@tonic-gate 	 * initialize _g0_stuff
1037c478bd9Sstevel@tonic-gate 	 */
1047c478bd9Sstevel@tonic-gate 	if (_des_states[G0].width == -1) {
1057c478bd9Sstevel@tonic-gate 		_des_states[G0].width = isoinfo->g0_len;
1067c478bd9Sstevel@tonic-gate 		_des_states[G1].width = isoinfo->g1_len;
1077c478bd9Sstevel@tonic-gate 		_des_states[G2].width = isoinfo->g2_len;
1087c478bd9Sstevel@tonic-gate 		_des_states[G3].width = isoinfo->g3_len;
1097c478bd9Sstevel@tonic-gate 		_my_env = isoinfo->bit_env;
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 		Invoked_G0 = _des_states[G0];
1127c478bd9Sstevel@tonic-gate 		Invoked_G1 = _des_states[G1];
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	/*
1167c478bd9Sstevel@tonic-gate 	 * get character and proceed
1177c478bd9Sstevel@tonic-gate 	 */
1187c478bd9Sstevel@tonic-gate loop:
1197c478bd9Sstevel@tonic-gate 	ch = *us++;
1207c478bd9Sstevel@tonic-gate 	if (++length > n) return (-1);		/* too long */
1217c478bd9Sstevel@tonic-gate 	switch (ch) {	/* get a character */
1227c478bd9Sstevel@tonic-gate 	/* escape sequence or locking shifts */
1237c478bd9Sstevel@tonic-gate 	case ESC:	/* escape sequence */
1247c478bd9Sstevel@tonic-gate 		gen_wide_state = USE_STATE; /* used in gen_wide: */
1257c478bd9Sstevel@tonic-gate 		ch = *us++;
1267c478bd9Sstevel@tonic-gate 		if (++length > n) return (-1);	/* too long */
1277c478bd9Sstevel@tonic-gate 		switch (ch) {
1287c478bd9Sstevel@tonic-gate 		/* DESIGNATE */
1297c478bd9Sstevel@tonic-gate 		case 0x24:		/* designate */
1307c478bd9Sstevel@tonic-gate 			ch = *us++;
1317c478bd9Sstevel@tonic-gate 			if (++length > n) return (-1);	/* too long */
1327c478bd9Sstevel@tonic-gate 			switch (ch) {
1337c478bd9Sstevel@tonic-gate 			case 0x28:	case 0x29:
1347c478bd9Sstevel@tonic-gate 			case 0x2A:	case 0x2B:
1357c478bd9Sstevel@tonic-gate 			case 0x2D:	case 0x2E:
1367c478bd9Sstevel@tonic-gate 			case 0x2F:
1377c478bd9Sstevel@tonic-gate 				tch = ch;	/* save this to decide _des_state */
1387c478bd9Sstevel@tonic-gate 				/* Skip intermidiates */
1397c478bd9Sstevel@tonic-gate 				do {
1407c478bd9Sstevel@tonic-gate 					ch = *us++;
1417c478bd9Sstevel@tonic-gate 					if (++length > n) return (-1);	/* too long */
1427c478bd9Sstevel@tonic-gate 				} while (ch >= 0x20 && ch <= 0x2F);
1437c478bd9Sstevel@tonic-gate 				if (ch < 0x30)		/* ch should be a final character */
1447c478bd9Sstevel@tonic-gate 					return (-1);	/* error */
1457c478bd9Sstevel@tonic-gate 				if (tch == 0x28)
1467c478bd9Sstevel@tonic-gate 					i = G0;
1477c478bd9Sstevel@tonic-gate 				else if (tch == 0x29 || tch == 0x2D)
1487c478bd9Sstevel@tonic-gate 					i = G1;
1497c478bd9Sstevel@tonic-gate 				else if (tch == 0x2A || tch == 0x2E)
1507c478bd9Sstevel@tonic-gate 					i = G2;
1517c478bd9Sstevel@tonic-gate 				else /* (tch == 0x2B || tch == 0x2F) */
1527c478bd9Sstevel@tonic-gate 					i = G3;
1537c478bd9Sstevel@tonic-gate 				/* updates state info */
1547c478bd9Sstevel@tonic-gate 				_des_states[i].width = TO_MULTI;
1557c478bd9Sstevel@tonic-gate 				_des_states[i].final = ch;
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 				goto loop;
1587c478bd9Sstevel@tonic-gate 				break;
1597c478bd9Sstevel@tonic-gate 			default:
1607c478bd9Sstevel@tonic-gate 				/* This is an illegal sequence */
1617c478bd9Sstevel@tonic-gate 				return (-1);
1627c478bd9Sstevel@tonic-gate 				break;
1637c478bd9Sstevel@tonic-gate 			}
1647c478bd9Sstevel@tonic-gate 			break;
1657c478bd9Sstevel@tonic-gate 		case 0x28:		/* designate */
1667c478bd9Sstevel@tonic-gate 		case 0x29: case 0x2A: case 0x2B:
1677c478bd9Sstevel@tonic-gate 		case 0x2D: case 0x2E: case 0x2F:
1687c478bd9Sstevel@tonic-gate 			tch = ch;	/* save this to decide _des_state */
1697c478bd9Sstevel@tonic-gate 			/* Skip intermidiates */
1707c478bd9Sstevel@tonic-gate 			do {
1717c478bd9Sstevel@tonic-gate 				ch = *us++;
1727c478bd9Sstevel@tonic-gate 				if (++length > n) return (-1);	/* too long */
1737c478bd9Sstevel@tonic-gate 			} while (ch >= 0x20 && ch <= 0x2F);
1747c478bd9Sstevel@tonic-gate 			if (ch < 0x30)		/* ch should be a final character */
1757c478bd9Sstevel@tonic-gate 				return (-1);	/* error */
1767c478bd9Sstevel@tonic-gate 			if (tch == 0x28)
1777c478bd9Sstevel@tonic-gate 				i = G0;
1787c478bd9Sstevel@tonic-gate 			else if (tch == 0x29 || tch == 0x2D)
1797c478bd9Sstevel@tonic-gate 				i = G1;
1807c478bd9Sstevel@tonic-gate 			else if (tch == 0x2A || tch == 0x2E)
1817c478bd9Sstevel@tonic-gate 				i = G2;
1827c478bd9Sstevel@tonic-gate 			else /* (tch == 0x2B || tch == 0x2F) */
1837c478bd9Sstevel@tonic-gate 				i = G3;
1847c478bd9Sstevel@tonic-gate 			/* updates state info */
1857c478bd9Sstevel@tonic-gate 			_des_states[i].width = TO_SINGLE;
1867c478bd9Sstevel@tonic-gate 			_des_states[i].final = ch;
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 			goto loop;
1897c478bd9Sstevel@tonic-gate 			break;
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 		/* LOCKING SHIFTS */
1927c478bd9Sstevel@tonic-gate 		case LS1R:		/* locking shift LS1R */;
1937c478bd9Sstevel@tonic-gate 			Invoked_G1 = _des_states[G1];
1947c478bd9Sstevel@tonic-gate 			_currentG1 = G1;
1957c478bd9Sstevel@tonic-gate 			goto loop;
1967c478bd9Sstevel@tonic-gate 			break;
1977c478bd9Sstevel@tonic-gate 		case LS2:		/* locking shift LS2 */
1987c478bd9Sstevel@tonic-gate 			Invoked_G0 = _des_states[G2];
1997c478bd9Sstevel@tonic-gate 			_currentG0 = G2;
2007c478bd9Sstevel@tonic-gate 			goto loop;
2017c478bd9Sstevel@tonic-gate 			break;
2027c478bd9Sstevel@tonic-gate 		case LS2R:		/* locking shift LS2R */
2037c478bd9Sstevel@tonic-gate 			Invoked_G1 = _des_states[G2];
2047c478bd9Sstevel@tonic-gate 			_currentG1 = G2;
2057c478bd9Sstevel@tonic-gate 			goto loop;
2067c478bd9Sstevel@tonic-gate 			break;
2077c478bd9Sstevel@tonic-gate 		case LS3:		/* locking shift LS3 */
2087c478bd9Sstevel@tonic-gate 			Invoked_G0 = _des_states[G3];
2097c478bd9Sstevel@tonic-gate 			_currentG0 = G3;
2107c478bd9Sstevel@tonic-gate 			goto loop;
2117c478bd9Sstevel@tonic-gate 			break;
2127c478bd9Sstevel@tonic-gate 		case LS3R:		/* locking shift LS3R */
2137c478bd9Sstevel@tonic-gate 			Invoked_G1 = _des_states[G3];
2147c478bd9Sstevel@tonic-gate 			_currentG1 = G3;
2157c478bd9Sstevel@tonic-gate 			goto loop;
2167c478bd9Sstevel@tonic-gate 			break;
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 		/* CONTROL FUNCTIONS */
2197c478bd9Sstevel@tonic-gate 		case 0x21:		/* C0 sets */
2207c478bd9Sstevel@tonic-gate 		case 0x22:		/* C1 sets */
2217c478bd9Sstevel@tonic-gate 			do {
2227c478bd9Sstevel@tonic-gate 				ch = *us++;
2237c478bd9Sstevel@tonic-gate 				if (++length > n) return (-1);	/* too long */
2247c478bd9Sstevel@tonic-gate 			} while (ch >= 0x20 && ch <= 0x2F);
2257c478bd9Sstevel@tonic-gate 			if (ch < 0x30)		/* ch should be a final character */
2267c478bd9Sstevel@tonic-gate 				return (-1);	/* error */
2277c478bd9Sstevel@tonic-gate 			goto loop;
2287c478bd9Sstevel@tonic-gate 			break;
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 		/* SINGLE SHIFT for 7bit environment */
2317c478bd9Sstevel@tonic-gate 		case SS2_7B:		/* Single shift SS2 for 7bits */
2327c478bd9Sstevel@tonic-gate 		case SS3_7B:		/* Single shoft SS3 for 7bits */
2337c478bd9Sstevel@tonic-gate 			if (ch == SS2_7B)
2347c478bd9Sstevel@tonic-gate 				gen_wide_state = USE_SS2;
2357c478bd9Sstevel@tonic-gate 			else
2367c478bd9Sstevel@tonic-gate 				gen_wide_state = USE_SS3;
2377c478bd9Sstevel@tonic-gate 			goto loop;
2387c478bd9Sstevel@tonic-gate 			break;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 		default:		/* should be an error */
2417c478bd9Sstevel@tonic-gate 			return (-1);
2427c478bd9Sstevel@tonic-gate 			break;
2437c478bd9Sstevel@tonic-gate 		}
2447c478bd9Sstevel@tonic-gate 	/* locking shifts */
2457c478bd9Sstevel@tonic-gate 	case LS0:
2467c478bd9Sstevel@tonic-gate 		gen_wide_state = USE_STATE; /* used in gen_wide: */
2477c478bd9Sstevel@tonic-gate 		Invoked_G0 = _des_states[G0];
2487c478bd9Sstevel@tonic-gate 		_currentG0 = G0;
2497c478bd9Sstevel@tonic-gate 		goto loop;
2507c478bd9Sstevel@tonic-gate 		break;
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	case LS1:
2537c478bd9Sstevel@tonic-gate 		gen_wide_state = USE_STATE; /* used in gen_wide: */
2547c478bd9Sstevel@tonic-gate 		Invoked_G0 = _des_states[G1];
2557c478bd9Sstevel@tonic-gate 		_currentG0 = G1;
2567c478bd9Sstevel@tonic-gate 		goto loop;
2577c478bd9Sstevel@tonic-gate 		break;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	/* Single shift SS3 and SS2 for 8bits */
2607c478bd9Sstevel@tonic-gate 	case SS2_8B:
2617c478bd9Sstevel@tonic-gate 	case SS3_8B:
2627c478bd9Sstevel@tonic-gate 		if (ch == SS2_8B)
2637c478bd9Sstevel@tonic-gate 			gen_wide_state = USE_SS2;
2647c478bd9Sstevel@tonic-gate 		else
2657c478bd9Sstevel@tonic-gate 			gen_wide_state = USE_SS3;
2667c478bd9Sstevel@tonic-gate 		goto loop;
2677c478bd9Sstevel@tonic-gate 		break;
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	/* This character is not any special character/
2707c478bd9Sstevel@tonic-gate 	 * It does not change any state.
2717c478bd9Sstevel@tonic-gate 	 * Goto where it generates wide character.
2727c478bd9Sstevel@tonic-gate 	 */
2737c478bd9Sstevel@tonic-gate 	default:
2747c478bd9Sstevel@tonic-gate 		/*
2757c478bd9Sstevel@tonic-gate 		 * Use this ch to generate pwc.
2767c478bd9Sstevel@tonic-gate 		 */
2777c478bd9Sstevel@tonic-gate 		if (ch == 0) {	/* end of string or 0 */
2787c478bd9Sstevel@tonic-gate 			wide = 0;
2797c478bd9Sstevel@tonic-gate 			mask = 0;
2807c478bd9Sstevel@tonic-gate 			goto gen_wide;
2817c478bd9Sstevel@tonic-gate 		}
2827c478bd9Sstevel@tonic-gate 		break;
2837c478bd9Sstevel@tonic-gate 	}
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	/*
2877c478bd9Sstevel@tonic-gate 	 * Generate pwc here.
2887c478bd9Sstevel@tonic-gate 	 * The information here is
2897c478bd9Sstevel@tonic-gate 	 * 	current state and length. If the length is two, you need to
2907c478bd9Sstevel@tonic-gate 	 *      read one more character.
2917c478bd9Sstevel@tonic-gate 	 */
2927c478bd9Sstevel@tonic-gate 	switch (gen_wide_state) {
2937c478bd9Sstevel@tonic-gate 	case USE_STATE:
2947c478bd9Sstevel@tonic-gate 		if (BIT8(ch)) {	/* 8bit environment ? */
2957c478bd9Sstevel@tonic-gate 			/* current mode is G1 mode */
2967c478bd9Sstevel@tonic-gate 			if (Invoked_G1.width == 2) {
2977c478bd9Sstevel@tonic-gate 				tch = *us++;
2987c478bd9Sstevel@tonic-gate 				if (++length > n) return (-1);
2997c478bd9Sstevel@tonic-gate 				wide = ch;
3007c478bd9Sstevel@tonic-gate 				wide = (wide << 8 | tch);
3017c478bd9Sstevel@tonic-gate 			}
3027c478bd9Sstevel@tonic-gate 			else {
3037c478bd9Sstevel@tonic-gate 				wide = ch;
3047c478bd9Sstevel@tonic-gate 			}
3057c478bd9Sstevel@tonic-gate 			if (_currentG1 == G0)	mask = G0MASK;
3067c478bd9Sstevel@tonic-gate 			else if (_currentG1 == G1) mask = G1MASK;
3077c478bd9Sstevel@tonic-gate 			else if (_currentG1 == G2) mask = G2MASK;
3087c478bd9Sstevel@tonic-gate 			else mask = G3MASK;
3097c478bd9Sstevel@tonic-gate 		}
3107c478bd9Sstevel@tonic-gate 		else {
3117c478bd9Sstevel@tonic-gate 			/* current mode is G0 mode */
3127c478bd9Sstevel@tonic-gate 			if (Invoked_G0.width == 2) {
3137c478bd9Sstevel@tonic-gate 				tch = *us++;
3147c478bd9Sstevel@tonic-gate 				if (++length > n) return (-1);
3157c478bd9Sstevel@tonic-gate 				wide = ch;
3167c478bd9Sstevel@tonic-gate 				wide = (wide << 8 | tch);
3177c478bd9Sstevel@tonic-gate 			}
3187c478bd9Sstevel@tonic-gate 			else {
3197c478bd9Sstevel@tonic-gate 				wide = ch;
3207c478bd9Sstevel@tonic-gate 			}
3217c478bd9Sstevel@tonic-gate 			if (_currentG0 == G0)	mask = G0MASK;
3227c478bd9Sstevel@tonic-gate 			else if (_currentG0 == G1) mask = G1MASK;
3237c478bd9Sstevel@tonic-gate 			else if (_currentG0 == G2) mask = G2MASK;
3247c478bd9Sstevel@tonic-gate 			else mask = G3MASK;
3257c478bd9Sstevel@tonic-gate 		}
3267c478bd9Sstevel@tonic-gate 		break;
3277c478bd9Sstevel@tonic-gate 	case USE_SS2:
3287c478bd9Sstevel@tonic-gate 		if (_des_states[G2].width == 2) {
3297c478bd9Sstevel@tonic-gate 			tch = *us++;
3307c478bd9Sstevel@tonic-gate 			if (++length > n) return (-1);
3317c478bd9Sstevel@tonic-gate 			wide = ch;
3327c478bd9Sstevel@tonic-gate 			wide = (wide << 8 | tch);
3337c478bd9Sstevel@tonic-gate 		}
3347c478bd9Sstevel@tonic-gate 		else {
3357c478bd9Sstevel@tonic-gate 			wide = ch;
3367c478bd9Sstevel@tonic-gate 		}
3377c478bd9Sstevel@tonic-gate 		mask = G2MASK;
3387c478bd9Sstevel@tonic-gate 		break;
3397c478bd9Sstevel@tonic-gate 	case USE_SS3:
3407c478bd9Sstevel@tonic-gate 		if (_des_states[G3].width == 2) {
3417c478bd9Sstevel@tonic-gate 			tch = *us++;
3427c478bd9Sstevel@tonic-gate 			if (++length > n) return (-1);
3437c478bd9Sstevel@tonic-gate 			wide = ch;
3447c478bd9Sstevel@tonic-gate 			wide = (wide << 8 | tch);
3457c478bd9Sstevel@tonic-gate 		}
3467c478bd9Sstevel@tonic-gate 		else {
3477c478bd9Sstevel@tonic-gate 			wide = ch;
3487c478bd9Sstevel@tonic-gate 		}
3497c478bd9Sstevel@tonic-gate 		mask = G3MASK;
3507c478bd9Sstevel@tonic-gate 		break;
3517c478bd9Sstevel@tonic-gate 	default:
3527c478bd9Sstevel@tonic-gate 		/* shoult be internal error */
3537c478bd9Sstevel@tonic-gate 		return (-1);
3547c478bd9Sstevel@tonic-gate 		break;
3557c478bd9Sstevel@tonic-gate 	}
3567c478bd9Sstevel@tonic-gate gen_wide:
3577c478bd9Sstevel@tonic-gate 	wide &= 0x7F7F;			/* strip off the top bit */
3587c478bd9Sstevel@tonic-gate 	wide = wide | mask;
3597c478bd9Sstevel@tonic-gate 	if (pwc != NULL)
3607c478bd9Sstevel@tonic-gate 		*pwc = wide;
3617c478bd9Sstevel@tonic-gate 	return (length);
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate #define MAXMBSIZE	128
3667c478bd9Sstevel@tonic-gate /*
3677c478bd9Sstevel@tonic-gate  *  mbstowcs()
3687c478bd9Sstevel@tonic-gate  */
3697c478bd9Sstevel@tonic-gate size_t
370*5d54f3d8Smuffin _mbstowcs_iso(wchar_t *pwcs, unsigned char *s, size_t n)
3717c478bd9Sstevel@tonic-gate {
3727c478bd9Sstevel@tonic-gate 	int ret1;
3737c478bd9Sstevel@tonic-gate 	int accsum = 0;
3747c478bd9Sstevel@tonic-gate 	wchar_t pwc;
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	/*
3777c478bd9Sstevel@tonic-gate 	 * If pwcs == 0, do nothing.
3787c478bd9Sstevel@tonic-gate 	 */
3797c478bd9Sstevel@tonic-gate 	if (pwcs == 0)
3807c478bd9Sstevel@tonic-gate 		return (0);
3817c478bd9Sstevel@tonic-gate 	/*
3827c478bd9Sstevel@tonic-gate 	 * States things
3837c478bd9Sstevel@tonic-gate 	 */
3847c478bd9Sstevel@tonic-gate 	 _savestates(); _initializestates();
3857c478bd9Sstevel@tonic-gate 	 while (accsum < n) {
386*5d54f3d8Smuffin 		ret1 = _mbtowc_iso (&pwc, (char *)s, MAXMBSIZE);
3877c478bd9Sstevel@tonic-gate 		if (ret1 < 0)
3887c478bd9Sstevel@tonic-gate 			return (-1);	/* error */
3897c478bd9Sstevel@tonic-gate 		if (ret1 == 0 || pwc == 0) {
3907c478bd9Sstevel@tonic-gate 			if (pwcs == 0)
3917c478bd9Sstevel@tonic-gate 				*pwcs = 0;
3927c478bd9Sstevel@tonic-gate 			/*
3937c478bd9Sstevel@tonic-gate 			 * Restore states
3947c478bd9Sstevel@tonic-gate 			 */
3957c478bd9Sstevel@tonic-gate 			_restorestates();
3967c478bd9Sstevel@tonic-gate 			return (accsum);
3977c478bd9Sstevel@tonic-gate 		}
3987c478bd9Sstevel@tonic-gate 		s = s + ret1;		/* increment the pointer */
3997c478bd9Sstevel@tonic-gate 		*pwcs++ = pwc;
4007c478bd9Sstevel@tonic-gate 		++accsum;
4017c478bd9Sstevel@tonic-gate 	}
4027c478bd9Sstevel@tonic-gate 	/*
4037c478bd9Sstevel@tonic-gate 	 * Restore states
4047c478bd9Sstevel@tonic-gate 	 */
4057c478bd9Sstevel@tonic-gate 	_restorestates();
4067c478bd9Sstevel@tonic-gate 	return (accsum);
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate /*
4107c478bd9Sstevel@tonic-gate  * wctomb -
4117c478bd9Sstevel@tonic-gate  */
4127c478bd9Sstevel@tonic-gate int
413*5d54f3d8Smuffin _wctomb_iso(unsigned char *s, wchar_t pwc)
4147c478bd9Sstevel@tonic-gate {
4157c478bd9Sstevel@tonic-gate 	unsigned char ch;
4167c478bd9Sstevel@tonic-gate 	unsigned char tch;	/* temporary use */
4177c478bd9Sstevel@tonic-gate 	unsigned char *us = (unsigned char *)s;
4187c478bd9Sstevel@tonic-gate 	int gen_wide_state = USE_STATE; /* used in gen_wide: */
4197c478bd9Sstevel@tonic-gate 	int length = 0;
4207c478bd9Sstevel@tonic-gate 	int len = 0;
4217c478bd9Sstevel@tonic-gate 	wchar_t wide;
4227c478bd9Sstevel@tonic-gate 	unsigned short mode;
4237c478bd9Sstevel@tonic-gate 	unsigned char buf[MAXSIZE];
4247c478bd9Sstevel@tonic-gate 	unsigned char *bp;
4257c478bd9Sstevel@tonic-gate 	int csize, i;
4267c478bd9Sstevel@tonic-gate 	int n = MMB_CUR_MAX;
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	/*
4317c478bd9Sstevel@tonic-gate 	 * If pwc is 0, do this first.
4327c478bd9Sstevel@tonic-gate 	 */
4337c478bd9Sstevel@tonic-gate 	if (pwc  == 0) {
4347c478bd9Sstevel@tonic-gate 		if (s != 0) {
4357c478bd9Sstevel@tonic-gate 			*s = 0;
4367c478bd9Sstevel@tonic-gate 			return (1);
4377c478bd9Sstevel@tonic-gate 		}
4387c478bd9Sstevel@tonic-gate 		else {
4397c478bd9Sstevel@tonic-gate 			return (0);
4407c478bd9Sstevel@tonic-gate 		}
4417c478bd9Sstevel@tonic-gate 	}
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	mode = pwc & G3MASK;	/* The mode of this character */
4447c478bd9Sstevel@tonic-gate 	if (((pwc >> 8) & 0x007f) == 0)
4457c478bd9Sstevel@tonic-gate 		csize = 1;
4467c478bd9Sstevel@tonic-gate 	else
4477c478bd9Sstevel@tonic-gate 		csize = 2;
4487c478bd9Sstevel@tonic-gate 	bp = buf;
4497c478bd9Sstevel@tonic-gate 	length = 0;
4507c478bd9Sstevel@tonic-gate #ifdef DDDebug
4517c478bd9Sstevel@tonic-gate 	if (_my_env == BIT7ENV)
4527c478bd9Sstevel@tonic-gate 		printf ("7b ");
4537c478bd9Sstevel@tonic-gate 	else
4547c478bd9Sstevel@tonic-gate 		printf ("8b ");
4557c478bd9Sstevel@tonic-gate 	printf ("csize = %d, prevcsize = %d, (%x,%x) ",csize, prevcsize, (pwc>>8)&0x00ff, pwc&0x00ff);
4567c478bd9Sstevel@tonic-gate 	switch (mode) {
4577c478bd9Sstevel@tonic-gate 	case G0MASK:
4587c478bd9Sstevel@tonic-gate 		printf ("G0"); break;
4597c478bd9Sstevel@tonic-gate 	case G1MASK:
4607c478bd9Sstevel@tonic-gate 		printf ("G1"); break;
4617c478bd9Sstevel@tonic-gate 	case G2MASK:
4627c478bd9Sstevel@tonic-gate 		printf ("G2"); break;
4637c478bd9Sstevel@tonic-gate 	case G3MASK:
4647c478bd9Sstevel@tonic-gate 		printf ("G3"); break;
4657c478bd9Sstevel@tonic-gate 	default:
4667c478bd9Sstevel@tonic-gate 		printf ("XXXX"); break;
4677c478bd9Sstevel@tonic-gate 	}
4687c478bd9Sstevel@tonic-gate #endif
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	switch (_my_env) {
4717c478bd9Sstevel@tonic-gate 	case BIT7ENV:	/* 7 bit environment */
4727c478bd9Sstevel@tonic-gate 		switch (mode) {
4737c478bd9Sstevel@tonic-gate 		case G0MASK:
4747c478bd9Sstevel@tonic-gate 			if (_currentOUT != G0 || prevcsize != csize) {
4757c478bd9Sstevel@tonic-gate 				 _currentOUT = G0;
4767c478bd9Sstevel@tonic-gate 				if (csize == 2) {
4777c478bd9Sstevel@tonic-gate 					/*
4787c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
4797c478bd9Sstevel@tonic-gate 					 */
4807c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
4817c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
4827c478bd9Sstevel@tonic-gate 					 *bp++ = 0x28;
4837c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
4847c478bd9Sstevel@tonic-gate 					 length += 4;
4857c478bd9Sstevel@tonic-gate 				}
4867c478bd9Sstevel@tonic-gate 				else {
4877c478bd9Sstevel@tonic-gate 					/*
4887c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
4897c478bd9Sstevel@tonic-gate 					 */
4907c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
4917c478bd9Sstevel@tonic-gate 					 *bp++ = 0x28;
4927c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
4937c478bd9Sstevel@tonic-gate 					 length += 3;
4947c478bd9Sstevel@tonic-gate 				}
4957c478bd9Sstevel@tonic-gate 				*bp++ = SI;
4967c478bd9Sstevel@tonic-gate 				++length;
4977c478bd9Sstevel@tonic-gate 			}
4987c478bd9Sstevel@tonic-gate 			if (csize == 1) {
4997c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5007c478bd9Sstevel@tonic-gate 				++length;
5017c478bd9Sstevel@tonic-gate 			}
5027c478bd9Sstevel@tonic-gate 			else {
5037c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
5047c478bd9Sstevel@tonic-gate 				++length;
5057c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5067c478bd9Sstevel@tonic-gate 				++length;
5077c478bd9Sstevel@tonic-gate 			}
5087c478bd9Sstevel@tonic-gate 			break;
5097c478bd9Sstevel@tonic-gate 		case G1MASK:
5107c478bd9Sstevel@tonic-gate 			if (_currentOUT != G1 || prevcsize != csize) {
5117c478bd9Sstevel@tonic-gate 				 _currentOUT = G1;
5127c478bd9Sstevel@tonic-gate 				if (csize == 2) {
5137c478bd9Sstevel@tonic-gate 					/*
5147c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
5157c478bd9Sstevel@tonic-gate 					 */
5167c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
5177c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
5187c478bd9Sstevel@tonic-gate 					 *bp++ = 0x29;
5197c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
5207c478bd9Sstevel@tonic-gate 					 length += 4;
5217c478bd9Sstevel@tonic-gate 				}
5227c478bd9Sstevel@tonic-gate 				else {
5237c478bd9Sstevel@tonic-gate 					/*
5247c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
5257c478bd9Sstevel@tonic-gate 					 */
5267c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
5277c478bd9Sstevel@tonic-gate 					 *bp++ = 0x29;
5287c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
5297c478bd9Sstevel@tonic-gate 					 length += 3;
5307c478bd9Sstevel@tonic-gate 				}
5317c478bd9Sstevel@tonic-gate 				*bp++ = SO;
5327c478bd9Sstevel@tonic-gate 				++length;
5337c478bd9Sstevel@tonic-gate 			}
5347c478bd9Sstevel@tonic-gate 			if (csize == 1) {
5357c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5367c478bd9Sstevel@tonic-gate 				++length;
5377c478bd9Sstevel@tonic-gate 			}
5387c478bd9Sstevel@tonic-gate 			else {
5397c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
5407c478bd9Sstevel@tonic-gate 				++length;
5417c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5427c478bd9Sstevel@tonic-gate 				++length;
5437c478bd9Sstevel@tonic-gate 			}
5447c478bd9Sstevel@tonic-gate 			break;
5457c478bd9Sstevel@tonic-gate 		case G2MASK:
5467c478bd9Sstevel@tonic-gate 			if (_currentOUT != G2 || prevcsize != csize) {
5477c478bd9Sstevel@tonic-gate 				 _currentOUT = G2;
5487c478bd9Sstevel@tonic-gate 				if (csize == 2) {
5497c478bd9Sstevel@tonic-gate 					/*
5507c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
5517c478bd9Sstevel@tonic-gate 					 */
5527c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
5537c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
5547c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2A;
5557c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
5567c478bd9Sstevel@tonic-gate 					 length += 4;
5577c478bd9Sstevel@tonic-gate 				}
5587c478bd9Sstevel@tonic-gate 				else {
5597c478bd9Sstevel@tonic-gate 					/*
5607c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
5617c478bd9Sstevel@tonic-gate 					 */
5627c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
5637c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2A;
5647c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
5657c478bd9Sstevel@tonic-gate 					 length += 3;
5667c478bd9Sstevel@tonic-gate 				}
5677c478bd9Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS2;
5687c478bd9Sstevel@tonic-gate 				length += 2;
5697c478bd9Sstevel@tonic-gate 			}
5707c478bd9Sstevel@tonic-gate 			if (csize == 1) {
5717c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5727c478bd9Sstevel@tonic-gate 				++length;
5737c478bd9Sstevel@tonic-gate 			}
5747c478bd9Sstevel@tonic-gate 			else {
5757c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
5767c478bd9Sstevel@tonic-gate 				++length;
5777c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5787c478bd9Sstevel@tonic-gate 				++length;
5797c478bd9Sstevel@tonic-gate 			}
5807c478bd9Sstevel@tonic-gate 			break;
5817c478bd9Sstevel@tonic-gate 		case G3MASK:
5827c478bd9Sstevel@tonic-gate 			if (_currentOUT != G3 || prevcsize != csize) {
5837c478bd9Sstevel@tonic-gate 				 _currentOUT = G3;
5847c478bd9Sstevel@tonic-gate 				if (csize == 2) {
5857c478bd9Sstevel@tonic-gate 					/*
5867c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
5877c478bd9Sstevel@tonic-gate 					 */
5887c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
5897c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
5907c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2B;
5917c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
5927c478bd9Sstevel@tonic-gate 					 length += 4;
5937c478bd9Sstevel@tonic-gate 				}
5947c478bd9Sstevel@tonic-gate 				else {
5957c478bd9Sstevel@tonic-gate 					/*
5967c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
5977c478bd9Sstevel@tonic-gate 					 */
5987c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
5997c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2B;
6007c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
6017c478bd9Sstevel@tonic-gate 					 length += 3;
6027c478bd9Sstevel@tonic-gate 				}
6037c478bd9Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS3;
6047c478bd9Sstevel@tonic-gate 				length += 2;
6057c478bd9Sstevel@tonic-gate 			}
6067c478bd9Sstevel@tonic-gate 			if (csize == 1) {
6077c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6087c478bd9Sstevel@tonic-gate 				++length;
6097c478bd9Sstevel@tonic-gate 			}
6107c478bd9Sstevel@tonic-gate 			else {
6117c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
6127c478bd9Sstevel@tonic-gate 				++length;
6137c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6147c478bd9Sstevel@tonic-gate 				++length;
6157c478bd9Sstevel@tonic-gate 			}
6167c478bd9Sstevel@tonic-gate 			break;
6177c478bd9Sstevel@tonic-gate 		}
6187c478bd9Sstevel@tonic-gate 		break;
6197c478bd9Sstevel@tonic-gate 	case BIT8ENV:	/* 8 bit environment */
6207c478bd9Sstevel@tonic-gate 		switch (mode) {
6217c478bd9Sstevel@tonic-gate 		case G0MASK:
6227c478bd9Sstevel@tonic-gate 			if (_currentOUT != G0 || prevcsize != csize) {
6237c478bd9Sstevel@tonic-gate 				_currentOUT = G0;
6247c478bd9Sstevel@tonic-gate 				if (csize == 2) {
6257c478bd9Sstevel@tonic-gate 					/*
6267c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
6277c478bd9Sstevel@tonic-gate 					 */
6287c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
6297c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
6307c478bd9Sstevel@tonic-gate 					 *bp++ = 0x28;
6317c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
6327c478bd9Sstevel@tonic-gate 					 length += 4;
6337c478bd9Sstevel@tonic-gate 				}
6347c478bd9Sstevel@tonic-gate 				else {
6357c478bd9Sstevel@tonic-gate 					/*
6367c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
6377c478bd9Sstevel@tonic-gate 					 */
6387c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
6397c478bd9Sstevel@tonic-gate 					 *bp++ = 0x28;
6407c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
6417c478bd9Sstevel@tonic-gate 					 length += 3;
6427c478bd9Sstevel@tonic-gate 				}
6437c478bd9Sstevel@tonic-gate 				*bp++ = LS0;
6447c478bd9Sstevel@tonic-gate 				++length;
6457c478bd9Sstevel@tonic-gate 			}
6467c478bd9Sstevel@tonic-gate 			if (csize == 1) {
6477c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6487c478bd9Sstevel@tonic-gate 				++length;
6497c478bd9Sstevel@tonic-gate 			}
6507c478bd9Sstevel@tonic-gate 			else {
6517c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
6527c478bd9Sstevel@tonic-gate 				++length;
6537c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6547c478bd9Sstevel@tonic-gate 				++length;
6557c478bd9Sstevel@tonic-gate 			}
6567c478bd9Sstevel@tonic-gate 			break;
6577c478bd9Sstevel@tonic-gate 		case G1MASK:
6587c478bd9Sstevel@tonic-gate 			if (_currentOUT != G1 || prevcsize != csize) {
6597c478bd9Sstevel@tonic-gate 				_currentOUT = G1;
6607c478bd9Sstevel@tonic-gate 				if (csize == 2) {
6617c478bd9Sstevel@tonic-gate 					/*
6627c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
6637c478bd9Sstevel@tonic-gate 					 */
6647c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
6657c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
6667c478bd9Sstevel@tonic-gate 					 *bp++ = 0x29;
6677c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
6687c478bd9Sstevel@tonic-gate 					 length += 4;
6697c478bd9Sstevel@tonic-gate 				}
6707c478bd9Sstevel@tonic-gate 				else {
6717c478bd9Sstevel@tonic-gate 					/*
6727c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
6737c478bd9Sstevel@tonic-gate 					 */
6747c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
6757c478bd9Sstevel@tonic-gate 					 *bp++ = 0x29;
6767c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
6777c478bd9Sstevel@tonic-gate 					 length += 3;
6787c478bd9Sstevel@tonic-gate 				}
6797c478bd9Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS1R;
6807c478bd9Sstevel@tonic-gate 				length += 2;
6817c478bd9Sstevel@tonic-gate 			}
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 			/*
6847c478bd9Sstevel@tonic-gate 			 * If state is G1 or G2, or G3, assume that
6857c478bd9Sstevel@tonic-gate 			 * this is 8bit characters. To do this more
6867c478bd9Sstevel@tonic-gate 			 * accurately, wide character needs to be
6877c478bd9Sstevel@tonic-gate 			 * larger than 16 bits to keep more information.
6887c478bd9Sstevel@tonic-gate 			 */
6897c478bd9Sstevel@tonic-gate 			pwc |= 0x8080;
6907c478bd9Sstevel@tonic-gate 			if (csize == 1) {
6917c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
6927c478bd9Sstevel@tonic-gate 				++length;
6937c478bd9Sstevel@tonic-gate 			}
6947c478bd9Sstevel@tonic-gate 			else {
6957c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0xff00) >> 8;
6967c478bd9Sstevel@tonic-gate 				++length;
6977c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
6987c478bd9Sstevel@tonic-gate 				++length;
6997c478bd9Sstevel@tonic-gate 			}
7007c478bd9Sstevel@tonic-gate 			break;
7017c478bd9Sstevel@tonic-gate 		case G2MASK:
7027c478bd9Sstevel@tonic-gate 			if (_currentOUT != G2 || prevcsize != csize) {
7037c478bd9Sstevel@tonic-gate 				_currentOUT = G2;
7047c478bd9Sstevel@tonic-gate 				if (csize == 2) {
7057c478bd9Sstevel@tonic-gate 					/*
7067c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
7077c478bd9Sstevel@tonic-gate 					 */
7087c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
7097c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
7107c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2A;
7117c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
7127c478bd9Sstevel@tonic-gate 					 length += 4;
7137c478bd9Sstevel@tonic-gate 				}
7147c478bd9Sstevel@tonic-gate 				else {
7157c478bd9Sstevel@tonic-gate 					/*
7167c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
7177c478bd9Sstevel@tonic-gate 					 */
7187c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
7197c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2A;
7207c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
7217c478bd9Sstevel@tonic-gate 					 length += 3;
7227c478bd9Sstevel@tonic-gate 				}
7237c478bd9Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS2R;
7247c478bd9Sstevel@tonic-gate 				length += 2;
7257c478bd9Sstevel@tonic-gate 			}
7267c478bd9Sstevel@tonic-gate 			/*
7277c478bd9Sstevel@tonic-gate 			 * If state is G1 or G2, or G3, assume that
7287c478bd9Sstevel@tonic-gate 			 * this is 8bit characters. To do this more
7297c478bd9Sstevel@tonic-gate 			 * accurately, wide character needs to be
7307c478bd9Sstevel@tonic-gate 			 * larger than 16 bits to keep more information.
7317c478bd9Sstevel@tonic-gate 			 */
7327c478bd9Sstevel@tonic-gate 			pwc |= 0x8080;
7337c478bd9Sstevel@tonic-gate 			if (csize == 1) {
7347c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7357c478bd9Sstevel@tonic-gate 				++length;
7367c478bd9Sstevel@tonic-gate 			}
7377c478bd9Sstevel@tonic-gate 			else {
7387c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0xff00) >> 8;
7397c478bd9Sstevel@tonic-gate 				++length;
7407c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7417c478bd9Sstevel@tonic-gate 				++length;
7427c478bd9Sstevel@tonic-gate 			}
7437c478bd9Sstevel@tonic-gate 			break;
7447c478bd9Sstevel@tonic-gate 		case G3MASK:
7457c478bd9Sstevel@tonic-gate 			if (_currentOUT != G3 || prevcsize != csize) {
7467c478bd9Sstevel@tonic-gate 				_currentOUT = G3;
7477c478bd9Sstevel@tonic-gate 				if (csize == 2) {
7487c478bd9Sstevel@tonic-gate 					/*
7497c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
7507c478bd9Sstevel@tonic-gate 					 */
7517c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
7527c478bd9Sstevel@tonic-gate 					 *bp++ = 0x24;
7537c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2B;
7547c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
7557c478bd9Sstevel@tonic-gate 					 length += 4;
7567c478bd9Sstevel@tonic-gate 				}
7577c478bd9Sstevel@tonic-gate 				else {
7587c478bd9Sstevel@tonic-gate 					/*
7597c478bd9Sstevel@tonic-gate 					 * Emit escape sequences
7607c478bd9Sstevel@tonic-gate 					 */
7617c478bd9Sstevel@tonic-gate 					 *bp++ = ESC;
7627c478bd9Sstevel@tonic-gate 					 *bp++ = 0x2B;
7637c478bd9Sstevel@tonic-gate 					 *bp++ = FINAL;
7647c478bd9Sstevel@tonic-gate 					 length += 3;
7657c478bd9Sstevel@tonic-gate 				}
7667c478bd9Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS3R;
7677c478bd9Sstevel@tonic-gate 				length += 2;
7687c478bd9Sstevel@tonic-gate 			}
7697c478bd9Sstevel@tonic-gate 			/*
7707c478bd9Sstevel@tonic-gate 			 * If state is G1 or G2, or G3, assume that
7717c478bd9Sstevel@tonic-gate 			 * this is 8bit characters. To do this more
7727c478bd9Sstevel@tonic-gate 			 * accurately, wide character needs to be
7737c478bd9Sstevel@tonic-gate 			 * larger than 16 bits to keep more information.
7747c478bd9Sstevel@tonic-gate 			 */
7757c478bd9Sstevel@tonic-gate 			pwc |= 0x8080;
7767c478bd9Sstevel@tonic-gate 			if (csize == 1) {
7777c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7787c478bd9Sstevel@tonic-gate 				++length;
7797c478bd9Sstevel@tonic-gate 			}
7807c478bd9Sstevel@tonic-gate 			else {
7817c478bd9Sstevel@tonic-gate 				*bp++ = (pwc & 0xff00) >> 8;
7827c478bd9Sstevel@tonic-gate 				++length;
7837c478bd9Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7847c478bd9Sstevel@tonic-gate 				++length;
7857c478bd9Sstevel@tonic-gate 			}
7867c478bd9Sstevel@tonic-gate 			break;
7877c478bd9Sstevel@tonic-gate 		}
7887c478bd9Sstevel@tonic-gate 		break;
7897c478bd9Sstevel@tonic-gate 	default:	/* Should never happens */
7907c478bd9Sstevel@tonic-gate 		return (-1);
7917c478bd9Sstevel@tonic-gate 		break;
7927c478bd9Sstevel@tonic-gate 	}
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate 	prevcsize = csize;
7957c478bd9Sstevel@tonic-gate 
7967c478bd9Sstevel@tonic-gate 	if (length > n) {
7977c478bd9Sstevel@tonic-gate 		return (-1);	/* buffer too small */
7987c478bd9Sstevel@tonic-gate 	}
7997c478bd9Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
8007c478bd9Sstevel@tonic-gate 		*s++ = buf[i];
8017c478bd9Sstevel@tonic-gate 	}
8027c478bd9Sstevel@tonic-gate #ifdef DDDebug
8037c478bd9Sstevel@tonic-gate 	printf ("\t(");
8047c478bd9Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
8057c478bd9Sstevel@tonic-gate 		printf ("%x,", buf[i]);
8067c478bd9Sstevel@tonic-gate 	}
8077c478bd9Sstevel@tonic-gate 	printf (")\n");
8087c478bd9Sstevel@tonic-gate #endif
8097c478bd9Sstevel@tonic-gate 	return (length);
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate /*
8137c478bd9Sstevel@tonic-gate  * wcstombs
8147c478bd9Sstevel@tonic-gate  */
8157c478bd9Sstevel@tonic-gate size_t
816*5d54f3d8Smuffin _wcstombs_iso(char *s, wchar_t *pwcs, int n)
8177c478bd9Sstevel@tonic-gate {
8187c478bd9Sstevel@tonic-gate 	int acclen = 0;
8197c478bd9Sstevel@tonic-gate 	char buf[MMB_CUR_MAX];
8207c478bd9Sstevel@tonic-gate 	int ret1;
8217c478bd9Sstevel@tonic-gate 	int i;
8227c478bd9Sstevel@tonic-gate 
8237c478bd9Sstevel@tonic-gate 	if (n < 0)
8247c478bd9Sstevel@tonic-gate 		return (-1);
8257c478bd9Sstevel@tonic-gate 	/*
8267c478bd9Sstevel@tonic-gate 	 * Initialize State
8277c478bd9Sstevel@tonic-gate 	 */
8287c478bd9Sstevel@tonic-gate 	 _savestates(); _initializestates();
8297c478bd9Sstevel@tonic-gate 	 while (acclen < n) {
830*5d54f3d8Smuffin 		ret1 = _wctomb_iso ((unsigned char *)buf, *pwcs);
8317c478bd9Sstevel@tonic-gate 		/*
8327c478bd9Sstevel@tonic-gate 		 * end of string ?
8337c478bd9Sstevel@tonic-gate 		 */
8347c478bd9Sstevel@tonic-gate 		if (ret1 == 1 && buf[0] == 0) {
8357c478bd9Sstevel@tonic-gate 			*s = 0;
8367c478bd9Sstevel@tonic-gate 			/*
8377c478bd9Sstevel@tonic-gate 			 * restore states
8387c478bd9Sstevel@tonic-gate 			 */
8397c478bd9Sstevel@tonic-gate 			_restorestates();
8407c478bd9Sstevel@tonic-gate 			return (acclen);
8417c478bd9Sstevel@tonic-gate 		}
8427c478bd9Sstevel@tonic-gate 		/*
8437c478bd9Sstevel@tonic-gate 		 * Error ?
8447c478bd9Sstevel@tonic-gate 		 */
8457c478bd9Sstevel@tonic-gate 		if (ret1 < 0)
8467c478bd9Sstevel@tonic-gate 			return (-1);
8477c478bd9Sstevel@tonic-gate 		acclen += ret1;
8487c478bd9Sstevel@tonic-gate 		for (i = 0; i < ret1; i++)
8497c478bd9Sstevel@tonic-gate 			*s++ = buf[i];
8507c478bd9Sstevel@tonic-gate 		++pwcs;
8517c478bd9Sstevel@tonic-gate 	 }
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 	/*
8547c478bd9Sstevel@tonic-gate 	 * restore states
8557c478bd9Sstevel@tonic-gate 	 */
8567c478bd9Sstevel@tonic-gate 	_restorestates();
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	 /*
8597c478bd9Sstevel@tonic-gate 	  * return the length
8607c478bd9Sstevel@tonic-gate 	  */
8617c478bd9Sstevel@tonic-gate 	 return (acclen);
8627c478bd9Sstevel@tonic-gate }
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate /*
8667c478bd9Sstevel@tonic-gate  * Supplementary routines
8677c478bd9Sstevel@tonic-gate  */
8687c478bd9Sstevel@tonic-gate 
869*5d54f3d8Smuffin void
870*5d54f3d8Smuffin _initializestates(void)
8717c478bd9Sstevel@tonic-gate {
8727c478bd9Sstevel@tonic-gate 	_currentG0 = G0;
8737c478bd9Sstevel@tonic-gate 	_currentG1 = G1;
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate 	_des_states[G0].width = -1;	/* This makes it Initialize */
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	_currentOUT = G0;
8787c478bd9Sstevel@tonic-gate 	prevcsize = 1;
8797c478bd9Sstevel@tonic-gate }
8807c478bd9Sstevel@tonic-gate 
8817c478bd9Sstevel@tonic-gate static char SAVED_currentG0;
8827c478bd9Sstevel@tonic-gate static char SAVED_currentG1;
8837c478bd9Sstevel@tonic-gate static struct state SAVED_des_states[NUM_OF_STATES];
8847c478bd9Sstevel@tonic-gate static struct state SAVED_Invoked_G0, SAVED_Invoked_G1;
8857c478bd9Sstevel@tonic-gate static char SAVED_currentOUT = G0; /* G0, G1, G2 or G3 */
886*5d54f3d8Smuffin static int	SAVED_prevcsize = 1;
8877c478bd9Sstevel@tonic-gate 
888*5d54f3d8Smuffin void
889*5d54f3d8Smuffin _savestates(void)
8907c478bd9Sstevel@tonic-gate {
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate 	SAVED_currentG0 = _currentG0;
8937c478bd9Sstevel@tonic-gate 	SAVED_currentG1 = _currentG1;
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate 	SAVED_des_states[G0] = _des_states[G0];
8967c478bd9Sstevel@tonic-gate 	SAVED_des_states[G1] = _des_states[G1];
8977c478bd9Sstevel@tonic-gate 	SAVED_des_states[G2] = _des_states[G2];
8987c478bd9Sstevel@tonic-gate 	SAVED_des_states[G3] = _des_states[G3];
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 	SAVED_Invoked_G0 = Invoked_G0;
9017c478bd9Sstevel@tonic-gate 	SAVED_Invoked_G1 = Invoked_G1;
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate 	SAVED_currentOUT = _currentOUT;
9047c478bd9Sstevel@tonic-gate 	SAVED_prevcsize = prevcsize;
9057c478bd9Sstevel@tonic-gate }
9067c478bd9Sstevel@tonic-gate 
907*5d54f3d8Smuffin void
908*5d54f3d8Smuffin _restorestates(void)
9097c478bd9Sstevel@tonic-gate {
9107c478bd9Sstevel@tonic-gate 	_currentG0 = SAVED_currentG0;
9117c478bd9Sstevel@tonic-gate 	_currentG1 = SAVED_currentG1;
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	_des_states[G0] = SAVED_des_states[G0];
9147c478bd9Sstevel@tonic-gate 	_des_states[G1] = SAVED_des_states[G1];
9157c478bd9Sstevel@tonic-gate 	_des_states[G2] = SAVED_des_states[G2];
9167c478bd9Sstevel@tonic-gate 	_des_states[G3] = SAVED_des_states[G3];
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 	Invoked_G0 = SAVED_Invoked_G0;
9197c478bd9Sstevel@tonic-gate 	Invoked_G1 = SAVED_Invoked_G1;
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 	_currentOUT = SAVED_currentOUT;
9227c478bd9Sstevel@tonic-gate 	prevcsize = SAVED_prevcsize;
9237c478bd9Sstevel@tonic-gate }
924