Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // avp 2016 find one file (av[2]) into other file (av[1])
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <err.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sysexits.h>
- struct fmap {
- char *data;
- size_t len;
- };
- struct fmap
- mapfile (const char *fn)
- {
- struct fmap fm = {0};
- if (fn) {
- int fd = open(fn, O_RDONLY);
- struct stat st;
- if (fd > -1)
- if ((fstat(fd, &st), fm.len = st.st_size) &&
- (fm.data = (char *)mmap(NULL, st.st_size,
- PROT_READ, MAP_PRIVATE, fd, 0))) {
- madvise(fm.data, fm.len, MADV_SEQUENTIAL);
- close(fd);
- }
- }
- return fm;
- }
- static inline size_t
- skipnl (struct fmap *p, size_t from)
- {
- while (from < p->len && p->data[from++] != '\n');
- return from;
- }
- int
- main (int ac, char *av[])
- {
- if (ac != 3)
- err(EX_USAGE,
- "search file2 in file1 (by lines) Usage: %s file1 file2", av[0]);
- struct fmap f1 = mapfile(av[1]),
- f2 = mapfile(av[2]);
- if (!f1.data)
- err(EX_DATAERR, "file %s", av[1]);
- if (!f2.data)
- err(EX_DATAERR, "file %s", av[2]);
- size_t i = 0,
- lineno = 0, // current line number in f1
- n2l = 0; // number of '\n' in f2 (for adjust lineno when found f2 in f1
- for (i = 0; i < f2.len; i++)
- if (f2.data[i] == '\n')
- n2l++;
- int need_skipnl = f2.data[f2.len - 1] != '\n';
- i = 0;
- while (i < f1.len) {
- if (memcmp(f1.data + i, f2.data, f2.len) == 0) {
- printf("%ld\n", (long)lineno + 1);
- lineno += n2l;
- i += f2.len;
- if (need_skipnl)
- i = skipnl(&f1, i), lineno++;
- } else
- i = skipnl(&f1, i), lineno++;
- }
- return munmap(f1.data, f1.len) + munmap(f2.data, f2.len);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement