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