typetest

Typing speed benchmarker
git clone git@sinitax.com:sinitax/typetest
Log | Files | Refs | LICENSE | sfeed.txt

commit 5a92fc280937a2d6f19a821124736e98f15016af
parent cd78494b61532c846e7ae2f4d9142330160a6560
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed, 18 May 2022 19:32:33 +0200

Minor fixes

Diffstat:
M.gitignore | 1+
Mmain.c | 57++++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1 +1,2 @@ typetest +input diff --git a/main.c b/main.c @@ -10,9 +10,10 @@ #define LINTERP(a,b,v) ((a) * (v) + (b) * (1 - (v))) enum { - C_EOF = 0x03, - C_EOT = 0x04, - C_DEL = 0x7f + C_EOF = 0x03, /* CTRL+C */ + C_EOT = 0x04, /* CTRL+D */ + C_DEL = 0x7f, + C_SKIP = 0x17, /* CTRL+W */ }; enum { @@ -88,33 +89,44 @@ time_sub(struct timespec *new, struct timespec *old) int type(const char *text, const char *preview) { - char input[1024]; int i, c, right, wrong, tlen; struct timespec start = { 0 }, end; float cps; + if (typed > 0) clock_gettime(CLOCK_REALTIME, &start); + tlen = strlen(text); c = right = wrong = 0; - do { + while (1) { printf("\r\x1b[2K"); /* goto beginning of row and clear */ printf("\n\x1b[2K\x1b[1A"); /* down a row and clear */ switch (c) { case C_EOF: - case C_EOT: goto quit; + case C_EOT: + goto exit; case C_DEL: if (wrong) wrong--; else if (right) right--; break; + case C_SKIP: + right += wrong + 1; + if (right >= tlen) + goto exit; + wrong = 0; + break; + case u'\r': case u'\n': case u'\0': break; + case ' ': + if (!wrong && right == tlen) + goto exit; default: if (!start.tv_sec) clock_gettime(CLOCK_REALTIME, &start); if (right + wrong == tlen) break; - if (right + wrong == sizeof(input)) break; if (c == text[right + wrong] && !wrong) right++; else wrong++; break; @@ -136,20 +148,33 @@ type(const char *text, const char *preview) if (right + wrong) printf("\x1b[%iC", right + wrong); - if (!wrong && right + wrong == tlen) break; - } while ((c = getchar()) > 0); + if (!*preview && !wrong && right == tlen) + goto exit; -quit: - if (!start.tv_sec || typed + right + wrong < 20) return 1; + c = getchar(); + if (c < 0) goto quit; + }; + +exit: + printf("\r\x1b[2K"); /* goto beginning of line and clear */ + printf("\n\x1b[2K\x1b[1A"); /* down a row and clear */ + + if (!start.tv_sec) return 1; clock_gettime(CLOCK_REALTIME, &end); time_sub(&end, &start); - cps = (right + wrong) / (end.tv_sec + end.tv_nsec / 1e9f); + typed += right; + + end.tv_nsec /= 1000000; /* reduce precision to millis */ + cps = right / (end.tv_sec + end.tv_nsec / 1e3f); if (!typed) gcps = cps; - else gcps = LINTERP(gcps, cps, typed * 1.f / (typed + right + wrong)); + else gcps = LINTERP(cps, gcps, right * 1.f / typed); return 0; + +quit: + return 1; } int @@ -158,8 +183,7 @@ getl(FILE *f, char *buf, size_t size) int i; do { - if (!fgets(buf, size, f)) - return 1; + if (!fgets(buf, size, f)) return 1; for (i = strlen(buf) - 1; *buf; buf[i--] = '\0') if (!strchr("\n\r", buf[i])) break; @@ -177,8 +201,8 @@ reset() int main(int argc, const char **argv) { - struct termios t; char cur[256], next[256]; + struct termios t; int eof; FILE *f; @@ -207,7 +231,6 @@ main(int argc, const char **argv) if (type(cur, eof ? "" : next)) break; } - printf("\r\x1b[2K"); if (gcps) { printf("CPM: %0.2f\n\r", gcps * 60); printf("WPM: %0.2f\n\r", gcps * 12);