Advertisement
avp210159

filefind.c search one file into other (use mmap)

Sep 6th, 2016
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.78 KB | None | 0 0
  1. // avp 2016 find one file (av[2]) into other file (av[1])
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/mman.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <err.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <sysexits.h>
  12.  
  13. struct fmap {
  14.   char *data;
  15.   size_t len;
  16. };
  17.  
  18. struct fmap
  19. mapfile (const char *fn)
  20. {
  21.   struct fmap fm = {0};
  22.  
  23.   if (fn) {
  24.     int fd = open(fn, O_RDONLY);
  25.     struct stat st;
  26.  
  27.     if (fd > -1)
  28.       if ((fstat(fd, &st), fm.len = st.st_size) &&
  29.           (fm.data = (char *)mmap(NULL, st.st_size,
  30.                                   PROT_READ, MAP_PRIVATE, fd, 0))) {
  31.         madvise(fm.data, fm.len, MADV_SEQUENTIAL);
  32.         close(fd);
  33.       }
  34.   }
  35.  
  36.   return fm;
  37. }
  38.  
  39. static inline size_t
  40. skipnl (struct fmap *p, size_t from)
  41. {
  42.   while (from < p->len && p->data[from++] != '\n');
  43.  
  44.   return from;
  45. }
  46.  
  47. int
  48. main (int ac, char *av[])
  49. {
  50.   if (ac != 3)
  51.     err(EX_USAGE,
  52.     "search file2 in file1 (by lines) Usage: %s file1 file2", av[0]);
  53.   struct fmap f1 = mapfile(av[1]),
  54.     f2 = mapfile(av[2]);
  55.  
  56.   if (!f1.data)
  57.     err(EX_DATAERR, "file %s", av[1]);
  58.   if (!f2.data)
  59.     err(EX_DATAERR, "file %s", av[2]);
  60.  
  61.   size_t i = 0,
  62.     lineno = 0, // current line number in f1
  63.     n2l = 0;    // number of '\n' in f2 (for adjust lineno when found f2 in f1
  64.   for (i = 0; i < f2.len; i++)
  65.     if (f2.data[i] == '\n')
  66.       n2l++;
  67.   int need_skipnl = f2.data[f2.len - 1] != '\n';
  68.  
  69.   i = 0;
  70.   while (i < f1.len) {
  71.     if (memcmp(f1.data + i, f2.data, f2.len) == 0) {
  72.       printf("%ld\n", (long)lineno + 1);
  73.       lineno += n2l;
  74.       i += f2.len;
  75.       if (need_skipnl)
  76.         i = skipnl(&f1, i), lineno++;
  77.     } else
  78.       i = skipnl(&f1, i), lineno++;
  79.   }
  80.  
  81.   return munmap(f1.data, f1.len) + munmap(f2.data, f2.len);
  82. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement