1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LSTDIO/UNGETC.C Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,151 @@
1.4 +/* UNGETC.C
1.5 + *
1.6 + * Portions Copyright (c) 1990-1999 Nokia Corporation and/or its subsidiary(-ies).
1.7 + * All rights reserved.
1.8 + */
1.9 +
1.10 +/*
1.11 + * Copyright (c) 1990 The Regents of the University of California.
1.12 + * All rights reserved.
1.13 + *
1.14 + * Redistribution and use in source and binary forms are permitted
1.15 + * provided that the above copyright notice and this paragraph are
1.16 + * duplicated in all such forms and that any documentation,
1.17 + * advertising materials, and other materials related to such
1.18 + * distribution and use acknowledge that the software was developed
1.19 + * by the University of California, Berkeley. The name of the
1.20 + * University may not be used to endorse or promote products derived
1.21 + * from this software without specific prior written permission.
1.22 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1.23 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1.24 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1.25 + */
1.26 +
1.27 +#include <stdio_r.h>
1.28 +#include <stdlib_r.h>
1.29 +#include <string.h>
1.30 +#include "LOCAL.H"
1.31 +
1.32 +/*
1.33 + * Expand the ungetc buffer `in place'. That is, adjust fp->_p when
1.34 + * the buffer moves, so that it points the same distance from the end,
1.35 + * and move the bytes in the buffer around as necessary so that they
1.36 + * are all at the end (stack-style).
1.37 + */
1.38 +
1.39 +/*static*/
1.40 +int
1.41 +__submore (register FILE *fp)
1.42 +{
1.43 + register int i;
1.44 + register unsigned char *p;
1.45 +
1.46 + if (fp->_ub._base == fp->_ubuf)
1.47 + {
1.48 + /*
1.49 + * Get a new buffer (rather than expanding the old one).
1.50 + */
1.51 + if ((p = (unsigned char *) _malloc_r (fp->_data, (size_t) BUFSIZ)) == NULL)
1.52 + return EOF;
1.53 + fp->_ub._base = p;
1.54 + fp->_ub._size = BUFSIZ;
1.55 + p += BUFSIZ - sizeof (fp->_ubuf);
1.56 + for (i = sizeof (fp->_ubuf); --i >= 0;)
1.57 + p[i] = fp->_ubuf[i];
1.58 + fp->_p = p;
1.59 + return 0;
1.60 + }
1.61 + i = fp->_ub._size;
1.62 + p = (unsigned char *) _realloc_r (fp->_data, (void*) (fp->_ub._base), i << 1);
1.63 + if (p == NULL)
1.64 + return EOF;
1.65 + (void) memcpy ((void *) (p + i), (void *) p, (size_t) i);
1.66 + fp->_p = p + i;
1.67 + fp->_ub._base = p;
1.68 + fp->_ub._size = i << 1;
1.69 + return 0;
1.70 +}
1.71 +
1.72 +/**
1.73 +Push a character back into stream.
1.74 +@return If successful, the character putted is returned.
1.75 +Otherwise EOF is returned and the stream remains unchanged.
1.76 +@param c character to be pushed.
1.77 +@param fp pointer to an open file.
1.78 +*/
1.79 +EXPORT_C int
1.80 +ungetc (int c,register FILE *fp)
1.81 +{
1.82 + if (c == EOF)
1.83 + return (EOF);
1.84 +
1.85 + /* Ensure stdio has been initialized.
1.86 + ??? Might be able to remove this as some other stdio routine should
1.87 + have already been called to get the char we are un-getting. */
1.88 +
1.89 + CHECK_INIT (fp);
1.90 +
1.91 + /* After ungetc, we won't be at eof anymore */
1.92 + fp->_flags &= ~__SEOF;
1.93 +
1.94 + if ((fp->_flags & __SRD) == 0)
1.95 + {
1.96 + /*
1.97 + * Not already reading: no good unless reading-and-writing.
1.98 + * Otherwise, flush any current write stuff.
1.99 + */
1.100 + if ((fp->_flags & __SRW) == 0)
1.101 + return EOF;
1.102 + if (fp->_flags & __SWR)
1.103 + {
1.104 + if (fflush (fp))
1.105 + return EOF;
1.106 + fp->_flags &= ~__SWR;
1.107 + fp->_w = 0;
1.108 + fp->_lbfsize = 0;
1.109 + }
1.110 + fp->_flags |= __SRD;
1.111 + }
1.112 + c = (unsigned char) c;
1.113 +
1.114 + /*
1.115 + * If we are in the middle of ungetc'ing, just continue.
1.116 + * This may require expanding the current ungetc buffer.
1.117 + */
1.118 +
1.119 + if (HASUB (fp))
1.120 + {
1.121 + if (fp->_r >= fp->_ub._size && __submore (fp))
1.122 + return EOF;
1.123 + *--fp->_p = (unsigned char)c;
1.124 + fp->_r++;
1.125 + return c;
1.126 + }
1.127 +
1.128 + /*
1.129 + * If we can handle this by simply backing up, do so,
1.130 + * but never replace the original character.
1.131 + * (This makes sscanf() work when scanning `const' data.)
1.132 + */
1.133 +
1.134 + if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && fp->_p[-1] == c)
1.135 + {
1.136 + fp->_p--;
1.137 + fp->_r++;
1.138 + return c;
1.139 + }
1.140 +
1.141 + /*
1.142 + * Create an ungetc buffer.
1.143 + * Initially, we will use the `reserve' buffer.
1.144 + */
1.145 +
1.146 + fp->_ur = fp->_r;
1.147 + fp->_up = fp->_p;
1.148 + fp->_ub._base = fp->_ubuf;
1.149 + fp->_ub._size = sizeof (fp->_ubuf);
1.150 + fp->_ubuf[sizeof (fp->_ubuf) - 1] = (unsigned char)c;
1.151 + fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1];
1.152 + fp->_r = 1;
1.153 + return c;
1.154 +}