1 #include "common.h"
2 #include <ctype.h>
3
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7
8 #include "mba/suba.h"
9 #include "mba/hashmap.h"
10
11 struct test {
12 char *src;
13 char *slim;
14 struct hashmap *words;
15 struct allocator *al;
16 };
17
18 int
get_word(struct test * t,char ** w)19 get_word(struct test *t, char **w)
20 {
21 int count = 0;
22
23 for ( ; t->src < t->slim; t->src++) {
24 if (isspace(*t->src)) {
25 if (count) {
26 *t->src++ = '\0';
27 return count;
28 }
29 } else {
30 if (!count) {
31 *w = t->src;
32 }
33 count++;
34 }
35 }
36
37 return 0; /* EOF */
38 }
39 int
load_words(struct test * t)40 load_words(struct test *t)
41 {
42 int n;
43 char *word;
44 int count = 1;
45
46 while ((n = get_word(t, &word)) > 0) {
47 errno = 0;
48 if (hashmap_put(t->words, word, (void *)count) == -1) {
49 char *key = word;
50 int data;
51
52 if (errno != EEXIST) {
53 AMSG("");
54 return -1;
55 }
56 if (hashmap_remove(t->words, (void **)&key, (void **)&data) == -1) {
57 AMSG("");
58 return -1;
59 }
60 data++;
61 if (hashmap_put(t->words, word, (void *)data) == -1) {
62 AMSG("");
63 return -1;
64 }
65 }
66 }
67 if (n == -1) {
68 MMSG("");
69 return -1;
70 }
71
72 return 0;
73 }
74
75 int
print_key(void * context,void * object)76 print_key(void *context, void *object)
77 {
78 fprintf(stderr, "%s\n", (char *)object);
79 context = NULL;
80 return 0;
81 }
82 int
print_values(struct hashmap * words)83 print_values(struct hashmap *words)
84 {
85 iter_t iter;
86 char *word;
87 int val;
88
89 hashmap_iterate(words, &iter);
90 while ((word = hashmap_next(words, &iter))) {
91 val = (int)hashmap_get(words, word);
92 fprintf(stderr, "%d %s\n", val, word);
93 }
94
95 return 0;
96 }
97
98 int
HashmapCount(int verbose,struct cfg * cfg,char * args[])99 HashmapCount(int verbose, struct cfg *cfg, char *args[])
100 {
101 struct test t;
102 char *mem = NULL;
103 int ret = 0, fd = 0, data;
104 int useal = atoi(args[0]);
105 struct stat st;
106 void *mm;
107
108 if (useal) {
109 if ((mem = malloc(0xFFFFFF)) == NULL ||
110 (t.al = suba_init(mem, 0xFFFFFF, 1, 0)) == NULL) {
111 AMSG("");
112 ret = -1;
113 goto err;
114 }
115 } else {
116 t.al = NULL;
117 }
118 if ((t.words = hashmap_new(hash_str, (cmp_fn)strcmp, NULL, t.al)) == NULL ||
119 (fd = open(args[1], 0)) == -1 ||
120 fstat(fd, &st) == -1) {
121 AMSG("");
122 ret = -1;
123 goto err;
124 }
125 if ((t.src = mm = mmap(NULL, (int)st.st_size,
126 PROT_READ | PROT_WRITE,
127 MAP_PRIVATE,
128 fd, 0)) == NULL) {
129 AMSG("");
130 ret = -1;
131 goto err;
132 }
133
134 t.slim = t.src + st.st_size;
135 if (load_words(&t) == -1) {
136 AMSG("");
137 ret = -1;
138 goto err;
139 }
140
141 if ((data = (int)hashmap_get(t.words, args[2])) == 0 ||
142 atoi(args[3]) != data ||
143 (data = (int)hashmap_get(t.words, args[4])) == 0 ||
144 atoi(args[5]) != data) {
145 errno = ERANGE;
146 PMNF(errno, ": %d != %d", atoi(args[3]), data);
147 ret = -1;
148 goto err;
149 }
150
151 if (verbose)
152 print_values(t.words);
153 err:
154 munmap(mm, st.st_size);
155 if (fd)
156 close(fd);
157 hashmap_del(t.words, NULL, NULL, NULL);
158 free(mem);
159
160 cfg = NULL;
161 return ret;
162 }
163
164