~mysql/mysql-server/mysql-6.0

« back to all changes in this revision

Viewing changes to mit-pthreads/stdio/ungetc.c

  • Committer: bk at mysql
  • Date: 2000-07-31 19:29:14 UTC
  • Revision ID: sp1r-bk@work.mysql.com-20000731192914-08846
Import changeset

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * Copyright (c) 1990 The Regents of the University of California.
 
3
 * Copyright (c) 1993, 1994 Chris Provenzano. 
 
4
 * All rights reserved.
 
5
 *
 
6
 * This code is derived from software contributed to Berkeley by
 
7
 * Chris Torek.
 
8
 *
 
9
 * Redistribution and use in source and binary forms, with or without
 
10
 * modification, are permitted provided that the following conditions
 
11
 * are met:
 
12
 * 1. Redistributions of source code must retain the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer.
 
14
 * 2. Redistributions in binary form must reproduce the above copyright
 
15
 *    notice, this list of conditions and the following disclaimer in the
 
16
 *    documentation and/or other materials provided with the distribution.
 
17
 * 3. All advertising materials mentioning features or use of this software
 
18
 *    must display the following acknowledgement:
 
19
 *      This product includes software developed by the University of
 
20
 *      California, Berkeley and its contributors.
 
21
 * 4. Neither the name of the University nor the names of its contributors
 
22
 *    may be used to endorse or promote products derived from this software
 
23
 *    without specific prior written permission.
 
24
 *
 
25
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
26
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
27
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
28
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
29
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
30
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
31
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
32
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
33
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
34
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
35
 * SUCH DAMAGE.
 
36
 */
 
37
 
 
38
#if defined(LIBC_SCCS) && !defined(lint)
 
39
/*static char *sccsid = "from: @(#)ungetc.c     5.6 (Berkeley) 5/4/91";*/
 
40
static char *rcsid = "$Id$";
 
41
#endif /* LIBC_SCCS and not lint */
 
42
 
 
43
#include <pthread.h>
 
44
#include <stdio.h>
 
45
#include <stdlib.h>
 
46
#include <string.h>
 
47
#include "local.h"
 
48
 
 
49
/*
 
50
 * Expand the ungetc buffer `in place'.  That is, adjust fp->_p when
 
51
 * the buffer moves, so that it points the same distance from the end,
 
52
 * and move the bytes in the buffer around as necessary so that they
 
53
 * are all at the end (stack-style).
 
54
 */
 
55
static
 
56
__submore(fp)
 
57
        register FILE *fp;
 
58
{
 
59
        register int i;
 
60
        register unsigned char *p;
 
61
 
 
62
        if (fp->_ub._base == fp->_ubuf) {
 
63
                /*
 
64
                 * Get a new buffer (rather than expanding the old one).
 
65
                 */
 
66
                if ((p = malloc((size_t)BUFSIZ)) == NULL)
 
67
                        return (EOF);
 
68
                fp->_ub._base = p;
 
69
                fp->_ub._size = BUFSIZ;
 
70
                p += BUFSIZ - sizeof(fp->_ubuf);
 
71
                for (i = sizeof(fp->_ubuf); --i >= 0;)
 
72
                        p[i] = fp->_ubuf[i];
 
73
                fp->_p = p;
 
74
                return (0);
 
75
        }
 
76
        i = fp->_ub._size;
 
77
        p = realloc(fp->_ub._base, i << 1);
 
78
        if (p == NULL)
 
79
                return (EOF);
 
80
        (void) memcpy((void *)(p + i), (void *)p, (size_t)i);
 
81
        fp->_p = p + i;
 
82
        fp->_ub._base = p;
 
83
        fp->_ub._size = i << 1;
 
84
        return (0);
 
85
}
 
86
 
 
87
ungetc(c, fp)
 
88
        int c;
 
89
        register FILE *fp;
 
90
{
 
91
        if (c == EOF)
 
92
                return (EOF);
 
93
        __sinit ();
 
94
 
 
95
        flockfile(fp);
 
96
        if ((fp->_flags & __SRD) == 0) {
 
97
                /*
 
98
                 * Not already reading: no good unless reading-and-writing.
 
99
                 * Otherwise, flush any current write stuff.
 
100
                 */
 
101
                if ((fp->_flags & __SRW) == 0)
 
102
                        c = EOF;
 
103
                        goto ungetc_end;
 
104
                if (fp->_flags & __SWR) {
 
105
                        if (__sflush(fp))
 
106
                                c = EOF;
 
107
                                goto ungetc_end;
 
108
                        fp->_flags &= ~__SWR;
 
109
                        fp->_w = 0;
 
110
                        fp->_lbfsize = 0;
 
111
                }
 
112
                fp->_flags |= __SRD;
 
113
        }
 
114
        c = (unsigned char)c;
 
115
 
 
116
        /*
 
117
         * If we are in the middle of ungetc'ing, just continue.
 
118
         * This may require expanding the current ungetc buffer.
 
119
         */
 
120
        if (HASUB(fp)) {
 
121
                if (fp->_r >= fp->_ub._size && __submore(fp))
 
122
                        return (EOF);
 
123
                *--fp->_p = c;
 
124
                fp->_r++;
 
125
                goto ungetc_end;
 
126
        }
 
127
 
 
128
        /*
 
129
         * If we can handle this by simply backing up, do so,
 
130
         * but never replace the original character.
 
131
         * (This makes sscanf() work when scanning `const' data.)
 
132
         */
 
133
        if (fp->_bf._base != NULL && fp->_p > fp->_bf._base &&
 
134
            fp->_p[-1] == c) {
 
135
                fp->_p--;
 
136
                fp->_r++;
 
137
                goto ungetc_end;
 
138
        }
 
139
 
 
140
        /*
 
141
         * Create an ungetc buffer.
 
142
         * Initially, we will use the `reserve' buffer.
 
143
         */
 
144
        fp->_ur = fp->_r;
 
145
        fp->_up = fp->_p;
 
146
        fp->_ub._base = fp->_ubuf;
 
147
        fp->_ub._size = sizeof(fp->_ubuf);
 
148
        fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
 
149
        fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
 
150
        fp->_r = 1;
 
151
 
 
152
ungetc_end:;
 
153
        funlockfile(fp);
 
154
        return (c);
 
155
}