aboutsummaryrefslogtreecommitdiff
path: root/typ.c
blob: 8c6d808979c0454ebe3d6a798ebc7269c2961724 (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
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>

double atime() {
	struct timespec now;
	clock_gettime(CLOCK_REALTIME, &now);
	return now.tv_sec + now.tv_nsec * 1e-9;
}

int main() {
	double *wt;
	int c, l, t, ttyfd, wi, *wl, ws;
	struct termios orig, raw;

	ws = 100; /* allocated number of words */
	wl = malloc(ws * sizeof(int)); /* word lengths */
	if (wl == NULL) err(1, "malloc");
	wt = malloc(ws * sizeof(double)); /* word times */
	if (wt == NULL) err(1, "malloc");

	for (int i = 0; i < ws; i++)
		wt[i] = 0;

	l = 0; /* current word length */
	wi = -1; /* index of current word in order */

	/* enter "raw" mode */
	ttyfd = open("/dev/tty", O_RDWR);
	if (ttyfd == -1) err(1, "open");
	tcgetattr(ttyfd, &orig);
	raw = orig;
	raw.c_lflag &= ~(ECHO | ICANON);
	tcsetattr(ttyfd, TCSANOW, &raw);

	/* read loop */
	while (read(ttyfd, &c, 1)) {
		/* backspace */
		if (c == 127) {
			l--;
			write(ttyfd, &c, 1);
			if (l == -1) {
				wi--;
				fprintf(stderr, "<\n");
			}
			continue;
		}

		/* back to previous word (after backspace) */
		if (l == -1) {
			l = wl[wi];
			fprintf(stderr, "%d\n", wl[wi-1]);
		}

		/* new word */
		if (c != ' ' && c != '\n' && (l == 0 || l == -1)) {
			wi++;
			t = atime(); /* current word start time */
			fprintf(stderr, "*\n");
		}

		/* end word */
		if (c == ' ' || c == '\n') {
			wl[wi] = l;
			if (t > -1) {
				wt[wi] += atime() - t;
				// fprintf(stderr, "[+%f]", atime() - t);
			}
			l = 0;
			t = -1;
		} else
			l++;
		if (c == '\n')
			break;
		write(ttyfd, &c, 1);
	}
	write(ttyfd, "\n", 1);

	/* print statistics */
	double tt = 0;
	int tl = 0;
	for (int i = 0; i <= wi; i++) {
		tt += wt[i];
		tl += wl[i];
	}
	printf("%f seconds per word (%d)\n", tt / (wi + 1), wi + 1);
	printf("%f seconds per word character (%d)\n", tt / tl, tl);

	/* restore original terminal settings */
	tcsetattr(ttyfd, TCSANOW, &orig);
}