aboutsummaryrefslogtreecommitdiff
path: root/browser-cli.c
blob: 4f2ff3ba1e52a52f6b64ca2fd864e5f131fcc297 (plain) (blame)
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
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <string.h>
#include <sds/sds.h>
#include <regex.h>
#include <util.h>

struct md_syntax {
	regex_t anchor;
};

struct md_syntax syntax = {
	.anchor = NULL,
};

int* anchorsIndecies;
int anchorsCount = 0;

void initRendering() {
	/*
	 * Compile regexes used in rendering
	 */

	 herr(regcomp(&syntax.anchor, "\\[\\([^]]*\\)\\](\\([^)]*\\))", 0), "regcomp");
}

void freeRendering() {
	regfree(&syntax.anchor);

	free(anchorsIndecies);
}

void renderPage(const sds page) {
	if (sdslen(page) == 0) {
		printf("Server didn't return page!\n");
		return;
	}

	sds toPrint = sdsdup(page);
	
	/*
	 * Parse Markdown constructs
	 */

	/* Substitute and store anchorsIndecies */
	if (anchorsIndecies != NULL) {
		free(anchorsIndecies);
		anchorsCount = 0;
		anchorsIndecies = NULL;
	}
	toPrint = gsub_getm(toPrint, &syntax.anchor, "\033[4m\1\033[0m\16", &anchorsIndecies, &anchorsCount);
	
	sds newPrint;
	for (int i = 0, anchorInd = 0; i < anchorsCount; i++) {
		anchorInd = strchr(toPrint, '\16') - toPrint;

		/* In toPrint, replace '\16' with "\033[30;46m%d\033[0m", where %d is the variable i */
		toPrint[anchorInd] = '\0';
		newPrint = sdsgrowzero(sdsempty(), sdslen(toPrint) + digits(i) + 8 + 4);
		sprintf(newPrint, "%s\033[30;46m%d\033[0m%s", toPrint, i, toPrint + anchorInd + 1);

		sdsfree(toPrint);
		toPrint = newPrint;
	}

	/*
	 * Print page on stdout
	 */
	write(1, toPrint, sdslen(toPrint));

	sdsfree(toPrint);
}

#define MAX_LEN_COMMAND 16
#define COMMAND_FORMAT ": %16s"

int handleCLI(sds authority, sds *address, const sds page) {
	// Get a line
	char line[1024];
	fgets(line, 1024, stdin);

	// Nothing
	if (line[0] == '\0') {
		printf("Please enter a valid command!\n");
		return 0;
	}

	// Number or URL
	if (line[0] != ':') {
		// Index of anchor
		if (strchr(line, '/') == NULL) {
			int gotoIndex = 0;
			sscanf(line, "%d", &gotoIndex);

			if (gotoIndex < 0 || gotoIndex >= anchorsCount) {
				printf("Invalid anchor index!\n");
				return 0;
			}

			char* newplace = strchr(page + anchorsIndecies[gotoIndex], '(') + 1;
			sdsfree(*address);
			*address = sdscatlen(sdsdup(authority), newplace, strchr(newplace, ')') - newplace);
		}
		// New address
		else {
			sdsfree(*address);
			*address = sdsnewlen(line, strlen(line)-1 /* skip newline */);
		}
		return 0;
	}

	// Special command
	
	// Get command name and it's arguments
	// Currently no command takes arguments
	char name[MAX_LEN_COMMAND+1] = { '\0' };
	int argsAssigned = sscanf(line, COMMAND_FORMAT, name);

	if (streq(name, "q") || streq(name, "e") || streq(name, "quit") || streq(name, "exit")) {
		return 1;
	}

	printf("Invalid command %s!\n", name);
	return 0;
}