From 163235bf0cc3872fac69a495af0d2b5e9c96ada2 Mon Sep 17 00:00:00 2001 From: Tibor Bizjak Date: Sun, 25 Jun 2023 15:39:03 +0200 Subject: [PATCH] further optimizations --- k&r/04-funcs-and-prog-struct/04-grep-grace.c | 54 ++++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/k&r/04-funcs-and-prog-struct/04-grep-grace.c b/k&r/04-funcs-and-prog-struct/04-grep-grace.c index 4085ace..604561c 100644 --- a/k&r/04-funcs-and-prog-struct/04-grep-grace.c +++ b/k&r/04-funcs-and-prog-struct/04-grep-grace.c @@ -1,7 +1,7 @@ #include #include - -#define LNBUFF_LEN 10 +#include +#include int grep(char pattern[]); @@ -67,54 +67,52 @@ void println() /* ------------------------ line buffer ---------------------- */ +#define LNBUFF_LEN 8 + +/* the line buffer lenght must be a power of two */ +static_assert(!(LNBUFF_LEN % 2), "Line buffer length is not a power of two!"); /* line_buffer: global overflowing line buffer */ struct { char self[LNBUFF_LEN]; - unsigned i; - unsigned trunc; -} lnbuff = {.i = 0, .trunc = 0}; + unsigned len; +} lnbuff = {.len= 0}; -/* reset_lnbuff: reset buffer */ -#define reset_lnbuff() lnbuff.i = lnbuff.trunc = 0 +/* LNBUFF_I: current index in line buffer */ +#define LNBUFF_I (lnbuff.len & (LNBUFF_LEN - 1)) /* getch_lnbuff: getchar and add it to buffer */ int getch_lnbuff() { int c = getchar(); - if (c == EOF || c == '\n') { // new line - reset_lnbuff(); - return c; + if (c == EOF || c == '\n') // new line + lnbuff.len = 0; + else { + lnbuff.self[LNBUFF_I] = c; + lnbuff.len++; } - if (lnbuff.trunc) - lnbuff.trunc++; - - if (lnbuff.i == LNBUFF_LEN) { - lnbuff.i = 0; - if (!lnbuff.trunc) - lnbuff.trunc = 1; - } - - lnbuff.self[lnbuff.i++] = c; return c; } /* flush_lnbuff: print contents of line buffer, return length */ int flush_lnbuff() { - int i, len = lnbuff.i; + int i; - if (lnbuff.trunc) { - len = LNBUFF_LEN + lnbuff.trunc; - for (i = 0; i < lnbuff.trunc; i++) + /* handle overflowing chars */ + if (lnbuff.len > LNBUFF_LEN) { + for (i = LNBUFF_LEN; i < lnbuff.len; i++) putchar('.'); - for (i = lnbuff.i; i < LNBUFF_LEN; i++) + for (i = LNBUFF_I; i < LNBUFF_LEN; i++) putchar(lnbuff.self[i]); } - for (i = 0; i < lnbuff.i; i++) + /* handle rest of chars */ + for (i = 0; i < LNBUFF_I; i++) putchar(lnbuff.self[i]); - reset_lnbuff(); - return len; + + i = lnbuff.len; + lnbuff.len = 0; + return i; }