Skip to content

Instantly share code, notes, and snippets.

@nanokatze
Last active July 31, 2019 17:50
Show Gist options
  • Save nanokatze/414027d5e8458241ea959557a60abae4 to your computer and use it in GitHub Desktop.
Save nanokatze/414027d5e8458241ea959557a60abae4 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include "printf2.h"
size_t
vfprintf2(FILE *stream, const char *format, va_list ap)
{
typedef size_t (*pp_print)(FILE *stream, va_list *);
va_list ap2;
va_copy(ap2, ap);
size_t n = 0;
while (ferror(stream) == 0) {
char c;
switch (c = *(format++)) {
case '\0':
goto done;
case '%':
switch (c = *(format++)) {
case '\0':
goto done;
case '%':
if (fputc('%', stream) != 0) {
n++;
}
break;
case 'B': {
const char *s = va_arg(ap2, int) != 0 ? "true" : "false";
n += fwrite(s, strlen(s), 1, stream);
break;
}
case 'c':
if (fputc(va_arg(ap2, int), stream) != 0) {
n++;
}
break;
case 's': {
const char *s = va_arg(ap2, const char *);
n += fwrite(s, strlen(s), 1, stream);
break;
}
case 't': {
pp_print pr = va_arg(ap2, pp_print);
n += pr(stream, &ap2);
break;
}
default:
assert(0);
}
break;
default:
if (fputc((int) c, stream) != 0) {
n++;
}
break;
}
}
done:
va_end(ap2);
return n;
}
size_t
fprintf2(FILE *stream, const char *format, ...)
{
va_list ap;
va_start(ap, format);
size_t n = vfprintf2(stream, format, ap);
va_end(ap);
return n;
}
size_t
printf2(const char *format, ...)
{
va_list ap;
va_start(ap, format);
size_t n = vfprintf2(stdout, format, ap);
va_end(ap);
return n;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment