ungetc.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:7k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ungetc.c - return a character to a stream. stdio.h */
  2. /* Copyright 1992-1993 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01c,05mar93,jdi  documentation cleanup for 5.1.
  7. 01b,20sep92,smb  documentation additions
  8. 01a,29jul92,jcf  Added OBJ_VERIFY
  9.    +smb  taken from UCB stdio
  10. */
  11. /*
  12. DESCRIPTION
  13.  * Copyright (c) 1990 The Regents of the University of California.
  14.  * All rights reserved.
  15.  *
  16.  * This code is derived from software contributed to Berkeley by
  17.  * Chris Torek.
  18.  *
  19.  * Redistribution and use in source and binary forms, with or without
  20.  * modification, are permitted provided that the following conditions
  21.  * are met:
  22.  * 1. Redistributions of source code must retain the above copyright
  23.  *    notice, this list of conditions and the following disclaimer.
  24.  * 2. Redistributions in binary form must reproduce the above copyright
  25.  *    notice, this list of conditions and the following disclaimer in the
  26.  *    documentation and/or other materials provided with the distribution.
  27.  * 3. All advertising materials mentioning features or use of this software
  28.  *    must display the following acknowledgement:
  29.  * This product includes software developed by the University of
  30.  * California, Berkeley and its contributors.
  31.  * 4. Neither the name of the University nor the names of its contributors
  32.  *    may be used to endorse or promote products derived from this software
  33.  *    without specific prior written permission.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  36.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  38.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  39.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  40.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  41.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  42.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  43.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  44.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  45.  * SUCH DAMAGE.
  46. INCLUDE FILE: stdio.h, stdlib.h, string.h
  47. SEE ALSO: American National Standard X3.159-1989
  48. NOMANUAL
  49. */
  50. #include "vxWorks.h"
  51. #include "stdio.h"
  52. #include "stdlib.h"
  53. #include "string.h"
  54. #include "objLib.h"
  55. #include "private/stdioP.h"
  56. /******************************************************************************
  57. *
  58. * __submore - internal routine
  59. *
  60. * Expand the ungetc buffer `in place'.  That is, adjust fp->_p when
  61. * the buffer moves, so that it points the same distance from the end,
  62. * and move the bytes in the buffer around as necessary so that they
  63. * are all at the end (stack-style).
  64. * INCLUDE FILES: stdio.h 
  65. *
  66. * RETURNS: 
  67. * NOMANUAL
  68. */
  69. static int __submore
  70.     (
  71.     FAST FILE *fp
  72.     )
  73.     {
  74.     FAST int       i;
  75.     FAST uchar_t * p;
  76.     if (fp->_ub._base == fp->_ubuf) 
  77. {
  78. /* Get a new buffer (rather than expanding the old one) */
  79. if ((p = malloc ((size_t)BUFSIZ)) == NULL)
  80.     return (EOF);
  81. fp->_ub._base = p;
  82. fp->_ub._size = BUFSIZ;
  83. p += BUFSIZ - sizeof(fp->_ubuf);
  84. for (i = sizeof(fp->_ubuf); --i >= 0;)
  85.     p[i] = fp->_ubuf[i];
  86. fp->_p = p;
  87. return (0);
  88. }
  89.     i = fp->_ub._size;
  90.     p = realloc (fp->_ub._base, i << 1);
  91.     if (p == NULL)
  92. return (EOF);
  93.     (void) bcopy ((void *)p, (void *)(p + i), (size_t)i);
  94.     fp->_p   = p + i;
  95.     fp->_ub._base = p;
  96.     fp->_ub._size = i << 1;
  97.     return (0);
  98.     }
  99. /******************************************************************************
  100. *
  101. * ungetc - push a character back into an input stream (ANSI)
  102. *
  103. * This routine pushes a character <c> (converted to an `unsigned char') back
  104. * into the specified input stream.  The pushed-back characters will be
  105. * returned by subsequent reads on that stream in the reverse order of their
  106. * pushing.  A successful intervening call on the stream to a file
  107. * positioning function (fseek(), fsetpos(), or rewind()) discards any
  108. * pushed-back characters for the stream.  The external storage corresponding
  109. * to the stream is unchanged.
  110. *
  111. * One character of push-back is guaranteed.  If ungetc() is called too many
  112. * times on the same stream without an intervening read or file positioning
  113. * operation, the operation may fail.
  114. *
  115. * If the value of <c> equals EOF, the operation fails and the 
  116. * input stream is unchanged.
  117. *
  118. * A successful call to ungetc() clears the end-of-file indicator for the
  119. * stream.  The value of the file position indicator for the stream after
  120. * reading or discarding all pushed-back characters is the same as it was
  121. * before the character were pushed back.  For a text stream, the value of
  122. * its file position indicator after a successful call to ungetc() is
  123. * unspecified until all pushed-back characters are read or discarded.
  124. * For a binary stream, the file position indicator is decremented by each
  125. * successful call to ungetc(); if its value was zero before a call, it is
  126. * indeterminate after the call.
  127. * INCLUDE: stdio.h 
  128. *
  129. * RETURNS:
  130. * The pushed-back character after conversion, or EOF if the operation fails.
  131. *
  132. * SEE ALSO: getc(), fgetc()
  133. */
  134. int ungetc
  135.     (
  136.     int  c, /* character to push */
  137.     FAST FILE *  fp /* input stream */
  138.     )
  139.     {
  140.     if (OBJ_VERIFY (fp, fpClassId) != OK)
  141. return (EOF);
  142.     if (c == EOF)
  143. return (EOF);
  144.     if ((fp->_flags & __SRD) == 0) 
  145. {
  146. /*
  147.  * Not already reading: no good unless reading-and-writing.
  148.  * Otherwise, flush any current write stuff.
  149.  */
  150. if ((fp->_flags & __SRW) == 0)
  151.     return (EOF);
  152. if (fp->_flags & __SWR) 
  153.     {
  154.     if (__sflush(fp))
  155. return (EOF);
  156.     fp->_flags  &= ~__SWR;
  157.     fp->_w  = 0;
  158.     fp->_lbfsize = 0;
  159.     }
  160. fp->_flags |= __SRD;
  161. }
  162.     c = (uchar_t) c;
  163.     /*
  164.      * If we are in the middle of ungetc'ing, just continue.
  165.      * This may require expanding the current ungetc buffer.
  166.      */
  167.     if (HASUB(fp)) 
  168. {
  169. if (fp->_r >= fp->_ub._size && __submore(fp))
  170.     return (EOF);
  171. *--fp->_p = c;
  172. fp->_r++;
  173. return (c);
  174. }
  175.     /*
  176.      * If we can handle this by simply backing up, do so,
  177.      * but never replace the original character.
  178.      * (This makes sscanf() work when scanning `const' data.)
  179.      */
  180.     if ((fp->_bf._base != NULL) && 
  181. (fp->_p > fp->_bf._base) &&
  182. (fp->_p[-1] == c)) 
  183. {
  184. fp->_p--;
  185. fp->_r++;
  186. return (c);
  187. }
  188.     /*
  189.      * Create an ungetc buffer.
  190.      * Initially, we will use the `reserve' buffer.
  191.      */
  192.     fp->_ur = fp->_r;
  193.     fp->_up = fp->_p;
  194.     fp->_ub._base = fp->_ubuf;
  195.     fp->_ub._size = sizeof(fp->_ubuf);
  196.     fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
  197.     fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
  198.     fp->_r = 1;
  199.     return (c);
  200.     }