0001
0002
0003
0004
0005
0006
0007 #ifndef _NOLIBC_STDIO_H
0008 #define _NOLIBC_STDIO_H
0009
0010 #include <stdarg.h>
0011
0012 #include "std.h"
0013 #include "arch.h"
0014 #include "errno.h"
0015 #include "types.h"
0016 #include "sys.h"
0017 #include "stdlib.h"
0018 #include "string.h"
0019
0020 #ifndef EOF
0021 #define EOF (-1)
0022 #endif
0023
0024
0025 typedef struct FILE {
0026 char dummy[1];
0027 } FILE;
0028
0029
0030
0031
0032 static __attribute__((unused)) FILE* const stdin = (FILE*)-3;
0033 static __attribute__((unused)) FILE* const stdout = (FILE*)-2;
0034 static __attribute__((unused)) FILE* const stderr = (FILE*)-1;
0035
0036
0037
0038 #define getc(stream) fgetc(stream)
0039
0040 static __attribute__((unused))
0041 int fgetc(FILE* stream)
0042 {
0043 unsigned char ch;
0044 int fd;
0045
0046 if (stream < stdin || stream > stderr)
0047 return EOF;
0048
0049 fd = 3 + (long)stream;
0050
0051 if (read(fd, &ch, 1) <= 0)
0052 return EOF;
0053 return ch;
0054 }
0055
0056 static __attribute__((unused))
0057 int getchar(void)
0058 {
0059 return fgetc(stdin);
0060 }
0061
0062
0063
0064
0065 #define putc(c, stream) fputc(c, stream)
0066
0067 static __attribute__((unused))
0068 int fputc(int c, FILE* stream)
0069 {
0070 unsigned char ch = c;
0071 int fd;
0072
0073 if (stream < stdin || stream > stderr)
0074 return EOF;
0075
0076 fd = 3 + (long)stream;
0077
0078 if (write(fd, &ch, 1) <= 0)
0079 return EOF;
0080 return ch;
0081 }
0082
0083 static __attribute__((unused))
0084 int putchar(int c)
0085 {
0086 return fputc(c, stdout);
0087 }
0088
0089
0090
0091
0092
0093
0094
0095 static __attribute__((unused))
0096 int _fwrite(const void *buf, size_t size, FILE *stream)
0097 {
0098 ssize_t ret;
0099 int fd;
0100
0101 if (stream < stdin || stream > stderr)
0102 return EOF;
0103
0104 fd = 3 + (long)stream;
0105
0106 while (size) {
0107 ret = write(fd, buf, size);
0108 if (ret <= 0)
0109 return EOF;
0110 size -= ret;
0111 buf += ret;
0112 }
0113 return 0;
0114 }
0115
0116 static __attribute__((unused))
0117 size_t fwrite(const void *s, size_t size, size_t nmemb, FILE *stream)
0118 {
0119 size_t written;
0120
0121 for (written = 0; written < nmemb; written++) {
0122 if (_fwrite(s, size, stream) != 0)
0123 break;
0124 s += size;
0125 }
0126 return written;
0127 }
0128
0129 static __attribute__((unused))
0130 int fputs(const char *s, FILE *stream)
0131 {
0132 return _fwrite(s, strlen(s), stream);
0133 }
0134
0135 static __attribute__((unused))
0136 int puts(const char *s)
0137 {
0138 if (fputs(s, stdout) == EOF)
0139 return EOF;
0140 return putchar('\n');
0141 }
0142
0143
0144
0145 static __attribute__((unused))
0146 char *fgets(char *s, int size, FILE *stream)
0147 {
0148 int ofs;
0149 int c;
0150
0151 for (ofs = 0; ofs + 1 < size;) {
0152 c = fgetc(stream);
0153 if (c == EOF)
0154 break;
0155 s[ofs++] = c;
0156 if (c == '\n')
0157 break;
0158 }
0159 if (ofs < size)
0160 s[ofs] = 0;
0161 return ofs ? s : NULL;
0162 }
0163
0164
0165
0166
0167
0168
0169
0170 static __attribute__((unused))
0171 int vfprintf(FILE *stream, const char *fmt, va_list args)
0172 {
0173 char escape, lpref, c;
0174 unsigned long long v;
0175 unsigned int written;
0176 size_t len, ofs;
0177 char tmpbuf[21];
0178 const char *outstr;
0179
0180 written = ofs = escape = lpref = 0;
0181 while (1) {
0182 c = fmt[ofs++];
0183
0184 if (escape) {
0185
0186 escape = 0;
0187 if (c == 'c' || c == 'd' || c == 'u' || c == 'x' || c == 'p') {
0188 char *out = tmpbuf;
0189
0190 if (c == 'p')
0191 v = va_arg(args, unsigned long);
0192 else if (lpref) {
0193 if (lpref > 1)
0194 v = va_arg(args, unsigned long long);
0195 else
0196 v = va_arg(args, unsigned long);
0197 } else
0198 v = va_arg(args, unsigned int);
0199
0200 if (c == 'd') {
0201
0202 if (lpref == 0)
0203 v = (long long)(int)v;
0204 else if (lpref == 1)
0205 v = (long long)(long)v;
0206 }
0207
0208 switch (c) {
0209 case 'c':
0210 out[0] = v;
0211 out[1] = 0;
0212 break;
0213 case 'd':
0214 i64toa_r(v, out);
0215 break;
0216 case 'u':
0217 u64toa_r(v, out);
0218 break;
0219 case 'p':
0220 *(out++) = '0';
0221 *(out++) = 'x';
0222
0223 default:
0224 u64toh_r(v, out);
0225 break;
0226 }
0227 outstr = tmpbuf;
0228 }
0229 else if (c == 's') {
0230 outstr = va_arg(args, char *);
0231 if (!outstr)
0232 outstr="(null)";
0233 }
0234 else if (c == '%') {
0235
0236 continue;
0237 }
0238 else {
0239
0240 if (c == 'l') {
0241
0242 lpref++;
0243 }
0244 escape = 1;
0245 goto do_escape;
0246 }
0247 len = strlen(outstr);
0248 goto flush_str;
0249 }
0250
0251
0252 if (c == 0 || c == '%') {
0253
0254 escape = 1;
0255 lpref = 0;
0256 outstr = fmt;
0257 len = ofs - 1;
0258 flush_str:
0259 if (_fwrite(outstr, len, stream) != 0)
0260 break;
0261
0262 written += len;
0263 do_escape:
0264 if (c == 0)
0265 break;
0266 fmt += ofs;
0267 ofs = 0;
0268 continue;
0269 }
0270
0271
0272 }
0273 return written;
0274 }
0275
0276 static __attribute__((unused, format(printf, 2, 3)))
0277 int fprintf(FILE *stream, const char *fmt, ...)
0278 {
0279 va_list args;
0280 int ret;
0281
0282 va_start(args, fmt);
0283 ret = vfprintf(stream, fmt, args);
0284 va_end(args);
0285 return ret;
0286 }
0287
0288 static __attribute__((unused, format(printf, 1, 2)))
0289 int printf(const char *fmt, ...)
0290 {
0291 va_list args;
0292 int ret;
0293
0294 va_start(args, fmt);
0295 ret = vfprintf(stdout, fmt, args);
0296 va_end(args);
0297 return ret;
0298 }
0299
0300 static __attribute__((unused))
0301 void perror(const char *msg)
0302 {
0303 fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno);
0304 }
0305
0306 #endif