/*
 * |-----------------------------------------------------------|
 * | 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: fputwc.c,v 1.1.2.1 92/06/24 14:10:58 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 MNLS on Sep.03.86		*/
/*	This module is modified for MNLS 3.2 on Jan.18.1989		*/

#ident	"@(#)libw-port:wstdio/fputwc.c	1.0"

/*
 * Fputwc transforms the process code c into the EUC,
 * and writes it onto the output stream "iop".
 */
#include "shlib.h"
#include <stdio.h>
#include <errno.h>
/*	start for MNLS3.2 by Unix Pacific on Jan.18.1989	*/
#include <euc.h>
/*	end for MNLS3.2	*/
#include "pcode.h"
#define putbyte(x,p)	{ if (putc((x),(p)) == EOF) return(EOF); }

extern int  _flsbuf();
extern void _xgetwidth();
extern int  _cswidth[];
/*	start for MNLS3.2 by Unix Pacific on Jan.18.1989	*/
extern eucwidth_t _eucwidth;
#define pcw	_eucwidth._pcw
/*	end for MNLS3.2	*/

int
fputwc(c, iop)
register c;
register FILE *iop;
{
	register size, i, ssch;

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

	/*
	 * "Switch" on a pattern of "00", "11", "01", or "10",
	 * depending on high bits of low two bytes of Process Code.
	 */
/*	start for MNLS3.2 by Unix Pacific on Jan.18.1989	*/
	if(pcw > sizeof(unsigned short)) {
	switch (c & F_EUCMASK) {
		case F_P00: /* Code Set 0 */
			putbyte(c, iop);
			return(c);
		case F_P11: /* Code Set 1 */
			ssch = 0;
			size = _cswidth[1];
			break;
		case F_P01: /* Code Set 2 */
			if (control1(c)) { /* control character 1 */
				putbyte(c, iop);
				return(c);
			}
			ssch = SS2;
			size = _cswidth[2];
			break;
		case F_P10: /* Code Set 3 */
			ssch = SS3;
			size = _cswidth[3];
	}
	} else {
	switch (c & EUCMASK) {
		case P00: /* Code Set 0 */
			putbyte(c, iop);
			return(c);
		case P11: /* Code Set 1 */
			ssch = 0;
			size = _cswidth[1];
			break;
		case P01: /* Code Set 2 */
			if (control1(c)) { /* control character 1 */
				putbyte(c, iop);
				return(c);
			}
			ssch = SS2;
			size = _cswidth[2];
			break;
		case P10: /* Code Set 3 */
			ssch = SS3;
			size = _cswidth[3];
	}
	}
/*	end for MNLS3.2	*/
	/*
	 * Error checking for Process Code in supplementary code set.
	 */
	if (size == 0 ) { /* EUC size is zero */
		errno = EILSEQ;
		return(EOF);
	}
	i = size;
	while (i--) { /* Check each byte */
	/*	start for MNLS3.2 by Unix Pacific on Jan.18.1989	*/
		if(pcw > sizeof(unsigned short)) {
			if ( controlc(c >> (i * 7)) ) { /* Error if 8 bits pattern is */
				errno = EILSEQ;         /* a control character */
				return(EOF);
			}
		} else {
			if ( controlc(c >> (i * 8)) ) { /* Error if 8 bits pattern is */
				errno = EILSEQ;         /* a control character */
				return(EOF);
			}
		}
	/*	end for MNLS3.2	*/
	}
	/*
	 * Output Single Shift Code For Set 2 or 3
	 */
	if (ssch) {
		putbyte(ssch, iop);
	}
	/*
	 * Output bytes from highest order to lowest order, masking
	 * the high order bits of the process code to ON. The return
	 * expression shifts the char right by the correct number of
	 * bits, ANDs it with FF to make sure we only get the lowest
	 * byte. If unexpected EOF occurs in this loop, return EOF
	 * for the whole thing.
	 */
	while (size--) {
	/*	start for MNLS3.2 by Unix Pacific on Jan.18.1989	*/
		if(pcw > sizeof(unsigned short)) {
			putbyte((c >> (size * 7) & 0xFF | 0x80), iop);
		} else {
			putbyte((c >> (size * 8) & 0xFF | 0x80), iop);
		}
	/*	end for MNLS3.2	*/
	}
	return(c);
}
