#include #include #include #include #include #include "doc.h" #include "net.h" #include "err.h" #include "nav.h" /* pagination */ /* navigation */ int nav_to(const char *url) { struct addr a; static enum protocol prot_default = PROT_FILE; /* change to gopher later */ if (net_addr(url, &a, prot_default)) { return -1; } prot_default = a.prot; return 0; } int nav_link_nr(unsigned long link_nr) { return 0; } /* commands */ struct cmd { char ch; int (*fn)(const char *); }; /* cmd is mutated when trimming strings * returns whether to quit */ int cmd_do(char *cmd, struct nav_state *ns) { switch (*cmd) { case 'q': puts("goodbye!"); return 1; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { errno = 0; unsigned long n = strtoul(cmd, NULL, 10); if (errno) { perr("invalid link number"); } else if (nav_link_nr(n)) { perr("navigation failure"); } } break; case 'b': nav_pg_up(ns); break; case '\0': nav_pg_down(ns); break; case 'r': nav_redraw(ns); break; case 'g': if (nav_to(cmd + 1)) perr("navigation failure"); break; default: perr("?"); break; } return 0; } void cmd_trim(char *buf, size_t max) { size_t n = strlen(buf); while (n > 0 && isspace(buf[n - 1])) { buf[--n] = 0; } while (n > 1 && isspace(buf[1])) { memmove(&buf[0], &buf[1], n--); } } int cmd_get(char *buf, size_t n) { fputs("* ", stdout); return !!fgets(buf, n, stdin); } int main(void) { struct nav_state ns; char cmd_buf[1024]; nav_init(&ns); while (cmd_get(cmd_buf, sizeof cmd_buf)) { cmd_trim(cmd_buf, sizeof cmd_buf); if (cmd_do(cmd_buf, &ns)) { break; } } nav_fini(&ns); return 0; }