blob: 1b50007716841068a6cb0220a8b1739d7a954721 [file] [log] [blame]
Bert Frees84f9dbf2017-11-12 22:38:01 +01001#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
Bert Frees30981f62020-05-01 00:13:14 +02004#include <unistd.h>
5#include <limits.h>
Bert Frees84f9dbf2017-11-12 22:38:01 +01006#include "internal.h"
7#include "displayLanguage.h"
8
9static const char *
10displayLanguage(const char *lang) {
11 return DisplayLanguage((char *)lang);
12}
13
Bert Frees1ef1aa62022-02-18 15:46:42 +010014static const char *
15displayRegion(const char *region) {
16 return DisplayRegion((char *)region);
17}
18
Bert Frees84f9dbf2017-11-12 22:38:01 +010019static char *
20generateDisplayName(const char *table) {
21 char *name;
22 char *language;
Bert Frees1ef1aa62022-02-18 15:46:42 +010023 char *region;
Bert Frees84f9dbf2017-11-12 22:38:01 +010024 char *type;
25 char *dots;
26 char *contraction;
27 char *grade;
28 char *version;
29 char *query;
30 char **matches;
31 char *n;
32 char *q;
33 char **m;
34 name = (char *)malloc(100 * sizeof(*name));
35 n = name;
36 query = (char *)malloc(100 * sizeof(*query));
37 q = query;
Bert Frees1ef1aa62022-02-18 15:46:42 +010038 language = lou_getTableInfo(table, "language");
39 if (!language) return NULL;
40 n += sprintf(n, "%s", displayLanguage(language));
41 q += sprintf(q, "language:%s", language);
42 region = lou_getTableInfo(table, "region");
43 if (region) q += sprintf(q, " region:%s", region);
Bert Frees84f9dbf2017-11-12 22:38:01 +010044 type = lou_getTableInfo(table, "type");
45 if (type) {
46 q += sprintf(q, " type:%s", type);
47 if (!strcmp(type, "computer")) {
48 dots = lou_getTableInfo(table, "dots");
49 if (dots) {
50 if (!strcmp(dots, "6")) {
51 n += sprintf(n, " %s-dot", dots);
52 } else {
53 char *q_save = q;
54 q += sprintf(q, " dots:6");
55 matches = lou_findTables(query);
56 if (matches) {
57 n += sprintf(n, " %s-dot", dots);
Bert Freesa0bbb2e2022-02-20 17:52:22 +010058 // for (m = matches; *m; m++) free(*m);
59 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +010060 }
61 q = q_save;
62 }
63 q += sprintf(q, " dots:%s", dots);
Bert Freesa0bbb2e2022-02-20 17:52:22 +010064 // free(dots);
Bert Frees84f9dbf2017-11-12 22:38:01 +010065 }
66 n += sprintf(n, " %s", type);
67 } else if (!strcmp(type, "literary")) {
68 int uncontracted = 0;
69 int fullyContracted = 0;
70 int partiallyContracted = 0;
71 int otherUncontracted = 0;
72 int otherFullyContracted = 0;
73 int otherPartiallyContracted = 0;
74 int twoOrMorePartiallyContracted = 0;
75 contraction = lou_getTableInfo(table, "contraction");
76 if (contraction) {
77 char *q_save = q;
78 uncontracted = !strcmp(contraction, "no");
79 fullyContracted = !strcmp(contraction, "full");
80 partiallyContracted = !strcmp(contraction, "partial");
81 otherUncontracted = 0;
82 q += sprintf(q, " contraction:no");
83 matches = lou_findTables(query);
84 if (matches) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +010085 if (!uncontracted || matches[0] && matches[1]) otherUncontracted = 1;
86 // for (m = matches; *m; m++) free(*m);
87 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +010088 }
89 q = q_save;
90 otherPartiallyContracted = 0;
91 twoOrMorePartiallyContracted = 0;
92 grade = NULL;
93 q += sprintf(q, " contraction:partial");
94 matches = lou_findTables(query);
95 if (matches) {
96 for (m = matches; *m; m++) {
97 if (!twoOrMorePartiallyContracted) {
98 char *g = lou_getTableInfo(*m, "grade");
99 if (g) {
100 if (!grade)
101 grade = g;
102 else if (strcmp(grade, g))
103 twoOrMorePartiallyContracted = 1;
104 }
105 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100106 // free(*m);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100107 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100108 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100109 if (!partiallyContracted || twoOrMorePartiallyContracted)
110 otherPartiallyContracted = 1;
111 if (twoOrMorePartiallyContracted)
112 grade = lou_getTableInfo(table, "grade");
113 else
114 grade = NULL;
115 }
116 q = q_save;
117 otherFullyContracted = 0;
118 q += sprintf(q, " contraction:full");
119 matches = lou_findTables(query);
120 if (matches) {
121 if (!fullyContracted || matches[0] && matches[1])
122 otherFullyContracted = 1;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100123 // for (m = matches; *m; m++) free(*m);
124 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100125 }
126 q = q_save;
127 q += sprintf(q, " contraction:%s", contraction);
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100128 // free(contraction);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100129 }
130 dots = lou_getTableInfo(table, "dots");
131 if (dots) {
132 int otherDots = 0;
133 matches = lou_findTables(query);
134 if (matches) {
135 for (m = matches; *m; m++) {
136 if (!otherDots) {
137 char *d = lou_getTableInfo(*m, "dots");
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100138 if (d && strcmp(dots, d)) otherDots = 1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100139 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100140 // free(*m);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100141 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100142 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100143 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100144 if (otherDots) n += sprintf(n, " %s-dot", dots);
145 // free(dots);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100146 }
147 if (uncontracted) {
148 if (otherFullyContracted || otherPartiallyContracted)
149 n += sprintf(n, " uncontracted");
150 } else if (fullyContracted) {
151 if (otherPartiallyContracted) {
152 if (twoOrMorePartiallyContracted && grade)
153 n += sprintf(n, " grade %s contracted", grade);
154 else
Bert Frees5edfb612019-08-25 18:31:17 +0200155 n += sprintf(n, " contracted");
Bert Frees84f9dbf2017-11-12 22:38:01 +0100156 } else if (otherUncontracted) {
157 n += sprintf(n, " contracted");
158 }
159 } else if (partiallyContracted) {
160 if (twoOrMorePartiallyContracted && grade)
161 n += sprintf(n, " grade %s contracted", grade);
162 else
163 n += sprintf(n, " partially contracted");
164 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100165 // free(grade);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100166 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100167 // free(type);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100168 }
169 n += sprintf(n, " braille");
Bert Frees1ef1aa62022-02-18 15:46:42 +0100170 if (region && strlen(region) > strlen(language) &&
171 !strncmp(language, region, strlen(language)) &&
172 region[strlen(language)] == '-') {
173 char *r = displayRegion(&region[strlen(language) + 1]);
174 if (r && *r) n += sprintf(n, " as used in %s", r);
175 }
176 // free(region);
177 // free(language);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100178 version = lou_getTableInfo(table, "version");
179 if (version) {
Bert Frees3dc5f8f2022-02-20 18:12:02 +0100180 matches = lou_findTables(query);
181 if (matches) {
Bert Frees1ef1aa62022-02-18 15:46:42 +0100182 if (matches[0] && matches[1]) n += sprintf(n, " (%s standard)", version);
Bert Frees3dc5f8f2022-02-20 18:12:02 +0100183 // free(matches);
184 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100185 // free(version);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100186 }
187 return name;
188}
189
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100190int
191main(int argc, char **argv) {
Bert Frees4c3cedc2020-04-30 23:03:12 +0200192 int COLUMN_INDEX_NAME = -1;
193 int COLUMN_DISPLAY_NAME = -1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100194 int result = 0;
195 FILE *fp;
196 char *line = NULL;
197 size_t len = 0;
198 if (argc != 2) {
199 fprintf(stderr, "One argument expected\n");
200 exit(EXIT_FAILURE);
201 }
202 fp = fopen(argv[1], "rb");
203 if (!fp) {
204 fprintf(stderr, "Could not open file: %s\n", argv[1]);
205 exit(EXIT_FAILURE);
206 }
Christian Egli547815d2019-03-04 09:46:51 +0100207 lou_setLogLevel(LOU_LOG_WARN);
Bert Frees30981f62020-05-01 00:13:14 +0200208 char cwd[PATH_MAX];
209 if (getcwd(cwd, sizeof(cwd)) == NULL) {
210 fprintf(stderr, "Unexpected error\n");
211 exit(EXIT_FAILURE);
212 }
213 int cwdLen = strlen(cwd);
214 char *tablePath = _lou_getTablePath();
215 if (strncmp(cwd, tablePath, cwdLen) || tablePath[cwdLen] != '/') {
216 fprintf(stderr, "Unexpected table path: %s\n", tablePath);
217 exit(EXIT_FAILURE);
218 }
219 int tablePathLen = strlen(tablePath);
220 char **tables = lou_listTables();
221 int tableCount = 0;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100222 for (char **t = tables; *t; t++) {
Bert Frees30981f62020-05-01 00:13:14 +0200223 tableCount++;
224 if (strncmp(tablePath, *t, tablePathLen) || (*t)[tablePathLen] != '/') {
225 fprintf(stderr, "Unexpected table location: %s\n", *t);
226 exit(EXIT_FAILURE);
227 }
228 }
229 free(tablePath);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100230 while (getline(&line, &len, fp) != -1) {
231 char *cp = line;
232 int generate = 0;
233 if (*cp == '*') {
234 generate = 1;
235 cp++;
236 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100237 while (*cp == ' ') cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200238 if (*cp == '\0' || *cp == '\n' || *cp == '#') {
Bert Frees84f9dbf2017-11-12 22:38:01 +0100239 if (!generate)
240 continue;
241 else
242 goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200243 }
244 char *table = cp;
245 cp++;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100246 while (*cp != ' ' && *cp != '\0' && *cp != '\n' && *cp != '#') cp++;
247 if (*cp != ' ') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200248 *cp = '\0';
249 cp++;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100250 while (*cp == ' ') cp++;
251 if (*cp == '\0' || *cp == '\n' || *cp == '#') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200252 char *expectedIndexName = cp;
253 if (COLUMN_INDEX_NAME < 0)
254 COLUMN_INDEX_NAME = expectedIndexName - line;
255 else if (expectedIndexName != line + COLUMN_INDEX_NAME)
256 goto parse_error;
257 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
258 if (*cp == ' ' && cp[1] == ' ') {
259 *cp = '\0';
Bert Frees84f9dbf2017-11-12 22:38:01 +0100260 cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200261 break;
262 }
263 cp++;
264 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100265 if (*cp != ' ') goto parse_error;
266 while (*cp == ' ') cp++;
267 if (*cp == '\0' || *cp == '\n' || *cp == '#') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200268 char *expectedDisplayName = cp;
269 if (COLUMN_DISPLAY_NAME < 0)
270 COLUMN_DISPLAY_NAME = expectedDisplayName - line;
271 else if (expectedDisplayName != line + COLUMN_DISPLAY_NAME)
272 goto parse_error;
273 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100274 if (*cp == ' ' && cp[1] == ' ') break;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200275 cp++;
276 }
277 *cp = '\0';
Bert Frees30981f62020-05-01 00:13:14 +0200278 int found = 0;
279 for (int k = 0; k < tableCount; k++) {
280 if (tables[k]) {
281 if (!strcmp(&tables[k][cwdLen + 1], table)) {
282 tables[k] = NULL;
283 found = 1;
284 break;
285 }
286 }
287 }
288 if (!found) {
289 fprintf(stderr, "Table not in table path: %s\n", table);
290 result = 1;
291 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200292 const char *actualIndexName = lou_getTableInfo(table, "index-name");
293 if (!actualIndexName) {
294 fprintf(stderr, "No index-name field in table %s\n", table);
295 result = 1;
296 } else {
297 if (strcmp(actualIndexName, expectedIndexName) != 0) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100298 fprintf(stderr, "%s: %s != %s\n", table, actualIndexName,
299 expectedIndexName);
300 fprintf(stderr,
301 " cat %s | sed 's/^\\(#-index-name: *\\).*$/\\1%s/g' > "
302 "%s.tmp\n",
303 table, expectedIndexName, table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200304 fprintf(stderr, " mv %s.tmp %s\n", table, table);
305 result = 1;
306 }
307 }
308 const char *actualDisplayName = lou_getTableInfo(table, "display-name");
309 if (!actualDisplayName) {
310 fprintf(stderr, "No display-name field in table %s\n", table);
311 result = 1;
312 } else {
313 if (strcmp(actualDisplayName, expectedDisplayName) != 0) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100314 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName,
315 expectedDisplayName);
316 fprintf(stderr,
317 " cat %s | sed 's/^\\(#-display-name: *\\).*$/\\1%s/g' > "
318 "%s.tmp\n",
319 table, expectedDisplayName, table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200320 fprintf(stderr, " mv %s.tmp %s\n", table, table);
321 result = 1;
322 }
323 const char *generatedDisplayName = generateDisplayName(table);
324 if (!generatedDisplayName || !*generatedDisplayName) {
325 if (generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100326 fprintf(stderr, "No display-name could be generated for table %s\n",
327 table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200328 result = 1;
329 }
330 } else if (strcmp(actualDisplayName, generatedDisplayName) != 0) {
331 if (generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100332 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName,
333 generatedDisplayName);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200334 result = 1;
335 }
336 } else {
337 if (!generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100338 fprintf(stderr, "%s: %s == %s\n", table, actualDisplayName,
339 generatedDisplayName);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200340 result = 1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100341 }
342 }
343 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200344 continue;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100345 parse_error:
Bert Frees84f9dbf2017-11-12 22:38:01 +0100346 fprintf(stderr, "Could not parse line: %s\n", line);
347 exit(EXIT_FAILURE);
348 }
349 free(line);
Bert Frees30981f62020-05-01 00:13:14 +0200350 for (int k = 0; k < tableCount; k++) {
351 if (tables[k]) {
352 fprintf(stderr, "Table not in list: %s\n", tables[k]);
353 result = 1;
354 free(tables[k]);
355 }
356 }
357 free(tables);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100358 return result;
359}