Blob


1 /*
2 * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include <sys/mman.h>
19 #include <err.h>
20 #include <fcntl.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
26 #include "db.h"
27 #include "dictionary.h"
28 #include "tokenize.h"
30 #include "mkftsidx.h"
32 static int
33 pfile(struct dictionary *dict, struct db_entry **entries, size_t *len,
34 size_t *cap, const char *path)
35 {
36 char **toks;
37 int fd;
38 off_t end;
39 void *m;
41 if (*len == *cap) {
42 size_t newcap;
43 void *t;
45 newcap = *cap * 1.5;
46 if (newcap == 0)
47 newcap = 8;
48 t = recallocarray(*entries, *cap, newcap, sizeof(**entries));
49 if (t == NULL)
50 err(1, "recallocarray");
51 *cap = newcap;
52 *entries = t;
53 }
55 if ((fd = open(path, O_RDONLY)) == -1) {
56 warnx("can't open %s", path);
57 return 0;
58 }
60 if ((end = lseek(fd, 0, SEEK_END)) == -1)
61 err(1, "lseek %s", path);
63 end++;
64 m = mmap(NULL, end, PROT_READ, MAP_PRIVATE, fd, 0);
65 if (m == MAP_FAILED)
66 err(1, "can't mmap %s", path);
68 (*entries)[(*len)++].name = xstrdup(path);
70 if ((toks = tokenize(m)) == NULL)
71 err(1, "tokenize");
72 if (!dictionary_add_words(dict, toks, *len - 1))
73 err(1, "dictionary_add_words");
74 freetoks(toks);
75 munmap(m, end);
76 close(fd);
77 return 1;
78 }
80 int
81 idx_files(struct dictionary *dict, struct db_entry **entries, size_t *len,
82 int argc, char **argv)
83 {
84 char *line = NULL;
85 size_t linesize = 0, cap = *len;
86 ssize_t linelen;
87 int r = 0;
89 if (argc > 0) {
90 while (*argv) {
91 if (!pfile(dict, entries, len, &cap, *argv))
92 r = 1;
93 argv++;
94 }
95 return r;
96 }
98 while ((linelen = getline(&line, &linesize, stdin)) != -1) {
99 if (linelen > 1 && line[linelen-1] == '\n')
100 line[linelen-1] = '\0';
102 if (!pfile(dict, entries, len, &cap, line))
103 r = 1;
106 free(line);
107 if (ferror(stdin))
108 err(1, "getline");
109 return r;