summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-03-15 16:16:02 -0400
committerJakob Kaivo <jkk@ung.org>2019-03-15 16:16:02 -0400
commitc9d2617b4b40469c7b1a02ae50d7ecbce65f46b7 (patch)
tree0b692f6eacdd8c32d7d093c4447202482ab8e8aa
parente5232a0f3b116314ce0694d4e6d360ddd96179db (diff)
%b conversions support width and precision
-rw-r--r--printf.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/printf.c b/printf.c
index 757843f..c0388f7 100644
--- a/printf.c
+++ b/printf.c
@@ -81,11 +81,25 @@ static const char *escape(const char *esc, char *out)
return esc + 1;
}
-static const char *echo(const char *s)
+static char *echo(const char *s)
{
+ static char *buf = NULL;
+ static size_t blen = 0;
+
+ size_t slen = strlen(s);
+ if (slen > blen) {
+ blen = slen;
+ buf = realloc(buf, blen);
+ if (buf == NULL) {
+ diagnose("%s", strerror(errno));
+ exit(1);
+ }
+ }
+
+ size_t i = 0;
while (*s) {
if (*s != '\\') {
- putchar(*s++);
+ buf[i++] = (*s++);
continue;
}
@@ -97,13 +111,14 @@ static const char *echo(const char *s)
if (*s == '0' || !isdigit(*s)) {
char c = '\0';
s = escape(s + 1, &c);
- putchar(c);
+ buf[i++] = (c);
} else {
diagnose("unknown escape \"\\%c\"", *s);
s++;
}
}
- return s;
+
+ return buf;
}
static const char *convert(const char *conv, const char *operand)
@@ -141,8 +156,9 @@ static const char *convert(const char *conv, const char *operand)
/* conversion specifier */
switch (*conv) {
case 'b':
- /* TODO: print to string, then fallthru */
- return echo(operand);
+ strcat(oconv, "s");
+ printf(oconv, echo(operand));
+ break;
case 's':
strcat(oconv, "s");
@@ -292,7 +308,7 @@ int printf_main(int argc, char *argv[])
int echo_main(int argc, char *argv[])
{
for (int i = 1; i < argc; i++) {
- echo(argv[i]);
+ printf("%s", echo(argv[i]));
putchar(i == argc - 1 ? '\n' : ' ');
}
return errors;