101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes/*	$OpenBSD: ungetwc.c,v 1.5 2011/10/16 13:20:51 stsp Exp $	*/
201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes/* $NetBSD: ungetwc.c,v 1.2 2003/01/18 11:29:59 thorpej Exp $ */
301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes/*-
501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * Copyright (c)2001 Citrus Project,
601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * All rights reserved.
701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes *
801ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * Redistribution and use in source and binary forms, with or without
901ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * modification, are permitted provided that the following conditions
1001ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * are met:
1101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * 1. Redistributions of source code must retain the above copyright
1201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes *    notice, this list of conditions and the following disclaimer.
1301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright
1401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes *    notice, this list of conditions and the following disclaimer in the
1501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes *    documentation and/or other materials provided with the distribution.
1601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes *
1701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1801ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1901ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2001ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * SUCH DAMAGE.
2801ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes *
2901ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes * $Citrus$
3001ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes */
3101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
3201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes#include <errno.h>
3301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes#include <stdio.h>
3401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes#include <wchar.h>
3501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes#include "local.h"
3601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
3701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hugheswint_t
3801ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes__ungetwc(wint_t wc, FILE *fp)
3901ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes{
4001ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	struct wchar_io_data *wcio;
4101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
4201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	if (wc == WEOF)
4301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes		return WEOF;
4401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
4501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	_SET_ORIENTATION(fp, 1);
4601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	/*
4701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	 * XXX since we have no way to transform a wchar string to
4801ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	 * a char string in reverse order, we can't use ungetc.
4901ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	 */
5001ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	/* XXX should we flush ungetc buffer? */
5101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
5201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	wcio = WCIO_GET(fp);
5301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	if (wcio == 0) {
5401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes		errno = ENOMEM; /* XXX */
5501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes		return WEOF;
5601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	}
5701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
5801ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	if (wcio->wcio_ungetwc_inbuf >= WCIO_UNGETWC_BUFSIZE) {
5901ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes		return WEOF;
6001ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	}
6101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
6201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	wcio->wcio_ungetwc_buf[wcio->wcio_ungetwc_inbuf++] = wc;
6301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	__sclearerr(fp);
6401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
6501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	return wc;
6601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes}
6701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
6801ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hugheswint_t
6901ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughesungetwc(wint_t wc, FILE *fp)
7001ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes{
7101ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	wint_t r;
7201ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes
7301ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	FLOCKFILE(fp);
7401ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	r = __ungetwc(wc, fp);
7501ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	FUNLOCKFILE(fp);
7601ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes	return (r);
7701ae00f3170ad0e36c1657f6ff8c89dfa730fd37Elliott Hughes}
78