Welcome to little lamb

Code » limb » release » tree

[release] / src / liblimb / buffer.h / buffer_putmsg.c

/* 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;
}