First stage in modularising FILE*. Refactor so that printf/scanf don't rely on

FILE* innards; allow plats to replace the entire emulated FILE* system.
This commit is contained in:
David Given 2019-06-15 13:07:10 +02:00
parent 3798673afe
commit 9109d7af7f
37 changed files with 273 additions and 186 deletions

View file

@ -63,4 +63,9 @@
#define ACKCONF_WANT_STDIO 1 #define ACKCONF_WANT_STDIO 1
#endif #endif
#ifndef ACKCONF_WANT_EMULATED_FILE
/* Implement FILE* on top of read()/write() file descriptors. */
#define ACKCONF_WANT_EMULATED_FILE 1
#endif
#endif #endif

View file

@ -0,0 +1,59 @@
#ifndef ACK_EMUFILE_H
#define ACK_EMUFILE_H
/*
* Focus point of all stdio activity.
*/
struct FILE {
int _count;
int _fd;
int _flags;
int _bufsiz;
unsigned char *_buf;
unsigned char *_ptr;
};
#define _IOFBF 0x000
#define _IOREAD 0x001
#define _IOWRITE 0x002
#define _IONBF 0x004
#define _IOMYBUF 0x008
#define _IOEOF 0x010
#define _IOERR 0x020
#define _IOLBF 0x040
#define _IOREADING 0x080
#define _IOWRITING 0x100
#define _IOAPPEND 0x200
#define BUFSIZ 1024
#define FOPEN_MAX 20
extern FILE *__iotab[FOPEN_MAX];
#define FILENAME_MAX 255
#define TMP_MAX 999
#define L_tmpnam (sizeof("/tmp/") + 15)
#define ACK_TMP_PREFIX "/tmp/tmp."
extern int __fillbuf(FILE *_stream);
extern int __flushbuf(int _c, FILE *_stream);
#define getchar() getc(stdin)
#define putchar(c) putc(c,stdout)
#define getc(p) (--(p)->_count >= 0 ? (int) (*(p)->_ptr++) : \
__fillbuf(p))
#define putc(c, p) (--(p)->_count >= 0 ? \
(int) (*(p)->_ptr++ = (c)) : \
__flushbuf((c),(p)))
#define feof(p) (((p)->_flags & _IOEOF) != 0)
#define ferror(p) (((p)->_flags & _IOERR) != 0)
#define clearerr(p) ((p)->_flags &= ~(_IOERR|_IOEOF))
/* Non-standard extensions */
extern int fileno(FILE *_stream);
extern FILE* fdopen(int fildes, const char *type);
#define fileno(stream) ((stream)->_fd)
#endif

View file

@ -10,30 +10,14 @@
#define _STDIO_H #define _STDIO_H
#include <stddef.h> #include <stddef.h>
#include <stdarg.h>
#include <ack/config.h>
/* /* Public stdio entry points. */
* Focus point of all stdio activity.
*/
typedef struct __iobuf {
int _count;
int _fd;
int _flags;
int _bufsiz;
unsigned char *_buf;
unsigned char *_ptr;
} FILE;
#define _IOFBF 0x000 typedef struct FILE FILE;
#define _IOREAD 0x001
#define _IOWRITE 0x002 #define EOF (-1)
#define _IONBF 0x004
#define _IOMYBUF 0x008
#define _IOEOF 0x010
#define _IOERR 0x020
#define _IOLBF 0x040
#define _IOREADING 0x080
#define _IOWRITING 0x100
#define _IOAPPEND 0x200
#define SEEK_SET 0 #define SEEK_SET 0
#define SEEK_CUR 1 #define SEEK_CUR 1
@ -43,18 +27,8 @@ typedef struct __iobuf {
#define stdout (&__stdout) #define stdout (&__stdout)
#define stderr (&__stderr) #define stderr (&__stderr)
#define BUFSIZ 1024
#define EOF (-1)
#define FOPEN_MAX 20
#define FILENAME_MAX 255
#define TMP_MAX 999
#define L_tmpnam (sizeof("/tmp/") + 15)
typedef long int fpos_t; typedef long int fpos_t;
extern FILE *__iotab[FOPEN_MAX];
extern FILE __stdin, __stdout, __stderr; extern FILE __stdin, __stdout, __stderr;
extern int remove(const char *_filename); extern int remove(const char *_filename);
@ -69,6 +43,7 @@ extern void setbuf(FILE *_stream, char *_buf);
extern int setvbuf(FILE *_stream, char *_buf, int _mode, size_t _size); extern int setvbuf(FILE *_stream, char *_buf, int _mode, size_t _size);
extern int fprintf(FILE *_stream, const char *_format, ...); extern int fprintf(FILE *_stream, const char *_format, ...);
extern int fscanf(FILE *_stream, const char *_format, ...); extern int fscanf(FILE *_stream, const char *_format, ...);
extern int vfscanf(FILE *_stream, const char *_format, va_list ap);
extern int printf(const char *_format, ...); extern int printf(const char *_format, ...);
extern int scanf(const char *_format, ...); extern int scanf(const char *_format, ...);
extern int sprintf(char *_s, const char *_format, ...); extern int sprintf(char *_s, const char *_format, ...);
@ -76,8 +51,8 @@ extern int snprintf(char *_s, size_t _len, const char *_format, ...);
extern int sscanf(const char *_s, const char *_format, ...); extern int sscanf(const char *_s, const char *_format, ...);
extern int vfprintf(FILE *_stream, const char *_format, char *_arg); extern int vfprintf(FILE *_stream, const char *_format, char *_arg);
extern int vprintf(const char *_format, char *_arg); extern int vprintf(const char *_format, char *_arg);
extern int vsprintf(char *_s, const char *_format, char *_arg); extern int vsprintf(char *_s, const char *_format, va_list ap);
extern int vsnprintf(char *_s, size_t _len, const char *_format, char *_arg); extern int vsnprintf(char *_s, size_t _len, const char *_format, va_list ap);
extern int fgetc(FILE *_stream); extern int fgetc(FILE *_stream);
extern char *fgets(char *_s, int _n, FILE *_stream); extern char *fgets(char *_s, int _n, FILE *_stream);
extern int fputc(int _c, FILE *_stream); extern int fputc(int _c, FILE *_stream);
@ -101,25 +76,10 @@ extern int feof(FILE *_stream);
extern int ferror(FILE *_stream); extern int ferror(FILE *_stream);
extern void perror(const char *_s); extern void perror(const char *_s);
extern int __fillbuf(FILE *_stream); #if ACKCONF_WANT_EMULATED_FILE
extern int __flushbuf(int _c, FILE *_stream); #include <ack/emufile.h>
#else
#define getchar() getc(stdin) #include <ack/file.h>
#define putchar(c) putc(c,stdout) #endif
#define getc(p) (--(p)->_count >= 0 ? (int) (*(p)->_ptr++) : \
__fillbuf(p))
#define putc(c, p) (--(p)->_count >= 0 ? \
(int) (*(p)->_ptr++ = (c)) : \
__flushbuf((c),(p)))
#define feof(p) (((p)->_flags & _IOEOF) != 0)
#define ferror(p) (((p)->_flags & _IOERR) != 0)
#define clearerr(p) ((p)->_flags &= ~(_IOERR|_IOEOF))
/* Non-standard extensions */
extern int fileno(FILE *_stream);
extern FILE* fdopen(int fildes, const char *type);
#define fileno(stream) ((stream)->_fd)
#endif /* _STDIO_H */ #endif /* _STDIO_H */

View file

@ -5,19 +5,19 @@
#include <stdio.h> #include <stdio.h>
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
struct __iobuf __stdin = { struct FILE __stdin = {
0, 0, _IOREAD, 0, 0, 0, _IOREAD, 0,
(unsigned char*)NULL, (unsigned char*)NULL, (unsigned char*)NULL, (unsigned char*)NULL,
}; };
struct __iobuf __stdout = { struct FILE __stdout = {
0, 1, _IOWRITE, 0, 0, 1, _IOWRITE, 0,
(unsigned char*)NULL, (unsigned char*)NULL, (unsigned char*)NULL, (unsigned char*)NULL,
}; };
struct __iobuf __stderr = { struct FILE __stderr = {
0, 2, _IOWRITE | _IOLBF, 0, 0, 2, _IOWRITE | _IOLBF, 0,
(unsigned char*)NULL, (unsigned char*)NULL, (unsigned char*)NULL, (unsigned char*)NULL,
}; };

View file

@ -157,7 +157,7 @@ o_print(va_list* ap, int flags, char* s, char c, int precision, int is_signed)
return s; return s;
} }
int _doprnt(register const char* fmt, va_list ap, FILE* stream) int _doprnt(register const char* fmt, va_list ap, void (*put)(int))
{ {
register char* s; register char* s;
register int j; register int j;
@ -176,7 +176,7 @@ int _doprnt(register const char* fmt, va_list ap, FILE* stream)
PUTC('\r'); PUTC('\r');
} }
#endif #endif
PUTC(c); put(c);
nrchars++; nrchars++;
continue; continue;
} }
@ -263,7 +263,7 @@ int _doprnt(register const char* fmt, va_list ap, FILE* stream)
nrchars++; nrchars++;
} }
#endif #endif
PUTC(c); put(c);
nrchars++; nrchars++;
continue; continue;
case 'n': case 'n':
@ -366,32 +366,32 @@ int _doprnt(register const char* fmt, va_list ap, FILE* stream)
{ {
j--; j--;
nrchars++; nrchars++;
PUTC(*s1++); put(*s1++);
} }
else else
{ {
j -= 2; j -= 2;
nrchars += 2; nrchars += 2;
PUTC(*s1++); put(*s1++);
PUTC(*s1++); put(*s1++);
} }
} }
do do
{ {
PUTC(zfill); put(zfill);
} while (--i); } while (--i);
} }
nrchars += j; nrchars += j;
while (--j >= 0) while (--j >= 0)
{ {
PUTC(*s1++); put(*s1++);
} }
if (i > 0) if (i > 0)
nrchars += i; nrchars += i;
while (--i >= 0) while (--i >= 0)
PUTC(zfill); put(zfill);
} }
return nrchars; return nrchars;
} }

View file

@ -33,8 +33,7 @@ static char inp_buf[NUMLEN];
* is then set to 0, so strtol() will get the right argument. * is then set to 0, so strtol() will get the right argument.
*/ */
static char* static char*
o_collect(register int c, register FILE* stream, char type, o_collect(register int c, char type, int width, int* basep, int (*get)(void), void (*unget)(int c))
int width, int* basep)
{ {
register char* bufp = inp_buf; register char* bufp = inp_buf;
register int base; register int base;
@ -63,14 +62,14 @@ o_collect(register int c, register FILE* stream, char type,
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
if (width && c == '0' && base == 16) if (width && c == '0' && base == 16)
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
if (c != 'x' && c != 'X') if (c != 'x' && c != 'X')
{ {
if (type == 'i') if (type == 'i')
@ -80,7 +79,7 @@ o_collect(register int c, register FILE* stream, char type,
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
} }
else if (type == 'i') else if (type == 'i')
@ -95,14 +94,14 @@ o_collect(register int c, register FILE* stream, char type,
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
else else
break; break;
} }
if (width && c != EOF) if (width && c != EOF)
ungetc(c, stream); unget(c);
if (type == 'i') if (type == 'i')
base = 0; base = 0;
*basep = base; *basep = base;
@ -120,7 +119,7 @@ o_collect(register int c, register FILE* stream, char type,
* numbers to be passed to strtod(). (e.g. 1.3e+) * numbers to be passed to strtod(). (e.g. 1.3e+)
*/ */
static char* static char*
f_collect(register int c, register FILE* stream, register int width) f_collect(register int c, register int width, int (*get)(void), void (*unget)(int c))
{ {
register char* bufp = inp_buf; register char* bufp = inp_buf;
int digit_seen = 0; int digit_seen = 0;
@ -129,7 +128,7 @@ f_collect(register int c, register FILE* stream, register int width)
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
while (width && isdigit(c)) while (width && isdigit(c))
@ -137,26 +136,26 @@ f_collect(register int c, register FILE* stream, register int width)
digit_seen++; digit_seen++;
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
if (width && c == '.') if (width && c == '.')
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
while (width && isdigit(c)) while (width && isdigit(c))
{ {
digit_seen++; digit_seen++;
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
} }
if (!digit_seen) if (!digit_seen)
{ {
if (width && c != EOF) if (width && c != EOF)
ungetc(c, stream); unget(c);
return inp_buf - 1; return inp_buf - 1;
} }
else else
@ -166,30 +165,30 @@ f_collect(register int c, register FILE* stream, register int width)
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
if (width && (c == '+' || c == '-')) if (width && (c == '+' || c == '-'))
{ {
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
while (width && isdigit(c)) while (width && isdigit(c))
{ {
digit_seen++; digit_seen++;
*bufp++ = c; *bufp++ = c;
if (--width) if (--width)
c = getc(stream); c = get();
} }
if (!digit_seen) if (!digit_seen)
{ {
if (width && c != EOF) if (width && c != EOF)
ungetc(c, stream); unget(c);
return inp_buf - 1; return inp_buf - 1;
} }
} }
if (width && c != EOF) if (width && c != EOF)
ungetc(c, stream); unget(c);
*bufp = '\0'; *bufp = '\0';
return bufp - 1; return bufp - 1;
} }
@ -199,7 +198,7 @@ f_collect(register int c, register FILE* stream, register int width)
* the routine that does the scanning * the routine that does the scanning
*/ */
int _doscan(register FILE* stream, const char* format, va_list ap) int _doscan(const char* format, va_list ap, int (*get)(void), void (*unget)(int c))
{ {
int done = 0; /* number of items done */ int done = 0; /* number of items done */
int nrchars = 0; /* number of characters read */ int nrchars = 0; /* number of characters read */
@ -226,15 +225,15 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
{ {
while (isspace(*format)) while (isspace(*format))
format++; /* skip whitespace */ format++; /* skip whitespace */
ic = getc(stream); ic = get();
nrchars++; nrchars++;
while (isspace(ic)) while (isspace(ic))
{ {
ic = getc(stream); ic = get();
nrchars++; nrchars++;
} }
if (ic != EOF) if (ic != EOF)
ungetc(ic, stream); unget(ic);
nrchars--; nrchars--;
} }
if (!*format) if (!*format)
@ -242,12 +241,12 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
if (*format != '%') if (*format != '%')
{ {
ic = getc(stream); ic = get();
nrchars++; nrchars++;
if (ic != *format++) if (ic != *format++)
{ {
if (ic != EOF) if (ic != EOF)
ungetc(ic, stream); unget(ic);
nrchars--; nrchars--;
break; /* error */ break; /* error */
} }
@ -256,7 +255,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
format++; format++;
if (*format == '%') if (*format == '%')
{ {
ic = getc(stream); ic = get();
nrchars++; nrchars++;
if (ic == '%') if (ic == '%')
{ {
@ -299,7 +298,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
{ {
do do
{ {
ic = getc(stream); ic = get();
nrchars++; nrchars++;
} while (isspace(ic)); } while (isspace(ic));
if (ic == EOF) if (ic == EOF)
@ -307,7 +306,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
} }
else if (kind != 'n') else if (kind != 'n')
{ /* %c or %[ */ { /* %c or %[ */
ic = getc(stream); ic = get();
if (ic == EOF) if (ic == EOF)
break; /* outer while */ break; /* outer while */
nrchars++; nrchars++;
@ -344,7 +343,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
if (!width) if (!width)
return done; return done;
str = o_collect(ic, stream, kind, width, &base); str = o_collect(ic, kind, width, &base, get, unget);
if (str < inp_buf if (str < inp_buf
|| (str == inp_buf || (str == inp_buf
&& (*str == '-' && (*str == '-'
@ -385,7 +384,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
*str++ = (char)ic; *str++ = (char)ic;
if (--width) if (--width)
{ {
ic = getc(stream); ic = get();
nrchars++; nrchars++;
} }
} }
@ -393,7 +392,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
if (width) if (width)
{ {
if (ic != EOF) if (ic != EOF)
ungetc(ic, stream); unget(ic);
nrchars--; nrchars--;
} }
break; break;
@ -411,7 +410,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
*str++ = (char)ic; *str++ = (char)ic;
if (--width) if (--width)
{ {
ic = getc(stream); ic = get();
nrchars++; nrchars++;
} }
} }
@ -421,7 +420,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
if (width) if (width)
{ {
if (ic != EOF) if (ic != EOF)
ungetc(ic, stream); unget(ic);
nrchars--; nrchars--;
} }
break; break;
@ -468,7 +467,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
if (!*format || !(Xtable[ic] ^ reverse)) if (!*format || !(Xtable[ic] ^ reverse))
{ {
if (ic != EOF) if (ic != EOF)
ungetc(ic, stream); unget(ic);
return done; return done;
} }
@ -481,7 +480,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
*str++ = (char)ic; *str++ = (char)ic;
if (--width) if (--width)
{ {
ic = getc(stream); ic = get();
nrchars++; nrchars++;
} }
} while (width && ic != EOF && (Xtable[ic] ^ reverse)); } while (width && ic != EOF && (Xtable[ic] ^ reverse));
@ -489,7 +488,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
if (width) if (width)
{ {
if (ic != EOF) if (ic != EOF)
ungetc(ic, stream); unget(ic);
nrchars--; nrchars--;
} }
if (!(flags & FL_NOASSIGN)) if (!(flags & FL_NOASSIGN))
@ -508,7 +507,7 @@ int _doscan(register FILE* stream, const char* format, va_list ap)
if (!width) if (!width)
return done; return done;
str = f_collect(ic, stream, width); str = f_collect(ic, width, get, unget);
if (str < inp_buf if (str < inp_buf
|| (str == inp_buf || (str == inp_buf

View file

@ -8,7 +8,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
int fclose(FILE* fp) int fclose(FILE* fp)
{ {

View file

@ -7,7 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "../stdio/loc_incl.h" #include "../stdio/loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
FILE* fdopen(int fd, const char* mode) FILE* fdopen(int fd, const char* mode)
{ {

View file

@ -8,7 +8,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
int fflush(FILE* stream) int fflush(FILE* stream)
{ {

View file

@ -5,7 +5,7 @@
#include <stdio.h> #include <stdio.h>
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
int(fileno)(FILE* stream) int(fileno)(FILE* stream)
{ {

View file

@ -8,7 +8,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
int __fillbuf(register FILE* stream) int __fillbuf(register FILE* stream)
{ {

View file

@ -8,7 +8,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
static int static int
do_write(int d, char* buf, int nbytes) do_write(int d, char* buf, int nbytes)

View file

@ -10,7 +10,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
#define PMODE 0666 #define PMODE 0666

View file

@ -15,9 +15,7 @@ int fprintf(FILE* stream, const char* format, ...)
int retval; int retval;
va_start(ap, format); va_start(ap, format);
retval = vfprintf(stream, format, ap);
retval = _doprnt(format, ap, stream);
va_end(ap); va_end(ap);
return retval; return retval;

View file

@ -9,7 +9,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
#define PMODE 0666 #define PMODE 0666

View file

@ -15,9 +15,7 @@ int fscanf(FILE* stream, const char* format, ...)
int retval; int retval;
va_start(ap, format); va_start(ap, format);
retval = vfscanf(stream, format, ap);
retval = _doscan(stream, format, ap);
va_end(ap); va_end(ap);
return retval; return retval;

View file

@ -8,7 +8,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
int fseek(FILE* stream, long int offset, int whence) int fseek(FILE* stream, long int offset, int whence)
{ {

View file

@ -8,7 +8,7 @@
#include <unistd.h> #include <unistd.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
long ftell(FILE* stream) long ftell(FILE* stream)
{ {

View file

@ -10,8 +10,8 @@
#define io_testflag(p,x) ((p)->_flags & (x)) #define io_testflag(p,x) ((p)->_flags & (x))
#include <stdarg.h> #include <stdarg.h>
int _doprnt(const char *format, va_list ap, FILE *stream); int _doprnt(const char *format, va_list ap, void (*put)(int c));
int _doscan(FILE * stream, const char *format, va_list ap); int _doscan(const char *format, va_list ap, int (*get)(void), void (*unget)(int c));
char *_i_compute(unsigned long val, int base, char *s, int nrdigits); char *_i_compute(unsigned long val, int base, char *s, int nrdigits);
char *_f_print(va_list *ap, int flags, char *s, char c, int precision); char *_f_print(va_list *ap, int flags, char *s, char c, int precision);

View file

@ -15,9 +15,7 @@ int printf(const char* format, ...)
int retval; int retval;
va_start(ap, format); va_start(ap, format);
retval = vfprintf(stdout, format, ap);
retval = _doprnt(format, ap, stdout);
va_end(ap); va_end(ap);
return retval; return retval;

View file

@ -15,9 +15,7 @@ int scanf(const char* format, ...)
int retval; int retval;
va_start(ap, format); va_start(ap, format);
retval = vfscanf(stdin, format, ap);
retval = _doscan(stdin, format, ap);
va_end(ap); va_end(ap);
return retval; return retval;

View file

@ -6,7 +6,7 @@
#include <stdio.h> #include <stdio.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
void setbuf(register FILE* stream, char* buf) void setbuf(register FILE* stream, char* buf)
{ {

View file

@ -7,7 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
int setvbuf(register FILE* stream, char* buf, int mode, size_t size) int setvbuf(register FILE* stream, char* buf, int mode, size_t size)
{ {

View file

@ -9,22 +9,29 @@
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO
static char* output_buffer;
static size_t output_buffer_len;
static void snprintf_putc(int c)
{
if (output_buffer_len)
{
*output_buffer++ = c;
output_buffer_len--;
}
}
int snprintf(char* s, size_t len, const char* format, ...) int snprintf(char* s, size_t len, const char* format, ...)
{ {
va_list ap; va_list ap;
int retval; int retval;
FILE tmp_stream;
va_start(ap, format); va_start(ap, format);
tmp_stream._fd = -1; output_buffer = s;
tmp_stream._flags = _IOWRITE + _IONBF + _IOWRITING; output_buffer_len = len;
tmp_stream._buf = (unsigned char*)s; retval = _doprnt(format, ap, snprintf_putc);
tmp_stream._ptr = (unsigned char*)s; snprintf_putc('\0');
tmp_stream._count = len;
retval = _doprnt(format, ap, &tmp_stream);
putc('\0', &tmp_stream);
va_end(ap); va_end(ap);

View file

@ -13,19 +13,9 @@ int sprintf(char* s, const char* format, ...)
{ {
va_list ap; va_list ap;
int retval; int retval;
FILE tmp_stream;
va_start(ap, format); va_start(ap, format);
retval = vsnprintf(s, 32767, format, ap);
tmp_stream._fd = -1;
tmp_stream._flags = _IOWRITE + _IONBF + _IOWRITING;
tmp_stream._buf = (unsigned char*)s;
tmp_stream._ptr = (unsigned char*)s;
tmp_stream._count = 32767;
retval = _doprnt(format, ap, &tmp_stream);
putc('\0', &tmp_stream);
va_end(ap); va_end(ap);
return retval; return retval;

View file

@ -10,21 +10,32 @@
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO
static const char* input_buffer;
static int sscanf_getc(void)
{
char c = *input_buffer;
if (c == 0)
return EOF;
input_buffer++;
return c;
}
static void sscanf_ungetc(int c)
{
/* sscanf always ungets the last character read. */
input_buffer--;
}
int sscanf(const char* s, const char* format, ...) int sscanf(const char* s, const char* format, ...)
{ {
va_list ap; va_list ap;
int retval; int retval;
FILE tmp_stream;
va_start(ap, format); va_start(ap, format);
tmp_stream._fd = -1; input_buffer = s;
tmp_stream._flags = _IOREAD + _IONBF + _IOREADING; retval = _doscan(format, ap, sscanf_getc, sscanf_ungetc);
tmp_stream._buf = (unsigned char*)s;
tmp_stream._ptr = (unsigned char*)s;
tmp_stream._count = strlen(s);
retval = _doscan(&tmp_stream, format, ap);
va_end(ap); va_end(ap);

View file

@ -13,7 +13,7 @@
FILE* tmpfile(void) FILE* tmpfile(void)
{ {
static char name_buffer[L_tmpnam] = "/tmp/tmp."; static char name_buffer[L_tmpnam] = ACK_TMP_PREFIX;
static char* name = NULL; static char* name = NULL;
FILE* file; FILE* file;

View file

@ -13,7 +13,7 @@
char* tmpnam(char* s) char* tmpnam(char* s)
{ {
static char name_buffer[L_tmpnam] = "/tmp/tmp."; static char name_buffer[L_tmpnam] = ACK_TMP_PREFIX;
static unsigned long count = 0; static unsigned long count = 0;
static char* name = NULL; static char* name = NULL;

View file

@ -6,7 +6,7 @@
#include <stdio.h> #include <stdio.h>
#include "loc_incl.h" #include "loc_incl.h"
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
int ungetc(int ch, FILE* stream) int ungetc(int ch, FILE* stream)
{ {

View file

@ -9,9 +9,17 @@
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO
static FILE* vfprintf_stream;
static void vfprintf_putc(int c)
{
putc(c, vfprintf_stream);
}
int vfprintf(FILE* stream, const char* format, va_list arg) int vfprintf(FILE* stream, const char* format, va_list arg)
{ {
return _doprnt(format, arg, stream); vfprintf_stream = stream;
return _doprnt(format, arg, vfprintf_putc);
} }
#endif #endif

View file

@ -0,0 +1,30 @@
/*
* vfscanf.c - read formatted input from stream
*/
/* $Id$ */
#include <stdio.h>
#include <stdarg.h>
#include "loc_incl.h"
#if ACKCONF_WANT_STDIO
static FILE* vfscanf_stream;
static int vfscanf_getc(void)
{
return getc(vfscanf_stream);
}
static void vfscanf_ungetc(int c)
{
ungetc(c, vfscanf_stream);
}
int vfscanf(FILE* stream, const char* format, va_list ap)
{
vfscanf_stream = stream;
return _doscan(format, ap, vfscanf_getc, vfscanf_ungetc);
}
#endif

View file

@ -11,7 +11,7 @@
int vprintf(const char* format, va_list arg) int vprintf(const char* format, va_list arg)
{ {
return _doprnt(format, arg, stdout); return vfprintf(stdout, format, arg);
} }
#endif #endif

View file

@ -9,19 +9,26 @@
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO
int vsnprintf(char* s, size_t len, const char* format, va_list arg) static char* output_buffer;
static size_t output_buffer_len;
static void snprintf_putc(int c)
{
if (output_buffer_len)
{
*output_buffer++ = c;
output_buffer_len--;
}
}
int vsnprintf(char* s, size_t len, const char* format, va_list ap)
{ {
int retval; int retval;
FILE tmp_stream;
tmp_stream._fd = -1; output_buffer = s;
tmp_stream._flags = _IOWRITE + _IONBF + _IOWRITING; output_buffer_len = len;
tmp_stream._buf = (unsigned char*)s; retval = _doprnt(format, ap, snprintf_putc);
tmp_stream._ptr = (unsigned char*)s; snprintf_putc('\0');
tmp_stream._count = len;
retval = _doprnt(format, arg, &tmp_stream);
putc('\0', &tmp_stream);
return retval; return retval;
} }

View file

@ -9,21 +9,9 @@
#if ACKCONF_WANT_STDIO #if ACKCONF_WANT_STDIO
int vsprintf(char* s, const char* format, va_list arg) int vsprintf(char* s, const char* format, va_list ap)
{ {
int retval; return vsnprintf(s, 32767, format, ap);
FILE tmp_stream;
tmp_stream._fd = -1;
tmp_stream._flags = _IOWRITE + _IONBF + _IOWRITING;
tmp_stream._buf = (unsigned char*)s;
tmp_stream._ptr = (unsigned char*)s;
tmp_stream._count = 32767;
retval = _doprnt(format, arg, &tmp_stream);
putc('\0', &tmp_stream);
return retval;
} }
#endif #endif

View file

@ -0,0 +1,22 @@
#ifndef ACK_FILE_H
#define ACK_FILE_H
/* CP/M custom FILE* implementation. */
#define L_tmpnam 16 /* 0a:12345678.abc */
#define ACK_TMP_PREFIX "0a:tmp"
#define TMP_MAX 999
#include <cpm.h>
struct FILE
{
uint8_t user;
FCB fcb;
char buffer[128];
};
#define FOPEN_MAX 8
extern FILE* __files[FOPEN_MAX];
#endif

View file

@ -11,4 +11,12 @@
#define ACKCONF_WANT_EMULATED_TIME 0 #define ACKCONF_WANT_EMULATED_TIME 0
/* CP/M's underlying file abstraction is weird and doesn't map well onto
* file descriptors. Disable the standard FILE* mechanism in favour of our
* own.
*/
#define ACKCONF_WANT_EMULATED_FILE 0
#define ACKCONF_WANT_EMULATED_POPEN 0
#endif #endif

View file

@ -9,6 +9,7 @@ local function addheader(h)
end end
addheader("ack/plat.h") addheader("ack/plat.h")
addheader("ack/file.h")
addheader("sys/types.h") addheader("sys/types.h")
addheader("cpm.h") addheader("cpm.h")