+++ /dev/null
-/** @file\r
- Implementation of ungetc as declared in <stdio.h>.\r
-\r
- Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials are licensed and made available\r
- under the terms and conditions of the BSD License that accompanies this\r
- distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
- Copyright (c) 1990, 1993\r
- The Regents of the University of California. All rights reserved.\r
-\r
- This code is derived from software contributed to Berkeley by\r
- Chris Torek.\r
-\r
- Redistribution and use in source and binary forms, with or without\r
- modification, are permitted provided that the following conditions\r
- are met:\r
- - Redistributions of source code must retain the above copyright\r
- notice, this list of conditions and the following disclaimer.\r
- - Redistributions in binary form must reproduce the above copyright\r
- notice, this list of conditions and the following disclaimer in the\r
- documentation and/or other materials provided with the distribution.\r
- - Neither the name of the University nor the names of its contributors\r
- may be used to endorse or promote products derived from this software\r
- without specific prior written permission.\r
-\r
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE\r
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- POSSIBILITY OF SUCH DAMAGE.\r
-\r
- NetBSD: ungetc.c,v 1.14 2003/08/07 16:43:34 agc Exp\r
- ungetc.c 8.2 (Berkeley) 11/3/93\r
-**/\r
-#include <LibConfig.h>\r
-\r
-#include <assert.h>\r
-#include <errno.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include "reentrant.h"\r
-#include "local.h"\r
-\r
-static int __submore(FILE *);\r
-/*\r
- * Expand the ungetc buffer `in place'. That is, adjust fp->_p when\r
- * the buffer moves, so that it points the same distance from the end,\r
- * and move the bytes in the buffer around as necessary so that they\r
- * are all at the end (stack-style).\r
- */\r
-static int\r
-__submore(FILE *fp)\r
-{\r
- int i;\r
- unsigned char *p;\r
-\r
- _DIAGASSERT(fp != NULL);\r
- if(fp == NULL) {\r
- errno = EINVAL;\r
- return (EOF);\r
- }\r
-\r
- if (_UB(fp)._base == fp->_ubuf) {\r
- /*\r
- * Get a new buffer (rather than expanding the old one).\r
- */\r
- if ((p = malloc((size_t)BUFSIZ)) == NULL)\r
- return (EOF);\r
- _UB(fp)._base = p;\r
- _UB(fp)._size = BUFSIZ;\r
- p += BUFSIZ - sizeof(fp->_ubuf);\r
- for (i = sizeof(fp->_ubuf); --i >= 0;)\r
- p[i] = fp->_ubuf[i];\r
- fp->_p = p;\r
- return (0);\r
- }\r
- i = _UB(fp)._size;\r
- p = realloc(_UB(fp)._base, (size_t)(i << 1));\r
- if (p == NULL)\r
- return (EOF);\r
- /* no overlap (hence can use memcpy) because we doubled the size */\r
- (void)memcpy((void *)(p + i), (void *)p, (size_t)i);\r
- fp->_p = p + i;\r
- _UB(fp)._base = p;\r
- _UB(fp)._size = i << 1;\r
- return (0);\r
-}\r
-\r
-int\r
-ungetc(int c, FILE *fp)\r
-{\r
- _DIAGASSERT(fp != NULL);\r
- if(fp == NULL) {\r
- errno = EINVAL;\r
- return (EOF);\r
- }\r
-\r
- if (c == EOF)\r
- return (EOF);\r
- if (!__sdidinit)\r
- __sinit();\r
- FLOCKFILE(fp);\r
- _SET_ORIENTATION(fp, -1);\r
- if ((fp->_flags & __SRD) == 0) {\r
- /*\r
- * Not already reading: no good unless reading-and-writing.\r
- * Otherwise, flush any current write stuff.\r
- */\r
- if ((fp->_flags & __SRW) == 0) {\r
- FUNLOCKFILE(fp);\r
- return (EOF);\r
- }\r
- if (fp->_flags & __SWR) {\r
- if (__sflush(fp)) {\r
- FUNLOCKFILE(fp);\r
- return (EOF);\r
- }\r
- fp->_flags &= ~__SWR;\r
- fp->_w = 0;\r
- fp->_lbfsize = 0;\r
- }\r
- fp->_flags |= __SRD;\r
- }\r
- c = (unsigned char)c;\r
-\r
- /*\r
- * If we are in the middle of ungetc'ing, just continue.\r
- * This may require expanding the current ungetc buffer.\r
- */\r
- if (HASUB(fp)) {\r
- if (fp->_r >= _UB(fp)._size && __submore(fp)) {\r
- FUNLOCKFILE(fp);\r
- return (EOF);\r
- }\r
- *--fp->_p = (unsigned char)c;\r
- fp->_r++;\r
- FUNLOCKFILE(fp);\r
- return (c);\r
- }\r
- fp->_flags &= ~__SEOF;\r
-\r
- /*\r
- * If we can handle this by simply backing up, do so,\r
- * but never replace the original character.\r
- * (This makes sscanf() work when scanning `const' data.)\r
- */\r
- if (fp->_bf._base != NULL && fp->_p > fp->_bf._base &&\r
- fp->_p[-1] == c) {\r
- fp->_p--;\r
- fp->_r++;\r
- FUNLOCKFILE(fp);\r
- return (c);\r
- }\r
-\r
- /*\r
- * Create an ungetc buffer.\r
- * Initially, we will use the `reserve' buffer.\r
- */\r
- fp->_ur = fp->_r;\r
- fp->_up = fp->_p;\r
- _UB(fp)._base = fp->_ubuf;\r
- _UB(fp)._size = sizeof(fp->_ubuf);\r
- fp->_ubuf[sizeof(fp->_ubuf) - 1] = (unsigned char)c;\r
- fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];\r
- fp->_r = 1;\r
- FUNLOCKFILE(fp);\r
- return (c);\r
-}\r