|
|
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.