blob: 6730fede741a75c2bb3cbc2cc99b3d0db210c60c [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 Frees84f9dbf2017-11-12 22:38:01 +010014static char *
15generateDisplayName(const char *table) {
16 char *name;
17 char *language;
18 char *locale;
19 char *type;
20 char *dots;
21 char *contraction;
22 char *grade;
23 char *version;
24 char *query;
25 char **matches;
26 char *n;
27 char *q;
28 char **m;
29 name = (char *)malloc(100 * sizeof(*name));
30 n = name;
31 query = (char *)malloc(100 * sizeof(*query));
32 q = query;
33 locale = lou_getTableInfo(table, "locale");
Bert Freesa0bbb2e2022-02-20 17:52:22 +010034 if (!locale) return NULL;
Bert Frees84f9dbf2017-11-12 22:38:01 +010035 language = displayLanguage(locale);
36 n += sprintf(n, "%s", language);
37 q += sprintf(q, "locale:%s", locale);
Bert Freesa0bbb2e2022-02-20 17:52:22 +010038 // free(locale);
Bert Frees84f9dbf2017-11-12 22:38:01 +010039 type = lou_getTableInfo(table, "type");
40 if (type) {
41 q += sprintf(q, " type:%s", type);
42 if (!strcmp(type, "computer")) {
43 dots = lou_getTableInfo(table, "dots");
44 if (dots) {
45 if (!strcmp(dots, "6")) {
46 n += sprintf(n, " %s-dot", dots);
47 } else {
48 char *q_save = q;
49 q += sprintf(q, " dots:6");
50 matches = lou_findTables(query);
51 if (matches) {
52 n += sprintf(n, " %s-dot", dots);
Bert Freesa0bbb2e2022-02-20 17:52:22 +010053 // for (m = matches; *m; m++) free(*m);
54 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +010055 }
56 q = q_save;
57 }
58 q += sprintf(q, " dots:%s", dots);
Bert Freesa0bbb2e2022-02-20 17:52:22 +010059 // free(dots);
Bert Frees84f9dbf2017-11-12 22:38:01 +010060 }
61 n += sprintf(n, " %s", type);
62 } else if (!strcmp(type, "literary")) {
63 int uncontracted = 0;
64 int fullyContracted = 0;
65 int partiallyContracted = 0;
66 int otherUncontracted = 0;
67 int otherFullyContracted = 0;
68 int otherPartiallyContracted = 0;
69 int twoOrMorePartiallyContracted = 0;
70 contraction = lou_getTableInfo(table, "contraction");
71 if (contraction) {
72 char *q_save = q;
73 uncontracted = !strcmp(contraction, "no");
74 fullyContracted = !strcmp(contraction, "full");
75 partiallyContracted = !strcmp(contraction, "partial");
76 otherUncontracted = 0;
77 q += sprintf(q, " contraction:no");
78 matches = lou_findTables(query);
79 if (matches) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +010080 if (!uncontracted || matches[0] && matches[1]) otherUncontracted = 1;
81 // for (m = matches; *m; m++) free(*m);
82 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +010083 }
84 q = q_save;
85 otherPartiallyContracted = 0;
86 twoOrMorePartiallyContracted = 0;
87 grade = NULL;
88 q += sprintf(q, " contraction:partial");
89 matches = lou_findTables(query);
90 if (matches) {
91 for (m = matches; *m; m++) {
92 if (!twoOrMorePartiallyContracted) {
93 char *g = lou_getTableInfo(*m, "grade");
94 if (g) {
95 if (!grade)
96 grade = g;
97 else if (strcmp(grade, g))
98 twoOrMorePartiallyContracted = 1;
99 }
100 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100101 // free(*m);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100102 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100103 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100104 if (!partiallyContracted || twoOrMorePartiallyContracted)
105 otherPartiallyContracted = 1;
106 if (twoOrMorePartiallyContracted)
107 grade = lou_getTableInfo(table, "grade");
108 else
109 grade = NULL;
110 }
111 q = q_save;
112 otherFullyContracted = 0;
113 q += sprintf(q, " contraction:full");
114 matches = lou_findTables(query);
115 if (matches) {
116 if (!fullyContracted || matches[0] && matches[1])
117 otherFullyContracted = 1;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100118 // for (m = matches; *m; m++) free(*m);
119 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100120 }
121 q = q_save;
122 q += sprintf(q, " contraction:%s", contraction);
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100123 // free(contraction);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100124 }
125 dots = lou_getTableInfo(table, "dots");
126 if (dots) {
127 int otherDots = 0;
128 matches = lou_findTables(query);
129 if (matches) {
130 for (m = matches; *m; m++) {
131 if (!otherDots) {
132 char *d = lou_getTableInfo(*m, "dots");
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100133 if (d && strcmp(dots, d)) otherDots = 1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100134 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100135 // free(*m);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100136 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100137 // free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100138 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100139 if (otherDots) n += sprintf(n, " %s-dot", dots);
140 // free(dots);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100141 }
142 if (uncontracted) {
143 if (otherFullyContracted || otherPartiallyContracted)
144 n += sprintf(n, " uncontracted");
145 } else if (fullyContracted) {
146 if (otherPartiallyContracted) {
147 if (twoOrMorePartiallyContracted && grade)
148 n += sprintf(n, " grade %s contracted", grade);
149 else
Bert Frees5edfb612019-08-25 18:31:17 +0200150 n += sprintf(n, " contracted");
Bert Frees84f9dbf2017-11-12 22:38:01 +0100151 } else if (otherUncontracted) {
152 n += sprintf(n, " contracted");
153 }
154 } else if (partiallyContracted) {
155 if (twoOrMorePartiallyContracted && grade)
156 n += sprintf(n, " grade %s contracted", grade);
157 else
158 n += sprintf(n, " partially contracted");
159 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100160 // free(grade);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100161 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100162 // free(type);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100163 }
164 n += sprintf(n, " braille");
165 version = lou_getTableInfo(table, "version");
166 if (version) {
167 n += sprintf(n, " (%s standard)", version);
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100168 // free(version);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100169 }
170 return name;
171}
172
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100173int
174main(int argc, char **argv) {
Bert Frees4c3cedc2020-04-30 23:03:12 +0200175 int COLUMN_INDEX_NAME = -1;
176 int COLUMN_DISPLAY_NAME = -1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100177 int result = 0;
178 FILE *fp;
179 char *line = NULL;
180 size_t len = 0;
181 if (argc != 2) {
182 fprintf(stderr, "One argument expected\n");
183 exit(EXIT_FAILURE);
184 }
185 fp = fopen(argv[1], "rb");
186 if (!fp) {
187 fprintf(stderr, "Could not open file: %s\n", argv[1]);
188 exit(EXIT_FAILURE);
189 }
Christian Egli547815d2019-03-04 09:46:51 +0100190 lou_setLogLevel(LOU_LOG_WARN);
Bert Frees30981f62020-05-01 00:13:14 +0200191 char cwd[PATH_MAX];
192 if (getcwd(cwd, sizeof(cwd)) == NULL) {
193 fprintf(stderr, "Unexpected error\n");
194 exit(EXIT_FAILURE);
195 }
196 int cwdLen = strlen(cwd);
197 char *tablePath = _lou_getTablePath();
198 if (strncmp(cwd, tablePath, cwdLen) || tablePath[cwdLen] != '/') {
199 fprintf(stderr, "Unexpected table path: %s\n", tablePath);
200 exit(EXIT_FAILURE);
201 }
202 int tablePathLen = strlen(tablePath);
203 char **tables = lou_listTables();
204 int tableCount = 0;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100205 for (char **t = tables; *t; t++) {
Bert Frees30981f62020-05-01 00:13:14 +0200206 tableCount++;
207 if (strncmp(tablePath, *t, tablePathLen) || (*t)[tablePathLen] != '/') {
208 fprintf(stderr, "Unexpected table location: %s\n", *t);
209 exit(EXIT_FAILURE);
210 }
211 }
212 free(tablePath);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100213 while (getline(&line, &len, fp) != -1) {
214 char *cp = line;
215 int generate = 0;
216 if (*cp == '*') {
217 generate = 1;
218 cp++;
219 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100220 while (*cp == ' ') cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200221 if (*cp == '\0' || *cp == '\n' || *cp == '#') {
Bert Frees84f9dbf2017-11-12 22:38:01 +0100222 if (!generate)
223 continue;
224 else
225 goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200226 }
227 char *table = cp;
228 cp++;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100229 while (*cp != ' ' && *cp != '\0' && *cp != '\n' && *cp != '#') cp++;
230 if (*cp != ' ') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200231 *cp = '\0';
232 cp++;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100233 while (*cp == ' ') cp++;
234 if (*cp == '\0' || *cp == '\n' || *cp == '#') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200235 char *expectedIndexName = cp;
236 if (COLUMN_INDEX_NAME < 0)
237 COLUMN_INDEX_NAME = expectedIndexName - line;
238 else if (expectedIndexName != line + COLUMN_INDEX_NAME)
239 goto parse_error;
240 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
241 if (*cp == ' ' && cp[1] == ' ') {
242 *cp = '\0';
Bert Frees84f9dbf2017-11-12 22:38:01 +0100243 cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200244 break;
245 }
246 cp++;
247 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100248 if (*cp != ' ') goto parse_error;
249 while (*cp == ' ') cp++;
250 if (*cp == '\0' || *cp == '\n' || *cp == '#') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200251 char *expectedDisplayName = cp;
252 if (COLUMN_DISPLAY_NAME < 0)
253 COLUMN_DISPLAY_NAME = expectedDisplayName - line;
254 else if (expectedDisplayName != line + COLUMN_DISPLAY_NAME)
255 goto parse_error;
256 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100257 if (*cp == ' ' && cp[1] == ' ') break;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200258 cp++;
259 }
260 *cp = '\0';
Bert Frees30981f62020-05-01 00:13:14 +0200261 int found = 0;
262 for (int k = 0; k < tableCount; k++) {
263 if (tables[k]) {
264 if (!strcmp(&tables[k][cwdLen + 1], table)) {
265 tables[k] = NULL;
266 found = 1;
267 break;
268 }
269 }
270 }
271 if (!found) {
272 fprintf(stderr, "Table not in table path: %s\n", table);
273 result = 1;
274 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200275 const char *actualIndexName = lou_getTableInfo(table, "index-name");
276 if (!actualIndexName) {
277 fprintf(stderr, "No index-name field in table %s\n", table);
278 result = 1;
279 } else {
280 if (strcmp(actualIndexName, expectedIndexName) != 0) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100281 fprintf(stderr, "%s: %s != %s\n", table, actualIndexName,
282 expectedIndexName);
283 fprintf(stderr,
284 " cat %s | sed 's/^\\(#-index-name: *\\).*$/\\1%s/g' > "
285 "%s.tmp\n",
286 table, expectedIndexName, table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200287 fprintf(stderr, " mv %s.tmp %s\n", table, table);
288 result = 1;
289 }
290 }
291 const char *actualDisplayName = lou_getTableInfo(table, "display-name");
292 if (!actualDisplayName) {
293 fprintf(stderr, "No display-name field in table %s\n", table);
294 result = 1;
295 } else {
296 if (strcmp(actualDisplayName, expectedDisplayName) != 0) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100297 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName,
298 expectedDisplayName);
299 fprintf(stderr,
300 " cat %s | sed 's/^\\(#-display-name: *\\).*$/\\1%s/g' > "
301 "%s.tmp\n",
302 table, expectedDisplayName, table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200303 fprintf(stderr, " mv %s.tmp %s\n", table, table);
304 result = 1;
305 }
306 const char *generatedDisplayName = generateDisplayName(table);
307 if (!generatedDisplayName || !*generatedDisplayName) {
308 if (generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100309 fprintf(stderr, "No display-name could be generated for table %s\n",
310 table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200311 result = 1;
312 }
313 } else if (strcmp(actualDisplayName, generatedDisplayName) != 0) {
314 if (generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100315 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName,
316 generatedDisplayName);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200317 result = 1;
318 }
319 } else {
320 if (!generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100321 fprintf(stderr, "%s: %s == %s\n", table, actualDisplayName,
322 generatedDisplayName);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200323 result = 1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100324 }
325 }
326 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200327 continue;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100328 parse_error:
Bert Frees84f9dbf2017-11-12 22:38:01 +0100329 fprintf(stderr, "Could not parse line: %s\n", line);
330 exit(EXIT_FAILURE);
331 }
332 free(line);
Bert Frees30981f62020-05-01 00:13:14 +0200333 for (int k = 0; k < tableCount; k++) {
334 if (tables[k]) {
335 fprintf(stderr, "Table not in list: %s\n", tables[k]);
336 result = 1;
337 free(tables[k]);
338 }
339 }
340 free(tables);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100341 return result;
342}