Handle (hopefuly) all invalid format streams - sacc - sacc(omys), simple consol… | |
git clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65… | |
Log | |
Files | |
Refs | |
Tags | |
LICENSE | |
--- | |
commit fdae99f75651ec33854a55654887608fb4f2947c | |
parent 4dff6dde00bd2e8062f678d6ca2207d00119474f | |
Author: Quentin Rameau <[email protected]> | |
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; |