summary refs log tree commit diff
path: root/main.c
blob: adc488a67aa32283abf31943981f48eb149e5646 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "doc.h"
#include "net.h"
#include "err.h"

/* pagination */

size_t pg_lines() {
	return 24;
}

void pg_down(void) {
	size_t lines = pg_lines();
	while (lines--) doc_print_line();
}

void pg_up(void) {
	size_t lines = pg_lines() << 1;
	while (lines--) doc_back_line();
	pg_down();
}

void pg_redraw(void) {
	size_t lines = pg_lines();
	while (lines--) doc_back_line();
	pg_down();
}

/* 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) {
	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':
		pg_up();
		break;
	case '\0':
		pg_down();
		break;
	case 'r':
		pg_redraw();
		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);
}

void init(void) {
	doc_init();
}

void fini(void) {
	doc_fini();
}

int main(void) {
	char cmd_buf[1024];
	init();
	atexit(fini);
	while (cmd_get(cmd_buf, sizeof cmd_buf)) {
		cmd_trim(cmd_buf, sizeof cmd_buf);
		if (cmd_do(cmd_buf)) {
			break;
		}
	}
	return 0;
}