/*
 * |-----------------------------------------------------------|
 * | Copyright (c) 1990 MIPS Computer Systems, Inc.            |
 * | All Rights Reserved                                       |
 * |-----------------------------------------------------------|
 * |          Restricted Rights Legend                         |
 * | Use, duplication, or disclosure by the Government is      |
 * | subject to restrictions as set forth in                   |
 * | subparagraph (c)(1)(ii) of the Rights in Technical        |
 * | Data and Computer Software Clause of DFARS 52.227-7013.   |
 * |         MIPS Computer Systems, Inc.                       |
 * |         928 Arques Avenue                                 |
 * |         Sunnyvale, CA 94086                               |
 * |-----------------------------------------------------------|
 */
#ident	"$Header: strtows.c,v 1.1.2.1 92/06/24 14:11:06 marker Exp $"

/*	Copyright (c) 1986 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

/*	This module is created for NLS on Sep.03.86		*/

/*	This module is modified for MNLS 3.2 on Lan 18 1989	*/

#ident	"@(#)libw-port:wstring/strtows.c	1.0"

/*
 * Strtows transforms EUC in character string "s2" into
 * the process codes, and transfers those to wchar_t string "s1",
 * stopping after the NULL character has been processed.
 */

#include "shlib.h"
#include <widec.h>
#include <errno.h>
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
#include <euc.h>
/*	end for MNLS 3.2	*/
#include "pcode.h"
#define  NULL	0

extern void _xgetwidth();
extern int  _cswidth[];
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/* extern int  _pcmask[];	*/
extern eucwidth_t _eucwidth;
#define pcw	_eucwidth._pcw	/* use for checking wchar_t is 2 or 4 bytes	*/
/*	end for MNLS 3.2	*/

wchar_t *
strtows(s1, s2)
register wchar_t *s1;
register char *s2;
{
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*	register size, temp, cset;	*/
	register size, temp, mask;
/*	end for MNLS 3.2	*/
	register wchar_t *os1 = s1;

	if (! *_cswidth)
		_xgetwidth(); /* get character width */

	while (*s2) {
		if (! (*s2 & 0x80)) { /* Code Set 0 */
			*s1++ = *s2++;
			continue;
		}
		/*
		 * "Size" tells us how many bytes to expect following.
		 */
		temp = 0;
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*		switch (*s2) {	*/
		switch (*s2 & 0377) {
/*	end for MNLS 3.2	*/
			case SS2: /* Code Set 2 */
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*				cset = 2;	*/
				if (pcw > sizeof(unsigned short))
					mask = F_P01;	/* wchar_t is long	*/
				else
					mask = P01;	/* wchar_t is short	*/
/*	end for MNLS 3.2	*/
				size = _cswidth[2];
				goto testsize;
			case SS3: /* Code set 3 */
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*				cset = 3;	*/
				if (pcw > sizeof(unsigned short))
					mask = F_P10;	/* wchar_t is long	*/
				else
					mask = P10;	/* wchar_t is short	*/
/*	end for MNLS 3.2	*/
				size = _cswidth[3];
			testsize:
				if (size == 0) {
					*s1++ = *s2++;
					continue;
				}
				break;
			default:  /* Code Set 1 */
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*				if (control1(*s2)) { /* control character 1 */
				if (control1(*s2 & 0377)) { /* control character 1 */
/*	end for MNLS 3.2	*/
					*s1++ = *s2++;
					continue;
				}
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*				cset = 1;	*/
				if (pcw > sizeof(unsigned short))
					mask = F_P11;	/* wchar_t is long	*/
				else
					mask = P11;	/* wchar_t is short	*/
/*	end for MNLS 3.2	*/
				if ((size = _cswidth[1] - 1) >= 0)
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*					temp = *s2;		*/
					temp = (*s2 & 0177);
/*	end for MNLS 3.2	*/
				else { /* EUC size is zero */
					*s1 = 0;
					errno = EILSEQ;
					return(NULL);
				}
		}
		s2++;
		/*
		 * This loop shifts previous bytes left, sticking
		 * the new byte into the low order byte of temp.
		 */
		while (size--) {
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*			if (!graphic(*s2)) {	*/
			if (!graphic(*s2 & 0377)) {
/*	end for MNLS 3.2	*/
				*s1 = 0;
				errno = EILSEQ;
				return(NULL);
			}
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*			temp = (temp << 8) | *s2++;		*/
			if (pcw > sizeof(unsigned short))
				temp = ((temp << 7) | (*s2++ & 0177));
			else
				temp = ((temp << 8) | (*s2++ & 0177));
/*	end for MNLS 3.2	*/
		}
		/*
		 * Mask the value so that it fits into the proper
		 * character set pattern for the high order bits
		 * of each byte:
		 *     CS0-0000  CS1=0011  CS2=0001  CS3=0010
		 */
/*	start for MNLS 3.2 by UNIX Pacific on Jan 19 1989	*/
/*		*s1++ = (temp | EUCMASK) & _pcmask[cset];	*/
		*s1++ = (temp | mask);
/*	end for MNLS 3.2	*/
	}
	*s1 = 0;
	return(os1);
}
