blob: 17e22059d53a03e17bdb51b2e0ba4c43d8350697 [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) {
Bert Frees3dc5f8f2022-02-20 18:12:02 +0100167 matches = lou_findTables(query);
168 if (matches) {
169 if (matches[0] && matches[1])
170 n += sprintf(n, " (%s standard)", version);
171 // free(matches);
172 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100173 // free(version);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100174 }
175 return name;
176}
177
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100178int
179main(int argc, char **argv) {
Bert Frees4c3cedc2020-04-30 23:03:12 +0200180 int COLUMN_INDEX_NAME = -1;
181 int COLUMN_DISPLAY_NAME = -1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100182 int result = 0;
183 FILE *fp;
184 char *line = NULL;
185 size_t len = 0;
186 if (argc != 2) {
187 fprintf(stderr, "One argument expected\n");
188 exit(EXIT_FAILURE);
189 }
190 fp = fopen(argv[1], "rb");
191 if (!fp) {
192 fprintf(stderr, "Could not open file: %s\n", argv[1]);
193 exit(EXIT_FAILURE);
194 }
Christian Egli547815d2019-03-04 09:46:51 +0100195 lou_setLogLevel(LOU_LOG_WARN);
Bert Frees30981f62020-05-01 00:13:14 +0200196 char cwd[PATH_MAX];
197 if (getcwd(cwd, sizeof(cwd)) == NULL) {
198 fprintf(stderr, "Unexpected error\n");
199 exit(EXIT_FAILURE);
200 }
201 int cwdLen = strlen(cwd);
202 char *tablePath = _lou_getTablePath();
203 if (strncmp(cwd, tablePath, cwdLen) || tablePath[cwdLen] != '/') {
204 fprintf(stderr, "Unexpected table path: %s\n", tablePath);
205 exit(EXIT_FAILURE);
206 }
207 int tablePathLen = strlen(tablePath);
208 char **tables = lou_listTables();
209 int tableCount = 0;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100210 for (char **t = tables; *t; t++) {
Bert Frees30981f62020-05-01 00:13:14 +0200211 tableCount++;
212 if (strncmp(tablePath, *t, tablePathLen) || (*t)[tablePathLen] != '/') {
213 fprintf(stderr, "Unexpected table location: %s\n", *t);
214 exit(EXIT_FAILURE);
215 }
216 }
217 free(tablePath);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100218 while (getline(&line, &len, fp) != -1) {
219 char *cp = line;
220 int generate = 0;
221 if (*cp == '*') {
222 generate = 1;
223 cp++;
224 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100225 while (*cp == ' ') cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200226 if (*cp == '\0' || *cp == '\n' || *cp == '#') {
Bert Frees84f9dbf2017-11-12 22:38:01 +0100227 if (!generate)
228 continue;
229 else
230 goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200231 }
232 char *table = cp;
233 cp++;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100234 while (*cp != ' ' && *cp != '\0' && *cp != '\n' && *cp != '#') cp++;
235 if (*cp != ' ') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200236 *cp = '\0';
237 cp++;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100238 while (*cp == ' ') cp++;
239 if (*cp == '\0' || *cp == '\n' || *cp == '#') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200240 char *expectedIndexName = cp;
241 if (COLUMN_INDEX_NAME < 0)
242 COLUMN_INDEX_NAME = expectedIndexName - line;
243 else if (expectedIndexName != line + COLUMN_INDEX_NAME)
244 goto parse_error;
245 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
246 if (*cp == ' ' && cp[1] == ' ') {
247 *cp = '\0';
Bert Frees84f9dbf2017-11-12 22:38:01 +0100248 cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200249 break;
250 }
251 cp++;
252 }
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100253 if (*cp != ' ') goto parse_error;
254 while (*cp == ' ') cp++;
255 if (*cp == '\0' || *cp == '\n' || *cp == '#') goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200256 char *expectedDisplayName = cp;
257 if (COLUMN_DISPLAY_NAME < 0)
258 COLUMN_DISPLAY_NAME = expectedDisplayName - line;
259 else if (expectedDisplayName != line + COLUMN_DISPLAY_NAME)
260 goto parse_error;
261 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100262 if (*cp == ' ' && cp[1] == ' ') break;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200263 cp++;
264 }
265 *cp = '\0';
Bert Frees30981f62020-05-01 00:13:14 +0200266 int found = 0;
267 for (int k = 0; k < tableCount; k++) {
268 if (tables[k]) {
269 if (!strcmp(&tables[k][cwdLen + 1], table)) {
270 tables[k] = NULL;
271 found = 1;
272 break;
273 }
274 }
275 }
276 if (!found) {
277 fprintf(stderr, "Table not in table path: %s\n", table);
278 result = 1;
279 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200280 const char *actualIndexName = lou_getTableInfo(table, "index-name");
281 if (!actualIndexName) {
282 fprintf(stderr, "No index-name field in table %s\n", table);
283 result = 1;
284 } else {
285 if (strcmp(actualIndexName, expectedIndexName) != 0) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100286 fprintf(stderr, "%s: %s != %s\n", table, actualIndexName,
287 expectedIndexName);
288 fprintf(stderr,
289 " cat %s | sed 's/^\\(#-index-name: *\\).*$/\\1%s/g' > "
290 "%s.tmp\n",
291 table, expectedIndexName, table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200292 fprintf(stderr, " mv %s.tmp %s\n", table, table);
293 result = 1;
294 }
295 }
296 const char *actualDisplayName = lou_getTableInfo(table, "display-name");
297 if (!actualDisplayName) {
298 fprintf(stderr, "No display-name field in table %s\n", table);
299 result = 1;
300 } else {
301 if (strcmp(actualDisplayName, expectedDisplayName) != 0) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100302 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName,
303 expectedDisplayName);
304 fprintf(stderr,
305 " cat %s | sed 's/^\\(#-display-name: *\\).*$/\\1%s/g' > "
306 "%s.tmp\n",
307 table, expectedDisplayName, table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200308 fprintf(stderr, " mv %s.tmp %s\n", table, table);
309 result = 1;
310 }
311 const char *generatedDisplayName = generateDisplayName(table);
312 if (!generatedDisplayName || !*generatedDisplayName) {
313 if (generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100314 fprintf(stderr, "No display-name could be generated for table %s\n",
315 table);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200316 result = 1;
317 }
318 } else if (strcmp(actualDisplayName, generatedDisplayName) != 0) {
319 if (generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100320 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName,
321 generatedDisplayName);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200322 result = 1;
323 }
324 } else {
325 if (!generate) {
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100326 fprintf(stderr, "%s: %s == %s\n", table, actualDisplayName,
327 generatedDisplayName);
Bert Frees4c3cedc2020-04-30 23:03:12 +0200328 result = 1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100329 }
330 }
331 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200332 continue;
Bert Freesa0bbb2e2022-02-20 17:52:22 +0100333 parse_error:
Bert Frees84f9dbf2017-11-12 22:38:01 +0100334 fprintf(stderr, "Could not parse line: %s\n", line);
335 exit(EXIT_FAILURE);
336 }
337 free(line);
Bert Frees30981f62020-05-01 00:13:14 +0200338 for (int k = 0; k < tableCount; k++) {
339 if (tables[k]) {
340 fprintf(stderr, "Table not in list: %s\n", tables[k]);
341 result = 1;
342 free(tables[k]);
343 }
344 }
345 free(tables);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100346 return result;
347}