ttypr.c - typr - Typing practice program
 (HTM) git clone git://git.z3bra.org/typr.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       ttypr.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 }