ungetc.c (50476) | ungetc.c (71579) |
---|---|
1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 25 unchanged lines hidden (view full) --- 34 * SUCH DAMAGE. 35 */ 36 37#if defined(LIBC_SCCS) && !defined(lint) 38#if 0 39static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93"; 40#endif 41static const char rcsid[] = | 1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 25 unchanged lines hidden (view full) --- 34 * SUCH DAMAGE. 35 */ 36 37#if defined(LIBC_SCCS) && !defined(lint) 38#if 0 39static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93"; 40#endif 41static const char rcsid[] = |
42 "$FreeBSD: head/lib/libc/stdio/ungetc.c 50476 1999-08-28 00:22:10Z peter $"; | 42 "$FreeBSD: head/lib/libc/stdio/ungetc.c 71579 2001-01-24 13:01:12Z deischen $"; |
43#endif /* LIBC_SCCS and not lint */ 44 | 43#endif /* LIBC_SCCS and not lint */ 44 |
45#include "namespace.h" |
|
45#include <stdio.h> 46#include <stdlib.h> 47#include <string.h> | 46#include <stdio.h> 47#include <stdlib.h> 48#include <string.h> |
49#include "un-namespace.h" |
|
48#include "local.h" 49#include "libc_private.h" 50 51static int __submore __P((FILE *)); 52 53/* 54 * Expand the ungetc buffer `in place'. That is, adjust fp->_p when 55 * the buffer moves, so that it points the same distance from the end, 56 * and move the bytes in the buffer around as necessary so that they 57 * are all at the end (stack-style). 58 */ 59static int | 50#include "local.h" 51#include "libc_private.h" 52 53static int __submore __P((FILE *)); 54 55/* 56 * Expand the ungetc buffer `in place'. That is, adjust fp->_p when 57 * the buffer moves, so that it points the same distance from the end, 58 * and move the bytes in the buffer around as necessary so that they 59 * are all at the end (stack-style). 60 */ 61static int |
60__submore(fp) 61 register FILE *fp; | 62__submore(FILE *fp) |
62{ | 63{ |
63 register int i; 64 register unsigned char *p; | 64 int i; 65 unsigned char *p; |
65 66 if (fp->_ub._base == fp->_ubuf) { 67 /* 68 * Get a new buffer (rather than expanding the old one). 69 */ 70 if ((p = malloc((size_t)BUFSIZ)) == NULL) 71 return (EOF); 72 fp->_ub._base = p; --- 11 unchanged lines hidden (view full) --- 84 /* no overlap (hence can use memcpy) because we doubled the size */ 85 (void)memcpy((void *)(p + i), (void *)p, (size_t)i); 86 fp->_p = p + i; 87 fp->_ub._base = p; 88 fp->_ub._size = i << 1; 89 return (0); 90} 91 | 66 67 if (fp->_ub._base == fp->_ubuf) { 68 /* 69 * Get a new buffer (rather than expanding the old one). 70 */ 71 if ((p = malloc((size_t)BUFSIZ)) == NULL) 72 return (EOF); 73 fp->_ub._base = p; --- 11 unchanged lines hidden (view full) --- 85 /* no overlap (hence can use memcpy) because we doubled the size */ 86 (void)memcpy((void *)(p + i), (void *)p, (size_t)i); 87 fp->_p = p + i; 88 fp->_ub._base = p; 89 fp->_ub._size = i << 1; 90 return (0); 91} 92 |
93/* 94 * MT-safe version 95 */ |
|
92int | 96int |
93ungetc(c, fp) 94 int c; 95 register FILE *fp; | 97ungetc(int c, FILE *fp) |
96{ | 98{ |
99 int ret; 100 |
|
97 if (c == EOF) 98 return (EOF); 99 if (!__sdidinit) 100 __sinit(); 101 FLOCKFILE(fp); | 101 if (c == EOF) 102 return (EOF); 103 if (!__sdidinit) 104 __sinit(); 105 FLOCKFILE(fp); |
106 ret = __ungetc(c, fp); 107 FUNLOCKFILE(fp); 108 return (ret); 109} 110 111/* 112 * Non-MT-safe version 113 */ 114int 115__ungetc(int c, FILE *fp) 116{ 117 if (c == EOF) 118 return (EOF); |
|
102 if ((fp->_flags & __SRD) == 0) { 103 /* 104 * Not already reading: no good unless reading-and-writing. 105 * Otherwise, flush any current write stuff. 106 */ | 119 if ((fp->_flags & __SRD) == 0) { 120 /* 121 * Not already reading: no good unless reading-and-writing. 122 * Otherwise, flush any current write stuff. 123 */ |
107 if ((fp->_flags & __SRW) == 0) { 108 FUNLOCKFILE(fp); | 124 if ((fp->_flags & __SRW) == 0) |
109 return (EOF); | 125 return (EOF); |
110 } | |
111 if (fp->_flags & __SWR) { | 126 if (fp->_flags & __SWR) { |
112 if (__sflush(fp)) { 113 FUNLOCKFILE(fp); | 127 if (__sflush(fp)) |
114 return (EOF); | 128 return (EOF); |
115 } | |
116 fp->_flags &= ~__SWR; 117 fp->_w = 0; 118 fp->_lbfsize = 0; 119 } 120 fp->_flags |= __SRD; 121 } 122 c = (unsigned char)c; 123 124 /* 125 * If we are in the middle of ungetc'ing, just continue. 126 * This may require expanding the current ungetc buffer. 127 */ 128 if (HASUB(fp)) { | 129 fp->_flags &= ~__SWR; 130 fp->_w = 0; 131 fp->_lbfsize = 0; 132 } 133 fp->_flags |= __SRD; 134 } 135 c = (unsigned char)c; 136 137 /* 138 * If we are in the middle of ungetc'ing, just continue. 139 * This may require expanding the current ungetc buffer. 140 */ 141 if (HASUB(fp)) { |
129 if (fp->_r >= fp->_ub._size && __submore(fp)) { 130 FUNLOCKFILE(fp); | 142 if (fp->_r >= fp->_ub._size && __submore(fp)) |
131 return (EOF); | 143 return (EOF); |
132 } | |
133 *--fp->_p = c; 134 fp->_r++; | 144 *--fp->_p = c; 145 fp->_r++; |
135 FUNLOCKFILE(fp); | |
136 return (c); 137 } 138 fp->_flags &= ~__SEOF; 139 140 /* 141 * If we can handle this by simply backing up, do so, 142 * but never replace the original character. 143 * (This makes sscanf() work when scanning `const' data.) 144 */ 145 if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && 146 fp->_p[-1] == c) { 147 fp->_p--; 148 fp->_r++; | 146 return (c); 147 } 148 fp->_flags &= ~__SEOF; 149 150 /* 151 * If we can handle this by simply backing up, do so, 152 * but never replace the original character. 153 * (This makes sscanf() work when scanning `const' data.) 154 */ 155 if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && 156 fp->_p[-1] == c) { 157 fp->_p--; 158 fp->_r++; |
149 FUNLOCKFILE(fp); | |
150 return (c); 151 } 152 153 /* 154 * Create an ungetc buffer. 155 * Initially, we will use the `reserve' buffer. 156 */ 157 fp->_ur = fp->_r; 158 fp->_up = fp->_p; 159 fp->_ub._base = fp->_ubuf; 160 fp->_ub._size = sizeof(fp->_ubuf); 161 fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; 162 fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1]; 163 fp->_r = 1; | 159 return (c); 160 } 161 162 /* 163 * Create an ungetc buffer. 164 * Initially, we will use the `reserve' buffer. 165 */ 166 fp->_ur = fp->_r; 167 fp->_up = fp->_p; 168 fp->_ub._base = fp->_ubuf; 169 fp->_ub._size = sizeof(fp->_ubuf); 170 fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; 171 fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1]; 172 fp->_r = 1; |
164 FUNLOCKFILE(fp); | |
165 return (c); 166} | 173 return (c); 174} |