docs: don't forget to pass -I m4 to aclocal
[mit.git] / modindex.c
blobaa56b6a0769126373276838e754c2fdf4a1b1b95
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <getopt.h>
4 #include <errno.h>
5 #include <string.h>
7 #include "logging.h"
8 #include "index.h"
10 static char *getline_wrapped(FILE *file, unsigned int *linenum)
12 int size = 256;
13 int i = 0;
14 char *buf = NOFAIL(malloc(size));
15 for(;;) {
16 int ch = getc_unlocked(file);
18 switch(ch) {
19 case EOF:
20 if (i == 0) {
21 free(buf);
22 return NULL;
24 /* else fall through */
26 case '\n':
27 if (linenum)
28 (*linenum)++;
29 if (i == size)
30 buf = NOFAIL(realloc(buf, size + 1));
31 buf[i] = '\0';
32 return buf;
34 case '\\':
35 ch = getc_unlocked(file);
37 if (ch == '\n') {
38 if (linenum)
39 (*linenum)++;
40 continue;
42 /* else fall through */
44 default:
45 buf[i++] = ch;
47 if (i == size) {
48 size *= 2;
49 buf = NOFAIL(realloc(buf, size));
55 static void write_index(const char *filename)
57 struct index_node *index;
58 char *line, *pos;
59 FILE *cfile;
60 unsigned int linenum = 0;
62 cfile = fopen(filename, "w");
63 if (!cfile)
64 fatal("Could not open %s for writing: %s\n",
65 filename, strerror(errno));
67 index = index_create();
69 while((line = getline_wrapped(stdin, &linenum))) {
70 pos = strchr(line, ' ');
71 *pos++ = '\0';
72 index_insert(index, line, pos, linenum);
73 free(line);
76 index_write(index, cfile);
77 index_destroy(index);
78 fclose(cfile);
81 static struct index_file *open_index(const char *filename)
83 struct index_file *index;
85 index = index_file_open(filename);
86 if (!index) {
87 if (errno == EINVAL)
88 fatal("%s has wrong magic or version number", filename);
90 fatal("Could not open %s for reading: %s\n",
91 filename, strerror(errno));
94 return index;
97 static void dump_index(const char *filename)
99 struct index_file *index = open_index(filename);
101 index_dump(index, stdout, "");
103 index_file_close(index);
106 static void search_index(const char *filename, char *key)
108 struct index_file *index = open_index(filename);
109 char *value;
111 value = index_search(index, key);
112 if (value)
113 printf("Found value:\n%s\n", value);
114 else
115 printf("Not found.\n");
117 free(value);
118 index_file_close(index);
121 static void searchwild_index(const char *filename, char *key)
123 struct index_file *index = open_index(filename);
124 struct index_value *values, *v;
126 values = index_searchwild(index, key);
127 if (values)
128 printf("Found value(s):\n");
129 else
130 printf("Not found.\n");
132 for (v = values; v; v = v->next)
133 printf("%s\n", v->value);
135 index_values_free(values);
136 index_file_close(index);
139 static void print_usage(const char *progname)
141 fprintf(stderr,
142 "Usage: %s [MODE] [FILE] ...\n"
143 " -o, --output <outfile>\n"
144 " -d, --dump <infile>\n"
145 " -s, --search <infile> <key>\n"
146 " -w, --searchwild <infile> <key>\n"
147 ,progname);
148 exit(1);
151 static struct option options[] = {
152 { "output", 0, NULL, 'o' },
153 { "dump", 0, NULL, 'd' },
154 { "search", 0, NULL, 's' },
155 { "searchwild", 0, NULL, 'w' },
158 int main(int argc, char *argv[])
160 char opt;
161 char mode = 0;
162 char *filename = NULL;
163 char *key = NULL;
165 while ((opt = getopt_long(argc, argv, "odsw", options, NULL))
166 != -1) {
167 switch (opt) {
168 case 'o':
169 mode = 'o';
170 break;
171 case 'd':
172 mode = 'd';
173 break;
174 case 's':
175 mode = 's';
176 break;
177 case 'w':
178 mode = 'w';
179 break;
180 default:
181 print_usage(argv[0]);
184 if (!mode)
185 print_usage(argv[0]);
187 if (optind >= argc)
188 print_usage(argv[0]);
189 filename = argv[optind];
191 if (mode == 's' || mode == 'w') {
192 if (optind+1 >= argc)
193 print_usage(argv[0]);
194 key = argv[optind+1];
197 switch(mode) {
198 case 'o':
199 write_index(filename);
200 break;
201 case 'd':
202 dump_index(filename);
203 break;
204 case 's':
205 search_index(filename, key);
206 break;
207 case 'w':
208 searchwild_index(filename, key);
209 break;
212 return 0;