Add function for creating hex string literals

This commit is contained in:
Justine Tunney 2021-08-07 07:05:19 -07:00
parent aeeb851422
commit 1f766a332f
14 changed files with 250 additions and 112 deletions

View file

@ -18,75 +18,30 @@
*/
#include "libc/fmt/fmt.h"
#include "libc/macros.internal.h"
#include "libc/stdio/append.internal.h"
#include "libc/stdio/hex.internal.h"
#include "libc/stdio/stdio.h"
struct Append {
size_t i, n;
char *p;
};
int AppendFmt(struct Append *b, const char *fmt, ...) {
int n;
char *p;
va_list va, vb;
va_start(va, fmt);
va_copy(vb, va);
n = vsnprintf(b->p + b->i, b->n - b->i, fmt, va);
if (n >= b->n - b->i) {
do {
if (b->n) {
b->n += b->n >> 1; /* this is the important line */
} else {
b->n = 16;
}
} while (b->i + n + 1 > b->n);
b->p = realloc(b->p, b->n);
vsnprintf(b->p + b->i, b->n - b->i, fmt, vb);
}
va_end(vb);
va_end(va);
b->i += n;
return n;
}
char *DumpHexc(const char *data, size_t size, size_t *z) {
long o;
int b, i, n;
char A[128], *p;
struct Append buf;
if (size == -1) size = data ? strlen(data) : 0;
buf.i = 0;
buf.n = 256;
buf.p = calloc(1, 256);
AppendFmt(&buf, "\"\\\n");
for (b = o = 0; (n = MIN(16, size)); data += n, size -= n) {
p = A;
for (i = 0; i < n; ++i) {
*p++ = '\\';
*p++ = 'x';
*p++ = "0123456789abcdef"[(data[i] & 0xF0) >> 4];
*p++ = "0123456789abcdef"[(data[i] & 0x0F) >> 0];
}
if (o) AppendFmt(&buf, "\\\n");
AppendFmt(&buf, "%.*s", p - A, A);
o += n;
}
AppendFmt(&buf, "\"");
if (z) *z = buf.i;
return buf.p;
}
/**
* @fileoverview Hex String Literal Converter, e.g.
*
* $ echo hello | o/tool/viz/dumphexc.com
* "\
* \x68\x65\x6c\x6c\x6f\x0a"
*/
int main(int argc, char *argv[]) {
char *p;
size_t n, g;
char *b = 0;
char buf[512];
struct Append b = {0};
while ((g = fread(buf, 1, sizeof(buf), stdin))) {
AppendFmt(&b, "%.*s", g, buf);
appendd(&b, buf, g);
}
if (!ferror(stdin)) {
p = DumpHexc(b.p, b.i, &n);
p = DumpHexc(b, appendz(b).i, &n);
fwrite(p, 1, n, stdout);
free(p);
}
printf("\n");
return ferror(stdin) || ferror(stdout) ? 1 : 0;