rewrote part of program for lower complexity

master
Tibor Bizjak 2023-07-23 12:13:43 +02:00
parent 11e44def75
commit 3fd2a66b17
1 changed files with 37 additions and 44 deletions

View File

@ -1,69 +1,48 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
void println(void);
int flush_lnbuff(void);
int getch_lnbuff(void);
void ignoreln_lnbuff(void);
/* find: prints lines containing pattern, returns number of matching lines
* gracefully handle line overflow */
* gracefully handle line overflow
* compile with -O3 */
int find(char *pattern, char lineno_flag, char except_flag)
{
int found, i, c;
const int plen = strlen(pattern);
long lineno = 1;
i = found = 0;
char match = 0;
#define print_lineno() if (lineno_flag) printf("%ld:", lineno)
extern long lineno;
int i, c, found;
const int plen = strlen(pattern);
i = found = 0;
while ((c = getch_lnbuff()) != EOF) {
if (c == '\n') { /* newline */
if (except_flag && !match) {
print_lineno();
flush_lnbuff();
putchar('\n');
}
match = 0;
lineno++;
}
if (c != pattern[i])
i = 0;
else if (++i == plen) { // found match
if (except_flag) {
match = 1;
continue;
}
i = 0;
i = (c == pattern[i]) ? i+1 : 0;
if (except_flag && i == plen)
ignoreln_lnbuff();
else if (except_flag ? c == '\n' : i == plen) { // match
found++;
print_lineno();
if (lineno_flag)
printf("%ld:", lineno);
flush_lnbuff();
println(), lineno++;
}
}
return found;
#undef print_lineno
}
/* println: prints next line from stdin
* prints newline on EOF */
void println()
{
int c;
while ((c = getchar()) != EOF && c != '\n')
putchar(c);
putchar(c);
}
/* ------------------------ line buffer ---------------------- */
#define LNBUFF_LEN 128
#define LNBUFF_LEN 1024
/* the line buffer lenght must be a power of two */
static_assert(!(LNBUFF_LEN % 2), "Line buffer length is not a power of two!");
long lineno;
/* line_buffer: global overflowing line buffer */
struct {
char self[LNBUFF_LEN];
@ -82,6 +61,7 @@ int getch_lnbuff()
if (lnbuff.newline) {
lnbuff.len = 0;
lnbuff.newline = 0;
lineno++;
}
if (c == EOF || c == '\n') // new line
lnbuff.newline = 1;
@ -108,9 +88,22 @@ int flush_lnbuff()
/* handle rest of chars */
for (i = 0; i < LNBUFF_I; i++)
putchar(lnbuff.self[i]);
i = lnbuff.len;
lnbuff.len = 0;
return i;
/* print unbuffered part of line */
if (!lnbuff.newline)
while ((i = getchar()) != EOF && i != '\n')
putchar(i);
putchar('\n');
lnbuff.newline = 1;
return lnbuff.len;
}
/* ignoreln_lnbuff: ignore line of input */
void ignoreln_lnbuff()
{
int c;
if (lnbuff.newline)
return;
while ((c = getchar()) != EOF && c != '\n')
;
lnbuff.newline = 1;
}