/* This file is part of limb https://lila.oss/limb
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <errno.h>
#include <limb/buffer.h>
#include <limb/u64.h>
void
buffer_putmsg(buffer *b, const char * const *as, unsigned int n)
{
int e = errno;
ssize_t (*puts) (buffer *b, const char *s) = buffer_puts;
for (unsigned i = 0; i < n; ++i) {
if (as[i] == PUTMSG_FLUSH) {
buffer_flush(b);
} else if (as[i] == PUTMSG_ESC || as[i] == PUTMSG_TOGGLE_ESC) {
if (as[i] == PUTMSG_ESC)
buffer_put(b, "\"", 1);
if (puts == buffer_puts)
puts = buffer_putescs;
else
puts = buffer_puts;
} else if ((as[i] == PUTMSG_UINT_NEXT || as[i] == PUTMSG_INT_NEXT) && i + 1 < n) {
char buf_[U64_FMT], *buf = buf_;
u64 u = (uintptr_t) as[++i];
if ((as[i - 1] == PUTMSG_INT_NEXT) && ((intptr_t) u < 0)) {
*buf++ = '-';
u = -u;
}
buf[u64_fmt(buf, u)] = 0;
buffer_puts(b, buf_);
} else if (as[i] == PUTMSG_ERR_NEXT && i + 1 < n) {
puts(b, strerror((uintptr_t) as[++i]));
} else if (as[i] == PUTMSG_LEN_NEXT && i + 2 < n) {
if (puts == buffer_puts)
buffer_put(b, as[i + 1], (uintptr_t) as[i + 2]);
else
buffer_putesc(b, as[i + 1], (uintptr_t) as[i + 2]);
i += 2;
} else if ((as[i] == PUTMSG_HEX_NEXT || as[i] == PUTMSG_DUMP_NEXT) && i + 2 < n) {
buffer_puthex(b, as[i + 1], (uintptr_t) as[i + 2],
(as[i] == PUTMSG_DUMP_NEXT) ? HEX_SP | HEX_1BLOCK_SP | HEX_3BLOCK_LF | HEX_LF : 0);
i += 2;
} else if (as[i] && as[i][0]) {
puts(b, as[i]);
}
}
errno = e;
}