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