stdio: puts() and vprintf()
[neatlibc.git] / scanf.c
blobef6c77883ac0b1b1e1a8c2f92f9eb60c1b5dbd8d
1 #include <ctype.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <unistd.h>
7 static int ic(FILE *fp)
9 int nr;
10 if (fp->back != EOF) {
11 int i = fp->back;
12 fp->back = EOF;
13 return i;
15 while (fp->fd >= 0 && fp->icur == fp->ilen) {
16 int nr = read(fp->fd, fp->ibuf, fp->isize);
17 if (nr <= 0)
18 break;
19 fp->ilen = nr;
20 fp->icur = 0;
22 return fp->icur < fp->ilen ? (unsigned char) fp->ibuf[fp->icur++] : EOF;
25 void setbuf(FILE *fp, char *buf)
29 int fgetc(FILE *fp)
31 return ic(fp);
34 int getchar(void)
36 return ic(stdin);
39 int ungetc(int c, FILE *fp)
41 if (fp->back == EOF)
42 fp->back = c;
43 return fp->back;
46 /* t is 1 for char, 2 for short, 4 for int, and 8 for long */
47 static int iint(FILE *fp, void *dst, int t, int wid)
49 long n = 0;
50 int c;
51 int neg = 0;
52 c = ic(fp);
53 if (c == '-')
54 neg = 1;
55 if ((c == '-' || c == '+') && wid-- > 0)
56 c = ic(fp);
57 if (!isdigit(c) || wid <= 0) {
58 ungetc(c, fp);
59 return 1;
61 do {
62 n = n * 10 + c - '0';
63 } while (isdigit(c = ic(fp)) && --wid > 0);
64 ungetc(c, fp);
65 if (t == 8)
66 *(long *) dst = neg ? -n : n;
67 else if (t == 4)
68 *(int *) dst = neg ? -n : n;
69 else if (t == 2)
70 *(short *) dst = neg ? -n : n;
71 else
72 *(char *) dst = neg ? -n : n;
73 return 0;
76 static int istr(FILE *fp, char *dst, int wid)
78 char *d = dst;
79 int c;
80 while ((c = ic(fp)) != EOF && wid-- > 0 && !isspace(c))
81 *d++ = c;
82 *d = '\0';
83 ungetc(c, fp);
84 return d == dst;
87 int vfscanf(FILE *fp, char *fmt, va_list ap)
89 int ret = 0;
90 int t, c;
91 int wid = 1 << 20;
92 while (*fmt) {
93 while (isspace((unsigned char) *fmt))
94 fmt++;
95 while (isspace(c = ic(fp)))
97 ungetc(c, fp);
98 while (*fmt && *fmt != '%' && !isspace((unsigned char) *fmt))
99 if (*fmt++ != ic(fp))
100 return ret;
101 if (*fmt != '%')
102 continue;
103 fmt++;
104 if (isdigit((unsigned char) *fmt)) {
105 wid = 0;
106 while (isdigit((unsigned char) *fmt))
107 wid = wid * 10 + *fmt++ - '0';
109 t = sizeof(int);
110 while (*fmt == 'l') {
111 t = sizeof(long);
112 fmt++;
114 while (*fmt == 'h') {
115 t = t < sizeof(int) ? sizeof(char) : sizeof(short);
116 fmt++;
118 switch (*fmt++) {
119 case 'u':
120 case 'd':
121 if (iint(fp, va_arg(ap, long *), t, wid))
122 return ret;
123 ret++;
124 break;
125 case 's':
126 if (istr(fp, va_arg(ap, char *), wid))
127 return ret;
128 ret++;
129 break;
132 return ret;
135 int fscanf(FILE *fp, char *fmt, ...)
137 va_list ap;
138 int ret;
139 va_start(ap, fmt);
140 ret = vfscanf(fp, fmt, ap);
141 va_end(ap);
142 return ret;
145 int scanf(char *fmt, ...)
147 va_list ap;
148 int ret;
149 va_start(ap, fmt);
150 ret = vfscanf(stdin, fmt, ap);
151 va_end(ap);
152 return ret;
155 int vsscanf(char *s, char *fmt, va_list ap)
157 FILE f = {-1, EOF};
158 f.ibuf = s;
159 f.ilen = strlen(s);
160 return vfscanf(&f, fmt, ap);
163 int sscanf(char *s, char *fmt, ...)
165 va_list ap;
166 int ret;
167 va_start(ap, fmt);
168 ret = vsscanf(s, fmt, ap);
169 va_end(ap);
170 return ret;
173 char *fgets(char *s, int sz, FILE *fp)
175 int i = 0;
176 int c;
177 while (i + 1 < sz && (c = ic(fp)) != EOF) {
178 s[i++] = c;
179 if (c == '\n')
180 break;
182 s[i] = '\0';
183 return i ? s : NULL;