summaryrefslogtreecommitdiff
path: root/output.c
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2021-05-31 06:11:22 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2021-05-31 06:11:22 -0700
commit18bde7391efb9c6bd6ea7846891ab5d16276a809 (patch)
tree237cc152edbdf934ed32e4c8c54c5ce97535e57f /output.c
downloadstonks-master.tar.gz
stonks-master.tar.xz
initial importHEADmaster
A bit messy and missing error handling in some places.
Diffstat (limited to 'output.c')
-rw-r--r--output.c131
1 files changed, 131 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lua.h>
+
+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);
+}