stdio: add fgets()
[neatlibc.git] / scanf.c
blobe79f4f07bc223c9ba38b4bad1b32f62e7f772a5b
1 #include <stdarg.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <string.h>
6 static int ic(FILE *fp)
8 int nr;
9 if (fp->back != EOF) {
10 int i = fp->back;
11 fp->back = EOF;
12 return i;
14 while (fp->fd >= 0 && fp->icur == fp->ilen) {
15 int nr = read(fp->fd, fp->ibuf, fp->isize);
16 if (nr <= 0)
17 break;
18 fp->ilen = nr;
19 fp->icur = 0;
21 return fp->icur < fp->ilen ? (unsigned char) fp->ibuf[fp->icur++] : EOF;
24 void setbuf(FILE *fp, char *buf)
28 int fgetc(FILE *fp)
30 return ic(fp);
33 int getchar(void)
35 return ic(stdin);
38 int ungetc(int c, FILE *fp)
40 if (fp->back == EOF)
41 fp->back = c;
42 return fp->back;
45 static int iint(FILE *fp, void *dst, int l)
47 long n = 0;
48 int c;
49 int neg = 0;
50 c = ic(fp);
51 if (c == '-') {
52 neg = 1;
53 c = ic(fp);
55 if (!isdigit(c)) {
56 ungetc(c, fp);
57 return 1;
59 do {
60 n = n * 10 + c - '0';
61 } while (isdigit(c = ic(fp)));
62 ungetc(c, fp);
63 if (l)
64 *(long *) dst = neg ? -n : n;
65 else
66 *(int *) dst = neg ? -n : n;
67 return 0;
70 static int istr(FILE *fp, char *dst)
72 char *d = dst;
73 int c;
74 while ((c = ic(fp)) != EOF && !isspace(c))
75 *d++ = c;
76 *d = '\0';
77 ungetc(c, fp);
78 return d == dst;
81 int vfscanf(FILE *fp, char *fmt, va_list ap)
83 int ret = 0;
84 int l = 0;
85 int c;
86 char *s;
87 while (*fmt) {
88 while (isspace(*fmt))
89 fmt++;
90 while (isspace(c = ic(fp)))
92 ungetc(c, fp);
93 while (*fmt && *fmt != '%' && !isspace(*fmt))
94 if (*fmt++ != ic(fp))
95 return ret;
96 if (*fmt != '%')
97 continue;
98 fmt++;
99 if (*fmt == 'l') {
100 l = 1;
101 fmt++;
103 switch (*fmt++) {
104 case 'u':
105 case 'd':
106 if (iint(fp, va_arg(ap, long *), l))
107 return ret;
108 ret++;
109 break;
110 case 's':
111 if (istr(fp, va_arg(ap, char *)))
112 return ret;
113 ret++;
114 break;
117 return ret;
120 int fscanf(FILE *fp, char *fmt, ...)
122 va_list ap;
123 int ret;
124 va_start(ap, fmt);
125 ret = vfscanf(fp, fmt, ap);
126 va_end(ap);
127 return ret;
130 int scanf(char *fmt, ...)
132 va_list ap;
133 int ret;
134 va_start(ap, fmt);
135 ret = vfscanf(stdin, fmt, ap);
136 va_end(ap);
137 return ret;
140 int vsscanf(char *s, char *fmt, va_list ap)
142 FILE f = {-1, EOF};
143 f.ibuf = s;
144 f.ilen = strlen(s);
145 return vfscanf(&f, fmt, ap);
148 int sscanf(char *s, char *fmt, ...)
150 va_list ap;
151 int ret;
152 va_start(ap, fmt);
153 ret = vsscanf(s, fmt, ap);
154 va_end(ap);
155 return ret;
158 char *fgets(char *s, int sz, FILE *fp)
160 int i = 0;
161 int c;
162 while (i + 1 < sz && (c = ic(fp)) != EOF) {
163 s[i++] = c;
164 if (c == '\n')
165 break;
167 s[i] = '\0';
168 return i ? s : NULL;