sacc

sacc (saccomys): simple gopher client.
Log | Files | Refs | LICENSE

commit 5f2e561edb8bf36c8a19ec32e0a83abde936be34
parent b1d593674e9619d39191b87c769d8caf9723bc0e
Author: Quentin Rameau <quinq@fifth.space>
Date:   Fri, 30 Jun 2017 16:59:37 +0200

Move UI specific code to it's own file

Diffstat:
Makefile | 6+++++-
common.h | 24++++++++++++++++++++++++
config.mk | 7+++++--
sacc.c | 147++-----------------------------------------------------------------------------
ui_txt.c | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 165 insertions(+), 147 deletions(-)

diff --git a/Makefile b/Makefile @@ -5,11 +5,15 @@ include config.mk BIN = sacc +OBJ = $(BIN:=.o) ui_$(UI).o all: $(BIN) +$(BIN): config.mk $(OBJ) + $(CC) $(OBJ) $(SACCLDFLAGS) -o $@ + clean: - rm -f $(BIN) + rm -f $(BIN) $(OBJ) install: mkdir -p $(PREFIX)/bin/ diff --git a/common.h b/common.h @@ -0,0 +1,24 @@ +typedef struct item Item; +typedef struct dir Dir; + +struct item { + char type; + char *username; + char *selector; + char *host; + char *port; + char *raw; + size_t printoff; + Item *entry; + Dir *dir; +}; + +struct dir { + Item **items; + size_t nitems; +}; + +void die(const char *fmt, ...); +void display(Item *item); +Item *selectitem(Item *entry); +const char *typedisplay(char t); diff --git a/config.mk b/config.mk @@ -1,9 +1,12 @@ # Install paths PREFIX = /usr/local +# UI type, txt +UI=txt + # Stock FLAGS SACCCFLAGS = -D_POSIX_C_SOURCE=200809L $(CFLAGS) SACCLDFLAGS = $(LDFLAGS) -.c: - $(CC) -o $@ $(SACCCFLAGS) $(SACCLDFLAGS) $< +.c.o: + $(CC) $(SACCCFLAGS) -c $< diff --git a/sacc.c b/sacc.c @@ -6,33 +6,13 @@ #include <stdlib.h> #include <string.h> #include <stropts.h> -#include <termios.h> /* ifdef BSD */ #include <unistd.h> -#include <sys/ioctl.h> #include <sys/socket.h> #include <sys/types.h> -typedef struct item Item; -typedef struct dir Dir; - -struct item { - char type; - char *username; - char *selector; - char *host; - char *port; - char *raw; - size_t printoff; - Item *entry; - Dir *dir; -}; - -struct dir { - Item **items; - size_t nitems; -}; +#include "common.h" -static void +void die(const char *fmt, ...) { va_list arg; @@ -90,33 +70,7 @@ usage(void) die("usage: sacc URL"); } -static void -help(void) -{ - puts("Commands:\n" - "N = [1-9]...: browse item N.\n" - "0: browse previous item.\n" - "n: show next page.\n" - "p: show previous page.\n" - "!: refetch failed item.\n" - "^D, q: quit.\n" - "h: this help."); -} - -static int -termlines(void) -{ - struct winsize ws; - - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) { - die("Could not get terminal resolution: %s", - strerror(errno)); - } - - return ws.ws_row-1; -} - -static const char * +const char * typedisplay(char t) { switch (t) { @@ -159,41 +113,6 @@ typedisplay(char t) } } -static void -display(Item *item) -{ - Item **items; - size_t i, lines, nitems; - int ndigits; - - if (item->type > '1') - return; - - switch (item->type) { - case '0': - puts(item->raw); - break; - case '1': - items = item->dir->items; - nitems = item->dir->nitems; - lines = item->printoff + termlines(); - ndigits = (nitems < 10) ? 1 : (nitems < 100) ? 2 : 3; - - for (i = item->printoff; i < nitems && i < lines; ++i) { - if (item = items[i]) { - printf("%*d %-4s%c %s\n", ndigits, i+1, - item->type != 'i' ? - typedisplay(item->type) : "", - item->type > '1' ? '|' : '+', - items[i]->username); - } else { - printf("%*d !! |\n", ndigits, i+1); - } - } - break; - } -} - static char * pickfield(char **raw, char sep) { @@ -411,66 +330,6 @@ dig(Item *entry, Item *item) return 1; } -static Item * -selectitem(Item *entry) -{ - char buf[BUFSIZ], nl; - Item *hole; - int item, nitems, lines; - - nitems = entry->dir ? entry->dir->nitems : 0; - - do { - printf("%d items (h for help): ", nitems); - - if (!fgets(buf, sizeof(buf), stdin)) { - putchar('\n'); - return NULL; - } - if (!strcmp(buf, "q\n")) - return NULL; - - if (!strcmp(buf, "n\n")) { - lines = termlines(); - if (lines < entry->dir->nitems - entry->printoff && - lines < (size_t)-1 - entry->printoff) - entry->printoff += lines; - return entry; - } - if (!strcmp(buf, "p\n")) { - lines = termlines(); - if (lines <= entry->printoff) - entry->printoff -= lines; - else - entry->printoff = 0; - return entry; - } - - if (!strcmp(buf, "!\n")) { - if (entry->raw) - continue; - return entry; - } - - item = -1; - if (!strcmp(buf, "h\n")) { - help(); - continue; - } - if (*buf < '0' || *buf > '9') - continue; - - nl = '\0'; - if (sscanf(buf, "%d%c", &item, &nl) != 2 || nl != '\n') - item = -1; - } while (item < 0 || item > nitems); - - if (item > 0) - return entry->dir->items[item-1]; - - return entry->entry; -} - static void delve(Item *hole) { diff --git a/ui_txt.c b/ui_txt.c @@ -0,0 +1,128 @@ +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/types.h> + +#include "common.h" + +void +help(void) +{ + puts("Commands:\n" + "N = [1-9]...: browse item N.\n" + "0: browse previous item.\n" + "n: show next page.\n" + "p: show previous page.\n" + "!: refetch failed item.\n" + "^D, q: quit.\n" + "h: this help."); +} + +static int +termlines(void) +{ + struct winsize ws; + + if (ioctl(1, TIOCGWINSZ, &ws) < 0) { + die("Could not get terminal resolution: %s", + strerror(errno)); + } + + return ws.ws_row-1; +} + +void +display(Item *item) +{ + Item **items; + size_t i, lines, nitems; + int ndigits; + + if (item->type > '1') + return; + + switch (item->type) { + case '0': + puts(item->raw); + break; + case '1': + items = item->dir->items; + nitems = item->dir->nitems; + lines = item->printoff + termlines(); + ndigits = (nitems < 10) ? 1 : (nitems < 100) ? 2 : 3; + + for (i = item->printoff; i < nitems && i < lines; ++i) { + if (item = items[i]) { + printf("%*d %-4s%c %s\n", ndigits, i+1, + item->type != 'i' ? + typedisplay(item->type) : "", + item->type > '1' ? '|' : '+', + items[i]->username); + } else { + printf("%*d !! |\n", ndigits, i+1); + } + } + break; + } +} + +Item * +selectitem(Item *entry) +{ + char buf[BUFSIZ], nl; + int item, nitems, lines; + + nitems = entry->dir ? entry->dir->nitems : 0; + + do { + printf("%d items (h for help): ", nitems); + + if (!fgets(buf, sizeof(buf), stdin)) { + putchar('\n'); + return NULL; + } + if (!strcmp(buf, "q\n")) + return NULL; + + if (!strcmp(buf, "n\n")) { + lines = termlines(); + if (lines < entry->dir->nitems - entry->printoff && + lines < (size_t)-1 - entry->printoff) + entry->printoff += lines; + return entry; + } + if (!strcmp(buf, "p\n")) { + lines = termlines(); + if (lines <= entry->printoff) + entry->printoff -= lines; + else + entry->printoff = 0; + return entry; + } + + if (!strcmp(buf, "!\n")) { + if (entry->raw) + continue; + return entry; + } + + item = -1; + if (!strcmp(buf, "h\n")) { + help(); + continue; + } + if (*buf < '0' || *buf > '9') + continue; + + nl = '\0'; + if (sscanf(buf, "%d%c", &item, &nl) != 2 || nl != '\n') + item = -1; + } while (item < 0 || item > nitems); + + if (item > 0) + return entry->dir->items[item-1]; + + return entry->entry; +}