OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [stdio/] [ungetc.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1010 ivang
/*
2
 * Copyright (c) 1990 The Regents of the University of California.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms are permitted
6
 * provided that the above copyright notice and this paragraph are
7
 * duplicated in all such forms and that any documentation,
8
 * advertising materials, and other materials related to such
9
 * distribution and use acknowledge that the software was developed
10
 * by the University of California, Berkeley.  The name of the
11
 * University may not be used to endorse or promote products derived
12
 * from this software without specific prior written permission.
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
 */
17
 
18
#if defined(LIBC_SCCS) && !defined(lint)
19
static char sccsid[] = "%W% (Berkeley) %G%";
20
#endif /* LIBC_SCCS and not lint */
21
 
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include "local.h"
26
 
27
/*
28
 * Expand the ungetc buffer `in place'.  That is, adjust fp->_p when
29
 * the buffer moves, so that it points the same distance from the end,
30
 * and move the bytes in the buffer around as necessary so that they
31
 * are all at the end (stack-style).
32
 */
33
 
34
/*static*/
35
int
36
__submore (fp)
37
     register FILE *fp;
38
{
39
  register int i;
40
  register unsigned char *p;
41
 
42
  if (fp->_ub._base == fp->_ubuf)
43
    {
44
      /*
45
       * Get a new buffer (rather than expanding the old one).
46
       */
47
      if ((p = (unsigned char *) _malloc_r (fp->_data, (size_t) BUFSIZ)) == NULL)
48
        return EOF;
49
      fp->_ub._base = p;
50
      fp->_ub._size = BUFSIZ;
51
      p += BUFSIZ - sizeof (fp->_ubuf);
52
      for (i = sizeof (fp->_ubuf); --i >= 0;)
53
        p[i] = fp->_ubuf[i];
54
      fp->_p = p;
55
      return 0;
56
    }
57
  i = fp->_ub._size;
58
  p = (unsigned char *) _realloc_r (fp->_data, (_PTR) (fp->_ub._base), i << 1);
59
  if (p == NULL)
60
    return EOF;
61
  (void) memcpy ((void *) (p + i), (void *) p, (size_t) i);
62
  fp->_p = p + i;
63
  fp->_ub._base = p;
64
  fp->_ub._size = i << 1;
65
  return 0;
66
}
67
 
68
int
69
ungetc (c, fp)
70
     int c;
71
     register FILE *fp;
72
{
73
  if (c == EOF)
74
    return (EOF);
75
 
76
  /* Ensure stdio has been initialized.
77
     ??? Might be able to remove this as some other stdio routine should
78
     have already been called to get the char we are un-getting.  */
79
 
80
  CHECK_INIT (fp);
81
 
82
  /* After ungetc, we won't be at eof anymore */
83
  fp->_flags &= ~__SEOF;
84
 
85
  if ((fp->_flags & __SRD) == 0)
86
    {
87
      /*
88
       * Not already reading: no good unless reading-and-writing.
89
       * Otherwise, flush any current write stuff.
90
       */
91
      if ((fp->_flags & __SRW) == 0)
92
        return EOF;
93
      if (fp->_flags & __SWR)
94
        {
95
          if (fflush (fp))
96
            return EOF;
97
          fp->_flags &= ~__SWR;
98
          fp->_w = 0;
99
          fp->_lbfsize = 0;
100
        }
101
      fp->_flags |= __SRD;
102
    }
103
  c = (unsigned char) c;
104
 
105
  /*
106
   * If we are in the middle of ungetc'ing, just continue.
107
   * This may require expanding the current ungetc buffer.
108
   */
109
 
110
  if (HASUB (fp))
111
    {
112
      if (fp->_r >= fp->_ub._size && __submore (fp))
113
        return EOF;
114
      *--fp->_p = c;
115
      fp->_r++;
116
      return c;
117
    }
118
 
119
  /*
120
   * If we can handle this by simply backing up, do so,
121
   * but never replace the original character.
122
   * (This makes sscanf() work when scanning `const' data.)
123
   */
124
 
125
  if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && fp->_p[-1] == c)
126
    {
127
      fp->_p--;
128
      fp->_r++;
129
      return c;
130
    }
131
 
132
  /*
133
   * Create an ungetc buffer.
134
   * Initially, we will use the `reserve' buffer.
135
   */
136
 
137
  fp->_ur = fp->_r;
138
  fp->_up = fp->_p;
139
  fp->_ub._base = fp->_ubuf;
140
  fp->_ub._size = sizeof (fp->_ubuf);
141
  fp->_ubuf[sizeof (fp->_ubuf) - 1] = c;
142
  fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1];
143
  fp->_r = 1;
144
  return c;
145
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.