1 | /* message.c */ |
---|
2 | |
---|
3 | /* ERRC show diffs to newer version of error.c - most that are left in here aren't relevant */ |
---|
4 | |
---|
5 | /* loosely based on Survex's error.c, but uses SGML entities for accented |
---|
6 | * characters, and is rather more generic */ |
---|
7 | |
---|
8 | /* maps: */ |
---|
9 | |
---|
10 | /* (perfect hash) entity name to &#nnn; code */ |
---|
11 | |
---|
12 | /* (lookup table or switch) &#nnn; code to best rendition in each charset */ |
---|
13 | |
---|
14 | |
---|
15 | /* filename.c split off with filename manipulation stuff */ |
---|
16 | |
---|
17 | |
---|
18 | /* > error.c |
---|
19 | * Fairly general purpose error routines and path handling code |
---|
20 | * Copyright (C) 1993-1997 Olly Betts |
---|
21 | */ |
---|
22 | |
---|
23 | /* |
---|
24 | 1993.01.25 PC Compatibility OKed |
---|
25 | 1993.01.27 print newline before error messages |
---|
26 | 1993.02.17 changed #ifdef RISCOS to #if OS==... |
---|
27 | 1993.02.19 now look for ErrList in dir main exec was in |
---|
28 | for PC ERRLIST -> ERRLIST.TXT |
---|
29 | 1993.02.23 now do exit(EXIT_FAILURE) or exit(EXIT_SUCCESS) |
---|
30 | added guessed UNIX stuff |
---|
31 | 1993.03.12 Major recode to make it less crap. Especially: |
---|
32 | Now copes with *any* undefined message number |
---|
33 | Error file now has spaces, not underscores |
---|
34 | 1993.03.16 Merged 'PathCode.c' with this file. Updates for 'PathCode.c' were: |
---|
35 | >> 1993.02.19 written |
---|
36 | >> 1993.02.23 added guess at UNIX code |
---|
37 | >> 1993.02.24 (W) add (int) cast to suppress warning calculating lenpth |
---|
38 | >> 1993.02.25 Don't look for FNM_SEP_DRV if it's not defined |
---|
39 | 1993.03.18 Added LfFromFnm() |
---|
40 | 1993.03.19 Corrected bug which caused infinite loop for PC text error file |
---|
41 | 1993.04.06 slight fettles and copied fn headers to error.c |
---|
42 | 1993.04.07 Added UsePth() |
---|
43 | #error Don't ... -> #error Do not ... for GCC's happiness |
---|
44 | 1993.04.22 added fopenWithPthAndExt() |
---|
45 | added application name code |
---|
46 | 1993.04.25 added AMIGA version |
---|
47 | 1993.05.05 Slightly more elegant hack than Wook's to solve BC++ stderr bug |
---|
48 | 1993.05.12 (W) added FNTYPE for different DOS memory model proofing (non-ANSI) |
---|
49 | 1993.05.22 (W) removed stderr hack as it is not that simple??? |
---|
50 | improved 'error file not found' reporting |
---|
51 | 1993.05.27 removed commented out #define STDERR ... |
---|
52 | actually improved 'error file not found' et al - personally I do |
---|
53 | *not* regard caverot telling me 'SURVEX: <error message>' as an |
---|
54 | improvement. Mind you, I'm fussy. |
---|
55 | 1993.05.28 added signal catching code |
---|
56 | 1993.05.29 errno printed when signal received |
---|
57 | 1993.06.04 moved #define FNM_SEP_XXX to filelist.h |
---|
58 | added #ifdef SIGSTAK as unix GCC doesn't seem to have it |
---|
59 | 1993.06.05 removed 'superfluous' &'s in signal fns |
---|
60 | signal catcher now uses strerror() |
---|
61 | 1993.06.07 Unix libraries don't have strerror() - so don't use it! |
---|
62 | FNTYPE -> FAR to aid comprehension |
---|
63 | 1993.06.10 in report_sig() only print out errno if non-zero |
---|
64 | 1993.06.12 fixed bug in path&ext code: only added .ext when prepending path |
---|
65 | 1993.06.16 syserr() -> fatal(); osmalloc() added; char* -> sz |
---|
66 | osrealloc() added; osfree() comment added |
---|
67 | 1993.06.28 fixed bug which lost first character of each error message on |
---|
68 | big-endian machines |
---|
69 | fixed fopenWithPthAndExt() to osfree() fnmFull |
---|
70 | 1993.07.19 "common.h" -> "osdepend.h" |
---|
71 | 1993.07.27 changed "error number %d" to "#%d" in output |
---|
72 | 1993.08.10 added '\n' before errors reported in report_sig |
---|
73 | 1993.08.12 added more bomb-proofing |
---|
74 | 1993.08.13 fettled header |
---|
75 | 1993.08.16 added fAbsoluteFnm & fAmbiguousFnm; recoded fopenWithPthAndExt |
---|
76 | RISC OS version of fopenWithPthAndExt copes with "<My$Dir>.File" |
---|
77 | added AddExt; added pfExtUsed arg to fopenWithPthAndExt |
---|
78 | 1993.08.19 ./ in DOS is ambiguous, not absolute |
---|
79 | 1993.09.21 (W)fixed relative paths without preceding .\ for .svc files |
---|
80 | (W)changed DOS fAbsolute() so 'c:here' is returned as ambiguous |
---|
81 | 1993.09.22 (W)changed error functions for more general info line |
---|
82 | (W)added function list |
---|
83 | 1993.09.23 (IH)DOS uses farmalloc,farrealloc,farfree; osmalloc() takes a long |
---|
84 | 1993.10.15 (BP)changed erroneous ifdef MSDOS's to if (OS==MSDOS) |
---|
85 | 1993.10.18 (W)fWarningGiven added |
---|
86 | 1993.10.23 corrected fFALSE to fFalse |
---|
87 | 1993.11.03 changed error routines |
---|
88 | cWarnings rather than fWarningGiven |
---|
89 | fettled a bit |
---|
90 | 1993.11.05 OSSIZE_T added |
---|
91 | fixed problem with pth=="" in fopenWithPthAndExt |
---|
92 | added msg() and msgPerm() |
---|
93 | 1993.11.07 merged out of memory code from osmalloc & osrealloc |
---|
94 | 1993.11.08 added code to deal with quoted messages |
---|
95 | 1993.11.14 fettled |
---|
96 | 1993.11.15 added xosmalloc (returns NULL if malloc fails) |
---|
97 | 1993.11.18 xosrealloc added as macro in error.h |
---|
98 | added calls to fDirectory |
---|
99 | 1993.11.19 added TeX style escape sequences for accents; also ``,'' for " |
---|
100 | 1993.11.20 minor change to '' and `` code |
---|
101 | \/O & \/o now used for slashed Os |
---|
102 | extracted tables to tex.h |
---|
103 | 1993.11.26 moved chOpenQuotes & chCloseQuotes to tex.h |
---|
104 | 1993.11.28 added NO_TEX to turn it off for now |
---|
105 | 1993.11.29 (IH) void * FAR -> void FAR * ; void * FILE -> void FILE * |
---|
106 | use perror in UNIX version |
---|
107 | extracted messages from here too! (except for signal ones) |
---|
108 | 1993.11.30 corrected Wook's ungroks in function list |
---|
109 | error now returns (it was wrong, but limp on); use fatal to abort |
---|
110 | added cErrors |
---|
111 | 1993.12.01 added error_summary() |
---|
112 | most signals tell the user to report them as a bug (autograss?) |
---|
113 | check version of messages.txt file |
---|
114 | 1993.12.08 split off osdepend.c |
---|
115 | 1993.12.09 now makes less explicit reference to OS |
---|
116 | 1993.12.16 farmalloc use controlled by NO_FLATDOS macro |
---|
117 | fixed error bootstrap code problem-ette |
---|
118 | 1993.12.17 wr changed to send to stderr as it writes error info |
---|
119 | 1994.01.05 added missing FAR to fix >128 eqns bug |
---|
120 | and another |
---|
121 | bug-fixed in outofmem |
---|
122 | 1994.03.13 enabled TeX style characters |
---|
123 | will deal with `` and '' even if NO_TEX is defined |
---|
124 | 1994.03.14 altered fopenWithPthAndExt to give filename actually used |
---|
125 | 1994.03.19 signals now reported as `fatal error' since they are |
---|
126 | all error output to do with signals is now sent to stderr |
---|
127 | 1994.03.20 added a putnl() at end of error_summary() |
---|
128 | 1994.03.24 error summary to stderr too |
---|
129 | 1994.04.27 cWarnings and cErrors now static |
---|
130 | 1994.06.03 fixed so SunOS version should cope with DOS error message file |
---|
131 | 1994.06.09 added home directory environmental variable |
---|
132 | 1994.06.18 fixed Norcroft warning |
---|
133 | 1994.06.20 added int argument to warning, error and fatal |
---|
134 | 1994.08.31 added fputnl() |
---|
135 | 1994.09.13 added fix for caverot signals being invisible under RISC OS |
---|
136 | 1994.09.13 removed 'cos it doesn't work |
---|
137 | 1994.09.20 fixed signal handler to longjmp back so it's now truely ANSI |
---|
138 | miscellaneous fettling |
---|
139 | 1994.09.21 rearranged signal handler code to minimize stack use |
---|
140 | 1994.09.22 should now be able to read multi-language message file |
---|
141 | 1994.09.28 xosmalloc is now a macro in error.h |
---|
142 | 1994.10.04 no longer pass NULL for szExt to fopenWithPathAndExt |
---|
143 | 1994.10.05 DEFAULTLANG and szLangVar added |
---|
144 | 1994.10.08 sizeof -> ossizeof |
---|
145 | 1994.11.16 errno.h wanted even if we're not signal handling |
---|
146 | 1994.11.23 UsePth and AddExt now insert a separator if appropriate |
---|
147 | fopenWithPthAndExt now uses UsePth and AddExt |
---|
148 | 1994.12.03 added FNM_SEP_LEV2 |
---|
149 | 1994.12.06 stderr -> STDERR; STDERR #defined to stdout |
---|
150 | 1994.12.10 fopenWithPthAndExt() copes with NULL for pth or ext |
---|
151 | 1995.03.25 added osstrdup |
---|
152 | 1995.06.26 fixed bug with UsePth("",leafname) |
---|
153 | 1995.10.06 commented out some debug code |
---|
154 | 1995.10.11 fixed getline to take a buffer length |
---|
155 | 1996.02.10 pszTable entries can now be NULL, as can szSingTab |
---|
156 | 1996.02.19 fixed 2 sizeof() to ossizeof() |
---|
157 | 1996.03.22 fettled layout |
---|
158 | 1996.05.05 added CDECL |
---|
159 | 1997.01.19 started code to support multiple charsets at once |
---|
160 | 1997.01.22 finished off up charset code (merged in tex.h): |
---|
161 | >1993.11.20 created |
---|
162 | >1993.11.26 moved chOpenQuotes and chCloseQuotes to here too |
---|
163 | >1994.03.13 characters 128-159 translated to \xXX codes to placate compilers |
---|
164 | >1994.03.23 added caveat comment about top-bit-set characters |
---|
165 | >1994.12.03 added -DISO8859_1 to makefile to force iso-8859-1 |
---|
166 | >1995.02.14 changed "char foo[]=" to "char *foo=" |
---|
167 | >1996.02.10 pszTable is now an array of char *, which can be NULL |
---|
168 | > szSingTab can also be NULL |
---|
169 | 1997.06.05 added const |
---|
170 | 1998.03.04 more const |
---|
171 | 1998.03.21 fixed up to compile cleanly on Linux |
---|
172 | */ |
---|
173 | |
---|
174 | /* Beware: This file contains top-bit-set characters (160-255), so be */ |
---|
175 | /* careful of mailers, ascii ftp, etc */ |
---|
176 | |
---|
177 | /* Tables for TeX style accented chars, etc for use with Survex */ |
---|
178 | /* Copyright (C) Olly Betts 1993-1996 */ |
---|
179 | |
---|
180 | /* NB if (as in TeX) \o and \O mean slashed-o and slashed-O, we can't |
---|
181 | * have \oe and \OE for linked-oe and linked-OE without cleverer code. |
---|
182 | * Therefore, I've changed slashed-o and slashed-O to \/o and \/O. |
---|
183 | */ |
---|
184 | |
---|
185 | /* |
---|
186 | Function List |
---|
187 | xosmalloc: malloc, but indirected so we can eg do DOS XMS malloc |
---|
188 | osmalloc: ditto, but traps failure and gives fatal error |
---|
189 | xosrealloc: realloc, but indirected so we can eg do DOS XMS malloc |
---|
190 | osrealloc: ditto, but traps failure and gives fatal error |
---|
191 | osfree: free, but indirected so we can eg do DOS XMS malloc |
---|
192 | report_sig: catches signals and prints explanatory message |
---|
193 | ReadErrorFile: initialisation function - should be called first (ish) |
---|
194 | warning: report warning |
---|
195 | error: report error |
---|
196 | fatal: report fatal error and exit |
---|
197 | fAbsoluteFnm: is fnm definitely absolute? |
---|
198 | fAmbiguousFnm: could fnm be interpreted as both absolute and relative? |
---|
199 | PthFromFnm: extract path from fnm |
---|
200 | LfFromFnm: extract leafname from fnm |
---|
201 | UsePth: concatenate path & leafname |
---|
202 | UseExt: bung an extension on |
---|
203 | fopenWithPthAndExt: |
---|
204 | open file, passing back filename actually used |
---|
205 | safe_fopen: like fopen, but returns NULL for directories under all OS |
---|
206 | */ |
---|
207 | |
---|
208 | #include <stdio.h> |
---|
209 | #include <stdlib.h> |
---|
210 | #include <string.h> |
---|
211 | #include <ctype.h> |
---|
212 | #include <limits.h> |
---|
213 | #include <errno.h> |
---|
214 | |
---|
215 | #include "whichos.h" |
---|
216 | #include "filename.h" |
---|
217 | #include "message.h" |
---|
218 | #include "osdepend.h" |
---|
219 | #include "filelist.h" |
---|
220 | #include "debug.h" |
---|
221 | #include "version.h" |
---|
222 | |
---|
223 | #ifdef HAVE_SIGNAL |
---|
224 | # ifdef HAVE_SETJMP |
---|
225 | # include <setjmp.h> |
---|
226 | static jmp_buf jmpbufSignal; |
---|
227 | # include <signal.h> |
---|
228 | # else |
---|
229 | # undef HAVE_SIGNAL |
---|
230 | # endif |
---|
231 | #endif |
---|
232 | |
---|
233 | /* This is the name of the default language -- set like this so folks can |
---|
234 | * add (for eg) -DDEFAULTLANG="fr" to UFLG in the makefile |
---|
235 | */ |
---|
236 | #ifndef DEFAULTLANG |
---|
237 | # define DEFAULTLANG "en" |
---|
238 | #endif |
---|
239 | |
---|
240 | #define STDERR stdout |
---|
241 | |
---|
242 | /* For funcs which want to be immune from messing around with different |
---|
243 | * calling conventions */ |
---|
244 | #ifndef CDECL |
---|
245 | #define CDECL |
---|
246 | #endif |
---|
247 | |
---|
248 | /* These are English versions of messages which might be needed before the |
---|
249 | * alternative language version has been read from the message file. |
---|
250 | */ |
---|
251 | static const char * ergBootstrap[]={ |
---|
252 | "", |
---|
253 | "Out of memory (couldn't find %ul bytes).\n", |
---|
254 | "\nFatal error from %s: ", |
---|
255 | "\nError from %s: ", |
---|
256 | "\nWarning from %s: ", |
---|
257 | "Message file has incorrect format\n", /* was "Error message file ..." */ |
---|
258 | "Negative error numbers are not allowed\n", |
---|
259 | NULL /* NULL marks end of list */ |
---|
260 | }; |
---|
261 | |
---|
262 | static const char **erg = ergBootstrap; |
---|
263 | static int enMac = 32; /* Initially, grows automatically */ |
---|
264 | static const char *szBadEn = "???"; |
---|
265 | |
---|
266 | static int cWarnings = 0; /* keep track of how many warnings we've given */ |
---|
267 | static int cErrors = 0; /* and how many (non-fatal) errors */ |
---|
268 | |
---|
269 | extern int error_summary(void) { |
---|
270 | fprintf(STDERR,msg(16),cWarnings,cErrors); |
---|
271 | fputnl(STDERR); |
---|
272 | return ( cErrors ? EXIT_FAILURE : EXIT_SUCCESS ); |
---|
273 | } |
---|
274 | |
---|
275 | /* in case osmalloc() fails before szAppNameCopy is set up */ |
---|
276 | static const char *szAppNameCopy="anonymous program"; |
---|
277 | |
---|
278 | /* error code for failed osmalloc and osrealloc calls */ |
---|
279 | static void outofmem(OSSIZE_T size) { |
---|
280 | fprintf( STDERR, erg[2], szAppNameCopy ); |
---|
281 | fprintf( STDERR, erg[1], (unsigned long)size ); |
---|
282 | exit(EXIT_FAILURE); |
---|
283 | } |
---|
284 | |
---|
285 | /* malloc with error catching if it fails. Also allows us to write special |
---|
286 | * versions easily eg for DOS EMS or MS Windows. |
---|
287 | */ |
---|
288 | extern void FAR * osmalloc( OSSIZE_T size ) { |
---|
289 | void FAR *p; |
---|
290 | p=xosmalloc( size ); |
---|
291 | if (p==NULL) |
---|
292 | outofmem(size); |
---|
293 | return p; |
---|
294 | } |
---|
295 | |
---|
296 | /* realloc with error catching if it fails. */ |
---|
297 | extern void FAR * osrealloc( void *p, OSSIZE_T size ) { |
---|
298 | p=xosrealloc(p,size); |
---|
299 | if (p==NULL) |
---|
300 | outofmem(size); |
---|
301 | return p; |
---|
302 | } |
---|
303 | |
---|
304 | extern void FAR * osstrdup( const char *sz ) { |
---|
305 | char *p; |
---|
306 | int len; |
---|
307 | len=strlen(sz)+1; |
---|
308 | p=osmalloc(len); |
---|
309 | memmove(p,sz,len); |
---|
310 | return p; |
---|
311 | } |
---|
312 | |
---|
313 | /* osfree is currently a macro in error.h */ |
---|
314 | |
---|
315 | #ifdef HAVE_SIGNAL |
---|
316 | |
---|
317 | static int sigReceived; |
---|
318 | |
---|
319 | /* for systems not using autoconf, assume the signal handler returns void |
---|
320 | * unless specified elsewhere */ |
---|
321 | #ifndef RETSIGTYPE |
---|
322 | #define RETSIGTYPE void |
---|
323 | #endif |
---|
324 | |
---|
325 | static CDECL RETSIGTYPE FAR report_sig( int sig ) { |
---|
326 | sigReceived=sig; |
---|
327 | longjmp(jmpbufSignal,1); |
---|
328 | } |
---|
329 | |
---|
330 | static void init_signals( void ) { |
---|
331 | int en; |
---|
332 | if (!setjmp(jmpbufSignal)) { |
---|
333 | signal(SIGABRT,report_sig); /* abnormal termination eg abort() */ |
---|
334 | signal(SIGFPE ,report_sig); /* arithmetic error eg /0 or overflow */ |
---|
335 | signal(SIGILL ,report_sig); /* illegal function image eg illegal instruction */ |
---|
336 | signal(SIGINT ,report_sig); /* interactive attention eg interrupt */ |
---|
337 | signal(SIGSEGV,report_sig); /* illegal storage access eg access outside memory limits */ |
---|
338 | signal(SIGTERM,report_sig); /* termination request sent to program */ |
---|
339 | # ifdef SIGSTAK /* only on RISC OS AFAIK */ |
---|
340 | signal(SIGSTAK,report_sig); /* stack overflow */ |
---|
341 | # endif |
---|
342 | return; |
---|
343 | } |
---|
344 | fprintf(STDERR,msg(2),szAppNameCopy); |
---|
345 | switch (sigReceived) { |
---|
346 | case SIGABRT: en=90; break; |
---|
347 | case SIGFPE: en=91; break; |
---|
348 | case SIGILL: en=92; break; |
---|
349 | case SIGINT: en=93; break; |
---|
350 | case SIGSEGV: en=94; break; |
---|
351 | case SIGTERM: en=95; break; |
---|
352 | # ifdef SIGSTAK |
---|
353 | case SIGSTAK: en=96; break; |
---|
354 | # endif |
---|
355 | default: en=97; break; |
---|
356 | } |
---|
357 | fputsnl(msg(en),STDERR); |
---|
358 | if (errno >= 0) { |
---|
359 | # ifdef HAVE_STRERROR |
---|
360 | fputsnl(strerror(errno),STDERR); |
---|
361 | # elif defined(HAVE_SYS_ERRLIST) |
---|
362 | if (errno < sys_nerr) |
---|
363 | fputsnl( STDERR, sys_errlist[errno] ); |
---|
364 | # elif defined(HAVE_PERROR) |
---|
365 | perror(NULL); /* always goes to stderr */ |
---|
366 | /* if (arg!=NULL && *arg!='\0') fputs("<arg>: <err>\n",stderr); */ |
---|
367 | /* else fputs("<err>\n",stderr); */ |
---|
368 | # else |
---|
369 | fprintf( STDERR, "error code %d\n", errno ); |
---|
370 | # endif |
---|
371 | } |
---|
372 | if (sigReceived!=SIGINT && sigReceived!=SIGTERM) |
---|
373 | fatal(11,NULL,NULL,0); /* shouldn't get any others => bug */ |
---|
374 | exit(EXIT_FAILURE); |
---|
375 | } |
---|
376 | #endif |
---|
377 | |
---|
378 | /* write string and nl to STDERR */ |
---|
379 | extern void wr( const char *sz, int n ) { |
---|
380 | n=n; /* suppress warning */ |
---|
381 | fputsnl(sz,STDERR); |
---|
382 | } |
---|
383 | |
---|
384 | #define CHARSET_BAD -1 |
---|
385 | #define CHARSET_USASCII 0 |
---|
386 | #define CHARSET_ISO_8859_1 1 |
---|
387 | #define CHARSET_DOSCP850 2 |
---|
388 | #define CHARSET_RISCOS31 3 |
---|
389 | static int default_charset( void ) { |
---|
390 | #ifdef ISO8859_1 |
---|
391 | return CHARSET_ISO_8859_1; |
---|
392 | #elif (OS==RISCOS) |
---|
393 | /* |
---|
394 | RISCOS 3.1 and above |
---|
395 | CHARSET_RISCOS31 !HCAK! |
---|
396 | */ |
---|
397 | return CHARSET_ISO_8859_1; |
---|
398 | #elif (OS==MSDOS) |
---|
399 | return CHARSET_DOSCP850; |
---|
400 | #else |
---|
401 | return CHARSET_ISO_8859_1; /*!HACK!*/ |
---|
402 | #endif |
---|
403 | } |
---|
404 | |
---|
405 | static const char *pthMe = NULL, *lfErrs = NULL; |
---|
406 | static char prefix[32]; |
---|
407 | static int prefix_len; |
---|
408 | |
---|
409 | static char prefix_root[32]; |
---|
410 | static int prefix_root_len; |
---|
411 | |
---|
412 | static int add_unicode(int charset, char *p, int value) { |
---|
413 | if (value == 0) return 0; |
---|
414 | if (charset == CHARSET_ISO_8859_1 && value < 256) { |
---|
415 | *p = value; |
---|
416 | return 1; |
---|
417 | } |
---|
418 | return 0; |
---|
419 | } |
---|
420 | |
---|
421 | static int decode_entity(const char *entity, size_t len) { |
---|
422 | unsigned long value = 0; |
---|
423 | int i; |
---|
424 | for (i = 0; i < 4 && i < len; i++) value = (value<<8) | entity[i]; |
---|
425 | switch (value) { |
---|
426 | case 'nbsp': return 160; |
---|
427 | case 'iexc': return 161; |
---|
428 | case 'cent': return 162; |
---|
429 | case 'poun': return 163; |
---|
430 | case 'curr': return 164; |
---|
431 | case 'yen': return 165; |
---|
432 | case 'brvb': return 166; |
---|
433 | case 'sect': return 167; |
---|
434 | case 'uml': return 168; |
---|
435 | case 'copy': return 169; |
---|
436 | case 'ordf': return 170; |
---|
437 | case 'laqu': return 171; |
---|
438 | case 'not': return 172; |
---|
439 | case 'shy': return 173; |
---|
440 | case 'reg': return 174; |
---|
441 | case 'macr': return 175; |
---|
442 | case 'deg': return 176; |
---|
443 | case 'plus': return 177; |
---|
444 | case 'sup2': return 178; |
---|
445 | case 'sup3': return 179; |
---|
446 | case 'acut': return 180; |
---|
447 | case 'micr': return 181; |
---|
448 | case 'para': return 182; |
---|
449 | case 'midd': return 183; |
---|
450 | case 'cedi': return 184; |
---|
451 | case 'sup1': return 185; |
---|
452 | case 'ordm': return 186; |
---|
453 | case 'raqu': return 187; |
---|
454 | #if 0 |
---|
455 | case 'frac': return 188; |
---|
456 | case 'frac': return 189; |
---|
457 | case 'frac': return 190; |
---|
458 | #endif |
---|
459 | case 'ique': return 191; |
---|
460 | case 'Agra': return 192; |
---|
461 | case 'Aacu': return 193; |
---|
462 | case 'Acir': return 194; |
---|
463 | case 'Atil': return 195; |
---|
464 | case 'Auml': return 196; |
---|
465 | case 'Arin': return 197; |
---|
466 | case 'AEli': return 198; |
---|
467 | case 'Cced': return 199; |
---|
468 | case 'Egra': return 200; |
---|
469 | case 'Eacu': return 201; |
---|
470 | case 'Ecir': return 202; |
---|
471 | case 'Euml': return 203; |
---|
472 | case 'Igra': return 204; |
---|
473 | case 'Iacu': return 205; |
---|
474 | case 'Icir': return 206; |
---|
475 | case 'Iuml': return 207; |
---|
476 | case 'ETH': return 208; |
---|
477 | case 'Ntil': return 209; |
---|
478 | case 'Ogra': return 210; |
---|
479 | case 'Oacu': return 211; |
---|
480 | case 'Ocir': return 212; |
---|
481 | case 'Otil': return 213; |
---|
482 | case 'Ouml': return 214; |
---|
483 | case 'time': return 215; |
---|
484 | case 'Osla': return 216; |
---|
485 | case 'Ugra': return 217; |
---|
486 | case 'Uacu': return 218; |
---|
487 | case 'Ucir': return 219; |
---|
488 | case 'Uuml': return 220; |
---|
489 | case 'Yacu': return 221; |
---|
490 | case 'THOR': return 222; |
---|
491 | case 'szli': return 223; |
---|
492 | case 'agra': return 224; |
---|
493 | case 'aacu': return 225; |
---|
494 | case 'acir': return 226; |
---|
495 | case 'atil': return 227; |
---|
496 | case 'auml': return 228; |
---|
497 | case 'arin': return 229; |
---|
498 | case 'aeli': return 230; |
---|
499 | case 'cced': return 231; |
---|
500 | case 'egra': return 232; |
---|
501 | case 'eacu': return 233; |
---|
502 | case 'ecir': return 234; |
---|
503 | case 'euml': return 235; |
---|
504 | case 'igra': return 236; |
---|
505 | case 'iacu': return 237; |
---|
506 | case 'icir': return 238; |
---|
507 | case 'iuml': return 239; |
---|
508 | case 'eth': return 240; |
---|
509 | case 'ntil': return 241; |
---|
510 | case 'ogra': return 242; |
---|
511 | case 'oacu': return 243; |
---|
512 | case 'ocir': return 244; |
---|
513 | case 'otil': return 245; |
---|
514 | case 'ouml': return 246; |
---|
515 | case 'divi': return 247; |
---|
516 | case 'osla': return 248; |
---|
517 | case 'ugra': return 249; |
---|
518 | case 'uacu': return 250; |
---|
519 | case 'ucir': return 251; |
---|
520 | case 'uuml': return 252; |
---|
521 | case 'yacu': return 253; |
---|
522 | case 'thor': return 254; |
---|
523 | case 'yuml': return 255; |
---|
524 | } |
---|
525 | return 0; |
---|
526 | } |
---|
527 | |
---|
528 | static void parse_msg_file( int charset_code ) { |
---|
529 | FILE *fh; |
---|
530 | char estr[512], line[512]; |
---|
531 | int en; |
---|
532 | int c; |
---|
533 | bool fQuoted; |
---|
534 | #ifndef NO_ACCENTS |
---|
535 | char chOpenQuotes, chCloseQuotes; |
---|
536 | char *szSingles; |
---|
537 | char *szSingTab; |
---|
538 | char *szAccents; |
---|
539 | char *szLetters; |
---|
540 | char **pszTable; |
---|
541 | |
---|
542 | switch (charset_code) { |
---|
543 | case CHARSET_USASCII: { |
---|
544 | /* US ASCII */ |
---|
545 | chOpenQuotes = '\"'; |
---|
546 | chCloseQuotes = '\"'; |
---|
547 | szSingles = ""; |
---|
548 | szSingTab = NULL; |
---|
549 | szAccents = ""; |
---|
550 | szLetters = ""; |
---|
551 | pszTable = NULL; |
---|
552 | break; |
---|
553 | } |
---|
554 | case CHARSET_ISO_8859_1: { |
---|
555 | /* ISO 8859/1 (Latin 1) */ |
---|
556 | static char *my_pszTable[]={ |
---|
557 | "àèòÀìùÈÌÒÙ", |
---|
558 | "áéóÁíúÉÍÓÚýÝ", |
---|
559 | "âêôÂîûÊÎÔÛ", |
---|
560 | "äëöÄïüËÏÖÜÿ", |
---|
561 | "ã õÃ Õ ñÑ", |
---|
562 | NULL, |
---|
563 | NULL, |
---|
564 | NULL, |
---|
565 | NULL, |
---|
566 | NULL, |
---|
567 | NULL, |
---|
568 | " ç", |
---|
569 | " Ç", |
---|
570 | NULL, |
---|
571 | "ª º", |
---|
572 | "åæ", |
---|
573 | " Å Æ", |
---|
574 | " ß", |
---|
575 | NULL, |
---|
576 | NULL, |
---|
577 | " ø Ø" |
---|
578 | }; |
---|
579 | chOpenQuotes = '\"'; |
---|
580 | chCloseQuotes = '\"'; |
---|
581 | szSingles = ""; |
---|
582 | szSingTab = NULL; |
---|
583 | szAccents = "`'^\"~=.uvHtcCdbaAsOo/"; |
---|
584 | szLetters = "aeoAiuEIOUyYnNcCwWs"; |
---|
585 | pszTable = my_pszTable; |
---|
586 | break; |
---|
587 | } |
---|
588 | case CHARSET_RISCOS31: { |
---|
589 | /* Archimedes RISC OS 3.1 and above |
---|
590 | * ISO 8859/1 (Latin 1) + extensions in 128-159 */ |
---|
591 | static char *my_pszTable[]={ |
---|
592 | "àèòÀìùÈÌÒÙ", |
---|
593 | "áéóÁíúÉÍÓÚýÝ", |
---|
594 | "âêôÂîûÊÎÔÛ\x86\x85 \x82\x81", |
---|
595 | "äëöÄïüËÏÖÜÿ", |
---|
596 | "ã õÃ Õ ñÑ", |
---|
597 | NULL, |
---|
598 | NULL, |
---|
599 | NULL, |
---|
600 | NULL, |
---|
601 | NULL, |
---|
602 | NULL, |
---|
603 | " ç", |
---|
604 | " Ç", |
---|
605 | NULL, |
---|
606 | "ª º", |
---|
607 | "åæ", |
---|
608 | " Å Æ", |
---|
609 | " ß", |
---|
610 | " \x9a", |
---|
611 | " \x9b", |
---|
612 | " ø Ø" |
---|
613 | }; |
---|
614 | chOpenQuotes='\x94'; |
---|
615 | chCloseQuotes='\x95'; |
---|
616 | szSingles=""; |
---|
617 | szSingTab=NULL; |
---|
618 | szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
619 | szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
620 | pszTable = my_pszTable; |
---|
621 | break; |
---|
622 | } |
---|
623 | case CHARSET_DOSCP850: { |
---|
624 | /* MS DOS - Code page 850 */ |
---|
625 | static char *my_pszTable[]={ |
---|
626 | "\x85\x8A\x95·\x8D\x97Ô ãëìí", |
---|
627 | " \x82¢µ¡£\x90Öàé", |
---|
628 | "\x83\x88\x93¶\x8C\x96Ò×âê", |
---|
629 | "\x84\x89\x94\x8E\x8B\x81ÓØ\x99\x9A\x98", |
---|
630 | "Æ äÇ å ¤¥", |
---|
631 | NULL, |
---|
632 | NULL, |
---|
633 | NULL, |
---|
634 | NULL, |
---|
635 | NULL, |
---|
636 | NULL, |
---|
637 | " \x87", |
---|
638 | " \x80", |
---|
639 | NULL, |
---|
640 | "¦ §", |
---|
641 | "\x86\x91", |
---|
642 | " \x8F \x92", |
---|
643 | " á", |
---|
644 | NULL, |
---|
645 | NULL, |
---|
646 | " \x9B \x9D" |
---|
647 | }; |
---|
648 | chOpenQuotes='\"'; |
---|
649 | chCloseQuotes='\"'; |
---|
650 | szSingles="lLij"; |
---|
651 | szSingTab=" Õ"; |
---|
652 | szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
653 | szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
654 | pszTable = my_pszTable; |
---|
655 | break; |
---|
656 | } |
---|
657 | #if 0 |
---|
658 | /* MS DOS - PC-8 (code page 437?) */ |
---|
659 | static char chOpenQuotes='\"', chCloseQuotes='\"'; |
---|
660 | static char *szSingles=""; |
---|
661 | static char *szSingTab=NULL; |
---|
662 | static char *szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
663 | static char *szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
664 | static char *pszTable[]={ |
---|
665 | "\x85\x8A\x95 \x8D\x97", |
---|
666 | " \x82¢ ¡£\x90", |
---|
667 | "\x83\x88\x93 \x8C\x96", |
---|
668 | "\x84\x89\x94\x8E\x8B\x81 \x99\x9A\x98", |
---|
669 | " ¤¥", |
---|
670 | NULL, |
---|
671 | NULL, |
---|
672 | NULL, |
---|
673 | NULL, |
---|
674 | NULL, |
---|
675 | NULL, |
---|
676 | " \x87", |
---|
677 | " \x80", |
---|
678 | NULL, |
---|
679 | "¦ §", |
---|
680 | "\x86\x91", |
---|
681 | " \x8F \x92", |
---|
682 | " á", |
---|
683 | NULL, |
---|
684 | NULL, |
---|
685 | NULL |
---|
686 | }; |
---|
687 | |
---|
688 | #elif 0 |
---|
689 | /* MS DOS - PC-8 Denmark/Norway */ |
---|
690 | static char chOpenQuotes='\"', chCloseQuotes='\"'; |
---|
691 | static char *szSingles=""; |
---|
692 | static char *szSingTab=NULL; |
---|
693 | static char *szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
694 | static char *szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
695 | static char *pszTable[]={ |
---|
696 | "\x85\x8A\x95 \x8D\x97", |
---|
697 | " \x82¢ ¡£\x90 ¬", |
---|
698 | "\x83\x88\x93 \x8C\x96", |
---|
699 | "\x84\x89\x94\x8E\x8B\x81 \x99\x9A\x98", |
---|
700 | "© ¦ª § ¤¥", |
---|
701 | NULL, |
---|
702 | NULL, |
---|
703 | NULL, |
---|
704 | NULL, |
---|
705 | NULL, |
---|
706 | NULL, |
---|
707 | " \x87", |
---|
708 | " \x80", |
---|
709 | NULL, |
---|
710 | NULL, |
---|
711 | "\x86\x91", |
---|
712 | " \x8F \x92", |
---|
713 | " á", |
---|
714 | NULL, |
---|
715 | NULL, |
---|
716 | NULL |
---|
717 | }; |
---|
718 | #elif 0 |
---|
719 | /* No special chars... */ |
---|
720 | # define NO_TEX |
---|
721 | #endif |
---|
722 | default: /*!HACK! do something -- no_tex variable version of NO_TEX ? */ |
---|
723 | printf("oops, bad charset...\n"); |
---|
724 | (void)0; |
---|
725 | } |
---|
726 | #endif |
---|
727 | |
---|
728 | #if 0 |
---|
729 | printf("opening error file\n"); |
---|
730 | printf("(%s %s)\n",pthMe,lfErrs); |
---|
731 | #endif |
---|
732 | fh=fopenWithPthAndExt( pthMe, lfErrs, "", "rb", NULL ); |
---|
733 | #if 0 |
---|
734 | printf("opened error file\n"); |
---|
735 | #endif |
---|
736 | if (!fh) { |
---|
737 | /* no point extracting this error, as it won't get used if file opens */ |
---|
738 | fprintf(STDERR, erg[3], szAppNameCopy ); |
---|
739 | fprintf(STDERR, "Can't open message file '%s' using path '%s'\n", |
---|
740 | lfErrs, pthMe); |
---|
741 | exit(EXIT_FAILURE); |
---|
742 | } |
---|
743 | |
---|
744 | { /* copy bootstrap erg[] which'll get overwritten by file entries */ |
---|
745 | const char **ergMalloc; |
---|
746 | erg = ergBootstrap; |
---|
747 | ergMalloc = osmalloc( enMac * ossizeof(char*) ); |
---|
748 | /* NULL marks end of list */ |
---|
749 | for ( en = 0 ; erg[en] ; en++ ) ergMalloc[en]=erg[en]; |
---|
750 | for ( ; en < enMac ; en++ ) ergMalloc[en] = szBadEn; |
---|
751 | erg = ergMalloc; |
---|
752 | } |
---|
753 | |
---|
754 | while (!feof( fh )) { |
---|
755 | char *p; |
---|
756 | char *q; |
---|
757 | int exact; |
---|
758 | getline( line, ossizeof(line), fh ); |
---|
759 | if ((exact = (strncmp(line, prefix, prefix_len) == 0)) || |
---|
760 | (prefix_root_len && strncmp(line, prefix_root, prefix_root_len) == 0)) { |
---|
761 | long val; |
---|
762 | val = strtol( line + (exact?prefix_len:prefix_root_len), &q, 0); |
---|
763 | if (val < 0 || val > (unsigned long)INT_MAX) { |
---|
764 | fprintf( STDERR, erg[3], szAppNameCopy ); |
---|
765 | fprintf( STDERR, erg[ (errno==ERANGE) ? 5 : 6 ] ); |
---|
766 | exit(EXIT_FAILURE); |
---|
767 | } |
---|
768 | en = (int)val; |
---|
769 | while (isspace(*q)) q++; |
---|
770 | |
---|
771 | p = q + strlen(q); |
---|
772 | while (p > q && isspace(p[-1])) p--; |
---|
773 | |
---|
774 | fQuoted = (p > q + 1 && *q == '\"' && *(p-1) == '\"'); |
---|
775 | if (fQuoted) { |
---|
776 | q++; |
---|
777 | p--; |
---|
778 | } |
---|
779 | *p = '\0'; |
---|
780 | |
---|
781 | c = 0; |
---|
782 | while (*q) { |
---|
783 | if (*q == '&') { |
---|
784 | if (*(q+1) == '#') { |
---|
785 | if (isdigit(q[2])) { |
---|
786 | unsigned long value = strtoul( q+2, &q, 10); |
---|
787 | if (*q == ';') q++; |
---|
788 | if (value < 127) { |
---|
789 | estr[c++] = (char)value; |
---|
790 | } else { |
---|
791 | c += add_unicode(charset_code, estr+c, value); |
---|
792 | } |
---|
793 | continue; |
---|
794 | } |
---|
795 | } else if (isalnum(q[1])) { /* or isalpha? !HACK! */ |
---|
796 | /*const*/ char *entity; |
---|
797 | int entity_len; |
---|
798 | int len; |
---|
799 | entity = q+1; |
---|
800 | q += 2; |
---|
801 | while (isalnum(*q)) q++; |
---|
802 | entity_len = q - entity; |
---|
803 | if (*q == ';') q++; |
---|
804 | len = add_unicode(charset_code, estr+c, decode_entity(entity, entity_len)); |
---|
805 | if (len) { |
---|
806 | c += len; |
---|
807 | continue; |
---|
808 | } |
---|
809 | q = entity - 1; |
---|
810 | } |
---|
811 | } |
---|
812 | if (*q < 32 || *q >= 127) { |
---|
813 | fprintf(STDERR, "Warning: literal character '%c' (value %d) " |
---|
814 | "in message %d\n", *q, (int)*q, en); |
---|
815 | } |
---|
816 | estr[c++] = *q++; |
---|
817 | } |
---|
818 | estr[c] = '\0'; |
---|
819 | |
---|
820 | if (en >= enMac) { |
---|
821 | int enTmp; |
---|
822 | enTmp = enMac; |
---|
823 | enMac = enMac<<1; |
---|
824 | erg = osrealloc( erg, enMac * ossizeof(char*) ); |
---|
825 | while (enTmp < enMac) erg[enTmp++] = szBadEn; |
---|
826 | } |
---|
827 | erg[en] = osstrdup(estr); |
---|
828 | /*printf("Error number %d: %s\n",en,erg[en]);*/ |
---|
829 | } |
---|
830 | } |
---|
831 | fclose(fh); |
---|
832 | } |
---|
833 | |
---|
834 | extern const char * FAR ReadErrorFile( const char *szAppName, const char *szEnvVar, |
---|
835 | const char *szLangVar, const char *argv0, |
---|
836 | const char *lfErrFile ) { |
---|
837 | int c; |
---|
838 | char *szTmp; |
---|
839 | |
---|
840 | lfErrs = osstrdup(lfErrFile); |
---|
841 | #ifdef HAVE_SIGNAL |
---|
842 | init_signals(); |
---|
843 | #endif |
---|
844 | /* This code *should* be completely bomb-proof even if strcpy |
---|
845 | * generates a signal |
---|
846 | */ |
---|
847 | szAppNameCopy = szAppName; /* ... in case the osstrdup() fails */ |
---|
848 | szAppNameCopy = osstrdup(szAppName); |
---|
849 | |
---|
850 | /* Look for env. var. "SURVEXHOME" or the like */ |
---|
851 | if (szEnvVar && *szEnvVar && (szTmp=getenv(szEnvVar))!=NULL && *szTmp) { |
---|
852 | pthMe = osstrdup(szTmp); |
---|
853 | } else if (argv0) { |
---|
854 | /* else try the path on argv[0] */ |
---|
855 | pthMe = PthFromFnm(argv0); |
---|
856 | } else { |
---|
857 | /* otherwise, forget it - go for the current directory */ |
---|
858 | pthMe = ""; |
---|
859 | } |
---|
860 | |
---|
861 | /* Look for env. var. "SURVEXLANG" or the like */ |
---|
862 | if ((szTmp=getenv(szLangVar))==0 || !*szTmp) { |
---|
863 | szTmp = DEFAULTLANG; |
---|
864 | } |
---|
865 | for (c = 0 ; c < 4 && szTmp[c] ; c++) prefix[c] = tolower(szTmp[c]); |
---|
866 | prefix[c] = '\0'; |
---|
867 | if (c == 4) { |
---|
868 | if (strcmp(prefix, "engi") == 0) { |
---|
869 | strcpy(prefix, "en"); |
---|
870 | } else if (strcmp(prefix, "engu") == 0) { |
---|
871 | strcpy(prefix, "en-us"); |
---|
872 | } else if (strcmp(prefix, "fren") == 0) { |
---|
873 | strcpy(prefix, "fr"); |
---|
874 | } else if (strcmp(prefix, "germ") == 0) { |
---|
875 | strcpy(prefix, "de"); |
---|
876 | } else if (strcmp(prefix, "ital") == 0) { |
---|
877 | strcpy(prefix, "it"); |
---|
878 | } else if (strcmp(prefix, "span") == 0) { |
---|
879 | strcpy(prefix, "es"); |
---|
880 | } else if (strcmp(prefix, "cata") == 0) { |
---|
881 | strcpy(prefix, "ca"); |
---|
882 | } else if (strcmp(prefix, "port") == 0) { |
---|
883 | strcpy(prefix, "pt"); |
---|
884 | } else { |
---|
885 | while (szTmp[c] && c < sizeof(prefix)) { |
---|
886 | prefix[c] = tolower(szTmp[c]); |
---|
887 | c++; |
---|
888 | } |
---|
889 | prefix[c] = '\0'; |
---|
890 | } |
---|
891 | } |
---|
892 | strcat(prefix, ":"); |
---|
893 | prefix_len = strlen(prefix); |
---|
894 | |
---|
895 | /* If the language is something like "en-us", fallback to "en" if we don't |
---|
896 | * have an entry for en-us */ |
---|
897 | szTmp = strchr(prefix, '-'); |
---|
898 | if (szTmp) { |
---|
899 | c = szTmp - prefix; |
---|
900 | memcpy(prefix_root, prefix, c); |
---|
901 | prefix_root[c++] = ':'; |
---|
902 | prefix_root[c] = '\0'; |
---|
903 | prefix_root_len = strlen(prefix_root); |
---|
904 | } else { |
---|
905 | prefix_root_len = 0; |
---|
906 | } |
---|
907 | |
---|
908 | select_charset(default_charset()); |
---|
909 | |
---|
910 | if (erg[0]==szBadEn) { |
---|
911 | fprintf(STDERR, erg[3], szAppName ); |
---|
912 | /* no point extracting this message */ |
---|
913 | fprintf(STDERR, "No messages in language '%s'\n",prefix); |
---|
914 | exit(EXIT_FAILURE); |
---|
915 | } |
---|
916 | if (strcmp(MESSAGE_VERSION_MIN,erg[0])>0 || strcmp(VERSION,erg[0])<0) |
---|
917 | /* a little tacky, but'll work */ |
---|
918 | fatal(191,wr,MESSAGE_VERSION_MIN" - "VERSION,0); |
---|
919 | |
---|
920 | return pthMe; |
---|
921 | } |
---|
922 | |
---|
923 | extern const char *msg( int en ) /* message may be overwritten by next call */ { |
---|
924 | return ( (en<0||en>=enMac) ? szBadEn : erg[en] ); |
---|
925 | } |
---|
926 | |
---|
927 | extern const char *msgPerm( int en ) /* returns persistent copy of message */ { |
---|
928 | return ( (en<0||en>=enMac) ? szBadEn : erg[en] ); |
---|
929 | } |
---|
930 | |
---|
931 | static void FAR errdisp( int en, void (*fn)( const char *, int ), const char *arg, int n, |
---|
932 | int type ) { |
---|
933 | fputnl( STDERR ); |
---|
934 | fputnl( STDERR ); |
---|
935 | fprintf( STDERR, erg[type], szAppNameCopy ); |
---|
936 | fputs( msg(en), STDERR); |
---|
937 | fputnl( STDERR ); |
---|
938 | if (fn) (fn)(arg, n); |
---|
939 | /* if (fn) (fn)( (arg ? arg : "(null)"), n);*/ |
---|
940 | } |
---|
941 | |
---|
942 | extern void FAR warning( int en, void (*fn)( const char *, int ), const char *szArg, int n ) { |
---|
943 | cWarnings++; |
---|
944 | errdisp( en, fn, szArg, n, 4 ); |
---|
945 | } |
---|
946 | |
---|
947 | extern void FAR error( int en, void (*fn)( const char *, int ), const char *szArg, int n ) { |
---|
948 | cErrors++; |
---|
949 | errdisp( en, fn, szArg, n, 3 ); |
---|
950 | /* non-fatal errors now return... */ |
---|
951 | } |
---|
952 | |
---|
953 | extern void FAR fatal( int en, void (*fn)( const char *, int ), const char *szArg, int n ) { |
---|
954 | errdisp( en, fn, szArg, n, 2 ); |
---|
955 | exit(EXIT_FAILURE); |
---|
956 | } |
---|
957 | |
---|
958 | #if 1 |
---|
959 | /* Code to support switching character set at runtime (e.g. for a printer |
---|
960 | * driver to support different character sets on screen and on the printer) |
---|
961 | */ |
---|
962 | typedef struct charset_li { |
---|
963 | struct charset_li *next; |
---|
964 | int code; |
---|
965 | const char **erg; |
---|
966 | } charset_li; |
---|
967 | |
---|
968 | static charset_li *charset_head = NULL; |
---|
969 | |
---|
970 | static int charset = CHARSET_BAD; |
---|
971 | |
---|
972 | int select_charset( int charset_code ) { |
---|
973 | int old_charset = charset; |
---|
974 | charset_li *p; |
---|
975 | |
---|
976 | /* printf( "select_charset(%d), old charset = %d\n", charset_code, charset ); */ |
---|
977 | |
---|
978 | charset = charset_code; |
---|
979 | |
---|
980 | /* check if we've already parsed messages for new charset */ |
---|
981 | for( p = charset_head ; p ; p = p->next ) { |
---|
982 | /* printf("%p: code %d erg %p\n",p,p->code,p->erg); */ |
---|
983 | if (p->code == charset) { |
---|
984 | erg = p->erg; |
---|
985 | goto found; |
---|
986 | } |
---|
987 | } |
---|
988 | |
---|
989 | /* nope, got to reparse message file */ |
---|
990 | parse_msg_file( charset_code ); |
---|
991 | |
---|
992 | /* add to list */ |
---|
993 | p = osnew(charset_li); |
---|
994 | /* p = osmalloc(256); */ |
---|
995 | p->code = charset; |
---|
996 | p->erg = erg; |
---|
997 | p->next = charset_head; |
---|
998 | charset_head = p; |
---|
999 | |
---|
1000 | found: |
---|
1001 | return old_charset; |
---|
1002 | } |
---|
1003 | #endif |
---|