The purpose of this is written in the comment below (it is meant to be used in a text editor):
abuf.h:
#ifndef ABUF_H
#define ABUF_H 1
#include "stddef.h"
/* We define a simple 'append buffer', that is a heap allocated string
* where we can append to. This avoids calling write() every time we have
* to print something (e.g. escape sequences) while refreshing the screen,
* and any flickering effects. */
typedef struct abuf {
char *buf; /* A pointer to a chunk of allocated memory. */
size_t count; /* Total bytes occupied. */
size_t capacity; /* Total bytes allocated. */
} abuf;
[[gnu::hot]] bool append_abuf(abuf ab[restrict static 1],
size_t size,
const char s[restrict static size]);
void abuf_free(abuf ab[static 1]);
#endif /* ABUF_H */
abuf.c:
#include <stdlib.h>
#include <string.h>
#define GROW_CAPACITY(capacity) \
(size_t) ((capacity) < 8 ? 8 : (capacity) * 2)
bool abuf_append(abuf ab[restrict static 1],
size_t size,
const char s[restrict static size])
{
if ((ab->count + size) > ab->capacity) {
ab->capacity = GROW_CAPACITY(ab->capacity);
void *const tmp = realloc(ab->buf, ab->capacity);
if (tmp == nullptr) {
return false;
}
ab->buf = tmp;
}
memcpy(ab->buf + ab->count, s, size + 1);
ab->count += size;
return true;
}
void abuf_free(abuf ab[static 1])
{
free(ab->buf);
}
And it is used like this:
abuf ab = {};
ssize_t exit_stat;
const bool error = !abuf_append(...)
|| !abuf_append(...)
|| !draw_rows(...)
|| !draw_status_bar(...)
|| !draw_msg_bar(...)
|| !abuf_append(...)
|| !abuf_append(...);
if (!error
&& !(exit_stat = write_eintr(STDOUT_FILENO, ab.buf, ab.count))) {
perror("write()");
}
abuf_free(&ab);
return exit_stat;
Review Request:
Anything, everything.
Should I add the two missing overflow checks in abuf_append() when adding?