rewrote part of program for lower complexity
parent
11e44def75
commit
3fd2a66b17
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue