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
_mbtowc_iso(wchar_t * pwc,char * s,size_t n)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
_mbstowcs_iso(wchar_t * pwcs,unsigned char * s,size_t n)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
_wctomb_iso(unsigned char * s,wchar_t pwc)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
_wcstombs_iso(char * s,wchar_t * pwcs,int n)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
_initializestates(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
_savestates(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
_restorestates(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