commit fdae99f75651ec33854a55654887608fb4f2947c
parent 4dff6dde00bd2e8062f678d6ca2207d00119474f
Author: Quentin Rameau <quinq@fifth.space>
Date: Fri, 7 Jul 2017 15:16:30 +0200
Handle (hopefuly) all invalid format streams
Diffstat:
M | sacc.c | | | 112 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | ui_ti.c | | | 37 | +++++++++++++++++++------------------ |
M | ui_txt.c | | | 23 | ++++++++++------------- |
3 files changed, 84 insertions(+), 88 deletions(-)
diff --git a/sacc.c b/sacc.c
@@ -57,6 +57,17 @@ xmalloc(const size_t n)
return m;
}
+static void *
+xcalloc(size_t n)
+{
+ char *m = xmalloc(n);
+
+ while (n)
+ m[--n] = 0;
+
+ return m;
+}
+
static char *
xstrdup(const char *str)
{
@@ -147,20 +158,8 @@ pickfield(char **raw, char sep)
{
char *c, *f = *raw;
- for (c = *raw; *c != sep; ++c) {
- switch (*c) {
- case '\t':
- if (sep == '\r')
- *c = '\0';
- case '\n':
- case '\r':
- case '\0':
- return NULL;
- default:
- continue;
- }
- break;
- }
+ for (c = *raw; *c && *c != sep; ++c)
+ ;
*c = '\0';
*raw = c+1;
@@ -168,35 +167,47 @@ pickfield(char **raw, char sep)
return f;
}
+static char *
+invaliditem(char *raw)
+{
+ char c;
+ int tabs;
+
+ for (tabs = 0; (c = *raw) && c != '\n'; ++raw) {
+ if (c == '\t')
+ ++tabs;
+ }
+ if (c)
+ *raw++ = '\0';
+
+ return (tabs == 3) ? NULL : raw;
+}
+
static Item *
molditem(char **raw)
{
Item *item;
- char type, *username, *selector, *host, *port;
+ char *next;
if (!*raw)
return NULL;
- if (!(type = *raw[0]++) ||
- !(username = pickfield(raw, '\t')) ||
- !(selector = pickfield(raw, '\t')) ||
- !(host = pickfield(raw, '\t')) ||
- !(port = pickfield(raw, '\r')) ||
- *raw[0]++ != '\n')
- return NULL;
+ item = xcalloc(sizeof(Item));
- item = xmalloc(sizeof(Item));
+ if ((next = invaliditem(*raw))) {
+ item->type = 'i';
+ item->username = *raw;
+ *raw = next;
+ return item;
+ }
- item->type = type;
- item->username = username;
- item->selector = selector;
- item->host = host;
- item->port = port;
- item->raw = NULL;
- item->dir = NULL;
- item->entry = NULL;
- item->printoff = 0;
- item->curline = 0;
+ item->type = *raw[0]++;
+ item->username = pickfield(raw, '\t');
+ item->selector = pickfield(raw, '\t');
+ item->host = pickfield(raw, '\t');
+ item->port = pickfield(raw, '\r');
+ if (!*raw[0])
+ ++*raw;
return item;
}
@@ -204,38 +215,25 @@ molditem(char **raw)
static Dir *
molddiritem(char *raw)
{
- Item *item, **items = NULL;
- char *crlf, *p;
+ Item **items = NULL;
+ char *s, *nl, *p;
Dir *dir;
size_t i, nitems;
- for (crlf = raw, nitems = 0; p = strstr(crlf, "\r\n"); ++nitems)
- crlf = p+2;
- if (nitems <= 1)
- return NULL;
- if (!strcmp(crlf-3, ".\r\n"))
+ for (s = nl = raw, nitems = 0; p = strchr(nl, '\n'); ++nitems) {
+ s = nl;
+ nl = p+1;
+ }
+ if (!strcmp(s, ".\r\n") || !strcmp(s, ".\n"))
--nitems;
- else
- fprintf(stderr, "Parsing error: missing .\\r\\n last line\n");
+ if (!nitems)
+ return NULL;
dir = xmalloc(sizeof(Dir));
items = xreallocarray(items, nitems, sizeof(Item*));
- for (i = 0; i < nitems; ++i) {
- if (item = molditem(&raw)) {
- items[i] = item;
- } else {
- fprintf(stderr, "Parsing error: dir entity: %d\n", i+1);
- items = xreallocarray(items, i, sizeof(Item*));
- nitems = i;
- break;
- }
- }
-
- if (!items) {
- free(dir);
- return NULL;
- }
+ for (i = 0; i < nitems; ++i)
+ items[i] = molditem(&raw);
dir->items = items;
dir->nitems = nitems;
diff --git a/ui_ti.c b/ui_ti.c
@@ -57,7 +57,7 @@ help(void)
static void
displaystatus(Item *item)
{
- size_t nitems = item->dir->nitems;
+ size_t nitems = item->dir ? item->dir->nitems : 0;
putp(tparm(save_cursor));
@@ -75,13 +75,18 @@ displaystatus(Item *item)
void
display(Item *entry)
{
- Item *item, **items;
+ Item **items;
size_t i, curln, lastln, nitems, printoff;
if (entry->type != '1')
return;
putp(tparm(clear_screen));
+ displaystatus(entry);
+
+ if (!entry->dir)
+ return;
+
putp(tparm(save_cursor));
items = entry->dir->items;
@@ -91,22 +96,19 @@ display(Item *entry)
lastln = printoff + lines-1; /* one off for status bar */
for (i = printoff; i < nitems && i < lastln; ++i) {
- if (item = items[i]) {
- if (i != printoff)
- putp(tparm(cursor_down));
- if (i == curln) {
- putp(tparm(save_cursor));
- putp(tparm(enter_standout_mode));
- }
- printitem(item);
- putp(tparm(column_address, 0));
- if (i == curln)
- putp(tparm(exit_standout_mode));
+ if (i != printoff)
+ putp(tparm(cursor_down));
+ if (i == curln) {
+ putp(tparm(save_cursor));
+ putp(tparm(enter_standout_mode));
}
+ printitem(items[i]);
+ putp(tparm(column_address, 0));
+ if (i == curln)
+ putp(tparm(exit_standout_mode));
}
putp(tparm(restore_cursor));
- displaystatus(entry);
fflush(stdout);
}
@@ -166,8 +168,7 @@ movecurline(Item *item, int l)
Item *
selectitem(Item *entry)
{
- Item *hole;
- int item, nitems;
+ Dir *dir = entry->dir;
for (;;) {
switch (getchar()) {
@@ -199,8 +200,8 @@ selectitem(Item *entry)
case _key_pgnext:
case '\r':
pgnext:
- if (entry->dir->items[entry->curline]->type < '2')
- return entry->dir->items[entry->curline];
+ if (dir)
+ return dir->items[entry->curline];
continue;
case _key_lndown:
lndown:
diff --git a/ui_txt.c b/ui_txt.c
@@ -54,7 +54,7 @@ ndigits(size_t n)
static void
printstatus(Item *item)
{
- size_t nitems = item->dir->nitems;
+ size_t nitems = item->dir ? item->dir->nitems : 0;
printf("%3lld%%%*c %s:%s%s (h for help): ",
(item->printoff + lines >= nitems) ? 100 :
@@ -65,11 +65,11 @@ printstatus(Item *item)
void
display(Item *entry)
{
- Item *item, **items;
+ Item **items;
size_t i, lines, nitems;
int nd;
- if (entry->type != '1')
+ if (entry->type != '1' || !entry->dir)
return;
items = entry->dir->items;
@@ -78,15 +78,12 @@ display(Item *entry)
nd = ndigits(nitems);
for (i = entry->printoff; i < nitems && i < lines; ++i) {
- if (item = items[i]) {
- printf("%*zu %-4s%c %s\n", nd, i+1,
- item->type != 'i' ?
- typedisplay(item->type) : "",
- item->type > '1' ? '|' : '+',
- items[i]->username);
- } else {
- printf("%*zu !! |\n", nd, i+1);
- }
+ item = items[i];
+ printf("%*zu %-4s%c %s\n", nd, i+1,
+ item->type != 'i' ?
+ typedisplay(item->type) : "",
+ item->type > '1' ? '|' : '+',
+ item->username);
}
fflush(stdout);
@@ -113,7 +110,7 @@ selectitem(Item *entry)
if (!strcmp(buf, "n\n")) {
lines = termlines();
- if (lines < entry->dir->nitems - entry->printoff &&
+ if (lines < nitems - entry->printoff &&
lines < (size_t)-1 - entry->printoff)
entry->printoff += lines;
return entry;