mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-22 17:43:14 +00:00
03eb026b61
Ensure the resultant dump has consistently long lines. This will matter when we start rendering attributes on blanks. Additionally, simplify the code significantly taking advantage of first loop.
132 lines
3.4 KiB
C
132 lines
3.4 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <locale.h>
|
|
#include <unistd.h>
|
|
#include "tmt.h"
|
|
#define HASHSIZE 2053
|
|
#define MAXNAMELEN 256
|
|
#define MAXDATALEN 8192
|
|
struct terment {
|
|
struct terment *next;
|
|
char *name;
|
|
TMT *vt;
|
|
};
|
|
|
|
#define SETNODE 1
|
|
#define WRITE 2
|
|
#define READBUFF 0
|
|
static struct terment *buffers[HASHSIZE];
|
|
|
|
unsigned long hash(char *str)
|
|
/* djb2a */
|
|
{
|
|
unsigned long idx = 5381;
|
|
int c;
|
|
|
|
while ((c = *str++))
|
|
idx = ((idx << 5) + idx) + c;
|
|
return idx % HASHSIZE;
|
|
}
|
|
|
|
TMT *get_termentbyname(char *name) {
|
|
struct terment *ret;
|
|
for (ret = buffers[hash(name)]; ret != NULL; ret = ret->next)
|
|
if (strcmp(name, ret->name) == 0)
|
|
return ret->vt;
|
|
return NULL;
|
|
}
|
|
|
|
TMT *set_termentbyname(char *name) {
|
|
struct terment *ret;
|
|
int idx;
|
|
|
|
idx = hash(name);
|
|
for (ret = buffers[idx]; ret != NULL; ret = ret->next)
|
|
if (strcmp(name, ret->name) == 0)
|
|
return ret->vt;
|
|
ret = (struct terment *)malloc(sizeof(*ret));
|
|
ret->next = buffers[idx];
|
|
ret->name = strdup(name);
|
|
ret->vt = tmt_open(31, 100, NULL, NULL, L"→←↑↓■◆▒°±▒┘┐┌└┼⎺───⎽├┤┴┬│≤≥π≠£•");
|
|
buffers[idx] = ret;
|
|
return ret->vt;
|
|
}
|
|
|
|
void dump_vt(TMT* outvt) {
|
|
const TMTSCREEN *out = tmt_screen(outvt);
|
|
const TMTPOINT *curs = tmt_cursor(outvt);
|
|
int line, idx, maxcol, maxrow;
|
|
wprintf(L"\033[H\033[J");
|
|
maxcol = 0;
|
|
maxrow = 0;
|
|
for (line = out->nline - 1; line >= 0; --line) {
|
|
for (idx = out->ncol - 1; idx > maxcol; --idx) {
|
|
if (out->lines[line]->chars[idx].c != L' ') {
|
|
if (maxrow < line)
|
|
maxrow = line;
|
|
maxcol = idx;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for (line = 0; line <= maxrow; line++) {
|
|
for (idx = 0; idx <= maxcol; idx++) {
|
|
wprintf(L"%lc", out->lines[line]->chars[idx].c);
|
|
}
|
|
if (line < maxrow)
|
|
wprintf(L"\r\n");
|
|
}
|
|
fflush(stdout);
|
|
wprintf(L"\x1b[%ld;%ldH", curs->r + 1, curs->c + 1);
|
|
fflush(stdout);
|
|
idx = write(1, "\x00", 1);
|
|
if (idx < 0) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
int cmd, length;
|
|
setlocale(LC_ALL, "");
|
|
char cmdbuf[MAXDATALEN];
|
|
char currnode[MAXNAMELEN];
|
|
TMT *currvt = NULL;
|
|
TMT *outvt = NULL;
|
|
stdin = freopen(NULL, "rb", stdin);
|
|
if (stdin == NULL) {
|
|
exit(1);
|
|
}
|
|
while (1) {
|
|
length = fread(&cmd, 4, 1, stdin);
|
|
if (length < 0)
|
|
continue;
|
|
length = cmd & 536870911;
|
|
cmd = cmd >> 29;
|
|
if (cmd == SETNODE) {
|
|
currnode[length] = 0;
|
|
cmd = fread(currnode, 1, length, stdin);
|
|
if (cmd < 0)
|
|
continue;
|
|
currvt = set_termentbyname(currnode);
|
|
} else if (cmd == WRITE) {
|
|
if (currvt == NULL)
|
|
currvt = set_termentbyname("");
|
|
cmdbuf[length] = 0;
|
|
cmd = fread(cmdbuf, 1, length, stdin);
|
|
if (cmd < 0)
|
|
continue;
|
|
tmt_write(currvt, cmdbuf, length);
|
|
} else if (cmd == READBUFF) {
|
|
cmdbuf[length] = 0;
|
|
cmd = fread(cmdbuf, 1, length, stdin);
|
|
if (cmd < 0)
|
|
continue;
|
|
outvt = get_termentbyname(cmdbuf);
|
|
if (outvt != NULL) {
|
|
dump_vt(outvt);
|
|
}
|
|
}
|
|
}
|
|
}
|