|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2004, 2008 IBM Corporation
3: * All rights reserved.
4: * This program and the accompanying materials
5: * are made available under the terms of the BSD License
6: * which accompanies this distribution, and is available at
7: * http://www.opensource.org/licenses/bsd-license.php
8: *
9: * Contributors:
10: * IBM Corporation - initial implementation
11: *****************************************************************************/
12:
13: #include "string.h"
14: #include "ctype.h"
15: #include "stdlib.h"
16: #include "stdio.h"
17: #include "unistd.h"
18:
19:
20: static int
21: _getc(FILE * stream)
22: {
23: int count;
24: char c;
25:
26: if (stream->mode == _IONBF || stream->buf == NULL) {
27: if (read(stream->fd, &c, 1) == 1)
28: return (int) c;
29: else
30: return EOF;
31: }
32:
33: if (stream->pos == 0 || stream->pos >= BUFSIZ ||
34: stream->buf[stream->pos] == '\0') {
35: count = read(stream->fd, stream->buf, BUFSIZ);
36: if (count < 0)
37: count = 0;
38: if (count < BUFSIZ)
39: stream->buf[count] = '\0';
40: stream->pos = 0;
41: }
42:
43: return stream->buf[stream->pos++];
44: }
45:
46: static void
47: _ungetc(int ch, FILE * stream)
48: {
49: if (stream->mode != _IONBF && stream->pos > 0)
50: stream->pos--;
51: }
52:
53: static int
54: _is_voidage(int ch)
55: {
56: if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\0')
57: return 1;
58: else
59: return 0;
60: }
61:
62:
63: static int
64: _scanf(FILE * stream, const char *fmt, va_list * ap)
65: {
66: int i = 0;
67: int length = 0;
68:
69: fmt++;
70:
71: while (*fmt != '\0') {
72:
73: char tbuf[256];
74: char ch;
75:
76: switch (*fmt) {
77: case 'd':
78: case 'i':
79: ch = _getc(stream);
80: if (length == 0) {
81: while (!_is_voidage(ch) && isdigit(ch)) {
82: tbuf[i] = ch;
83: ch = _getc(stream);
84: i++;
85: }
86: } else {
87: while (!_is_voidage(ch) && i < length
88: && isdigit(ch)) {
89: tbuf[i] = ch;
90: ch = _getc(stream);
91: i++;
92: }
93: }
94: /* We tried to understand what this is good for...
95: * but we did not. We know for sure that it does not
96: * work on SLOF if this is active. */
97: /* _ungetc(ch, stream); */
98: tbuf[i] = '\0';
99:
100: /* ch = _getc(stream); */
101: if (!_is_voidage(ch))
102: _ungetc(ch, stream);
103:
104: if (strlen(tbuf) == 0)
105: return 0;
106:
107: *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10);
108: break;
109: case 'X':
110: case 'x':
111: ch = _getc(stream);
112: if (length == 0) {
113: while (!_is_voidage(ch) && isxdigit(ch)) {
114: tbuf[i] = ch;
115: ch = _getc(stream);
116: i++;
117: }
118: } else {
119: while (!_is_voidage(ch) && i < length
120: && isxdigit(ch)) {
121: tbuf[i] = ch;
122: ch = _getc(stream);
123: i++;
124: }
125: }
126: /* _ungetc(ch, stream); */
127: tbuf[i] = '\0';
128:
129: /* ch = _getc(stream); */
130: if (!_is_voidage(ch))
131: _ungetc(ch, stream);
132:
133: if (strlen(tbuf) == 0)
134: return 0;
135:
136: *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16);
137: break;
138: case 'O':
139: case 'o':
140: ch = _getc(stream);
141: if (length == 0) {
142: while (!_is_voidage(ch)
143: && !(ch < '0' || ch > '7')) {
144: tbuf[i] = ch;
145: ch = _getc(stream);
146: i++;
147: }
148: } else {
149: while (!_is_voidage(ch) && i < length
150: && !(ch < '0' || ch > '7')) {
151: tbuf[i] = ch;
152: ch = _getc(stream);
153: i++;
154: }
155: }
156: /* _ungetc(ch, stream); */
157: tbuf[i] = '\0';
158:
159: /* ch = _getc(stream); */
160: if (!_is_voidage(ch))
161: _ungetc(ch, stream);
162:
163: if (strlen(tbuf) == 0)
164: return 0;
165:
166: *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8);
167: break;
168: case 'c':
169: ch = _getc(stream);
170: while (_is_voidage(ch))
171: ch = _getc(stream);
172:
173: *(va_arg(*ap, char *)) = ch;
174:
175: ch = _getc(stream);
176: if (!_is_voidage(ch))
177: _ungetc(ch, stream);
178:
179: break;
180: case 's':
181: ch = _getc(stream);
182: if (length == 0) {
183: while (!_is_voidage(ch)) {
184: tbuf[i] = ch;
185: ch = _getc(stream);
186: i++;
187: }
188: } else {
189: while (!_is_voidage(ch) && i < length) {
190: tbuf[i] = ch;
191: ch = _getc(stream);
192: i++;
193: }
194: }
195: /* _ungetc(ch, stream); */
196: tbuf[i] = '\0';
197:
198: /* ch = _getc(stream); */
199: if (!_is_voidage(ch))
200: _ungetc(ch, stream);
201:
202: strcpy(va_arg(*ap, char *), tbuf);
203: break;
204: default:
205: if (*fmt >= '0' && *fmt <= '9')
206: length += *fmt - '0';
207: break;
208: }
209: fmt++;
210: }
211:
212: return 1;
213: }
214:
215:
216:
217: int
218: vfscanf(FILE * stream, const char *fmt, va_list ap)
219: {
220: int args = 0;
221:
222: while (*fmt != '\0') {
223:
224: if (*fmt == '%') {
225:
226: char formstr[20];
227: int i = 0;
228:
229: do {
230: formstr[i] = *fmt;
231: fmt++;
232: i++;
233: } while (!
234: (*fmt == 'd' || *fmt == 'i' || *fmt == 'x'
235: || *fmt == 'X' || *fmt == 'p' || *fmt == 'c'
236: || *fmt == 's' || *fmt == '%' || *fmt == 'O'
237: || *fmt == 'o'));
238: formstr[i++] = *fmt;
239: formstr[i] = '\0';
240: if (*fmt != '%') {
241: if (_scanf(stream, formstr, &ap) <= 0)
242: return args;
243: else
244: args++;
245: }
246:
247: }
248:
249: fmt++;
250:
251: }
252:
253: return args;
254: }
255:
256: int
257: getc(FILE * stream)
258: {
259: return _getc(stream);
260: }
261:
262: int
263: getchar(void)
264: {
265: return _getc(stdin);
266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.