xref: /onnv-gate/usr/src/lib/libbc/libc/gen/common/iso.multibyte.c (revision 722:636b850d4ee9)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 1988 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include "codeset.h"
310Sstevel@tonic-gate #include "mbextern.h"
320Sstevel@tonic-gate #include "iso2022.h"
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #define TO_MULTI	2
350Sstevel@tonic-gate #define TO_SINGLE	1
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #define BIT7ENV		7	/* 7bit enviornment */
380Sstevel@tonic-gate #define BIT8ENV		8	/* 8bit environment */
390Sstevel@tonic-gate #define NUM_OF_STATES	4	/* G0, G1, G2, G3 */
400Sstevel@tonic-gate #define BIT8(_ch)	(_ch & 0x80)
410Sstevel@tonic-gate #define MAXSIZE		100	/* ESC LOCK upper lower */
420Sstevel@tonic-gate 
430Sstevel@tonic-gate #define USE_STATE	0	/* use the actual _state info */
440Sstevel@tonic-gate #define USE_CONTROL	1	/* use C0 or C1 */
450Sstevel@tonic-gate #define USE_SS2		2	/* use Single shift 2 */
460Sstevel@tonic-gate #define USE_SS3		3	/* use Single shift 3 */
470Sstevel@tonic-gate 
480Sstevel@tonic-gate #define G0MASK	0x0000
490Sstevel@tonic-gate #define G1MASK	0x0080
500Sstevel@tonic-gate #define G2MASK	0x8000
510Sstevel@tonic-gate #define G3MASK	0x8080
520Sstevel@tonic-gate #define FINAL	0x33		/* Temporary final character */
530Sstevel@tonic-gate 
540Sstevel@tonic-gate #define MMB_CUR_MAX 128
550Sstevel@tonic-gate 
560Sstevel@tonic-gate /*
570Sstevel@tonic-gate  * Keep state informations
580Sstevel@tonic-gate  */
590Sstevel@tonic-gate struct state {
600Sstevel@tonic-gate 	char width;	/* 1 or 2 */
610Sstevel@tonic-gate 	char final;	/* final character */
620Sstevel@tonic-gate };
630Sstevel@tonic-gate 
640Sstevel@tonic-gate static char _my_env = BIT7ENV;	/* default 7bits environment */
650Sstevel@tonic-gate static struct state Invoked_G0, Invoked_G1;
660Sstevel@tonic-gate static char _currentG0 = G0;
670Sstevel@tonic-gate static char _currentG1 = G1;
680Sstevel@tonic-gate static struct state _des_states[NUM_OF_STATES] = {
690Sstevel@tonic-gate 	{-1, 0}, {-1, 0}, {-1, 0}, {01, 0}
700Sstevel@tonic-gate };
710Sstevel@tonic-gate 
72*722Smuffin void _savestates(void);	/* save states */
73*722Smuffin void _restorestates(void);	/* restore states */
74*722Smuffin void _initializestates(void);/* Initialize states */
75*722Smuffin 
760Sstevel@tonic-gate 
770Sstevel@tonic-gate /*
780Sstevel@tonic-gate  * Variables for wc*tomb*()
790Sstevel@tonic-gate  */
800Sstevel@tonic-gate static char _currentOUT = G0; /* G0, G1, G2 or G3 */
81*722Smuffin static int	prevcsize = 1;
820Sstevel@tonic-gate 
830Sstevel@tonic-gate /*
840Sstevel@tonic-gate  * mbtowc - subroutine for most iso codeset sequences
850Sstevel@tonic-gate  */
860Sstevel@tonic-gate int
_mbtowc_iso(wchar_t * pwc,char * s,size_t n)87*722Smuffin _mbtowc_iso(wchar_t *pwc, char *s, size_t n)
880Sstevel@tonic-gate {
890Sstevel@tonic-gate 	unsigned char ch;
900Sstevel@tonic-gate 	unsigned char tch;	/* temporary use */
910Sstevel@tonic-gate 	unsigned char *us = (unsigned char *)s;
920Sstevel@tonic-gate 	int gen_wide_state = USE_STATE; /* used in gen_wide: */
930Sstevel@tonic-gate 	int length = 0;
940Sstevel@tonic-gate 	int len = 0;
950Sstevel@tonic-gate 	wchar_t wide;
960Sstevel@tonic-gate 	int mask;
970Sstevel@tonic-gate 	int i;
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 	isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info;
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	/*
1020Sstevel@tonic-gate 	 * initialize _g0_stuff
1030Sstevel@tonic-gate 	 */
1040Sstevel@tonic-gate 	if (_des_states[G0].width == -1) {
1050Sstevel@tonic-gate 		_des_states[G0].width = isoinfo->g0_len;
1060Sstevel@tonic-gate 		_des_states[G1].width = isoinfo->g1_len;
1070Sstevel@tonic-gate 		_des_states[G2].width = isoinfo->g2_len;
1080Sstevel@tonic-gate 		_des_states[G3].width = isoinfo->g3_len;
1090Sstevel@tonic-gate 		_my_env = isoinfo->bit_env;
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate 		Invoked_G0 = _des_states[G0];
1120Sstevel@tonic-gate 		Invoked_G1 = _des_states[G1];
1130Sstevel@tonic-gate 	}
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	/*
1160Sstevel@tonic-gate 	 * get character and proceed
1170Sstevel@tonic-gate 	 */
1180Sstevel@tonic-gate loop:
1190Sstevel@tonic-gate 	ch = *us++;
1200Sstevel@tonic-gate 	if (++length > n) return (-1);		/* too long */
1210Sstevel@tonic-gate 	switch (ch) {	/* get a character */
1220Sstevel@tonic-gate 	/* escape sequence or locking shifts */
1230Sstevel@tonic-gate 	case ESC:	/* escape sequence */
1240Sstevel@tonic-gate 		gen_wide_state = USE_STATE; /* used in gen_wide: */
1250Sstevel@tonic-gate 		ch = *us++;
1260Sstevel@tonic-gate 		if (++length > n) return (-1);	/* too long */
1270Sstevel@tonic-gate 		switch (ch) {
1280Sstevel@tonic-gate 		/* DESIGNATE */
1290Sstevel@tonic-gate 		case 0x24:		/* designate */
1300Sstevel@tonic-gate 			ch = *us++;
1310Sstevel@tonic-gate 			if (++length > n) return (-1);	/* too long */
1320Sstevel@tonic-gate 			switch (ch) {
1330Sstevel@tonic-gate 			case 0x28:	case 0x29:
1340Sstevel@tonic-gate 			case 0x2A:	case 0x2B:
1350Sstevel@tonic-gate 			case 0x2D:	case 0x2E:
1360Sstevel@tonic-gate 			case 0x2F:
1370Sstevel@tonic-gate 				tch = ch;	/* save this to decide _des_state */
1380Sstevel@tonic-gate 				/* Skip intermidiates */
1390Sstevel@tonic-gate 				do {
1400Sstevel@tonic-gate 					ch = *us++;
1410Sstevel@tonic-gate 					if (++length > n) return (-1);	/* too long */
1420Sstevel@tonic-gate 				} while (ch >= 0x20 && ch <= 0x2F);
1430Sstevel@tonic-gate 				if (ch < 0x30)		/* ch should be a final character */
1440Sstevel@tonic-gate 					return (-1);	/* error */
1450Sstevel@tonic-gate 				if (tch == 0x28)
1460Sstevel@tonic-gate 					i = G0;
1470Sstevel@tonic-gate 				else if (tch == 0x29 || tch == 0x2D)
1480Sstevel@tonic-gate 					i = G1;
1490Sstevel@tonic-gate 				else if (tch == 0x2A || tch == 0x2E)
1500Sstevel@tonic-gate 					i = G2;
1510Sstevel@tonic-gate 				else /* (tch == 0x2B || tch == 0x2F) */
1520Sstevel@tonic-gate 					i = G3;
1530Sstevel@tonic-gate 				/* updates state info */
1540Sstevel@tonic-gate 				_des_states[i].width = TO_MULTI;
1550Sstevel@tonic-gate 				_des_states[i].final = ch;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 				goto loop;
1580Sstevel@tonic-gate 				break;
1590Sstevel@tonic-gate 			default:
1600Sstevel@tonic-gate 				/* This is an illegal sequence */
1610Sstevel@tonic-gate 				return (-1);
1620Sstevel@tonic-gate 				break;
1630Sstevel@tonic-gate 			}
1640Sstevel@tonic-gate 			break;
1650Sstevel@tonic-gate 		case 0x28:		/* designate */
1660Sstevel@tonic-gate 		case 0x29: case 0x2A: case 0x2B:
1670Sstevel@tonic-gate 		case 0x2D: case 0x2E: case 0x2F:
1680Sstevel@tonic-gate 			tch = ch;	/* save this to decide _des_state */
1690Sstevel@tonic-gate 			/* Skip intermidiates */
1700Sstevel@tonic-gate 			do {
1710Sstevel@tonic-gate 				ch = *us++;
1720Sstevel@tonic-gate 				if (++length > n) return (-1);	/* too long */
1730Sstevel@tonic-gate 			} while (ch >= 0x20 && ch <= 0x2F);
1740Sstevel@tonic-gate 			if (ch < 0x30)		/* ch should be a final character */
1750Sstevel@tonic-gate 				return (-1);	/* error */
1760Sstevel@tonic-gate 			if (tch == 0x28)
1770Sstevel@tonic-gate 				i = G0;
1780Sstevel@tonic-gate 			else if (tch == 0x29 || tch == 0x2D)
1790Sstevel@tonic-gate 				i = G1;
1800Sstevel@tonic-gate 			else if (tch == 0x2A || tch == 0x2E)
1810Sstevel@tonic-gate 				i = G2;
1820Sstevel@tonic-gate 			else /* (tch == 0x2B || tch == 0x2F) */
1830Sstevel@tonic-gate 				i = G3;
1840Sstevel@tonic-gate 			/* updates state info */
1850Sstevel@tonic-gate 			_des_states[i].width = TO_SINGLE;
1860Sstevel@tonic-gate 			_des_states[i].final = ch;
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 			goto loop;
1890Sstevel@tonic-gate 			break;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 		/* LOCKING SHIFTS */
1920Sstevel@tonic-gate 		case LS1R:		/* locking shift LS1R */;
1930Sstevel@tonic-gate 			Invoked_G1 = _des_states[G1];
1940Sstevel@tonic-gate 			_currentG1 = G1;
1950Sstevel@tonic-gate 			goto loop;
1960Sstevel@tonic-gate 			break;
1970Sstevel@tonic-gate 		case LS2:		/* locking shift LS2 */
1980Sstevel@tonic-gate 			Invoked_G0 = _des_states[G2];
1990Sstevel@tonic-gate 			_currentG0 = G2;
2000Sstevel@tonic-gate 			goto loop;
2010Sstevel@tonic-gate 			break;
2020Sstevel@tonic-gate 		case LS2R:		/* locking shift LS2R */
2030Sstevel@tonic-gate 			Invoked_G1 = _des_states[G2];
2040Sstevel@tonic-gate 			_currentG1 = G2;
2050Sstevel@tonic-gate 			goto loop;
2060Sstevel@tonic-gate 			break;
2070Sstevel@tonic-gate 		case LS3:		/* locking shift LS3 */
2080Sstevel@tonic-gate 			Invoked_G0 = _des_states[G3];
2090Sstevel@tonic-gate 			_currentG0 = G3;
2100Sstevel@tonic-gate 			goto loop;
2110Sstevel@tonic-gate 			break;
2120Sstevel@tonic-gate 		case LS3R:		/* locking shift LS3R */
2130Sstevel@tonic-gate 			Invoked_G1 = _des_states[G3];
2140Sstevel@tonic-gate 			_currentG1 = G3;
2150Sstevel@tonic-gate 			goto loop;
2160Sstevel@tonic-gate 			break;
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 		/* CONTROL FUNCTIONS */
2190Sstevel@tonic-gate 		case 0x21:		/* C0 sets */
2200Sstevel@tonic-gate 		case 0x22:		/* C1 sets */
2210Sstevel@tonic-gate 			do {
2220Sstevel@tonic-gate 				ch = *us++;
2230Sstevel@tonic-gate 				if (++length > n) return (-1);	/* too long */
2240Sstevel@tonic-gate 			} while (ch >= 0x20 && ch <= 0x2F);
2250Sstevel@tonic-gate 			if (ch < 0x30)		/* ch should be a final character */
2260Sstevel@tonic-gate 				return (-1);	/* error */
2270Sstevel@tonic-gate 			goto loop;
2280Sstevel@tonic-gate 			break;
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 		/* SINGLE SHIFT for 7bit environment */
2310Sstevel@tonic-gate 		case SS2_7B:		/* Single shift SS2 for 7bits */
2320Sstevel@tonic-gate 		case SS3_7B:		/* Single shoft SS3 for 7bits */
2330Sstevel@tonic-gate 			if (ch == SS2_7B)
2340Sstevel@tonic-gate 				gen_wide_state = USE_SS2;
2350Sstevel@tonic-gate 			else
2360Sstevel@tonic-gate 				gen_wide_state = USE_SS3;
2370Sstevel@tonic-gate 			goto loop;
2380Sstevel@tonic-gate 			break;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 		default:		/* should be an error */
2410Sstevel@tonic-gate 			return (-1);
2420Sstevel@tonic-gate 			break;
2430Sstevel@tonic-gate 		}
2440Sstevel@tonic-gate 	/* locking shifts */
2450Sstevel@tonic-gate 	case LS0:
2460Sstevel@tonic-gate 		gen_wide_state = USE_STATE; /* used in gen_wide: */
2470Sstevel@tonic-gate 		Invoked_G0 = _des_states[G0];
2480Sstevel@tonic-gate 		_currentG0 = G0;
2490Sstevel@tonic-gate 		goto loop;
2500Sstevel@tonic-gate 		break;
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	case LS1:
2530Sstevel@tonic-gate 		gen_wide_state = USE_STATE; /* used in gen_wide: */
2540Sstevel@tonic-gate 		Invoked_G0 = _des_states[G1];
2550Sstevel@tonic-gate 		_currentG0 = G1;
2560Sstevel@tonic-gate 		goto loop;
2570Sstevel@tonic-gate 		break;
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 	/* Single shift SS3 and SS2 for 8bits */
2600Sstevel@tonic-gate 	case SS2_8B:
2610Sstevel@tonic-gate 	case SS3_8B:
2620Sstevel@tonic-gate 		if (ch == SS2_8B)
2630Sstevel@tonic-gate 			gen_wide_state = USE_SS2;
2640Sstevel@tonic-gate 		else
2650Sstevel@tonic-gate 			gen_wide_state = USE_SS3;
2660Sstevel@tonic-gate 		goto loop;
2670Sstevel@tonic-gate 		break;
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 	/* This character is not any special character/
2700Sstevel@tonic-gate 	 * It does not change any state.
2710Sstevel@tonic-gate 	 * Goto where it generates wide character.
2720Sstevel@tonic-gate 	 */
2730Sstevel@tonic-gate 	default:
2740Sstevel@tonic-gate 		/*
2750Sstevel@tonic-gate 		 * Use this ch to generate pwc.
2760Sstevel@tonic-gate 		 */
2770Sstevel@tonic-gate 		if (ch == 0) {	/* end of string or 0 */
2780Sstevel@tonic-gate 			wide = 0;
2790Sstevel@tonic-gate 			mask = 0;
2800Sstevel@tonic-gate 			goto gen_wide;
2810Sstevel@tonic-gate 		}
2820Sstevel@tonic-gate 		break;
2830Sstevel@tonic-gate 	}
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 	/*
2870Sstevel@tonic-gate 	 * Generate pwc here.
2880Sstevel@tonic-gate 	 * The information here is
2890Sstevel@tonic-gate 	 * 	current state and length. If the length is two, you need to
2900Sstevel@tonic-gate 	 *      read one more character.
2910Sstevel@tonic-gate 	 */
2920Sstevel@tonic-gate 	switch (gen_wide_state) {
2930Sstevel@tonic-gate 	case USE_STATE:
2940Sstevel@tonic-gate 		if (BIT8(ch)) {	/* 8bit environment ? */
2950Sstevel@tonic-gate 			/* current mode is G1 mode */
2960Sstevel@tonic-gate 			if (Invoked_G1.width == 2) {
2970Sstevel@tonic-gate 				tch = *us++;
2980Sstevel@tonic-gate 				if (++length > n) return (-1);
2990Sstevel@tonic-gate 				wide = ch;
3000Sstevel@tonic-gate 				wide = (wide << 8 | tch);
3010Sstevel@tonic-gate 			}
3020Sstevel@tonic-gate 			else {
3030Sstevel@tonic-gate 				wide = ch;
3040Sstevel@tonic-gate 			}
3050Sstevel@tonic-gate 			if (_currentG1 == G0)	mask = G0MASK;
3060Sstevel@tonic-gate 			else if (_currentG1 == G1) mask = G1MASK;
3070Sstevel@tonic-gate 			else if (_currentG1 == G2) mask = G2MASK;
3080Sstevel@tonic-gate 			else mask = G3MASK;
3090Sstevel@tonic-gate 		}
3100Sstevel@tonic-gate 		else {
3110Sstevel@tonic-gate 			/* current mode is G0 mode */
3120Sstevel@tonic-gate 			if (Invoked_G0.width == 2) {
3130Sstevel@tonic-gate 				tch = *us++;
3140Sstevel@tonic-gate 				if (++length > n) return (-1);
3150Sstevel@tonic-gate 				wide = ch;
3160Sstevel@tonic-gate 				wide = (wide << 8 | tch);
3170Sstevel@tonic-gate 			}
3180Sstevel@tonic-gate 			else {
3190Sstevel@tonic-gate 				wide = ch;
3200Sstevel@tonic-gate 			}
3210Sstevel@tonic-gate 			if (_currentG0 == G0)	mask = G0MASK;
3220Sstevel@tonic-gate 			else if (_currentG0 == G1) mask = G1MASK;
3230Sstevel@tonic-gate 			else if (_currentG0 == G2) mask = G2MASK;
3240Sstevel@tonic-gate 			else mask = G3MASK;
3250Sstevel@tonic-gate 		}
3260Sstevel@tonic-gate 		break;
3270Sstevel@tonic-gate 	case USE_SS2:
3280Sstevel@tonic-gate 		if (_des_states[G2].width == 2) {
3290Sstevel@tonic-gate 			tch = *us++;
3300Sstevel@tonic-gate 			if (++length > n) return (-1);
3310Sstevel@tonic-gate 			wide = ch;
3320Sstevel@tonic-gate 			wide = (wide << 8 | tch);
3330Sstevel@tonic-gate 		}
3340Sstevel@tonic-gate 		else {
3350Sstevel@tonic-gate 			wide = ch;
3360Sstevel@tonic-gate 		}
3370Sstevel@tonic-gate 		mask = G2MASK;
3380Sstevel@tonic-gate 		break;
3390Sstevel@tonic-gate 	case USE_SS3:
3400Sstevel@tonic-gate 		if (_des_states[G3].width == 2) {
3410Sstevel@tonic-gate 			tch = *us++;
3420Sstevel@tonic-gate 			if (++length > n) return (-1);
3430Sstevel@tonic-gate 			wide = ch;
3440Sstevel@tonic-gate 			wide = (wide << 8 | tch);
3450Sstevel@tonic-gate 		}
3460Sstevel@tonic-gate 		else {
3470Sstevel@tonic-gate 			wide = ch;
3480Sstevel@tonic-gate 		}
3490Sstevel@tonic-gate 		mask = G3MASK;
3500Sstevel@tonic-gate 		break;
3510Sstevel@tonic-gate 	default:
3520Sstevel@tonic-gate 		/* shoult be internal error */
3530Sstevel@tonic-gate 		return (-1);
3540Sstevel@tonic-gate 		break;
3550Sstevel@tonic-gate 	}
3560Sstevel@tonic-gate gen_wide:
3570Sstevel@tonic-gate 	wide &= 0x7F7F;			/* strip off the top bit */
3580Sstevel@tonic-gate 	wide = wide | mask;
3590Sstevel@tonic-gate 	if (pwc != NULL)
3600Sstevel@tonic-gate 		*pwc = wide;
3610Sstevel@tonic-gate 	return (length);
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate #define MAXMBSIZE	128
3660Sstevel@tonic-gate /*
3670Sstevel@tonic-gate  *  mbstowcs()
3680Sstevel@tonic-gate  */
3690Sstevel@tonic-gate size_t
_mbstowcs_iso(wchar_t * pwcs,unsigned char * s,size_t n)370*722Smuffin _mbstowcs_iso(wchar_t *pwcs, unsigned char *s, size_t n)
3710Sstevel@tonic-gate {
3720Sstevel@tonic-gate 	int ret1;
3730Sstevel@tonic-gate 	int accsum = 0;
3740Sstevel@tonic-gate 	wchar_t pwc;
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 	/*
3770Sstevel@tonic-gate 	 * If pwcs == 0, do nothing.
3780Sstevel@tonic-gate 	 */
3790Sstevel@tonic-gate 	if (pwcs == 0)
3800Sstevel@tonic-gate 		return (0);
3810Sstevel@tonic-gate 	/*
3820Sstevel@tonic-gate 	 * States things
3830Sstevel@tonic-gate 	 */
3840Sstevel@tonic-gate 	 _savestates(); _initializestates();
3850Sstevel@tonic-gate 	 while (accsum < n) {
386*722Smuffin 		ret1 = _mbtowc_iso (&pwc, (char *)s, MAXMBSIZE);
3870Sstevel@tonic-gate 		if (ret1 < 0)
3880Sstevel@tonic-gate 			return (-1);	/* error */
3890Sstevel@tonic-gate 		if (ret1 == 0 || pwc == 0) {
3900Sstevel@tonic-gate 			if (pwcs == 0)
3910Sstevel@tonic-gate 				*pwcs = 0;
3920Sstevel@tonic-gate 			/*
3930Sstevel@tonic-gate 			 * Restore states
3940Sstevel@tonic-gate 			 */
3950Sstevel@tonic-gate 			_restorestates();
3960Sstevel@tonic-gate 			return (accsum);
3970Sstevel@tonic-gate 		}
3980Sstevel@tonic-gate 		s = s + ret1;		/* increment the pointer */
3990Sstevel@tonic-gate 		*pwcs++ = pwc;
4000Sstevel@tonic-gate 		++accsum;
4010Sstevel@tonic-gate 	}
4020Sstevel@tonic-gate 	/*
4030Sstevel@tonic-gate 	 * Restore states
4040Sstevel@tonic-gate 	 */
4050Sstevel@tonic-gate 	_restorestates();
4060Sstevel@tonic-gate 	return (accsum);
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate /*
4100Sstevel@tonic-gate  * wctomb -
4110Sstevel@tonic-gate  */
4120Sstevel@tonic-gate int
_wctomb_iso(unsigned char * s,wchar_t pwc)413*722Smuffin _wctomb_iso(unsigned char *s, wchar_t pwc)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate 	unsigned char ch;
4160Sstevel@tonic-gate 	unsigned char tch;	/* temporary use */
4170Sstevel@tonic-gate 	unsigned char *us = (unsigned char *)s;
4180Sstevel@tonic-gate 	int gen_wide_state = USE_STATE; /* used in gen_wide: */
4190Sstevel@tonic-gate 	int length = 0;
4200Sstevel@tonic-gate 	int len = 0;
4210Sstevel@tonic-gate 	wchar_t wide;
4220Sstevel@tonic-gate 	unsigned short mode;
4230Sstevel@tonic-gate 	unsigned char buf[MAXSIZE];
4240Sstevel@tonic-gate 	unsigned char *bp;
4250Sstevel@tonic-gate 	int csize, i;
4260Sstevel@tonic-gate 	int n = MMB_CUR_MAX;
4270Sstevel@tonic-gate 
4280Sstevel@tonic-gate 	isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info;
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	/*
4310Sstevel@tonic-gate 	 * If pwc is 0, do this first.
4320Sstevel@tonic-gate 	 */
4330Sstevel@tonic-gate 	if (pwc  == 0) {
4340Sstevel@tonic-gate 		if (s != 0) {
4350Sstevel@tonic-gate 			*s = 0;
4360Sstevel@tonic-gate 			return (1);
4370Sstevel@tonic-gate 		}
4380Sstevel@tonic-gate 		else {
4390Sstevel@tonic-gate 			return (0);
4400Sstevel@tonic-gate 		}
4410Sstevel@tonic-gate 	}
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	mode = pwc & G3MASK;	/* The mode of this character */
4440Sstevel@tonic-gate 	if (((pwc >> 8) & 0x007f) == 0)
4450Sstevel@tonic-gate 		csize = 1;
4460Sstevel@tonic-gate 	else
4470Sstevel@tonic-gate 		csize = 2;
4480Sstevel@tonic-gate 	bp = buf;
4490Sstevel@tonic-gate 	length = 0;
4500Sstevel@tonic-gate #ifdef DDDebug
4510Sstevel@tonic-gate 	if (_my_env == BIT7ENV)
4520Sstevel@tonic-gate 		printf ("7b ");
4530Sstevel@tonic-gate 	else
4540Sstevel@tonic-gate 		printf ("8b ");
4550Sstevel@tonic-gate 	printf ("csize = %d, prevcsize = %d, (%x,%x) ",csize, prevcsize, (pwc>>8)&0x00ff, pwc&0x00ff);
4560Sstevel@tonic-gate 	switch (mode) {
4570Sstevel@tonic-gate 	case G0MASK:
4580Sstevel@tonic-gate 		printf ("G0"); break;
4590Sstevel@tonic-gate 	case G1MASK:
4600Sstevel@tonic-gate 		printf ("G1"); break;
4610Sstevel@tonic-gate 	case G2MASK:
4620Sstevel@tonic-gate 		printf ("G2"); break;
4630Sstevel@tonic-gate 	case G3MASK:
4640Sstevel@tonic-gate 		printf ("G3"); break;
4650Sstevel@tonic-gate 	default:
4660Sstevel@tonic-gate 		printf ("XXXX"); break;
4670Sstevel@tonic-gate 	}
4680Sstevel@tonic-gate #endif
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate 	switch (_my_env) {
4710Sstevel@tonic-gate 	case BIT7ENV:	/* 7 bit environment */
4720Sstevel@tonic-gate 		switch (mode) {
4730Sstevel@tonic-gate 		case G0MASK:
4740Sstevel@tonic-gate 			if (_currentOUT != G0 || prevcsize != csize) {
4750Sstevel@tonic-gate 				 _currentOUT = G0;
4760Sstevel@tonic-gate 				if (csize == 2) {
4770Sstevel@tonic-gate 					/*
4780Sstevel@tonic-gate 					 * Emit escape sequences
4790Sstevel@tonic-gate 					 */
4800Sstevel@tonic-gate 					 *bp++ = ESC;
4810Sstevel@tonic-gate 					 *bp++ = 0x24;
4820Sstevel@tonic-gate 					 *bp++ = 0x28;
4830Sstevel@tonic-gate 					 *bp++ = FINAL;
4840Sstevel@tonic-gate 					 length += 4;
4850Sstevel@tonic-gate 				}
4860Sstevel@tonic-gate 				else {
4870Sstevel@tonic-gate 					/*
4880Sstevel@tonic-gate 					 * Emit escape sequences
4890Sstevel@tonic-gate 					 */
4900Sstevel@tonic-gate 					 *bp++ = ESC;
4910Sstevel@tonic-gate 					 *bp++ = 0x28;
4920Sstevel@tonic-gate 					 *bp++ = FINAL;
4930Sstevel@tonic-gate 					 length += 3;
4940Sstevel@tonic-gate 				}
4950Sstevel@tonic-gate 				*bp++ = SI;
4960Sstevel@tonic-gate 				++length;
4970Sstevel@tonic-gate 			}
4980Sstevel@tonic-gate 			if (csize == 1) {
4990Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5000Sstevel@tonic-gate 				++length;
5010Sstevel@tonic-gate 			}
5020Sstevel@tonic-gate 			else {
5030Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
5040Sstevel@tonic-gate 				++length;
5050Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5060Sstevel@tonic-gate 				++length;
5070Sstevel@tonic-gate 			}
5080Sstevel@tonic-gate 			break;
5090Sstevel@tonic-gate 		case G1MASK:
5100Sstevel@tonic-gate 			if (_currentOUT != G1 || prevcsize != csize) {
5110Sstevel@tonic-gate 				 _currentOUT = G1;
5120Sstevel@tonic-gate 				if (csize == 2) {
5130Sstevel@tonic-gate 					/*
5140Sstevel@tonic-gate 					 * Emit escape sequences
5150Sstevel@tonic-gate 					 */
5160Sstevel@tonic-gate 					 *bp++ = ESC;
5170Sstevel@tonic-gate 					 *bp++ = 0x24;
5180Sstevel@tonic-gate 					 *bp++ = 0x29;
5190Sstevel@tonic-gate 					 *bp++ = FINAL;
5200Sstevel@tonic-gate 					 length += 4;
5210Sstevel@tonic-gate 				}
5220Sstevel@tonic-gate 				else {
5230Sstevel@tonic-gate 					/*
5240Sstevel@tonic-gate 					 * Emit escape sequences
5250Sstevel@tonic-gate 					 */
5260Sstevel@tonic-gate 					 *bp++ = ESC;
5270Sstevel@tonic-gate 					 *bp++ = 0x29;
5280Sstevel@tonic-gate 					 *bp++ = FINAL;
5290Sstevel@tonic-gate 					 length += 3;
5300Sstevel@tonic-gate 				}
5310Sstevel@tonic-gate 				*bp++ = SO;
5320Sstevel@tonic-gate 				++length;
5330Sstevel@tonic-gate 			}
5340Sstevel@tonic-gate 			if (csize == 1) {
5350Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5360Sstevel@tonic-gate 				++length;
5370Sstevel@tonic-gate 			}
5380Sstevel@tonic-gate 			else {
5390Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
5400Sstevel@tonic-gate 				++length;
5410Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5420Sstevel@tonic-gate 				++length;
5430Sstevel@tonic-gate 			}
5440Sstevel@tonic-gate 			break;
5450Sstevel@tonic-gate 		case G2MASK:
5460Sstevel@tonic-gate 			if (_currentOUT != G2 || prevcsize != csize) {
5470Sstevel@tonic-gate 				 _currentOUT = G2;
5480Sstevel@tonic-gate 				if (csize == 2) {
5490Sstevel@tonic-gate 					/*
5500Sstevel@tonic-gate 					 * Emit escape sequences
5510Sstevel@tonic-gate 					 */
5520Sstevel@tonic-gate 					 *bp++ = ESC;
5530Sstevel@tonic-gate 					 *bp++ = 0x24;
5540Sstevel@tonic-gate 					 *bp++ = 0x2A;
5550Sstevel@tonic-gate 					 *bp++ = FINAL;
5560Sstevel@tonic-gate 					 length += 4;
5570Sstevel@tonic-gate 				}
5580Sstevel@tonic-gate 				else {
5590Sstevel@tonic-gate 					/*
5600Sstevel@tonic-gate 					 * Emit escape sequences
5610Sstevel@tonic-gate 					 */
5620Sstevel@tonic-gate 					 *bp++ = ESC;
5630Sstevel@tonic-gate 					 *bp++ = 0x2A;
5640Sstevel@tonic-gate 					 *bp++ = FINAL;
5650Sstevel@tonic-gate 					 length += 3;
5660Sstevel@tonic-gate 				}
5670Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS2;
5680Sstevel@tonic-gate 				length += 2;
5690Sstevel@tonic-gate 			}
5700Sstevel@tonic-gate 			if (csize == 1) {
5710Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5720Sstevel@tonic-gate 				++length;
5730Sstevel@tonic-gate 			}
5740Sstevel@tonic-gate 			else {
5750Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
5760Sstevel@tonic-gate 				++length;
5770Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
5780Sstevel@tonic-gate 				++length;
5790Sstevel@tonic-gate 			}
5800Sstevel@tonic-gate 			break;
5810Sstevel@tonic-gate 		case G3MASK:
5820Sstevel@tonic-gate 			if (_currentOUT != G3 || prevcsize != csize) {
5830Sstevel@tonic-gate 				 _currentOUT = G3;
5840Sstevel@tonic-gate 				if (csize == 2) {
5850Sstevel@tonic-gate 					/*
5860Sstevel@tonic-gate 					 * Emit escape sequences
5870Sstevel@tonic-gate 					 */
5880Sstevel@tonic-gate 					 *bp++ = ESC;
5890Sstevel@tonic-gate 					 *bp++ = 0x24;
5900Sstevel@tonic-gate 					 *bp++ = 0x2B;
5910Sstevel@tonic-gate 					 *bp++ = FINAL;
5920Sstevel@tonic-gate 					 length += 4;
5930Sstevel@tonic-gate 				}
5940Sstevel@tonic-gate 				else {
5950Sstevel@tonic-gate 					/*
5960Sstevel@tonic-gate 					 * Emit escape sequences
5970Sstevel@tonic-gate 					 */
5980Sstevel@tonic-gate 					 *bp++ = ESC;
5990Sstevel@tonic-gate 					 *bp++ = 0x2B;
6000Sstevel@tonic-gate 					 *bp++ = FINAL;
6010Sstevel@tonic-gate 					 length += 3;
6020Sstevel@tonic-gate 				}
6030Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS3;
6040Sstevel@tonic-gate 				length += 2;
6050Sstevel@tonic-gate 			}
6060Sstevel@tonic-gate 			if (csize == 1) {
6070Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6080Sstevel@tonic-gate 				++length;
6090Sstevel@tonic-gate 			}
6100Sstevel@tonic-gate 			else {
6110Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
6120Sstevel@tonic-gate 				++length;
6130Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6140Sstevel@tonic-gate 				++length;
6150Sstevel@tonic-gate 			}
6160Sstevel@tonic-gate 			break;
6170Sstevel@tonic-gate 		}
6180Sstevel@tonic-gate 		break;
6190Sstevel@tonic-gate 	case BIT8ENV:	/* 8 bit environment */
6200Sstevel@tonic-gate 		switch (mode) {
6210Sstevel@tonic-gate 		case G0MASK:
6220Sstevel@tonic-gate 			if (_currentOUT != G0 || prevcsize != csize) {
6230Sstevel@tonic-gate 				_currentOUT = G0;
6240Sstevel@tonic-gate 				if (csize == 2) {
6250Sstevel@tonic-gate 					/*
6260Sstevel@tonic-gate 					 * Emit escape sequences
6270Sstevel@tonic-gate 					 */
6280Sstevel@tonic-gate 					 *bp++ = ESC;
6290Sstevel@tonic-gate 					 *bp++ = 0x24;
6300Sstevel@tonic-gate 					 *bp++ = 0x28;
6310Sstevel@tonic-gate 					 *bp++ = FINAL;
6320Sstevel@tonic-gate 					 length += 4;
6330Sstevel@tonic-gate 				}
6340Sstevel@tonic-gate 				else {
6350Sstevel@tonic-gate 					/*
6360Sstevel@tonic-gate 					 * Emit escape sequences
6370Sstevel@tonic-gate 					 */
6380Sstevel@tonic-gate 					 *bp++ = ESC;
6390Sstevel@tonic-gate 					 *bp++ = 0x28;
6400Sstevel@tonic-gate 					 *bp++ = FINAL;
6410Sstevel@tonic-gate 					 length += 3;
6420Sstevel@tonic-gate 				}
6430Sstevel@tonic-gate 				*bp++ = LS0;
6440Sstevel@tonic-gate 				++length;
6450Sstevel@tonic-gate 			}
6460Sstevel@tonic-gate 			if (csize == 1) {
6470Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6480Sstevel@tonic-gate 				++length;
6490Sstevel@tonic-gate 			}
6500Sstevel@tonic-gate 			else {
6510Sstevel@tonic-gate 				*bp++ = (pwc & 0x7f00) >> 8;
6520Sstevel@tonic-gate 				++length;
6530Sstevel@tonic-gate 				*bp++ = pwc & 0x007f;
6540Sstevel@tonic-gate 				++length;
6550Sstevel@tonic-gate 			}
6560Sstevel@tonic-gate 			break;
6570Sstevel@tonic-gate 		case G1MASK:
6580Sstevel@tonic-gate 			if (_currentOUT != G1 || prevcsize != csize) {
6590Sstevel@tonic-gate 				_currentOUT = G1;
6600Sstevel@tonic-gate 				if (csize == 2) {
6610Sstevel@tonic-gate 					/*
6620Sstevel@tonic-gate 					 * Emit escape sequences
6630Sstevel@tonic-gate 					 */
6640Sstevel@tonic-gate 					 *bp++ = ESC;
6650Sstevel@tonic-gate 					 *bp++ = 0x24;
6660Sstevel@tonic-gate 					 *bp++ = 0x29;
6670Sstevel@tonic-gate 					 *bp++ = FINAL;
6680Sstevel@tonic-gate 					 length += 4;
6690Sstevel@tonic-gate 				}
6700Sstevel@tonic-gate 				else {
6710Sstevel@tonic-gate 					/*
6720Sstevel@tonic-gate 					 * Emit escape sequences
6730Sstevel@tonic-gate 					 */
6740Sstevel@tonic-gate 					 *bp++ = ESC;
6750Sstevel@tonic-gate 					 *bp++ = 0x29;
6760Sstevel@tonic-gate 					 *bp++ = FINAL;
6770Sstevel@tonic-gate 					 length += 3;
6780Sstevel@tonic-gate 				}
6790Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS1R;
6800Sstevel@tonic-gate 				length += 2;
6810Sstevel@tonic-gate 			}
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 			/*
6840Sstevel@tonic-gate 			 * If state is G1 or G2, or G3, assume that
6850Sstevel@tonic-gate 			 * this is 8bit characters. To do this more
6860Sstevel@tonic-gate 			 * accurately, wide character needs to be
6870Sstevel@tonic-gate 			 * larger than 16 bits to keep more information.
6880Sstevel@tonic-gate 			 */
6890Sstevel@tonic-gate 			pwc |= 0x8080;
6900Sstevel@tonic-gate 			if (csize == 1) {
6910Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
6920Sstevel@tonic-gate 				++length;
6930Sstevel@tonic-gate 			}
6940Sstevel@tonic-gate 			else {
6950Sstevel@tonic-gate 				*bp++ = (pwc & 0xff00) >> 8;
6960Sstevel@tonic-gate 				++length;
6970Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
6980Sstevel@tonic-gate 				++length;
6990Sstevel@tonic-gate 			}
7000Sstevel@tonic-gate 			break;
7010Sstevel@tonic-gate 		case G2MASK:
7020Sstevel@tonic-gate 			if (_currentOUT != G2 || prevcsize != csize) {
7030Sstevel@tonic-gate 				_currentOUT = G2;
7040Sstevel@tonic-gate 				if (csize == 2) {
7050Sstevel@tonic-gate 					/*
7060Sstevel@tonic-gate 					 * Emit escape sequences
7070Sstevel@tonic-gate 					 */
7080Sstevel@tonic-gate 					 *bp++ = ESC;
7090Sstevel@tonic-gate 					 *bp++ = 0x24;
7100Sstevel@tonic-gate 					 *bp++ = 0x2A;
7110Sstevel@tonic-gate 					 *bp++ = FINAL;
7120Sstevel@tonic-gate 					 length += 4;
7130Sstevel@tonic-gate 				}
7140Sstevel@tonic-gate 				else {
7150Sstevel@tonic-gate 					/*
7160Sstevel@tonic-gate 					 * Emit escape sequences
7170Sstevel@tonic-gate 					 */
7180Sstevel@tonic-gate 					 *bp++ = ESC;
7190Sstevel@tonic-gate 					 *bp++ = 0x2A;
7200Sstevel@tonic-gate 					 *bp++ = FINAL;
7210Sstevel@tonic-gate 					 length += 3;
7220Sstevel@tonic-gate 				}
7230Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS2R;
7240Sstevel@tonic-gate 				length += 2;
7250Sstevel@tonic-gate 			}
7260Sstevel@tonic-gate 			/*
7270Sstevel@tonic-gate 			 * If state is G1 or G2, or G3, assume that
7280Sstevel@tonic-gate 			 * this is 8bit characters. To do this more
7290Sstevel@tonic-gate 			 * accurately, wide character needs to be
7300Sstevel@tonic-gate 			 * larger than 16 bits to keep more information.
7310Sstevel@tonic-gate 			 */
7320Sstevel@tonic-gate 			pwc |= 0x8080;
7330Sstevel@tonic-gate 			if (csize == 1) {
7340Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7350Sstevel@tonic-gate 				++length;
7360Sstevel@tonic-gate 			}
7370Sstevel@tonic-gate 			else {
7380Sstevel@tonic-gate 				*bp++ = (pwc & 0xff00) >> 8;
7390Sstevel@tonic-gate 				++length;
7400Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7410Sstevel@tonic-gate 				++length;
7420Sstevel@tonic-gate 			}
7430Sstevel@tonic-gate 			break;
7440Sstevel@tonic-gate 		case G3MASK:
7450Sstevel@tonic-gate 			if (_currentOUT != G3 || prevcsize != csize) {
7460Sstevel@tonic-gate 				_currentOUT = G3;
7470Sstevel@tonic-gate 				if (csize == 2) {
7480Sstevel@tonic-gate 					/*
7490Sstevel@tonic-gate 					 * Emit escape sequences
7500Sstevel@tonic-gate 					 */
7510Sstevel@tonic-gate 					 *bp++ = ESC;
7520Sstevel@tonic-gate 					 *bp++ = 0x24;
7530Sstevel@tonic-gate 					 *bp++ = 0x2B;
7540Sstevel@tonic-gate 					 *bp++ = FINAL;
7550Sstevel@tonic-gate 					 length += 4;
7560Sstevel@tonic-gate 				}
7570Sstevel@tonic-gate 				else {
7580Sstevel@tonic-gate 					/*
7590Sstevel@tonic-gate 					 * Emit escape sequences
7600Sstevel@tonic-gate 					 */
7610Sstevel@tonic-gate 					 *bp++ = ESC;
7620Sstevel@tonic-gate 					 *bp++ = 0x2B;
7630Sstevel@tonic-gate 					 *bp++ = FINAL;
7640Sstevel@tonic-gate 					 length += 3;
7650Sstevel@tonic-gate 				}
7660Sstevel@tonic-gate 				*bp++ = ESC; *bp++ = LS3R;
7670Sstevel@tonic-gate 				length += 2;
7680Sstevel@tonic-gate 			}
7690Sstevel@tonic-gate 			/*
7700Sstevel@tonic-gate 			 * If state is G1 or G2, or G3, assume that
7710Sstevel@tonic-gate 			 * this is 8bit characters. To do this more
7720Sstevel@tonic-gate 			 * accurately, wide character needs to be
7730Sstevel@tonic-gate 			 * larger than 16 bits to keep more information.
7740Sstevel@tonic-gate 			 */
7750Sstevel@tonic-gate 			pwc |= 0x8080;
7760Sstevel@tonic-gate 			if (csize == 1) {
7770Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7780Sstevel@tonic-gate 				++length;
7790Sstevel@tonic-gate 			}
7800Sstevel@tonic-gate 			else {
7810Sstevel@tonic-gate 				*bp++ = (pwc & 0xff00) >> 8;
7820Sstevel@tonic-gate 				++length;
7830Sstevel@tonic-gate 				*bp++ = pwc & 0x00ff;
7840Sstevel@tonic-gate 				++length;
7850Sstevel@tonic-gate 			}
7860Sstevel@tonic-gate 			break;
7870Sstevel@tonic-gate 		}
7880Sstevel@tonic-gate 		break;
7890Sstevel@tonic-gate 	default:	/* Should never happens */
7900Sstevel@tonic-gate 		return (-1);
7910Sstevel@tonic-gate 		break;
7920Sstevel@tonic-gate 	}
7930Sstevel@tonic-gate 
7940Sstevel@tonic-gate 	prevcsize = csize;
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate 	if (length > n) {
7970Sstevel@tonic-gate 		return (-1);	/* buffer too small */
7980Sstevel@tonic-gate 	}
7990Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
8000Sstevel@tonic-gate 		*s++ = buf[i];
8010Sstevel@tonic-gate 	}
8020Sstevel@tonic-gate #ifdef DDDebug
8030Sstevel@tonic-gate 	printf ("\t(");
8040Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
8050Sstevel@tonic-gate 		printf ("%x,", buf[i]);
8060Sstevel@tonic-gate 	}
8070Sstevel@tonic-gate 	printf (")\n");
8080Sstevel@tonic-gate #endif
8090Sstevel@tonic-gate 	return (length);
8100Sstevel@tonic-gate }
8110Sstevel@tonic-gate 
8120Sstevel@tonic-gate /*
8130Sstevel@tonic-gate  * wcstombs
8140Sstevel@tonic-gate  */
8150Sstevel@tonic-gate size_t
_wcstombs_iso(char * s,wchar_t * pwcs,int n)816*722Smuffin _wcstombs_iso(char *s, wchar_t *pwcs, int n)
8170Sstevel@tonic-gate {
8180Sstevel@tonic-gate 	int acclen = 0;
8190Sstevel@tonic-gate 	char buf[MMB_CUR_MAX];
8200Sstevel@tonic-gate 	int ret1;
8210Sstevel@tonic-gate 	int i;
8220Sstevel@tonic-gate 
8230Sstevel@tonic-gate 	if (n < 0)
8240Sstevel@tonic-gate 		return (-1);
8250Sstevel@tonic-gate 	/*
8260Sstevel@tonic-gate 	 * Initialize State
8270Sstevel@tonic-gate 	 */
8280Sstevel@tonic-gate 	 _savestates(); _initializestates();
8290Sstevel@tonic-gate 	 while (acclen < n) {
830*722Smuffin 		ret1 = _wctomb_iso ((unsigned char *)buf, *pwcs);
8310Sstevel@tonic-gate 		/*
8320Sstevel@tonic-gate 		 * end of string ?
8330Sstevel@tonic-gate 		 */
8340Sstevel@tonic-gate 		if (ret1 == 1 && buf[0] == 0) {
8350Sstevel@tonic-gate 			*s = 0;
8360Sstevel@tonic-gate 			/*
8370Sstevel@tonic-gate 			 * restore states
8380Sstevel@tonic-gate 			 */
8390Sstevel@tonic-gate 			_restorestates();
8400Sstevel@tonic-gate 			return (acclen);
8410Sstevel@tonic-gate 		}
8420Sstevel@tonic-gate 		/*
8430Sstevel@tonic-gate 		 * Error ?
8440Sstevel@tonic-gate 		 */
8450Sstevel@tonic-gate 		if (ret1 < 0)
8460Sstevel@tonic-gate 			return (-1);
8470Sstevel@tonic-gate 		acclen += ret1;
8480Sstevel@tonic-gate 		for (i = 0; i < ret1; i++)
8490Sstevel@tonic-gate 			*s++ = buf[i];
8500Sstevel@tonic-gate 		++pwcs;
8510Sstevel@tonic-gate 	 }
8520Sstevel@tonic-gate 
8530Sstevel@tonic-gate 	/*
8540Sstevel@tonic-gate 	 * restore states
8550Sstevel@tonic-gate 	 */
8560Sstevel@tonic-gate 	_restorestates();
8570Sstevel@tonic-gate 
8580Sstevel@tonic-gate 	 /*
8590Sstevel@tonic-gate 	  * return the length
8600Sstevel@tonic-gate 	  */
8610Sstevel@tonic-gate 	 return (acclen);
8620Sstevel@tonic-gate }
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate /*
8660Sstevel@tonic-gate  * Supplementary routines
8670Sstevel@tonic-gate  */
8680Sstevel@tonic-gate 
869*722Smuffin void
_initializestates(void)870*722Smuffin _initializestates(void)
8710Sstevel@tonic-gate {
8720Sstevel@tonic-gate 	_currentG0 = G0;
8730Sstevel@tonic-gate 	_currentG1 = G1;
8740Sstevel@tonic-gate 
8750Sstevel@tonic-gate 	_des_states[G0].width = -1;	/* This makes it Initialize */
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	_currentOUT = G0;
8780Sstevel@tonic-gate 	prevcsize = 1;
8790Sstevel@tonic-gate }
8800Sstevel@tonic-gate 
8810Sstevel@tonic-gate static char SAVED_currentG0;
8820Sstevel@tonic-gate static char SAVED_currentG1;
8830Sstevel@tonic-gate static struct state SAVED_des_states[NUM_OF_STATES];
8840Sstevel@tonic-gate static struct state SAVED_Invoked_G0, SAVED_Invoked_G1;
8850Sstevel@tonic-gate static char SAVED_currentOUT = G0; /* G0, G1, G2 or G3 */
886*722Smuffin static int	SAVED_prevcsize = 1;
8870Sstevel@tonic-gate 
888*722Smuffin void
_savestates(void)889*722Smuffin _savestates(void)
8900Sstevel@tonic-gate {
8910Sstevel@tonic-gate 
8920Sstevel@tonic-gate 	SAVED_currentG0 = _currentG0;
8930Sstevel@tonic-gate 	SAVED_currentG1 = _currentG1;
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 	SAVED_des_states[G0] = _des_states[G0];
8960Sstevel@tonic-gate 	SAVED_des_states[G1] = _des_states[G1];
8970Sstevel@tonic-gate 	SAVED_des_states[G2] = _des_states[G2];
8980Sstevel@tonic-gate 	SAVED_des_states[G3] = _des_states[G3];
8990Sstevel@tonic-gate 
9000Sstevel@tonic-gate 	SAVED_Invoked_G0 = Invoked_G0;
9010Sstevel@tonic-gate 	SAVED_Invoked_G1 = Invoked_G1;
9020Sstevel@tonic-gate 
9030Sstevel@tonic-gate 	SAVED_currentOUT = _currentOUT;
9040Sstevel@tonic-gate 	SAVED_prevcsize = prevcsize;
9050Sstevel@tonic-gate }
9060Sstevel@tonic-gate 
907*722Smuffin void
_restorestates(void)908*722Smuffin _restorestates(void)
9090Sstevel@tonic-gate {
9100Sstevel@tonic-gate 	_currentG0 = SAVED_currentG0;
9110Sstevel@tonic-gate 	_currentG1 = SAVED_currentG1;
9120Sstevel@tonic-gate 
9130Sstevel@tonic-gate 	_des_states[G0] = SAVED_des_states[G0];
9140Sstevel@tonic-gate 	_des_states[G1] = SAVED_des_states[G1];
9150Sstevel@tonic-gate 	_des_states[G2] = SAVED_des_states[G2];
9160Sstevel@tonic-gate 	_des_states[G3] = SAVED_des_states[G3];
9170Sstevel@tonic-gate 
9180Sstevel@tonic-gate 	Invoked_G0 = SAVED_Invoked_G0;
9190Sstevel@tonic-gate 	Invoked_G1 = SAVED_Invoked_G1;
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate 	_currentOUT = SAVED_currentOUT;
9220Sstevel@tonic-gate 	prevcsize = SAVED_prevcsize;
9230Sstevel@tonic-gate }
924