aboutsummaryrefslogtreecommitdiff
path: root/typ.c
blob: 875f7593b22de9f62da114b6917fb76553989bc4 (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
#include <ctype.h>
#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() {
	int cs = 500; /* allocated number of characters */
	char *cb = malloc(cs * sizeof(char)); /* character buffer */
	if (cb == NULL) err(1, "malloc");
	double *ct = malloc(cs * sizeof(double)); /* character times */
	if (ct == NULL) err(1, "malloc");

	/* enter "raw" mode */
	struct termios orig, raw;
	int 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);

	int c;
	int ci = 0; /* character index */
	while (read(ttyfd, &c, 1)) {
		if (c == 127 && ci > 0) { /* backspace */
			ci--;
			write(ttyfd, &c, 1);
			continue;
		} else if (iscntrl(c) && c != '\n')
			continue;
		write(ttyfd, &c, 1);
		cb[ci] = c;
		ct[ci] = atime();
		ci++;
		if (c == '\n')
			break;
	}

	double finish = atime(); /* finish time */

	double tt = 0; /* total time */
	double t1 = -1; /* start time of current word */
	int words = 0; /* number of words */
	int nonspace = 0; /* number of non-space characters */
	int i;
	for (i = 0; i <= ci; i++) {
		if (cb[i] == ' ' || cb[i] == '\n') {
			if (t1 == -1) continue;	
			tt += ct[i - 1] - t1;
			t1 = -1;
			if (cb[i] == '\n') break;
			else continue;
		}
		if (t1 == -1) {
			t1 = ct[i];
			words++;
		}
		nonspace++;
	}

	/* print statistics */
	printf("%d\twords\n", words);
	printf("%d\tcharacters\n", ci - 1);
	printf("%d\tcharacters inside words\n", nonspace);
	printf("%.4f\tseconds\n", finish - ct[0]);
	printf("%.4f\tseconds inside words\n", tt);
	printf("%.4f\tseconds per character\n", tt / (ci - 1));
	printf("%.4f\tseconds per character inside word\n", tt / nonspace);
	printf("%.4f\tseconds per word\n", tt / words);

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