1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: usrtranslate.c
6 * User interface tool: language translator
7 * Written by: Steven M. Rubin, Static Free Software
8 *
9 * Copyright (c) 2001 Static Free Software.
10 *
11 * Electric(tm) is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Electric(tm) is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Electric(tm); see the file COPYING. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, Mass 02111-1307, USA.
25 *
26 * Static Free Software
27 * 4119 Alpine Road
28 * Portola Valley, California 94028
29 * support@staticfreesoft.com
30 */
31
32 #include "global.h"
33 #include "edialogs.h"
34 #include "usr.h"
35 #include "usrdiacom.h"
36
37 /********************************** CONTROL **********************************/
38
39 /* User Interface: Translate */
40 static DIALOGITEM us_transdialogitems[] =
41 {
42 /* 1 */ {0, {336,132,360,212}, BUTTON, N_("Next")},
43 /* 2 */ {0, {148,8,164,96}, MESSAGE, N_("Translation:")},
44 /* 3 */ {0, {148,100,196,528}, EDITTEXT, x_("")},
45 /* 4 */ {0, {8,324,24,472}, MESSAGE, N_("Total strings:")},
46 /* 5 */ {0, {8,473,24,529}, MESSAGE, x_("")},
47 /* 6 */ {0, {28,324,44,472}, MESSAGE, N_("Untranslated strings:")},
48 /* 7 */ {0, {28,472,44,528}, MESSAGE, x_("")},
49 /* 8 */ {0, {48,324,64,472}, MESSAGE, N_("Fuzzy strings:")},
50 /* 9 */ {0, {48,472,64,528}, MESSAGE, x_("")},
51 /* 10 */ {0, {92,8,108,96}, MESSAGE, N_("English:")},
52 /* 11 */ {0, {92,100,140,528}, EDITTEXT, x_("")},
53 /* 12 */ {0, {320,440,344,520}, BUTTON, N_("DONE")},
54 /* 13 */ {0, {172,8,188,96}, CHECK, N_("Fuzzy")},
55 /* 14 */ {0, {336,220,360,300}, BUTTON, N_("Prev")},
56 /* 15 */ {0, {336,12,360,92}, BUTTON, N_("First")},
57 /* 16 */ {0, {48,8,80,316}, MESSAGE, x_("")},
58 /* 17 */ {0, {288,441,312,521}, BUTTON, N_("Save")},
59 /* 18 */ {0, {8,8,24,132}, MESSAGE, N_("Language:")},
60 /* 19 */ {0, {8,132,24,188}, POPUP, x_("")},
61 /* 20 */ {0, {204,100,264,528}, SCROLL, x_("")},
62 /* 21 */ {0, {204,8,220,96}, MESSAGE, N_("Comments:")},
63 /* 22 */ {0, {272,12,288,100}, MESSAGE, N_("Choose:")},
64 /* 23 */ {0, {272,100,288,300}, POPUP, x_("")},
65 /* 24 */ {0, {8,192,24,304}, POPUP, x_("")},
66 /* 25 */ {0, {272,328,296,408}, BUTTON, N_("Unix-to-Mac")},
67 /* 26 */ {0, {305,328,329,408}, BUTTON, N_("Mac-to-UNIX")},
68 /* 27 */ {0, {292,100,308,300}, EDITTEXT, x_("")},
69 /* 28 */ {0, {292,24,308,84}, BUTTON, N_("Find:")},
70 /* 29 */ {0, {68,324,84,472}, MESSAGE, N_("Found strings:")},
71 /* 30 */ {0, {68,472,84,528}, MESSAGE, x_("")},
72 /* 31 */ {0, {312,24,328,152}, CHECK, N_("Find in English")},
73 /* 32 */ {0, {312,156,328,300}, CHECK, N_("Find in translation")},
74 /* 33 */ {0, {337,328,361,408}, BUTTON, N_("Validate")}
75 };
76 static DIALOG us_transdialog = {{75,75,444,613}, N_("Translate Electric Strings"), 0, 33, us_transdialogitems, 0, 0};
77
78 #define DTRN_NEXT 1 /* next string (button) */
79 #define DTRN_FOREIGN 3 /* translated string (edit text) */
80 #define DTRN_TOTSTR 5 /* total strings (message) */
81 #define DTRN_UNTSTR 7 /* untranslated strings (message) */
82 #define DTRN_FUZSTR 9 /* fuzzy strings (message) */
83 #define DTRN_ENGLISH 11 /* english string (message) */
84 #define DTRN_DONE 12 /* exit translator (button) */
85 #define DTRN_ISFUZZY 13 /* fuzzy indication (check) */
86 #define DTRN_PREV 14 /* previous string (button) */
87 #define DTRN_FIRST 15 /* first string (button) */
88 #define DTRN_MSGID 16 /* current message information (message) */
89 #define DTRN_SAVE 17 /* save (button) */
90 #define DTRN_LANGUAGE 19 /* language list (popup) */
91 #define DTRN_COMMENTS 20 /* comments (scroll) */
92 #define DTRN_NEXTTYPE 23 /* prev/next action (popup) */
93 #define DTRN_PLATFORM 24 /* platform list (popup) */
94 #define DTRN_UNIXTOMAC 25 /* Convert UNIX to Mac (button) */
95 #define DTRN_MACTOUNIX 26 /* Convert Mac to UNIX (button) */
96 #define DTRN_FINDSTR 27 /* String to find (message) */
97 #define DTRN_FINDBUT 28 /* Find (button) */
98 #define DTRN_FOUNDSTR 30 /* found strings (message) */
99 #define DTRN_FINDENG 31 /* Find in english (check) */
100 #define DTRN_FINDTRN 32 /* Find in translation (check) */
101 #define DTRN_VALIDATE 33 /* Validate translation (button) */
102
103 /* the type of strings being shown */
104 #define CHOOSEUNTRANS 0 /* show untranslated strings */
105 #define CHOOSEJUSTTRANS 1 /* show just translated strings */
106 #define CHOOSEFUZZY 2 /* show fuzzy strings */
107 #define CHOOSENLFUZZY 3 /* show no longer fuzzy strings */
108 #define CHOOSEFIND 4 /* show strings matching search pattern */
109 #define CHOOSEALL 5 /* show all strings */
110
111 #define NOSTRINGENTRY ((STRINGENTRY *)-1)
112
113 /* the meaning of STRINGENTRY->flags: */
114 #define CFORMAT 1
115 #define FUZZY 2
116 #define WASFUZZY 4 /* was fuzzy at start of session */
117 #define THISTIME 8 /* messages in doubt at start of session */
118 #define MATCHES 16 /* string matches search criteria */
119
120 typedef struct Istringentry
121 {
122 INTBIG headerlinecount;
123 CHAR **headerlines;
124 CHAR *english;
125 CHAR *translated;
126 INTBIG index;
127 INTBIG flags;
128 struct Istringentry *nextstringentry;
129 struct Istringentry *prevstringentry;
130 } STRINGENTRY;
131
132 STRINGENTRY *us_transfirststringentry;
133
134 static INTBIG us_transheaderlinecount;
135 static CHAR **us_transheaderlines;
136
137 static INTBIG us_transgatherlinecount;
138 static INTBIG us_transgatherlinetotal = 0;
139 static CHAR **us_transgatherlines;
140 static INTBIG us_filetypetrans = 0;
141 static CHAR *us_translation;
142 static INTBIG us_translationsize = 0;
143
144 /* prototypes for local routines */
145 static BOOLEAN us_transloadmessages(CHAR *file, INTBIG *entrycount, INTBIG *untranslatedcount,
146 INTBIG *fuzzycount, void *dia);
147 static BOOLEAN us_transgathermessage(CHAR *line);
148 static STRINGENTRY *us_transfirst(INTBIG choose);
149 static void us_transhowentry(STRINGENTRY *se, void *dia);
150 static void us_transave(CHAR *language, INTBIG platform);
151 static CHAR *us_transgetfiles(CHAR *language, INTBIG platform);
152 static CHAR *us_transquoteit(CHAR *message);
153 static STRINGENTRY *us_translast(INTBIG choose);
154 static BOOLEAN us_transmeetscriteria(STRINGENTRY *se, INTBIG choose);
155 static void us_transmactounix(CHAR *language);
156 static void us_transdumpline(FILE *io, CHAR *line, CHAR *prefix);
157 static INTBIG us_namesamennoamp(CHAR *pt1, CHAR *pt2, INTBIG count);
158 static void us_transvalidate(void);
159
160 /*
161 * Routine called to cleanup memory associated with translation.
162 */
us_freetranslatememory(void)163 void us_freetranslatememory(void)
164 {
165 if (us_translationsize > 0) efree((CHAR *)us_translation);
166 }
167
168 /*
169 * Routine called to translate Electric.
170 */
us_translationdlog(void)171 void us_translationdlog(void)
172 {
173 INTBIG itemno, total, untranslatedcount, fuzzycount, i, j, langcount, len, choose,
174 platform, ptlen, selen, tests, foundcount;
175 BOOLEAN dirty, findenglish, findtranslation;
176 CHAR *language, num[20], *pt, *sept, *par[6], **filelist, intlpath[300], **langlist;
177 REGISTER STRINGENTRY *se, *curse;
178 REGISTER void *dia;
179
180 if (us_filetypetrans == 0)
181 us_filetypetrans = setupfiletype(x_(""), x_("*.*"), MACFSTAG('TEXT'), FALSE, x_("transfile"), _("Translation File"));
182
183 /* examine the translation area */
184 esnprintf(intlpath, 300, x_("%sinternational%s"), el_libdir, DIRSEPSTR);
185 len = estrlen(intlpath);
186 j = filesindirectory(intlpath, &filelist);
187 if (j <= 0)
188 {
189 ttyputerr(_("No folders in '%s' to translate"), intlpath);
190 return;
191 }
192 langlist = (CHAR **)emalloc(j * (sizeof (CHAR *)), el_tempcluster);
193 if (langlist == 0) return;
194 langcount = 0;
195 for(i=0; i<j; i++)
196 {
197 if (filelist[i][0] == '.' || namesame (filelist[i], x_("CVS")) == 0) continue;
198 estrcpy(&intlpath[len], filelist[i]);
199 if (fileexistence(intlpath) != 2) continue;
200 langlist[langcount++] = filelist[i];
201 }
202
203 /* show the dialog */
204 dia = DiaInitDialog(&us_transdialog);
205 if (dia == 0) return;
206 DiaInitTextDialog(dia, DTRN_COMMENTS, DiaNullDlogList, DiaNullDlogItem,
207 DiaNullDlogDone, -1, 0);
208 DiaSetControl(dia, DTRN_FINDENG, 1);
209
210 /* setup the different languages */
211 DiaSetPopup(dia, DTRN_LANGUAGE, langcount, langlist);
212 language = langlist[0];
213
214 /* setup the different types of messages to preview */
215 par[CHOOSEUNTRANS] = _("Untranslated");
216 par[CHOOSEJUSTTRANS] = _("Just translated");
217 par[CHOOSEFUZZY] = _("Fuzzy");
218 par[CHOOSENLFUZZY] = _("No longer fuzzy");
219 par[CHOOSEFIND] = _("Matching");
220 par[CHOOSEALL] = _("All");
221 DiaSetPopup(dia, DTRN_NEXTTYPE, 6, par);
222 choose = CHOOSEUNTRANS;
223 DiaSetPopupEntry(dia, DTRN_NEXTTYPE, choose);
224
225 /* setup the different translation files */
226 par[0] = _("Macintosh");
227 par[1] = _("Windows,UNIX");
228 DiaSetPopup(dia, DTRN_PLATFORM, 2, par);
229 #ifdef MACOS
230 platform = 0;
231 #else
232 platform = 1;
233 #endif
234 DiaSetPopupEntry(dia, DTRN_PLATFORM, platform);
235
236 /* load the selected set of messages */
237 pt = us_transgetfiles(language, platform);
238 if (us_transloadmessages(pt, &total, &untranslatedcount, &fuzzycount, dia))
239 {
240 DiaDoneDialog(dia);
241 return;
242 }
243 curse = us_transfirst(choose);
244 us_transhowentry(curse, dia);
245
246 /* run the dialog */
247 dirty = FALSE;
248 for(;;)
249 {
250 itemno = DiaNextHit(dia);
251 if (itemno == DTRN_DONE)
252 {
253 if (dirty)
254 {
255 i = us_noyesdlog(_("Translations have changed. Quit without saving?"), par);
256 if (i == 0) break;
257 if (namesame(par[0], x_("no")) == 0) continue;
258 }
259 break;
260 }
261 if (itemno == DTRN_VALIDATE)
262 {
263 us_transvalidate();
264 continue;
265 }
266 if (itemno == DTRN_FINDENG || itemno == DTRN_FINDTRN)
267 {
268 DiaSetControl(dia, itemno, 1 - DiaGetControl(dia, itemno));
269 continue;
270 }
271 if (itemno == DTRN_FINDBUT)
272 {
273 DiaSetPopupEntry(dia, DTRN_NEXTTYPE, CHOOSEFIND);
274 itemno = DTRN_NEXTTYPE;
275 /* fall into next test */
276 }
277 if (itemno == DTRN_NEXTTYPE)
278 {
279 choose = DiaGetPopupEntry(dia, DTRN_NEXTTYPE);
280 if (choose == CHOOSEFIND)
281 {
282 /* do the search and mark strings that match */
283 if (DiaGetControl(dia, DTRN_FINDENG) != 0) findenglish = TRUE; else
284 findenglish = FALSE;
285 if (DiaGetControl(dia, DTRN_FINDTRN) != 0) findtranslation = TRUE; else
286 findtranslation = FALSE;
287 pt = DiaGetText(dia, DTRN_FINDSTR);
288 ptlen = estrlen(pt);
289 foundcount = 0;
290 for(se = us_transfirststringentry; se != NOSTRINGENTRY; se = se->nextstringentry)
291 {
292 se->flags &= ~MATCHES;
293 if (findenglish && se->english != 0)
294 {
295 sept = se->english;
296 selen = estrlen(sept);
297 tests = selen - ptlen + 1;
298 for(i=0; i<tests; i++)
299 if (us_namesamennoamp(pt, sept++, ptlen) == 0) break;
300 if (i < tests)
301 {
302 se->flags |= MATCHES;
303 foundcount++;
304 continue;
305 }
306 }
307 if (findtranslation && se->translated != 0)
308 {
309 sept = se->translated;
310 selen = estrlen(sept);
311 tests = selen - ptlen + 1;
312 for(i=0; i<tests; i++)
313 if (namesamen(pt, sept++, ptlen) == 0) break;
314 if (i < tests)
315 {
316 se->flags |= MATCHES;
317 foundcount++;
318 }
319 }
320 }
321 esnprintf(num, 20, x_("%ld"), foundcount);
322 DiaSetText(dia, DTRN_FOUNDSTR, num);
323 } else DiaSetText(dia, DTRN_FOUNDSTR, x_(""));
324 curse = us_transfirst(choose);
325 us_transhowentry(curse, dia);
326 continue;
327 }
328 if (itemno == DTRN_PLATFORM)
329 {
330 i = DiaGetPopupEntry(dia, DTRN_PLATFORM);
331 if (i == platform) continue;
332 if (dirty)
333 {
334 i = us_noyesdlog(_("Translations have changed. Change languages without saving?"), par);
335 if (i == 0) break;
336 if (namesame(par[0], x_("no")) == 0) continue;
337 }
338
339 pt = us_transgetfiles(language, i);
340 if (us_transloadmessages(pt, &total, &untranslatedcount, &fuzzycount, dia))
341 continue;
342
343 platform = i;
344 curse = us_transfirst(choose);
345 us_transhowentry(curse, dia);
346 dirty = FALSE;
347 continue;
348 }
349 if (itemno == DTRN_LANGUAGE)
350 {
351 i = DiaGetPopupEntry(dia, DTRN_LANGUAGE);
352 if (estrcmp(langlist[i], language) == 0) continue;
353 if (dirty)
354 {
355 i = us_noyesdlog(_("Translations have changed. Change languages without saving?"), par);
356 if (i == 0) break;
357 if (namesame(par[0], x_("no")) == 0) continue;
358 }
359
360 pt = us_transgetfiles(langlist[i], platform);
361 if (us_transloadmessages(pt, &total, &untranslatedcount, &fuzzycount, dia))
362 continue;
363
364 language = langlist[i];
365 curse = us_transfirst(choose);
366 us_transhowentry(curse, dia);
367 dirty = FALSE;
368 continue;
369 }
370 if (itemno == DTRN_SAVE)
371 {
372 us_transave(language, platform);
373 dirty = FALSE;
374 continue;
375 }
376 if (itemno == DTRN_MACTOUNIX)
377 {
378 if (dirty)
379 {
380 DiaMessageInDialog(_("Must save before translating files"));
381 continue;
382 }
383 us_transmactounix(language);
384 continue;
385 }
386 if (itemno == DTRN_UNIXTOMAC)
387 {
388 if (dirty)
389 {
390 DiaMessageInDialog(_("Must save before translating files"));
391 continue;
392 }
393 DiaMessageInDialog(x_("Can't yet"));
394 continue;
395 }
396 if (itemno == DTRN_NEXT)
397 {
398 if (curse == NOSTRINGENTRY) curse = us_transfirst(choose); else
399 {
400 for(se = curse->nextstringentry; se != NOSTRINGENTRY; se = se->nextstringentry)
401 {
402 if (us_transmeetscriteria(se, choose)) break;
403 }
404 curse = se;
405 }
406 us_transhowentry(curse, dia);
407 continue;
408 }
409 if (itemno == DTRN_PREV)
410 {
411 if (curse == NOSTRINGENTRY) curse = us_translast(choose); else
412 {
413 for(se = curse->prevstringentry; se != NOSTRINGENTRY; se = se->prevstringentry)
414 {
415 if (us_transmeetscriteria(se, choose)) break;
416 }
417 curse = se;
418 }
419 us_transhowentry(curse, dia);
420 continue;
421 }
422 if (itemno == DTRN_FIRST)
423 {
424 curse = us_transfirst(choose);
425 us_transhowentry(curse, dia);
426 continue;
427 }
428 if (itemno == DTRN_ISFUZZY)
429 {
430 if ((curse->flags&FUZZY) == 0) continue;
431 i = 1 - DiaGetControl(dia, DTRN_ISFUZZY);
432 DiaSetControl(dia, DTRN_ISFUZZY, i);
433 if (i == 0)
434 {
435 curse->flags |= WASFUZZY;
436 fuzzycount--;
437 } else
438 {
439 curse->flags &= ~WASFUZZY;
440 fuzzycount++;
441 }
442 esnprintf(num, 20, x_("%ld"), fuzzycount);
443 DiaSetText(dia, DTRN_FUZSTR, num);
444 dirty = TRUE;
445 continue;
446 }
447 if (itemno == DTRN_FOREIGN)
448 {
449 if (curse == NOSTRINGENTRY) continue;
450 pt = DiaGetText(dia, DTRN_FOREIGN);
451 if (curse->translated == 0)
452 {
453 if (*pt == 0) continue;
454 } else
455 {
456 if (estrcmp(pt, curse->translated) == 0) continue;
457 }
458
459 if (curse->translated == 0)
460 {
461 untranslatedcount--;
462 esnprintf(num, 20, x_("%ld"), untranslatedcount);
463 DiaSetText(dia, DTRN_UNTSTR, num);
464 }
465 if ((curse->flags & FUZZY) != 0)
466 {
467 fuzzycount--;
468 esnprintf(num, 20, x_("%ld"), fuzzycount);
469 DiaSetText(dia, DTRN_FUZSTR, num);
470 DiaSetControl(dia, DTRN_ISFUZZY, 0);
471 if ((curse->flags&FUZZY) != 0) curse->flags |= WASFUZZY;
472 }
473 if (curse->translated != 0) efree((CHAR *)curse->translated);
474 (void)allocstring(&curse->translated, pt, us_tool->cluster);
475 dirty = TRUE;
476 continue;
477 }
478 }
479 DiaDoneDialog(dia);
480 }
481
us_transhowentry(STRINGENTRY * se,void * dia)482 void us_transhowentry(STRINGENTRY *se, void *dia)
483 {
484 CHAR line[100];
485 REGISTER INTBIG whichone, i;
486 BOOLEAN matching;
487 REGISTER STRINGENTRY *ose;
488
489 DiaLoadTextDialog(dia, DTRN_COMMENTS, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, -1);
490 DiaSetControl(dia, DTRN_ISFUZZY, 0);
491 if (se == NOSTRINGENTRY)
492 {
493 DiaSetText(dia, DTRN_ENGLISH, x_(""));
494 DiaSetText(dia, DTRN_FOREIGN, x_(""));
495 DiaSetText(dia, DTRN_MSGID, _("No strings left"));
496 return;
497 }
498 whichone = 0;
499 if (DiaGetPopupEntry(dia, DTRN_NEXTTYPE) == CHOOSEFIND) matching = TRUE; else
500 matching = FALSE;
501 for(ose = us_transfirststringentry; ose != NOSTRINGENTRY; ose = ose->nextstringentry)
502 {
503 if (ose->english == 0) continue;
504 if (matching)
505 {
506 if ((ose->flags&MATCHES) != 0) whichone++;
507 } else
508 {
509 if ((se->flags&FUZZY) != 0)
510 {
511 if ((ose->flags&FUZZY) != 0) whichone++;
512 } else
513 {
514 if (ose->translated == 0) whichone++;
515 }
516 }
517 if (ose == se) break;
518 }
519 if (matching)
520 {
521 esnprintf(line, 100, _("String %ld (matched string %ld)"), se->index, whichone);
522 } else
523 {
524 if ((se->flags&FUZZY) != 0)
525 {
526 if ((se->flags&WASFUZZY) != 0)
527 esnprintf(line, 100, _("String %ld (was fuzzy)"), se->index); else
528 esnprintf(line, 100, _("String %ld (fuzzy string %ld)"), se->index, whichone);
529 } else if (se->translated == 0)
530 {
531 esnprintf(line, 100, _("String %ld (untranslated string %ld)"), se->index, whichone);
532 } else if ((se->flags&THISTIME) != 0)
533 {
534 esnprintf(line, 100, _("String %ld (just translated)"), se->index);
535 } else
536 {
537 esnprintf(line, 100, _("String %ld (already translated)"), se->index);
538 }
539 }
540 DiaSetText(dia, DTRN_MSGID, line);
541 if (se->english == 0) DiaSetText(dia, DTRN_ENGLISH, x_("")); else
542 DiaSetText(dia, DTRN_ENGLISH, se->english);
543 if (se->translated == 0) DiaSetText(dia, -DTRN_FOREIGN, x_("")); else
544 DiaSetText(dia, -DTRN_FOREIGN, se->translated);
545 if ((se->flags&(FUZZY|WASFUZZY)) == FUZZY) DiaSetControl(dia, DTRN_ISFUZZY, 1);
546 for(i=0; i<se->headerlinecount; i++)
547 DiaStuffLine(dia, DTRN_COMMENTS, se->headerlines[i]);
548 DiaSelectLine(dia, DTRN_COMMENTS, -1);
549 }
550
us_transfirst(INTBIG choose)551 STRINGENTRY *us_transfirst(INTBIG choose)
552 {
553 REGISTER STRINGENTRY *se;
554
555 for(se = us_transfirststringentry; se != NOSTRINGENTRY; se = se->nextstringentry)
556 {
557 if (us_transmeetscriteria(se, choose)) return(se);
558 }
559 return(NOSTRINGENTRY);
560 }
561
us_translast(INTBIG choose)562 STRINGENTRY *us_translast(INTBIG choose)
563 {
564 REGISTER STRINGENTRY *se, *lastse;
565
566 for(se = us_transfirststringentry; se != NOSTRINGENTRY; se = se->nextstringentry)
567 lastse = se;
568 for(se = lastse; se != NOSTRINGENTRY; se = se->prevstringentry)
569 {
570 if (us_transmeetscriteria(se, choose)) return(se);
571 }
572 return(NOSTRINGENTRY);
573 }
574
us_transmeetscriteria(STRINGENTRY * se,INTBIG choose)575 BOOLEAN us_transmeetscriteria(STRINGENTRY *se, INTBIG choose)
576 {
577 if (se->english == 0) return(FALSE);
578 switch (choose)
579 {
580 case CHOOSEUNTRANS:
581 if (se->translated == 0) return(TRUE);
582 break;
583 case CHOOSEJUSTTRANS:
584 if (se->translated != 0 &&
585 (se->flags&(FUZZY|WASFUZZY|THISTIME)) == THISTIME) return(TRUE);
586 break;
587 case CHOOSEFUZZY:
588 if ((se->flags&(FUZZY|WASFUZZY)) == FUZZY) return(TRUE);
589 break;
590 case CHOOSENLFUZZY:
591 if ((se->flags&WASFUZZY) != 0) return(TRUE);
592 break;
593 case CHOOSEFIND:
594 if ((se->flags&MATCHES) != 0) return(TRUE);
595 break;
596 case CHOOSEALL:
597 return(TRUE);
598 }
599 return(FALSE);
600 }
601
us_transloadmessages(CHAR * file,INTBIG * entrycount,INTBIG * untranslatedcount,INTBIG * fuzzycount,void * dia)602 BOOLEAN us_transloadmessages(CHAR *file, INTBIG *entrycount, INTBIG *untranslatedcount,
603 INTBIG *fuzzycount, void *dia)
604 {
605 REGISTER FILE *io;
606 REGISTER INTBIG i, j, eof, inenglish, endchr, haveline, index, lineno;
607 REGISTER CHAR *pt, *ptr;
608 CHAR line[500], build[700], *truename;
609 REGISTER STRINGENTRY *se, *lastse;
610
611 io = xopen(file, us_filetypetrans, 0, &truename);
612 if (io == 0)
613 {
614 ttyputmsg(_("Cannot find: %s"), file);
615 return(TRUE);
616 }
617 lineno = 0;
618
619 /* gather the header lines */
620 us_transgatherlinecount = 0;
621 for(;;)
622 {
623 if (xfgets(line, 500, io)) break;
624 lineno++;
625 if (line[0] == 0) break;
626 if (us_transgathermessage(line)) return(TRUE);
627 }
628 us_transheaderlinecount = us_transgatherlinecount;
629 us_transheaderlines = (CHAR **)emalloc(us_transheaderlinecount * (sizeof (CHAR *)), us_tool->cluster);
630 if (us_transheaderlines == 0) return(TRUE);
631 for(i=0; i<us_transheaderlinecount; i++)
632 {
633 us_transheaderlines[i] = us_transgatherlines[i];
634 us_transgatherlines[i] = 0;
635 }
636
637 /* now gather the rest */
638 lastse = NOSTRINGENTRY;
639 us_transfirststringentry = NOSTRINGENTRY;
640 index = 1;
641 eof = 0;
642 for(;;)
643 {
644 /* gather comment lines */
645 us_transgatherlinecount = 0;
646 for(;;)
647 {
648 if (xfgets(line, 500, io)) { eof = 1; break; }
649 lineno++;
650 if (line[0] != '#') break;
651 if (us_transgathermessage(line)) return(TRUE);
652 }
653 if (us_transgatherlinecount == 0 && eof != 0) break;
654
655 /* create a new translation block */
656 se = (STRINGENTRY *)emalloc(sizeof (STRINGENTRY), us_tool->cluster);
657 if (se == 0) return(TRUE);
658
659 /* look for flags in comment lines */
660 se->flags = 0;
661 for(i=0; i<us_transgatherlinecount; i++)
662 {
663 if (us_transgatherlines[i][0] == '#' && us_transgatherlines[i][1] == ',')
664 {
665 pt = &us_transgatherlines[i][1];
666 while (*pt != 0)
667 {
668 if (estrncmp(pt, x_(", c-format"), 10) == 0)
669 {
670 se->flags |= CFORMAT;
671 pt += 10;
672 continue;
673 }
674 if (estrncmp(pt, x_(", fuzzy"), 7) == 0)
675 {
676 se->flags |= FUZZY;
677 pt += 7;
678 continue;
679 }
680 ttyputmsg(_("Unknown flags on line %ld: '%s'"), lineno, us_transgatherlines[i]);
681 break;
682 }
683 for(j=i; j<us_transgatherlinecount-1; j++)
684 us_transgatherlines[j] = us_transgatherlines[j+1];
685 us_transgatherlinecount--;
686 i--;
687 }
688 }
689
690 /* store the comment lines */
691 se->headerlinecount = us_transgatherlinecount;
692 se->headerlines = (CHAR **)emalloc(se->headerlinecount * (sizeof (CHAR *)), us_tool->cluster);
693 if (se->headerlines == 0) return(TRUE);
694 for(i=0; i<us_transgatherlinecount; i++)
695 {
696 se->headerlines[i] = us_transgatherlines[i];
697 us_transgatherlines[i] = 0;
698 }
699
700 /* link it in */
701 if (lastse == NOSTRINGENTRY) us_transfirststringentry = se; else
702 lastse->nextstringentry = se;
703 se->nextstringentry = NOSTRINGENTRY;
704 se->prevstringentry = lastse;
705 lastse = se;
706
707 /* other initialization */
708 se->index = index++;
709 se->english = 0;
710 se->translated = 0;
711
712 /* get the strings */
713 if (eof != 0) break;
714 inenglish = 1;
715 haveline = 1;
716 for(;;)
717 {
718 if (haveline == 0)
719 {
720 if (xfgets(line, 500, io)) { eof = 1; break; }
721 lineno++;
722 } else haveline = 0;
723 if (line[0] == 0) break;
724 pt = line;
725 if (estrncmp(pt, x_("msgid "), 6) == 0)
726 {
727 inenglish = 1;
728 pt += 6;
729 } else if (estrncmp(pt, x_("msgstr "), 7) == 0)
730 {
731 inenglish = 0;
732 pt += 7;
733 }
734 if (*pt == '"') pt++;
735 endchr = estrlen(pt) - 1;
736 if (pt[endchr] == '"') pt[endchr] = 0;
737 if (*pt == 0) continue;
738
739 /* remove quoted quotes */
740 for(ptr = pt; *ptr != 0; ptr++)
741 {
742 if (*ptr != '\\') continue;
743 if (ptr[1] != '"') continue;
744 estrcpy(ptr, &ptr[1]);
745 }
746
747 if (inenglish != 0)
748 {
749 build[0] = 0;
750 if (se->english != 0)
751 {
752 estrcpy(build, se->english);
753 efree((CHAR *)se->english);
754 }
755 estrcat(build, pt);
756 (void)allocstring(&se->english, build, us_tool->cluster);
757 } else
758 {
759 build[0] = 0;
760 if (se->translated != 0)
761 {
762 estrcpy(build, se->translated);
763 efree((CHAR *)se->translated);
764 }
765 estrcat(build, pt);
766 (void)allocstring(&se->translated, build, us_tool->cluster);
767 }
768 }
769 }
770 xclose(io);
771
772 /* report information about this translation */
773 *entrycount = *untranslatedcount = *fuzzycount = 0;
774 for(se = us_transfirststringentry; se != NOSTRINGENTRY; se = se->nextstringentry)
775 {
776 if (se->english == 0) continue;
777 (*entrycount)++;
778 if (se->translated == 0)
779 {
780 (*untranslatedcount)++;
781 se->flags |= THISTIME;
782 } else if ((se->flags&FUZZY) != 0)
783 {
784 (*fuzzycount)++;
785 se->flags |= THISTIME;
786 }
787 }
788 esnprintf(line, 500, x_("%ld"), *entrycount);
789 DiaSetText(dia, DTRN_TOTSTR, line);
790 esnprintf(line, 500, x_("%ld"), *untranslatedcount);
791 DiaSetText(dia, DTRN_UNTSTR, line);
792 esnprintf(line, 500, x_("%ld"), *fuzzycount);
793 DiaSetText(dia, DTRN_FUZSTR, line);
794 return(FALSE);
795 }
796
us_transgathermessage(CHAR * line)797 BOOLEAN us_transgathermessage(CHAR *line)
798 {
799 REGISTER INTBIG newtotal, i;
800 REGISTER CHAR **newlines;
801
802 if (us_transgatherlinecount >= us_transgatherlinetotal)
803 {
804 newtotal = us_transgatherlinetotal * 2;
805 if (us_transgatherlinecount >= newtotal)
806 newtotal = us_transgatherlinecount + 30;
807 newlines = (CHAR **)emalloc(newtotal * (sizeof (CHAR *)), us_tool->cluster);
808 if (newlines == 0) return(TRUE);
809 for(i=0; i<us_transgatherlinecount; i++)
810 newlines[i] = us_transgatherlines[i];
811 for(i=us_transgatherlinecount; i<newtotal; i++)
812 newlines[i] = 0;
813 if (us_transgatherlinetotal > 0)
814 efree((CHAR *)us_transgatherlines);
815 us_transgatherlines = newlines;
816 us_transgatherlinetotal = newtotal;
817 }
818 if (us_transgatherlines[us_transgatherlinecount] != 0)
819 efree((CHAR *)us_transgatherlines[us_transgatherlinecount]);
820 if (allocstring(&us_transgatherlines[us_transgatherlinecount], line,
821 us_tool->cluster)) return(TRUE);
822 us_transgatherlinecount++;
823 return(FALSE);
824 }
825
us_transave(CHAR * language,INTBIG platform)826 void us_transave(CHAR *language, INTBIG platform)
827 {
828 REGISTER STRINGENTRY *se;
829 REGISTER INTBIG i;
830 INTBIG year, month, mday, hour, minute, second;
831 REGISTER time_t olddate;
832 CHAR filename[300], rename[300], datesuffix[100], *truename;
833 FILE *io;
834 REGISTER void *infstr;
835
836 /* rename the old file */
837 estrcpy(filename, us_transgetfiles(language, platform));
838 olddate = filedate(filename);
839 parsetime(olddate, &year, &month, &mday, &hour, &minute, &second);
840 for(i=0; i<1000; i++)
841 {
842 if (i == 0) esnprintf(datesuffix, 100, x_("-%ld-%ld-%ld"), year, month+1, mday); else
843 esnprintf(datesuffix, 100, x_("-%ld-%ld-%ld--%ld"), year, month+1, mday, i);
844 (void)estrcpy(rename, filename);
845 (void)estrcat(rename, datesuffix);
846 if (fileexistence(rename) == 0) break;
847 }
848 if (erename(filename, rename) != 0)
849 ttyputerr(_("Could not rename file '%s' to '%s'"), filename, rename);
850
851 /* create the new file */
852 io = xcreate(filename, us_filetypetrans, 0, &truename);
853 if (io == 0)
854 {
855 ttyputerr(_("Cannot write %s"), filename);
856 return;
857 }
858
859 /* write the header lines */
860 for(i=0; i<us_transheaderlinecount; i++)
861 efprintf(io, x_("%s\n"), us_transheaderlines[i]);
862
863 /* write the translations */
864 for(se = us_transfirststringentry; se != NOSTRINGENTRY; se = se->nextstringentry)
865 {
866 efprintf(io, x_("\n"));
867 for(i=0; i<se->headerlinecount; i++)
868 efprintf(io, x_("%s\n"), se->headerlines[i]);
869 if ((se->flags&(FUZZY|WASFUZZY)) == FUZZY ||
870 (se->flags&CFORMAT) != 0)
871 {
872 infstr = initinfstr();
873 addstringtoinfstr(infstr, x_("#"));
874 if ((se->flags&(FUZZY|WASFUZZY)) == FUZZY) addstringtoinfstr(infstr, x_(", fuzzy"));
875 if ((se->flags&CFORMAT) != 0) addstringtoinfstr(infstr, x_(", c-format"));
876 efprintf(io, x_("%s\n"), returninfstr(infstr));
877 }
878 if (se->english != 0)
879 us_transdumpline(io, us_transquoteit(se->english), x_("msgid"));
880 if (se->translated != 0)
881 us_transdumpline(io, us_transquoteit(se->translated), x_("msgstr"));
882 }
883 xclose(io);
884 }
885
886 #define MAXLEN 80
887
us_transdumpline(FILE * io,CHAR * line,CHAR * prefix)888 void us_transdumpline(FILE *io, CHAR *line, CHAR *prefix)
889 {
890 REGISTER INTBIG len, preflen, i;
891 CHAR save;
892
893 preflen = estrlen(prefix) + 3;
894 len = estrlen(line);
895 if (len+preflen <= MAXLEN)
896 {
897 efprintf(io, x_("%s \"%s\"\n"), prefix, line);
898 return;
899 }
900 efprintf(io, x_("%s \"\"\n"), prefix);
901 while (len > MAXLEN-4)
902 {
903 i = MAXLEN-4;
904 while (i > 0 && line[i] != ' ') i--;
905 if (i == 0) i = MAXLEN-4;
906 i++;
907 save = line[i];
908 line[i] = 0;
909 efprintf(io, x_("\"%s\"\n"), line);
910 line[i] = save;
911 line = &line[i];
912 len = estrlen(line);
913 }
914 if (len > 0)
915 efprintf(io, x_("\"%s\"\n"), line);
916 }
917
918 /*
919 * Routine to do a string comparison between "pt1" and "pt2" up to "count" characters.
920 * Ignores "&" characters.
921 */
us_namesamennoamp(CHAR * pt1,CHAR * pt2,INTBIG count)922 INTBIG us_namesamennoamp(CHAR *pt1, CHAR *pt2, INTBIG count)
923 {
924 REGISTER INTBIG c1, c2, i;
925
926 for(i=0; i<count; i++)
927 {
928 while (*pt1 == '&') pt1++;
929 while (*pt2 == '&') pt2++;
930 c1 = tolower(*pt1++ & 0377);
931 c2 = tolower(*pt2++ & 0377);
932 if (c1 != c2) return(c1-c2);
933 if (c1 == 0) break;
934 }
935 return(0);
936 }
937
us_transquoteit(CHAR * message)938 CHAR *us_transquoteit(CHAR *message)
939 {
940 REGISTER CHAR *pt;
941 REGISTER INTBIG j;
942 static CHAR result[500];
943
944 j = 0;
945 for(pt = message; *pt != 0; pt++)
946 {
947 if (*pt == '"') result[j++] = '\\';
948 result[j++] = *pt;
949 }
950 result[j] = 0;
951 return(result);
952 }
953
us_transgetfiles(CHAR * language,INTBIG platform)954 CHAR *us_transgetfiles(CHAR *language, INTBIG platform)
955 {
956 REGISTER CHAR *onmac;
957 REGISTER void *infstr;
958
959 if (platform == 0) onmac = x_("mac"); else
960 onmac = x_("");
961 infstr = initinfstr();
962 addstringtoinfstr(infstr, el_libdir);
963 formatinfstr(infstr, x_("international%s%s%sLC_MESSAGES%s%selectric.%s"),
964 DIRSEPSTR, language, DIRSEPSTR, DIRSEPSTR, onmac, language);
965 return(returninfstr(infstr));
966 }
967
us_transvalidate(void)968 void us_transvalidate(void)
969 {
970 REGISTER STRINGENTRY *se;
971 REGISTER INTBIG i;
972 REGISTER CHAR *pt;
973
974 for(se = us_transfirststringentry; se != NOSTRINGENTRY; se = se->nextstringentry)
975 {
976 if (se->translated == 0) continue;
977
978 /* see if the use of elipses at the end matches */
979 i = estrlen(se->translated);
980 if (i > 3 && estrcmp(&se->translated[i-3], x_("...")) == 0)
981 {
982 /* translation has ellipses: make sure original does, too */
983 i = estrlen(se->english);
984 if (i < 3 || estrcmp(&se->english[i-3], x_("...")) != 0)
985 {
986 ttyputmsg(x_("'%s' should not have '...' in translation"), se->english);
987 }
988 } else
989 {
990 /* translation does not have ellipses: make sure original doesn't either */
991 i = estrlen(se->english);
992 if (i > 3 && estrcmp(&se->english[i-3], x_("...")) == 0)
993 {
994 ttyputmsg(x_("'%s' must have '...' in translation"), se->english);
995 }
996 }
997
998 /* see if translation includes "&" erroneously */
999 for(pt = se->translated; *pt != 0; pt++)
1000 if (*pt == '&') break;
1001 if (*pt != 0)
1002 {
1003 /* see if this comes from the "lib" directory */
1004 for(i=0; i<se->headerlinecount; i++)
1005 {
1006 pt = se->headerlines[i];
1007 while (*pt == '#' || *pt == ' ') pt++;
1008 if (estrncmp(pt, x_("lib"), 3) == 0) break;
1009 }
1010 if (i < se->headerlinecount)
1011 {
1012 /* this should not have "&" */
1013 ttyputmsg(x_("'%s' should not have '&' in translation"), se->english);
1014 }
1015 }
1016 }
1017 }
1018
us_transmactounix(CHAR * language)1019 void us_transmactounix(CHAR *language)
1020 {
1021 REGISTER CHAR *macfile, *unixfile;
1022 CHAR buf[1000], *dummy;
1023 REGISTER INTBIG lineno;
1024 FILE *in, *out;
1025
1026 macfile = us_transgetfiles(language, 0);
1027 in = xopen(macfile, el_filetypetext, 0, &dummy);
1028 if (in == 0)
1029 {
1030 DiaMessageInDialog(x_("Cannot read %s"), macfile);
1031 return;
1032 }
1033 unixfile = us_transgetfiles(language, 1);
1034 out = xcreate(unixfile, el_filetypetext, 0, 0);
1035 if (out == 0)
1036 {
1037 DiaMessageInDialog(x_("Cannot write %s"), unixfile);
1038 return;
1039 }
1040 lineno = 0;
1041 for(;;)
1042 {
1043 if (xfgets(buf, 999, in)) break;
1044 lineno++;
1045 buf[estrlen(buf)] = 0;
1046 if (estrncmp(buf, x_("msgstr \""), 8) != 0)
1047 {
1048 efprintf(out, x_("%s\n"), buf);
1049 continue;
1050 }
1051
1052 /* found "msgstr", look for strange characters */
1053 estrcpy(&buf[7], us_convertmactoworld(&buf[7]));
1054 efprintf(out, x_("%s\n"), buf);
1055 for(;;)
1056 {
1057 if (xfgets(buf, 999, in)) break;
1058 lineno++;
1059 buf[estrlen(buf)] = 0;
1060 if (buf[0] == 0)
1061 {
1062 efprintf(out, x_("\n"));
1063 break;
1064 }
1065 estrcpy(buf, us_convertmactoworld(buf));
1066 efprintf(out, x_("%s\n"), buf);
1067 }
1068 }
1069 fclose(in);
1070 fclose(out);
1071 }
1072
1073 /*
1074 * WINDOWS MACINTOSH WINDOWS MACINTOSH
1075 * � 0xE0 0x88 � 0xC0 0xCB
1076 * � 0xE1 0x87 � 0xC1 none
1077 * � 0xE2 0x89 � 0xC2 none
1078 * � 0xE3 0x8B � 0xC3 0xCC
1079 * � 0xE4 0x8A � 0xC4 0x80
1080 * � 0xE5 0x8C � 0xC5 0x81
1081 *
1082 * � 0xE8 0x8F � 0xC8 none
1083 * � 0xE9 0x8E � 0xC9 0x83
1084 * � 0xEA 0x90 � 0xCA none
1085 * � 0xEB 0x91 � 0xCB none
1086 *
1087 * � 0xEC 0x93 � 0xCC none
1088 * � 0xED 0x92 � 0xCD none
1089 * � 0xEE 0x94 � 0xCE none
1090 * � 0xEF 0x95 � 0xCF none
1091 *
1092 * � 0xF2 0x98 � 0xD2 none
1093 * � 0xF3 0x97 � 0xD3 none
1094 * � 0xF4 0x99 � 0xD4 none
1095 * � 0xF5 0x9B � 0xD5 0xCD
1096 * � 0xF6 0x9A � 0xD6 0x85
1097 *
1098 * � 0xF9 0x9D � 0xD9 none
1099 * � 0xFA 0x9C � 0xDA none
1100 * � 0xFB 0x9E � 0xDB none
1101 * � 0xFC 0x9F � 0xDC 0x86
1102 *
1103 * � 0xE7 0x8D � 0xC7 0x82
1104 * � 0xE6 0xBE � 0xC6 0xAE
1105 * � 0xF1 0x96 � 0xD1 0x84
1106 * oe none 0xCF OE none 0xCE
1107 */
1108 typedef struct
1109 {
1110 int origchar;
1111 int newchar;
1112 int secondchar;
1113 } TRANSLATE;
1114
1115 TRANSLATE us_trans_mactoworld[] =
1116 {
1117 {0x80, 0xC4, 0}, /* "�" */
1118 {0x81, 0xC5, 0}, /* "�" */
1119 {0x82, 0xC7, 0}, /* "�" */
1120 {0x83, 0xC9, 0}, /* "�" */
1121 {0x84, 0xD1, 0}, /* "�" */
1122 {0x85, 0xD6, 0}, /* "�" */
1123 {0x86, 0xDC, 0}, /* "�" */
1124 {0x87, 0xE1, 0}, /* "�" */
1125 {0x88, 0xE0, 0}, /* "�" */
1126 {0x89, 0xE2, 0}, /* "�" */
1127 {0x8A, 0xE4, 0}, /* "�" */
1128 {0x8B, 0xE3, 0}, /* "�" */
1129 {0x8C, 0xE5, 0}, /* "�" */
1130 {0x8D, 0xE7, 0}, /* "�" */
1131 {0x8E, 0xE9, 0}, /* "�" */
1132 {0x8F, 0xE8, 0}, /* "�" */
1133 {0x90, 0xEA, 0}, /* "�" */
1134 {0x91, 0xEB, 0}, /* "�" */
1135 {0x92, 0xED, 0}, /* "�" */
1136 {0x93, 0xEC, 0}, /* "�" */
1137 {0x94, 0xEE, 0}, /* "�" */
1138 {0x95, 0xEF, 0}, /* "�" */
1139 {0x96, 0xF1, 0}, /* "�" */
1140 {0x97, 0xF3, 0}, /* "�" */
1141 {0x98, 0xF2, 0}, /* "�" */
1142 {0x99, 0xF4, 0}, /* "�" */
1143 {0x9A, 0xF6, 0}, /* "�" */
1144 {0x9B, 0xF5, 0}, /* "�" */
1145 {0x9C, 0xFA, 0}, /* "�" */
1146 {0x9D, 0xF9, 0}, /* "�" */
1147 {0x9E, 0xFB, 0}, /* "�" */
1148 {0x9F, 0xFC, 0}, /* "�" */
1149
1150 {0xAE, 0xC6, 0}, /* "�" */
1151 {0xBE, 0xE6, 0}, /* "�" */
1152 {0xCB, 0xC0, 0}, /* "�" */
1153 {0xCC, 0xC3, 0}, /* "�" */
1154 {0xCD, 0xD5, 0}, /* "�" */
1155 {0xCE, 'O', 'E'}, /* "OE" */
1156 {0xCF, 'o', 'e'}, /* "oe" */
1157 {0,0,0}
1158 };
1159
1160 /*
1161 * Routine to convert the string "buf" (which is has international characters
1162 * encoded Macintosh-sytle) and return the buffer in international characters
1163 * encoded Windows/UNIX style.
1164 */
us_convertmactoworld(CHAR * buf)1165 CHAR *us_convertmactoworld(CHAR *buf)
1166 {
1167 CHAR *pt;
1168 int i, len, thechar, outchar;
1169
1170 len = estrlen(buf) * 2;
1171 if (len > us_translationsize)
1172 {
1173 if (us_translationsize > 0) efree((CHAR *)us_translation);
1174 us_translation = (CHAR *)emalloc(len * SIZEOFCHAR, us_tool->cluster);
1175 if (us_translation == 0) return(buf);
1176 us_translationsize = len;
1177 }
1178 outchar = 0;
1179 for(pt = buf; *pt != 0; pt++)
1180 {
1181 thechar = *pt & 0xFF;
1182 if (isalnum(thechar) != 0 ||
1183 thechar == '"' || thechar == '!' || thechar == '@' ||
1184 thechar == '#' || thechar == '$' || thechar == '%' ||
1185 thechar == '&' || thechar == '*' || thechar == '(' ||
1186 thechar == ')' || thechar == '-' || thechar == '_' ||
1187 thechar == '=' || thechar == '+' || thechar == '[' ||
1188 thechar == ']' || thechar == '{' || thechar == '}' ||
1189 thechar == '\\' || thechar == '|' || thechar == ':' ||
1190 thechar == ';' || thechar == ',' || thechar == '.' ||
1191 thechar == '<' || thechar == '>' || thechar == '?' ||
1192 thechar == '/' || thechar == '~' || thechar == '\'' ||
1193 thechar == '\n' || thechar == ' ' || thechar == '^')
1194 {
1195 us_translation[outchar++] = *pt;
1196 continue;
1197 }
1198
1199 /* see if it is in the table */
1200 for(i=0; us_trans_mactoworld[i].origchar != 0; i++)
1201 if (thechar == us_trans_mactoworld[i].origchar) break;
1202 if (us_trans_mactoworld[i].origchar != 0)
1203 {
1204 us_translation[outchar++] = us_trans_mactoworld[i].newchar;
1205 if (us_trans_mactoworld[i].secondchar != 0)
1206 us_translation[outchar++] = us_trans_mactoworld[i].secondchar;
1207 continue;
1208 }
1209
1210 /* foreign character found */
1211 us_translation[outchar++] = *pt;
1212 }
1213 us_translation[outchar] = 0;
1214 return(us_translation);
1215 }
1216
us_convertworldtomac(CHAR * buf)1217 CHAR *us_convertworldtomac(CHAR *buf)
1218 {
1219 CHAR *pt;
1220 int i, len, thechar, outchar;
1221
1222 len = estrlen(buf);
1223 if (len > us_translationsize)
1224 {
1225 if (us_translationsize > 0) efree((CHAR *)us_translation);
1226 us_translation = (CHAR *)emalloc(len * SIZEOFCHAR, us_tool->cluster);
1227 if (us_translation == 0) return(buf);
1228 us_translationsize = len;
1229 }
1230 outchar = 0;
1231 for(pt = buf; *pt != 0; pt++)
1232 {
1233 thechar = *pt & 0xFF;
1234 if (isalnum(thechar) != 0 ||
1235 thechar == '"' || thechar == '!' || thechar == '@' ||
1236 thechar == '#' || thechar == '$' || thechar == '%' ||
1237 thechar == '&' || thechar == '*' || thechar == '(' ||
1238 thechar == ')' || thechar == '-' || thechar == '_' ||
1239 thechar == '=' || thechar == '+' || thechar == '[' ||
1240 thechar == ']' || thechar == '{' || thechar == '}' ||
1241 thechar == '\\' || thechar == '|' || thechar == ':' ||
1242 thechar == ';' || thechar == ',' || thechar == '.' ||
1243 thechar == '<' || thechar == '>' || thechar == '?' ||
1244 thechar == '/' || thechar == '~' || thechar == '\'' ||
1245 thechar == '\n' || thechar == ' ' || thechar == '^')
1246 {
1247 us_translation[outchar++] = *pt;
1248 continue;
1249 }
1250
1251 /* see if it is in the table */
1252 for(i=0; us_trans_mactoworld[i].newchar != 0; i++)
1253 if (thechar == us_trans_mactoworld[i].newchar &&
1254 us_trans_mactoworld[i].secondchar == 0) break;
1255 if (us_trans_mactoworld[i].newchar != 0)
1256 {
1257 us_translation[outchar++] = us_trans_mactoworld[i].origchar;
1258 continue;
1259 }
1260
1261 /* foreign character found */
1262 us_translation[outchar++] = *pt;
1263 }
1264 us_translation[outchar] = 0;
1265 return(us_translation);
1266 }
1267