Compare commits
3 Commits
2d2e6880a2
...
163235bf0c
Author | SHA1 | Date |
---|---|---|
Tibor Bizjak | 163235bf0c | |
Tibor Bizjak | e7eacc893f | |
Tibor Bizjak | b81504f2ee |
|
@ -53,8 +53,8 @@ void expand(char *s, char *t, int n)
|
|||
CHECK_OVERFLOW(i, n);
|
||||
t[i] = *s;
|
||||
}
|
||||
terminate:
|
||||
t[i] = '\0';
|
||||
terminate:
|
||||
t[i] = '\0';
|
||||
}
|
||||
|
||||
/* getstr: copies stdin to array s of length n, returns size of string or
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
int grep(char pattern[]);
|
||||
|
||||
/* grep with graceful buffer overflow */
|
||||
/* parse and verify arg pattern, pass it to grep */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* verify arg is given */
|
||||
if (argc < 2) {
|
||||
printf("error: excpected pattern\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *pattern = argv[1];
|
||||
|
||||
/* verify pattern */
|
||||
char c;
|
||||
int i;
|
||||
for (i = 0; (c = pattern[i]) != '\0'; i++)
|
||||
if (c == '\n') {
|
||||
printf("error: newline in pattern\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
int found = grep(pattern);
|
||||
printf("found = %d\n", found);
|
||||
return found;
|
||||
}
|
||||
|
||||
void println(void);
|
||||
int flush_lnbuff(void);
|
||||
int getch_lnbuff(void);
|
||||
|
||||
/* grep: prints lines containing pattern, returns number of matching lines */
|
||||
int grep(char *pattern)
|
||||
{
|
||||
int found, i, c;
|
||||
const int plen = strlen(pattern);
|
||||
|
||||
i = found = 0;
|
||||
|
||||
while ((c = getch_lnbuff()) != EOF)
|
||||
if (c != pattern[i])
|
||||
i = 0;
|
||||
else if (++i == plen) { // found match
|
||||
i = 0;
|
||||
found++;
|
||||
flush_lnbuff();
|
||||
println();
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/* 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 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 len;
|
||||
} lnbuff = {.len= 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
|
||||
lnbuff.len = 0;
|
||||
else {
|
||||
lnbuff.self[LNBUFF_I] = c;
|
||||
lnbuff.len++;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* flush_lnbuff: print contents of line buffer, return length */
|
||||
int flush_lnbuff()
|
||||
{
|
||||
int 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++)
|
||||
putchar(lnbuff.self[i]);
|
||||
}
|
||||
/* handle rest of chars */
|
||||
for (i = 0; i < LNBUFF_I; i++)
|
||||
putchar(lnbuff.self[i]);
|
||||
|
||||
i = lnbuff.len;
|
||||
lnbuff.len = 0;
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#define W 80
|
||||
#define REPEAT 4000000
|
||||
|
||||
int main()
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < REPEAT; i++) {
|
||||
for (j = 0; j < W; j++)
|
||||
putchar('y');
|
||||
putchar('\n');
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAXLINE 1000 /* maximum input line length */
|
||||
|
||||
int grep(char *pattern);
|
||||
|
||||
/* somewhat optimized book version of grep */
|
||||
/* find all lines matching pattern */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* verify arg is given */
|
||||
if (argc < 2) {
|
||||
printf("error: excpected pattern\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *pattern = argv[1];
|
||||
|
||||
/* verify pattern */
|
||||
char c;
|
||||
int i;
|
||||
for (i = 0; (c = pattern[i]) != '\0'; i++)
|
||||
if (c == '\n') {
|
||||
printf("error: newline in pattern\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
int found = grep(pattern);
|
||||
printf("found = %d\n", found);
|
||||
return found;
|
||||
}
|
||||
|
||||
int getln(char line[], int lim);
|
||||
int strindex(char source[], char searchfor[], int slen);
|
||||
|
||||
/* grep: prints lines containing pattern, returns number of matching lines */
|
||||
int grep(char *pattern)
|
||||
{
|
||||
char line[MAXLINE];
|
||||
int found = 0;
|
||||
int slen = strlen(pattern);
|
||||
|
||||
while (getln(line, MAXLINE) > 0)
|
||||
if (strindex(line, pattern, slen) >= 0) {
|
||||
printf("%s", line);
|
||||
found++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/* getline: get line (including \n) into s, return length */
|
||||
int getln(char *s, int lim)
|
||||
{
|
||||
int c, i = 0;
|
||||
|
||||
while (--lim > 0 && (c = getchar()) != EOF && (s[i++] = c) != '\n')
|
||||
;
|
||||
s[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
/* strindex: return index of t in s, -1 if none */
|
||||
int strindex(char s[], char t[], int slen)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; s[i]; i++)
|
||||
if (s[i] != t[j])
|
||||
j = 0;
|
||||
else if (++j == slen) { // found match
|
||||
return i - slen + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
Loading…
Reference in New Issue