116d86563SAlexander Pyhalov /*
216d86563SAlexander Pyhalov  * CDDL HEADER START
316d86563SAlexander Pyhalov  *
416d86563SAlexander Pyhalov  * The contents of this file are subject to the terms of the
516d86563SAlexander Pyhalov  * Common Development and Distribution License (the "License").
616d86563SAlexander Pyhalov  * You may not use this file except in compliance with the License.
716d86563SAlexander Pyhalov  *
816d86563SAlexander Pyhalov  * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
916d86563SAlexander Pyhalov  * or http://www.opensolaris.org/os/licensing.
1016d86563SAlexander Pyhalov  * See the License for the specific language governing permissions
1116d86563SAlexander Pyhalov  * and limitations under the License.
1216d86563SAlexander Pyhalov  *
1316d86563SAlexander Pyhalov  * When distributing Covered Code, include this CDDL HEADER in each
1416d86563SAlexander Pyhalov  * file and include the License file at src/OPENSOLARIS.LICENSE.
1516d86563SAlexander Pyhalov  * If applicable, add the following below this CDDL HEADER, with the
1616d86563SAlexander Pyhalov  * fields enclosed by brackets "[]" replaced with your own identifying
1716d86563SAlexander Pyhalov  * information: Portions Copyright [yyyy] [name of copyright owner]
1816d86563SAlexander Pyhalov  *
1916d86563SAlexander Pyhalov  * CDDL HEADER END
2016d86563SAlexander Pyhalov  */
2116d86563SAlexander Pyhalov /*
2216d86563SAlexander Pyhalov #include <stdlib.h>
2316d86563SAlexander Pyhalov  * Copyright (c) 1997, by Sun Microsystems, Inc.
2416d86563SAlexander Pyhalov  * All rights reserved.
2516d86563SAlexander Pyhalov  */
2616d86563SAlexander Pyhalov 
2716d86563SAlexander Pyhalov 
2816d86563SAlexander Pyhalov /*
2916d86563SAlexander Pyhalov    Converts From:	ISO2022-CN-EXT encoding.
3016d86563SAlexander Pyhalov    Converts To:		Taiwanese EUC encoding ( CNS11643 ) and big5 encoding
3116d86563SAlexander Pyhalov 
3216d86563SAlexander Pyhalov  */
3316d86563SAlexander Pyhalov 
3416d86563SAlexander Pyhalov #include "iso2022-cn.h"
3516d86563SAlexander Pyhalov 
3616d86563SAlexander Pyhalov /* Forward reference the functions constrained to the scope of this file */
3716d86563SAlexander Pyhalov static int process_esc_seq(char, _iconv_st *);
3816d86563SAlexander Pyhalov static int ascii_to_euc(char, _iconv_st *, unsigned char **, size_t *);
3916d86563SAlexander Pyhalov static int iscns( _iconv_st * );
4016d86563SAlexander Pyhalov 
4116d86563SAlexander Pyhalov 
4216d86563SAlexander Pyhalov extern int errno;
4316d86563SAlexander Pyhalov 
4416d86563SAlexander Pyhalov /*
4516d86563SAlexander Pyhalov  * _icv_open: Called from iconv_open(). Allocates and initializes _iconv_st
4616d86563SAlexander Pyhalov  *            structure. Returns pointer to the structure as (void *).
4716d86563SAlexander Pyhalov  */
4816d86563SAlexander Pyhalov 
4916d86563SAlexander Pyhalov 
5016d86563SAlexander Pyhalov void *
_icv_open()5116d86563SAlexander Pyhalov _icv_open()
5216d86563SAlexander Pyhalov {
5316d86563SAlexander Pyhalov 	_iconv_st  *st;
5416d86563SAlexander Pyhalov 
5516d86563SAlexander Pyhalov 	/* Allocate */
5616d86563SAlexander Pyhalov 	if (( st = (_iconv_st *) malloc( sizeof( _iconv_st ))) == NULL ){
5716d86563SAlexander Pyhalov 	    errno = ENOMEM;
5816d86563SAlexander Pyhalov 	    return ((void *) -1);
5916d86563SAlexander Pyhalov 	}
6016d86563SAlexander Pyhalov 
6116d86563SAlexander Pyhalov 	/* Initialize */
6216d86563SAlexander Pyhalov 	st->Sfunc = SI;
6316d86563SAlexander Pyhalov 	st->SSfunc = NONE;
6416d86563SAlexander Pyhalov 	st->ESCstate = OFF;
6516d86563SAlexander Pyhalov 	st->firstbyte = True;
6616d86563SAlexander Pyhalov 	st->numsav = 0;
67*f642269fSToomas Soome 	st->SOcharset = 0;		/* no default charset */
68*f642269fSToomas Soome 	st->SS2charset = 0;		/* no default charset */
69*f642269fSToomas Soome 	st->SS3charset = 0;		/* no default charset */
7016d86563SAlexander Pyhalov 	st->nonidcount = 0;
7116d86563SAlexander Pyhalov 	st->_errno = 0;
7216d86563SAlexander Pyhalov 
7316d86563SAlexander Pyhalov 	/* Return struct */
7416d86563SAlexander Pyhalov 	return ((void *) st);
7516d86563SAlexander Pyhalov }
7616d86563SAlexander Pyhalov 
7716d86563SAlexander Pyhalov 
7816d86563SAlexander Pyhalov 
7916d86563SAlexander Pyhalov /*
8016d86563SAlexander Pyhalov  * _icv_close: Called from iconv_close(). Frees the _iconv_st structure as
8116d86563SAlexander Pyhalov  *	       pointed by the argument.
8216d86563SAlexander Pyhalov  */
8316d86563SAlexander Pyhalov 
8416d86563SAlexander Pyhalov void
_icv_close(_iconv_st * st)8516d86563SAlexander Pyhalov _icv_close(_iconv_st *st)
8616d86563SAlexander Pyhalov {
8716d86563SAlexander Pyhalov 	if (st == NULL )
8816d86563SAlexander Pyhalov 	    errno = EBADF;
8916d86563SAlexander Pyhalov 	else
9016d86563SAlexander Pyhalov 	    free(st);
9116d86563SAlexander Pyhalov }
9216d86563SAlexander Pyhalov 
9316d86563SAlexander Pyhalov 
9416d86563SAlexander Pyhalov /*
9516d86563SAlexander Pyhalov  * _icv_iconv: Called from iconv(). Does the convertion from ISO2022-CN-EXT
9616d86563SAlexander Pyhalov  *			   to CNS11643
9716d86563SAlexander Pyhalov  */
9816d86563SAlexander Pyhalov /*=======================================================
9916d86563SAlexander Pyhalov  *
10016d86563SAlexander Pyhalov  *   State machine for interpreting ISO2022-CN-EXT code
10116d86563SAlexander Pyhalov  *
10216d86563SAlexander Pyhalov  *=======================================================
10316d86563SAlexander Pyhalov  *
10416d86563SAlexander Pyhalov  *
10516d86563SAlexander Pyhalov  *=======================================================*/
10616d86563SAlexander Pyhalov 
10716d86563SAlexander Pyhalov size_t
iso2022_icv_iconv(_iconv_st * st,char ** inbuf,size_t * inbytesleft,unsigned char ** outbuf,size_t * outbytesleft,int (* convert)())10816d86563SAlexander Pyhalov iso2022_icv_iconv(_iconv_st *st, char **inbuf, size_t *inbytesleft,
10916d86563SAlexander Pyhalov 			unsigned char **outbuf, size_t *outbytesleft, int (*convert)() )
11016d86563SAlexander Pyhalov {
11116d86563SAlexander Pyhalov 
11216d86563SAlexander Pyhalov 	int ret, n;
11316d86563SAlexander Pyhalov 
11416d86563SAlexander Pyhalov 	if (st == NULL) {
11516d86563SAlexander Pyhalov 	    errno = EBADF;
11616d86563SAlexander Pyhalov 	    return ((size_t) -1);
11716d86563SAlexander Pyhalov 	}
11816d86563SAlexander Pyhalov 
11916d86563SAlexander Pyhalov 	if ( inbuf == NULL || *inbuf == NULL || inbytesleft == NULL ||
12016d86563SAlexander Pyhalov 			*inbytesleft <= 0 ) { /* Reset request */
12116d86563SAlexander Pyhalov 	    st->Sfunc = SI;
12216d86563SAlexander Pyhalov 	    st->SSfunc = NONE;
12316d86563SAlexander Pyhalov 	    st->ESCstate = OFF;
12416d86563SAlexander Pyhalov 	    st->firstbyte = True;
12516d86563SAlexander Pyhalov 	    st->numsav = 0;
126*f642269fSToomas Soome 	    st->SOcharset = 0;
127*f642269fSToomas Soome 	    st->SS2charset = 0;
128*f642269fSToomas Soome 	    st->SS3charset = 0;
12916d86563SAlexander Pyhalov 	    st->nonidcount = 0;
13016d86563SAlexander Pyhalov 	    st->_errno = 0;
13116d86563SAlexander Pyhalov 	    return ((size_t) 0);
13216d86563SAlexander Pyhalov 	}
13316d86563SAlexander Pyhalov 
13416d86563SAlexander Pyhalov 	st->_errno = 0;
13516d86563SAlexander Pyhalov 	errno = 0;
13616d86563SAlexander Pyhalov 
13716d86563SAlexander Pyhalov 	/* Before we use *inbytesleft or *outbytesleft we should confirm that
13816d86563SAlexander Pyhalov 	inbytesleft and outbytesleft are non-NULL. I am considering inbytesleft
13916d86563SAlexander Pyhalov 	or *inbytesleft having 0 or negative value as a reset request. I am
14016d86563SAlexander Pyhalov 	considering outbytesleft having 0 value as no space in output buffer.
14116d86563SAlexander Pyhalov 	Also, here itself I am verifying that outbuf and *outbuf should be non-NULL
14216d86563SAlexander Pyhalov 	pointers so I do not have to worry about them being NULL below in the
14316d86563SAlexander Pyhalov 	conversion sub-routines. I also confirm here that *outbytesleft should be
14416d86563SAlexander Pyhalov 	greater than 0 before we can continue further */
14516d86563SAlexander Pyhalov 
14616d86563SAlexander Pyhalov 	if ( outbytesleft == NULL || *outbytesleft <= 0 ||
14716d86563SAlexander Pyhalov 			outbuf == NULL || *outbuf == NULL ) {
14816d86563SAlexander Pyhalov 	    errno = E2BIG;
14916d86563SAlexander Pyhalov 	    return((size_t)-1);
15016d86563SAlexander Pyhalov 	}
15116d86563SAlexander Pyhalov 
15216d86563SAlexander Pyhalov 	/* A state machine to interpret ISO, driven by the shift functions SI, SO */
15316d86563SAlexander Pyhalov 
15416d86563SAlexander Pyhalov 	do {
15516d86563SAlexander Pyhalov 	    if (st->firstbyte == False) { /* Is SO, SS2, SS3 second byte */
15616d86563SAlexander Pyhalov 		st->keepc[1] = **inbuf;
15716d86563SAlexander Pyhalov 		n = (*convert)( st, outbuf, outbytesleft, iscns(st) );
15816d86563SAlexander Pyhalov 		if ( n < 0 )
15916d86563SAlexander Pyhalov 		    return((size_t)-1); /* Insufficient space in output buffer */
16016d86563SAlexander Pyhalov 		else if ( n > 0 ){ /* No CNS for this Chinese code */
16116d86563SAlexander Pyhalov 		    n = ascii_to_euc(NON_ID_CHAR, st, outbuf, outbytesleft);
16216d86563SAlexander Pyhalov 		    if ( n < 0 )
16316d86563SAlexander Pyhalov 			return((size_t)-1);
16416d86563SAlexander Pyhalov 		    st->nonidcount += 1;
16516d86563SAlexander Pyhalov 		} else
16616d86563SAlexander Pyhalov 		    st->nonidcount -= 1; /* The first byte identified as
16716d86563SAlexander Pyhalov 						valid Chinese byte and is
16816d86563SAlexander Pyhalov 						processed */
16916d86563SAlexander Pyhalov 		st->firstbyte = True;
17016d86563SAlexander Pyhalov 		st->SSfunc = NONE;	/* If we just processed SS bytes,
17116d86563SAlexander Pyhalov 					   this will reset SSfunc to NONE. If
17216d86563SAlexander Pyhalov 					   we just processed SO bytes, this was
17316d86563SAlexander Pyhalov 					   already NONE */
17416d86563SAlexander Pyhalov 	    } else if ( st->SSfunc != NONE ) { /* We are currently expecting
17516d86563SAlexander Pyhalov 						 SS2 or SS3 Chinese bytes */
17616d86563SAlexander Pyhalov 		    st->keepc[0] = **inbuf;
17716d86563SAlexander Pyhalov 		    st->nonidcount += 1;
17816d86563SAlexander Pyhalov 		    st->firstbyte = False;
17916d86563SAlexander Pyhalov 	    } else if ( **inbuf == ESC && st->ESCstate == OFF ) {
18016d86563SAlexander Pyhalov 		    st->nonidcount += 1; /* For the ESC character */
18116d86563SAlexander Pyhalov 		    st->ESCstate = E0;
18216d86563SAlexander Pyhalov 	    } else if ( st->ESCstate != OFF ) { /* Continue processing the
18316d86563SAlexander Pyhalov 						  escape sequence */
18416d86563SAlexander Pyhalov 		ret = process_esc_seq( **inbuf, st );
185*f642269fSToomas Soome 		if ( ret == DONE ) {	/* ESC seq interpreted correctly.
18616d86563SAlexander Pyhalov 					     Switch off the escape machine */
18716d86563SAlexander Pyhalov 		    st->ESCstate = OFF;
18816d86563SAlexander Pyhalov 		} else if ( ret == INVALID ){
18916d86563SAlexander Pyhalov 		    if (st->Sfunc == SI){	/* An invalid ESC sequence
19016d86563SAlexander Pyhalov 						 encountered.  Process
19116d86563SAlexander Pyhalov 						 the text saved in
19216d86563SAlexander Pyhalov 						 st->savbuf as ASCII. Switch
19316d86563SAlexander Pyhalov 						 off the escape machine */
19416d86563SAlexander Pyhalov 			n = ascii_to_euc( **inbuf, st, outbuf, outbytesleft );
19516d86563SAlexander Pyhalov 			if ( n < 0 ) /* Insufficient space in output buffer */
19616d86563SAlexander Pyhalov 				return((size_t)-1);
19716d86563SAlexander Pyhalov 			st->nonidcount -= st->numsav; /* Since invalid Esc
19816d86563SAlexander Pyhalov 						       sequence is outputted
19916d86563SAlexander Pyhalov 						       as ASCII */
20016d86563SAlexander Pyhalov 		    } else if (st->Sfunc == SO) { /* An invalid ESC sequence
20116d86563SAlexander Pyhalov 						     encountered. Don't know
20216d86563SAlexander Pyhalov 						     what to do. So flag
20316d86563SAlexander Pyhalov 						     error illegal seq. It is
20416d86563SAlexander Pyhalov 						     wise not to continue
20516d86563SAlexander Pyhalov 						     processing input. Switch
20616d86563SAlexander Pyhalov 						     off the escape machine */
20716d86563SAlexander Pyhalov 			st->_errno = errno = EILSEQ;
20816d86563SAlexander Pyhalov 			st->nonidcount += 1; /* For this character */
20916d86563SAlexander Pyhalov 		    }
210*f642269fSToomas Soome 		    st->numsav = 0;	 /* Discard the saved characters of
21116d86563SAlexander Pyhalov 					    invalid sequence */
21216d86563SAlexander Pyhalov 		    st->ESCstate = OFF;
21316d86563SAlexander Pyhalov 		} /* more char. needed for escape sequence */
21416d86563SAlexander Pyhalov 	    } else if (st->Sfunc  == SI) {
21516d86563SAlexander Pyhalov 		/* Switch state to SO only if SOdesignation is set. */
216*f642269fSToomas Soome 		if ( **inbuf == SO && st->SOcharset != 0 ){
21716d86563SAlexander Pyhalov 		    st->Sfunc = SO;
21816d86563SAlexander Pyhalov 		} else { /* Is ASCII */
21916d86563SAlexander Pyhalov 		    n = ascii_to_euc(**inbuf, st, outbuf, outbytesleft );
22016d86563SAlexander Pyhalov 		    if ( n < 0 ) /* Insufficient space in output buffer */
22116d86563SAlexander Pyhalov 			return((size_t)-1);
22216d86563SAlexander Pyhalov 		}
22316d86563SAlexander Pyhalov 	    } else if (st->Sfunc  == SO) {
22416d86563SAlexander Pyhalov 		if ( **inbuf == SI ){ /* Switch state to SO */
22516d86563SAlexander Pyhalov 		    st->Sfunc = SI;
22616d86563SAlexander Pyhalov 		}
22716d86563SAlexander Pyhalov 		else {
22816d86563SAlexander Pyhalov 		    st->keepc[0] = **inbuf;
22916d86563SAlexander Pyhalov 		    st->nonidcount += 1;
23016d86563SAlexander Pyhalov 		    st->firstbyte = False;
23116d86563SAlexander Pyhalov 		}
23216d86563SAlexander Pyhalov 	    }
23316d86563SAlexander Pyhalov 	    else
23416d86563SAlexander Pyhalov 		fprintf(stderr,
23516d86563SAlexander Pyhalov 		    "_icv_iconv():ISO-CN-EXT->CNS:Should never have come here\n");
23616d86563SAlexander Pyhalov 
23716d86563SAlexander Pyhalov 	    (*inbuf)++;
23816d86563SAlexander Pyhalov 	    (*inbytesleft)--;
23916d86563SAlexander Pyhalov 
24016d86563SAlexander Pyhalov 	    if ( st->_errno)
24116d86563SAlexander Pyhalov 		break; /* Break out of while loop */
24216d86563SAlexander Pyhalov 
24316d86563SAlexander Pyhalov 	    if (errno) /* We set st->_errno before we set errno. If errno is set
24416d86563SAlexander Pyhalov 				      somewhere else we handle that here */
24516d86563SAlexander Pyhalov 		return((size_t)-1);
24616d86563SAlexander Pyhalov 
24716d86563SAlexander Pyhalov 	} while (*inbytesleft > 0 && *outbytesleft > 0);
24816d86563SAlexander Pyhalov 
24916d86563SAlexander Pyhalov 
25016d86563SAlexander Pyhalov /* We now have to handle the case where we have successfully processed the
25116d86563SAlexander Pyhalov    previous input character which exhausted the output buffer. This is handled
25216d86563SAlexander Pyhalov    by the while loop. However, since there are more input characters that
25316d86563SAlexander Pyhalov    haven't been processed yet, we need to set the errno appropriately and
25416d86563SAlexander Pyhalov    return -1. */
25516d86563SAlexander Pyhalov 	if ( *inbytesleft > 0 && *outbytesleft == 0) {
25616d86563SAlexander Pyhalov 	    errno = E2BIG;
25716d86563SAlexander Pyhalov 	    return((size_t)-1);
25816d86563SAlexander Pyhalov 	}
25916d86563SAlexander Pyhalov 	return (*inbytesleft + st->nonidcount);
26016d86563SAlexander Pyhalov }
26116d86563SAlexander Pyhalov 
26216d86563SAlexander Pyhalov 
26316d86563SAlexander Pyhalov static int
process_esc_seq(char c,_iconv_st * st)26416d86563SAlexander Pyhalov process_esc_seq( char c, _iconv_st *st )
26516d86563SAlexander Pyhalov {
26616d86563SAlexander Pyhalov 
26716d86563SAlexander Pyhalov 	switch(st->ESCstate){
26816d86563SAlexander Pyhalov 	case E0:
26916d86563SAlexander Pyhalov 	    switch (c){
27016d86563SAlexander Pyhalov 	    case SS2LOW:
271*f642269fSToomas Soome 		if ( st->SS2charset == 0 ){
27216d86563SAlexander Pyhalov 		    /* We do not expect SS2 shift function before
27316d86563SAlexander Pyhalov 		       SS2 designation is set */
27416d86563SAlexander Pyhalov 		    st->savbuf[0] = ESC;
27516d86563SAlexander Pyhalov 		    st->numsav = 1;
27616d86563SAlexander Pyhalov 		    return(INVALID);
27716d86563SAlexander Pyhalov 		}
27816d86563SAlexander Pyhalov 		st->SSfunc = SS2;
27916d86563SAlexander Pyhalov 		/* Since valid ESC sequence remove the ESC from the
28016d86563SAlexander Pyhalov 		   nonidcount */
28116d86563SAlexander Pyhalov 		st->nonidcount -= 1;
28216d86563SAlexander Pyhalov 		return(DONE);
28316d86563SAlexander Pyhalov 	    case SS3LOW:
284*f642269fSToomas Soome 		if ( st->SS3charset == 0 ){
28516d86563SAlexander Pyhalov 		    /* We do not expect SS3 shift function before
28616d86563SAlexander Pyhalov 		       SS3 designation is set */
28716d86563SAlexander Pyhalov 		    st->savbuf[0] = ESC;
28816d86563SAlexander Pyhalov 		    st->numsav = 1;
28916d86563SAlexander Pyhalov 		    return(INVALID);
29016d86563SAlexander Pyhalov 		}
29116d86563SAlexander Pyhalov 		st->SSfunc = SS3;
29216d86563SAlexander Pyhalov 		/* Since valid ESC sequence remove the ESC from the
29316d86563SAlexander Pyhalov 		   nonidcount */
29416d86563SAlexander Pyhalov 		st->nonidcount -= 1;
29516d86563SAlexander Pyhalov 		return(DONE);
29616d86563SAlexander Pyhalov 	    case '$':
29716d86563SAlexander Pyhalov 		st->nonidcount += 1; /* ESC sequence not complete yet */
29816d86563SAlexander Pyhalov 		st->ESCstate = E1;
29916d86563SAlexander Pyhalov 		return(NEEDMORE);
30016d86563SAlexander Pyhalov 	    default:
30116d86563SAlexander Pyhalov 		st->savbuf[0] = ESC;
30216d86563SAlexander Pyhalov 		st->numsav = 1;
30316d86563SAlexander Pyhalov 		return(INVALID);
30416d86563SAlexander Pyhalov 	    } /* end switch */
30516d86563SAlexander Pyhalov 
30616d86563SAlexander Pyhalov 
30716d86563SAlexander Pyhalov 	case E1:
30816d86563SAlexander Pyhalov 	    switch (c){
30916d86563SAlexander Pyhalov 	    case ')':
31016d86563SAlexander Pyhalov 		st->nonidcount += 1; /* ESC sequence not complete yet */
31116d86563SAlexander Pyhalov 		st->ESCstate = E2;
31216d86563SAlexander Pyhalov 		return(NEEDMORE);
31316d86563SAlexander Pyhalov 	    case '*':
31416d86563SAlexander Pyhalov 		st->nonidcount += 1; /* ESC sequence not complete yet */
31516d86563SAlexander Pyhalov 		st->ESCstate = E3;
31616d86563SAlexander Pyhalov 		return(NEEDMORE);
31716d86563SAlexander Pyhalov 	    case '+':
31816d86563SAlexander Pyhalov 		st->nonidcount += 1; /* ESC sequence not complete yet */
31916d86563SAlexander Pyhalov 		st->ESCstate = E4;
32016d86563SAlexander Pyhalov 		return(NEEDMORE);
32116d86563SAlexander Pyhalov 	    default:
32216d86563SAlexander Pyhalov 		st->savbuf[0] = ESC;
32316d86563SAlexander Pyhalov 		st->savbuf[1] = '$';
32416d86563SAlexander Pyhalov 		st->numsav = 2;
32516d86563SAlexander Pyhalov 		return(INVALID);
32616d86563SAlexander Pyhalov 	    }
32716d86563SAlexander Pyhalov 
32816d86563SAlexander Pyhalov 	case E2:
32916d86563SAlexander Pyhalov 	    st->SOcharset = c;
33016d86563SAlexander Pyhalov 	    /* Since valid ESC sequence remove decriment nonidcount
33116d86563SAlexander Pyhalov 	       appropriately for all earlier characters in escape sequence */
33216d86563SAlexander Pyhalov 	    st->nonidcount -= 3;
33316d86563SAlexander Pyhalov 	    return(DONE);
33416d86563SAlexander Pyhalov 
33516d86563SAlexander Pyhalov 	case E3:
33616d86563SAlexander Pyhalov 	    st->SS2charset = c;
33716d86563SAlexander Pyhalov 	    /* Since valid ESC sequence remove decriment nonidcount
33816d86563SAlexander Pyhalov 	       appropriately for all earlier characters in escape sequence */
33916d86563SAlexander Pyhalov 	    st->nonidcount -= 3;
34016d86563SAlexander Pyhalov 	    return(DONE);
34116d86563SAlexander Pyhalov 
34216d86563SAlexander Pyhalov 	case E4:
34316d86563SAlexander Pyhalov 	    st->SS3charset = c;
34416d86563SAlexander Pyhalov 	    /* Since valid ESC sequence remove decriment nonidcount
34516d86563SAlexander Pyhalov 	       appropriately for all earlier characters in escape sequence */
34616d86563SAlexander Pyhalov 	    st->nonidcount -= 3;
34716d86563SAlexander Pyhalov 	    return(DONE);
34816d86563SAlexander Pyhalov 
34916d86563SAlexander Pyhalov 	default:
35016d86563SAlexander Pyhalov 	    fprintf(stderr,
35116d86563SAlexander Pyhalov 		    "process_esc_seq():ISO-CN-EXT->CNS:Should never have come here\n");
35216d86563SAlexander Pyhalov 	    st->_errno = errno = EILSEQ;
35316d86563SAlexander Pyhalov 	    return(DONE);
35416d86563SAlexander Pyhalov 
35516d86563SAlexander Pyhalov 	} /* end switch */
35616d86563SAlexander Pyhalov }
35716d86563SAlexander Pyhalov 
35816d86563SAlexander Pyhalov 
35916d86563SAlexander Pyhalov static int
ascii_to_euc(char c,_iconv_st * st,unsigned char ** outbuf,size_t * outbytesleft)36016d86563SAlexander Pyhalov ascii_to_euc( char c, _iconv_st *st, unsigned char **outbuf, size_t *outbytesleft )
36116d86563SAlexander Pyhalov {
36216d86563SAlexander Pyhalov 
36316d86563SAlexander Pyhalov 	int i;
36416d86563SAlexander Pyhalov 
36516d86563SAlexander Pyhalov 	if ( *outbytesleft < (1 + st->numsav) ) {
36616d86563SAlexander Pyhalov 	    st->_errno = errno = E2BIG;
36716d86563SAlexander Pyhalov 	    return (-1);
36816d86563SAlexander Pyhalov 	}
36916d86563SAlexander Pyhalov 
37016d86563SAlexander Pyhalov 	for ( i=0; i < st->numsav; i++ ) {
37116d86563SAlexander Pyhalov 	    *(*outbuf)++ = (unsigned char) st->savbuf[i];
37216d86563SAlexander Pyhalov 	    (*outbytesleft)--;
37316d86563SAlexander Pyhalov 	}
37416d86563SAlexander Pyhalov 
37516d86563SAlexander Pyhalov 	*(*outbuf)++ = (unsigned char) c;
37616d86563SAlexander Pyhalov 	(*outbytesleft)--;
37716d86563SAlexander Pyhalov 
37816d86563SAlexander Pyhalov 	return(0);
37916d86563SAlexander Pyhalov }
38016d86563SAlexander Pyhalov 
38116d86563SAlexander Pyhalov 
38216d86563SAlexander Pyhalov static int
iscns(_iconv_st * st)38316d86563SAlexander Pyhalov iscns( _iconv_st *st )
38416d86563SAlexander Pyhalov {
38516d86563SAlexander Pyhalov 	int plane_no = -1;
38616d86563SAlexander Pyhalov 
387*f642269fSToomas Soome 	if ( st->SSfunc == NONE && st->SOcharset == 'G' )
38816d86563SAlexander Pyhalov 	    plane_no = 1;
38916d86563SAlexander Pyhalov 	else if ( st->SSfunc == SS2 && st->SS2charset == 'H' )
39016d86563SAlexander Pyhalov 	    plane_no = 2;
39116d86563SAlexander Pyhalov 	else if ( st->SSfunc == SS3 )
39216d86563SAlexander Pyhalov 	    switch ( st->SS3charset ){
39316d86563SAlexander Pyhalov 	    case 'I': plane_no = 3; break;
39416d86563SAlexander Pyhalov 	    case 'J': plane_no = 4; break;
39516d86563SAlexander Pyhalov 	    case 'K': plane_no = 5; break;
39616d86563SAlexander Pyhalov 	    case 'L': plane_no = 6; break;
39716d86563SAlexander Pyhalov 	    case 'M': plane_no = 7; break;
39816d86563SAlexander Pyhalov 	    }
39916d86563SAlexander Pyhalov 	return (plane_no);
40016d86563SAlexander Pyhalov }
401