blob: aa532a071fc1ec3d4012761f95768f6003937def [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");
34 if (!locale)
35 return NULL;
36 language = displayLanguage(locale);
37 n += sprintf(n, "%s", language);
38 q += sprintf(q, "locale:%s", locale);
Bert Frees9fc11fc2020-06-01 22:07:27 +020039 //free(locale);
Bert Frees84f9dbf2017-11-12 22:38:01 +010040 type = lou_getTableInfo(table, "type");
41 if (type) {
42 q += sprintf(q, " type:%s", type);
43 if (!strcmp(type, "computer")) {
44 dots = lou_getTableInfo(table, "dots");
45 if (dots) {
46 if (!strcmp(dots, "6")) {
47 n += sprintf(n, " %s-dot", dots);
48 } else {
49 char *q_save = q;
50 q += sprintf(q, " dots:6");
51 matches = lou_findTables(query);
52 if (matches) {
53 n += sprintf(n, " %s-dot", dots);
Bert Frees9fc11fc2020-06-01 22:07:27 +020054 //for (m = matches; *m; m++) free(*m);
55 //free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +010056 }
57 q = q_save;
58 }
59 q += sprintf(q, " dots:%s", dots);
Bert Frees9fc11fc2020-06-01 22:07:27 +020060 //free(dots);
Bert Frees84f9dbf2017-11-12 22:38:01 +010061 }
62 n += sprintf(n, " %s", type);
63 } else if (!strcmp(type, "literary")) {
64 int uncontracted = 0;
65 int fullyContracted = 0;
66 int partiallyContracted = 0;
67 int otherUncontracted = 0;
68 int otherFullyContracted = 0;
69 int otherPartiallyContracted = 0;
70 int twoOrMorePartiallyContracted = 0;
71 contraction = lou_getTableInfo(table, "contraction");
72 if (contraction) {
73 char *q_save = q;
74 uncontracted = !strcmp(contraction, "no");
75 fullyContracted = !strcmp(contraction, "full");
76 partiallyContracted = !strcmp(contraction, "partial");
77 otherUncontracted = 0;
78 q += sprintf(q, " contraction:no");
79 matches = lou_findTables(query);
80 if (matches) {
81 if (!uncontracted || matches[0] && matches[1])
82 otherUncontracted = 1;
Bert Frees9fc11fc2020-06-01 22:07:27 +020083 //for (m = matches; *m; m++) free(*m);
84 //free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +010085 }
86 q = q_save;
87 otherPartiallyContracted = 0;
88 twoOrMorePartiallyContracted = 0;
89 grade = NULL;
90 q += sprintf(q, " contraction:partial");
91 matches = lou_findTables(query);
92 if (matches) {
93 for (m = matches; *m; m++) {
94 if (!twoOrMorePartiallyContracted) {
95 char *g = lou_getTableInfo(*m, "grade");
96 if (g) {
97 if (!grade)
98 grade = g;
99 else if (strcmp(grade, g))
100 twoOrMorePartiallyContracted = 1;
101 }
102 }
Bert Frees9fc11fc2020-06-01 22:07:27 +0200103 //free(*m);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100104 }
Bert Frees9fc11fc2020-06-01 22:07:27 +0200105 //free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100106 if (!partiallyContracted || twoOrMorePartiallyContracted)
107 otherPartiallyContracted = 1;
108 if (twoOrMorePartiallyContracted)
109 grade = lou_getTableInfo(table, "grade");
110 else
111 grade = NULL;
112 }
113 q = q_save;
114 otherFullyContracted = 0;
115 q += sprintf(q, " contraction:full");
116 matches = lou_findTables(query);
117 if (matches) {
118 if (!fullyContracted || matches[0] && matches[1])
119 otherFullyContracted = 1;
Bert Frees9fc11fc2020-06-01 22:07:27 +0200120 //for (m = matches; *m; m++) free(*m);
121 //free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100122 }
123 q = q_save;
124 q += sprintf(q, " contraction:%s", contraction);
Bert Frees9fc11fc2020-06-01 22:07:27 +0200125 //free(contraction);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100126 }
127 dots = lou_getTableInfo(table, "dots");
128 if (dots) {
129 int otherDots = 0;
130 matches = lou_findTables(query);
131 if (matches) {
132 for (m = matches; *m; m++) {
133 if (!otherDots) {
134 char *d = lou_getTableInfo(*m, "dots");
135 if (d && strcmp(dots, d))
136 otherDots = 1;
137 }
Bert Frees9fc11fc2020-06-01 22:07:27 +0200138 //free(*m);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100139 }
Bert Frees9fc11fc2020-06-01 22:07:27 +0200140 //free(matches);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100141 }
142 if (otherDots)
143 n += sprintf(n, " %s-dot", dots);
Bert Frees9fc11fc2020-06-01 22:07:27 +0200144 //free(dots);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100145 }
146 if (uncontracted) {
147 if (otherFullyContracted || otherPartiallyContracted)
148 n += sprintf(n, " uncontracted");
149 } else if (fullyContracted) {
150 if (otherPartiallyContracted) {
151 if (twoOrMorePartiallyContracted && grade)
152 n += sprintf(n, " grade %s contracted", grade);
153 else
Bert Frees5edfb612019-08-25 18:31:17 +0200154 n += sprintf(n, " contracted");
Bert Frees84f9dbf2017-11-12 22:38:01 +0100155 } else if (otherUncontracted) {
156 n += sprintf(n, " contracted");
157 }
158 } else if (partiallyContracted) {
159 if (twoOrMorePartiallyContracted && grade)
160 n += sprintf(n, " grade %s contracted", grade);
161 else
162 n += sprintf(n, " partially contracted");
163 }
Bert Frees9fc11fc2020-06-01 22:07:27 +0200164 //free(grade);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100165 }
Bert Frees9fc11fc2020-06-01 22:07:27 +0200166 //free(type);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100167 }
168 n += sprintf(n, " braille");
169 version = lou_getTableInfo(table, "version");
170 if (version) {
171 n += sprintf(n, " (%s standard)", version);
Bert Frees9fc11fc2020-06-01 22:07:27 +0200172 //free(version);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100173 }
174 return name;
175}
176
177int main(int argc, char **argv) {
Bert Frees4c3cedc2020-04-30 23:03:12 +0200178 int COLUMN_INDEX_NAME = -1;
179 int COLUMN_DISPLAY_NAME = -1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100180 int result = 0;
181 FILE *fp;
182 char *line = NULL;
183 size_t len = 0;
184 if (argc != 2) {
185 fprintf(stderr, "One argument expected\n");
186 exit(EXIT_FAILURE);
187 }
188 fp = fopen(argv[1], "rb");
189 if (!fp) {
190 fprintf(stderr, "Could not open file: %s\n", argv[1]);
191 exit(EXIT_FAILURE);
192 }
Christian Egli547815d2019-03-04 09:46:51 +0100193 lou_setLogLevel(LOU_LOG_WARN);
Bert Frees30981f62020-05-01 00:13:14 +0200194 char cwd[PATH_MAX];
195 if (getcwd(cwd, sizeof(cwd)) == NULL) {
196 fprintf(stderr, "Unexpected error\n");
197 exit(EXIT_FAILURE);
198 }
199 int cwdLen = strlen(cwd);
200 char *tablePath = _lou_getTablePath();
201 if (strncmp(cwd, tablePath, cwdLen) || tablePath[cwdLen] != '/') {
202 fprintf(stderr, "Unexpected table path: %s\n", tablePath);
203 exit(EXIT_FAILURE);
204 }
205 int tablePathLen = strlen(tablePath);
206 char **tables = lou_listTables();
207 int tableCount = 0;
208 for (char** t = tables; *t; t++) {
209 tableCount++;
210 if (strncmp(tablePath, *t, tablePathLen) || (*t)[tablePathLen] != '/') {
211 fprintf(stderr, "Unexpected table location: %s\n", *t);
212 exit(EXIT_FAILURE);
213 }
214 }
215 free(tablePath);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100216 while (getline(&line, &len, fp) != -1) {
217 char *cp = line;
218 int generate = 0;
219 if (*cp == '*') {
220 generate = 1;
221 cp++;
222 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200223 while (*cp == ' ')
Bert Frees84f9dbf2017-11-12 22:38:01 +0100224 cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200225 if (*cp == '\0' || *cp == '\n' || *cp == '#') {
Bert Frees84f9dbf2017-11-12 22:38:01 +0100226 if (!generate)
227 continue;
228 else
229 goto parse_error;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200230 }
231 char *table = cp;
232 cp++;
233 while (*cp != ' ' && *cp != '\0' && *cp != '\n' && *cp != '#')
Bert Frees84f9dbf2017-11-12 22:38:01 +0100234 cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200235 if (*cp != ' ')
236 goto parse_error;
237 *cp = '\0';
238 cp++;
239 while (*cp == ' ')
240 cp++;
241 if (*cp == '\0' || *cp == '\n' || *cp == '#')
242 goto parse_error;
243 char *expectedIndexName = cp;
244 if (COLUMN_INDEX_NAME < 0)
245 COLUMN_INDEX_NAME = expectedIndexName - line;
246 else if (expectedIndexName != line + COLUMN_INDEX_NAME)
247 goto parse_error;
248 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
249 if (*cp == ' ' && cp[1] == ' ') {
250 *cp = '\0';
Bert Frees84f9dbf2017-11-12 22:38:01 +0100251 cp++;
Bert Frees4c3cedc2020-04-30 23:03:12 +0200252 break;
253 }
254 cp++;
255 }
256 if (*cp != ' ')
257 goto parse_error;
258 while (*cp == ' ')
259 cp++;
260 if (*cp == '\0' || *cp == '\n' || *cp == '#')
261 goto parse_error;
262 char *expectedDisplayName = cp;
263 if (COLUMN_DISPLAY_NAME < 0)
264 COLUMN_DISPLAY_NAME = expectedDisplayName - line;
265 else if (expectedDisplayName != line + COLUMN_DISPLAY_NAME)
266 goto parse_error;
267 while (*cp != '\0' && *cp != '\n' && *cp != '#') {
268 if (*cp == ' ' && cp[1] == ' ')
269 break;
270 cp++;
271 }
272 *cp = '\0';
Bert Frees30981f62020-05-01 00:13:14 +0200273 int found = 0;
274 for (int k = 0; k < tableCount; k++) {
275 if (tables[k]) {
276 if (!strcmp(&tables[k][cwdLen + 1], table)) {
277 tables[k] = NULL;
278 found = 1;
279 break;
280 }
281 }
282 }
283 if (!found) {
284 fprintf(stderr, "Table not in table path: %s\n", table);
285 result = 1;
286 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200287 const char *actualIndexName = lou_getTableInfo(table, "index-name");
288 if (!actualIndexName) {
289 fprintf(stderr, "No index-name field in table %s\n", table);
290 result = 1;
291 } else {
292 if (strcmp(actualIndexName, expectedIndexName) != 0) {
293 fprintf(stderr, "%s: %s != %s\n", table, actualIndexName, expectedIndexName);
294 fprintf(stderr, " cat %s | sed 's/^\\(#-index-name: *\\).*$/\\1%s/g' > %s.tmp\n", table, expectedIndexName, table);
295 fprintf(stderr, " mv %s.tmp %s\n", table, table);
296 result = 1;
297 }
298 }
299 const char *actualDisplayName = lou_getTableInfo(table, "display-name");
300 if (!actualDisplayName) {
301 fprintf(stderr, "No display-name field in table %s\n", table);
302 result = 1;
303 } else {
304 if (strcmp(actualDisplayName, expectedDisplayName) != 0) {
305 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName, expectedDisplayName);
306 fprintf(stderr, " cat %s | sed 's/^\\(#-display-name: *\\).*$/\\1%s/g' > %s.tmp\n", table, expectedDisplayName, table);
307 fprintf(stderr, " mv %s.tmp %s\n", table, table);
308 result = 1;
309 }
310 const char *generatedDisplayName = generateDisplayName(table);
311 if (!generatedDisplayName || !*generatedDisplayName) {
312 if (generate) {
313 fprintf(stderr, "No display-name could be generated for table %s\n", table);
314 result = 1;
315 }
316 } else if (strcmp(actualDisplayName, generatedDisplayName) != 0) {
317 if (generate) {
318 fprintf(stderr, "%s: %s != %s\n", table, actualDisplayName, generatedDisplayName);
319 result = 1;
320 }
321 } else {
322 if (!generate) {
323 fprintf(stderr, "%s: %s == %s\n", table, actualDisplayName, generatedDisplayName);
324 result = 1;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100325 }
326 }
327 }
Bert Frees4c3cedc2020-04-30 23:03:12 +0200328 continue;
Bert Frees84f9dbf2017-11-12 22:38:01 +0100329 parse_error:
330 fprintf(stderr, "Could not parse line: %s\n", line);
331 exit(EXIT_FAILURE);
332 }
333 free(line);
Bert Frees30981f62020-05-01 00:13:14 +0200334 for (int k = 0; k < tableCount; k++) {
335 if (tables[k]) {
336 fprintf(stderr, "Table not in list: %s\n", tables[k]);
337 result = 1;
338 free(tables[k]);
339 }
340 }
341 free(tables);
Bert Frees84f9dbf2017-11-12 22:38:01 +0100342 return result;
343}