typr

Typing practice program
git clone git://git.z3bra.org/typr.git
Log | Files | Refs

typr.c (1761B)


      1 /*
      2  * cc typr.c -o typr
      3  * ./typr [filename]
      4  *
      5  * Type the text that is under the cursor.
      6  * The cursor will stop on errors, no need to backspace
      7  *
      8  *
      9  * Typing speed can be calculated using the time(1) and wc(1) commands:
     10  *
     11  * $ time ./typr file.txt
     12  * […]
     13  * >> errors: 0
     14  *  0m28.64s real     0m00.00s user     0m00.00s system
     15  *    ^^^^^ TIMESPENT
     16  *
     17  * $ wc -w file.txt
     18  * 28 file.txt
     19  * ^^ WORDCOUNT
     20  *
     21  * WPM = (WORDCOUNT * 60) / TIMESPENT
     22  *       (    28    * 60) / 28.64     = 58 WPM
     23  */
     24 
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <unistd.h>
     28 #include <stdlib.h>
     29 #include <fcntl.h>
     30 #include <paths.h>
     31 #include <termios.h>
     32 
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 
     36 int
     37 wpm(int fd, char *line, int len)
     38 {
     39 	char c;
     40 	int i, rst, errors;
     41 
     42 	i = rst = errors = 0;
     43 	while (i < len) {
     44 		read(fd, &c, 1);
     45 		if (c == line[i]) {
     46 			i++;
     47 			dprintf(fd, "%c", c);
     48 			if (rst) {
     49 				rst = 0;
     50 				dprintf(fd, "");
     51 			}
     52 		} else {
     53 			rst = 1;
     54 			errors++;
     55 			dprintf(fd, "%c\b", line[i]);
     56 		}
     57 	}
     58 
     59 	/* wait for a newline */
     60 	while (read(fd, &c, 1) > 0 && c != '\n');
     61 	dprintf(fd, "\n");
     62 
     63 	return errors;
     64 }
     65 
     66 int
     67 main(int argc, char *argv[])
     68 {
     69 	int tty, tot;
     70 	char line[BUFSIZ], *p;
     71 	FILE *f;
     72 	struct termios term, save;
     73 
     74 	f = argc > 1 ? fopen(argv[1], "r") : stdin;
     75 
     76 	if (!f)
     77 		return -1;
     78 
     79 	tty = open(_PATH_TTY, O_RDWR);
     80 
     81 	tcgetattr(tty, &term);
     82 	tcgetattr(tty, &save);
     83 	term.c_lflag &= ~(ECHO|ICANON);
     84 	tcsetattr(tty, TCSANOW, &term);
     85 
     86 	tot = 0;
     87 	while (fgets(line, BUFSIZ, f)) {
     88 		line[strlen(line)-1] = 0;
     89 		if (strlen(line) > 0) {
     90 			dprintf(tty, "%s\r", line);
     91 			tot += wpm(tty, line, strlen(line));
     92 		}
     93 	}
     94 
     95 	tcsetattr(tty, TCSANOW, &save);
     96 	fclose(f);
     97 	close(tty);
     98 
     99 	fprintf(stderr, ">> errors: %d\n", tot);
    100 	
    101 	return 0;
    102 }