From 18bde7391efb9c6bd6ea7846891ab5d16276a809 Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Mon, 31 May 2021 06:11:22 -0700 Subject: initial import A bit messy and missing error handling in some places. --- output.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 output.c (limited to 'output.c') diff --git a/output.c b/output.c new file mode 100644 index 0000000..03199ab --- /dev/null +++ b/output.c @@ -0,0 +1,131 @@ +#include "assets.h" +#include "output.h" + +#include +#include +#include + +#include + +static int push_field(lua_State *L, struct asset *a, const char *field) +{ + int n = 0; + + if (strcmp(field, "symbol") == 0) { + lua_pushstring(L, a->symbol); + ++n; + } else if (strcmp(field, "type") == 0) { + lua_pushstring(L, ASSET_TYPE_NAMES[a->type]); + ++n; + } else if (strcmp(field, "usd_price") == 0) { + if (a->usd && a->type != TOTAL) { + lua_pushnumber(L, a->usd_pr); + ++n; + } + } else if (strcmp(field, "usd_change") == 0) { + if (a->usd && a->type != TOTAL) { + lua_pushnumber(L, a->usd_ch); + ++n; + } + } else if (strcmp(field, "usd_total") == 0) { + if (a->usd) { + lua_pushnumber(L, a->usd_tot); + ++n; + } + } else if (strcmp(field, "btc_price") == 0) { + if (a->btc && a->type != TOTAL) { + lua_pushnumber(L, a->btc_pr); + ++n; + } + } else if (strcmp(field, "btc_change") == 0) { + if (a->btc && a->type != TOTAL) { + lua_pushnumber(L, a->btc_ch); + ++n; + } + } else if (strcmp(field, "btc_total") == 0) { + if (a->btc) { + lua_pushnumber(L, a->btc_tot); + ++n; + } + } + + return n; +} + +static int decolour_len(const char *str) +{ + int len = strlen(str); + + while ((str = strchr(str, '\033'))) { + char *ptr = strchr(str, 'm') + 1; + len -= ptr - str; + str = ptr; + } + + return len; +} + +void output(struct asset **assets, int assets_len, lua_State *L) +{ + lua_getglobal(L, "columns"); + int len = lua_rawlen(L, -1); + lua_pop(L, 1); + + int *widths = calloc(len, sizeof(int)); + char ***out = calloc(assets_len, sizeof(char **)); + + for (int i = 0; i < assets_len; ++i) { + out[i] = calloc(len, sizeof(char *)); + + lua_getglobal(L, "columns"); + lua_pushnil(L); + int j = 0; + while (lua_next(L, -2)) { + lua_rawgeti(L, -1, 1); + const char *x = lua_tostring(L, -1); + lua_pop(L, 1); + + char *y; + lua_rawgeti(L, -1, 2); + if (push_field(L, assets[i], x) > 0) { + lua_pushlightuserdata(L, assets[i]); + lua_pcall(L, 2, 1, 0); + y = strdup(lua_tostring(L, -1)); + } else { + y = strdup(""); + } + lua_pop(L, 1); + + int dlen = decolour_len(y); + if (dlen > widths[j]) + widths[j] = dlen; + + out[i][j++] = y; + lua_pop(L, 1); + } + lua_pop(L, 1); + } + + for (int i = 0; i < assets_len; ++i) { + for (int j = 0; j < len; ++j) { + printf("%*s%s", widths[j] - decolour_len(out[i][j]) + 2, "", + out[i][j]); + } + printf("\n"); + } + + free(widths); + for (int i = 0; i < assets_len; ++i) { + for (int j = 0; j < len; ++j) { + free(out[i][j]); + } + free(out[i]); + } + free(out); +} + +int push_field_lua(lua_State *L) { + struct asset *a = lua_touserdata(L, 1); + const char *field = lua_tostring(L, 2); + return push_field(L, a, field); +} -- cgit v1.2.3-70-g09d2