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