[60f7018] | 1 | /* message.c */ |
---|
| 2 | |
---|
[a3e49dc] | 3 | /* ERRC show diffs to newer version of error.c - most that are left in here aren't relevant */ |
---|
| 4 | |
---|
[60f7018] | 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 |
---|
[a3e49dc] | 169 | 1997.06.05 added const |
---|
| 170 | 1998.03.04 more const |
---|
| 171 | 1998.03.21 fixed up to compile cleanly on Linux |
---|
[60f7018] | 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" |
---|
[4432f2e] | 216 | #include "filename.h" |
---|
| 217 | #include "message.h" |
---|
[60f7018] | 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 |
---|
[4432f2e] | 234 | * add (for eg) -DDEFAULTLANG="fr" to UFLG in the makefile |
---|
[60f7018] | 235 | */ |
---|
| 236 | #ifndef DEFAULTLANG |
---|
[4432f2e] | 237 | # define DEFAULTLANG "en" |
---|
[60f7018] | 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 | /* |
---|
[48e4121] | 394 | RISCOS 3.1 and above CHARSET_RISCOS31 !HACK! |
---|
[60f7018] | 395 | */ |
---|
[48e4121] | 396 | return CHARSET_CHARSET_RISCOS31; |
---|
[60f7018] | 397 | #elif (OS==MSDOS) |
---|
| 398 | return CHARSET_DOSCP850; |
---|
| 399 | #else |
---|
| 400 | return CHARSET_ISO_8859_1; /*!HACK!*/ |
---|
| 401 | #endif |
---|
| 402 | } |
---|
| 403 | |
---|
[4432f2e] | 404 | static const char *pthMe = NULL, *lfErrs = NULL; |
---|
| 405 | static char prefix[32]; |
---|
[60f7018] | 406 | static int prefix_len; |
---|
| 407 | |
---|
[4432f2e] | 408 | static char prefix_root[32]; |
---|
| 409 | static int prefix_root_len; |
---|
| 410 | |
---|
[48e4121] | 411 | #if (OS==MSDOS) |
---|
| 412 | static int xlate_dos_cp850(int unicode) { |
---|
| 413 | switch (unicode) { |
---|
| 414 | /*# include "unicode-to-dos-cp-default.tab"*/ |
---|
| 415 | case 160: return 255; |
---|
| 416 | case 161: return 173; |
---|
| 417 | case 162: return 189; |
---|
| 418 | case 163: return 156; |
---|
| 419 | case 164: return 207; |
---|
| 420 | case 165: return 190; |
---|
| 421 | case 167: return 245; |
---|
| 422 | case 168: return 249; |
---|
| 423 | case 169: return 184; |
---|
| 424 | case 170: return 166; |
---|
| 425 | case 171: return 174; |
---|
| 426 | case 172: return 170; |
---|
| 427 | case 173: return 240; |
---|
| 428 | case 174: return 169; |
---|
| 429 | #if 0 |
---|
| 430 | case 175: return 223; |
---|
| 431 | case 175: return 238; |
---|
| 432 | #endif |
---|
| 433 | case 176: return 248; |
---|
| 434 | case 177: return 241; |
---|
| 435 | case 178: return 253; |
---|
| 436 | case 179: return 252; |
---|
| 437 | case 180: return 239; |
---|
| 438 | case 181: return 230; |
---|
| 439 | case 182: return 244; |
---|
| 440 | case 183: return 250; |
---|
| 441 | case 184: return 247; |
---|
| 442 | case 185: return 251; |
---|
| 443 | case 186: return 167; |
---|
| 444 | case 187: return 175; |
---|
| 445 | case 188: return 172; |
---|
| 446 | case 189: return 171; |
---|
| 447 | case 190: return 243; |
---|
| 448 | case 191: return 168; |
---|
| 449 | case 192: return 183; |
---|
| 450 | case 193: return 181; |
---|
| 451 | case 194: return 182; |
---|
| 452 | case 195: return 199; |
---|
| 453 | case 196: return 142; |
---|
| 454 | case 197: return 143; |
---|
| 455 | case 198: return 146; |
---|
| 456 | case 199: return 128; |
---|
| 457 | case 200: return 212; |
---|
| 458 | case 201: return 144; |
---|
| 459 | case 202: return 210; |
---|
| 460 | case 203: return 211; |
---|
| 461 | case 204: return 222; |
---|
| 462 | case 205: return 214; |
---|
| 463 | case 206: return 215; |
---|
| 464 | case 207: return 216; |
---|
| 465 | case 208: return 209; |
---|
| 466 | case 209: return 165; |
---|
| 467 | case 210: return 227; |
---|
| 468 | case 211: return 224; |
---|
| 469 | case 212: return 226; |
---|
| 470 | case 213: return 229; |
---|
| 471 | case 214: return 153; |
---|
| 472 | case 215: return 158; |
---|
| 473 | case 216: return 157; |
---|
| 474 | case 217: return 235; |
---|
| 475 | case 218: return 233; |
---|
| 476 | case 219: return 234; |
---|
| 477 | case 220: return 154; |
---|
| 478 | case 221: return 237; |
---|
| 479 | case 222: return 232; |
---|
| 480 | case 223: return 225; |
---|
| 481 | case 224: return 133; |
---|
| 482 | case 225: return 160; |
---|
| 483 | case 226: return 131; |
---|
| 484 | case 227: return 198; |
---|
| 485 | case 228: return 132; |
---|
| 486 | case 229: return 134; |
---|
| 487 | case 230: return 145; |
---|
| 488 | case 231: return 135; |
---|
| 489 | case 232: return 138; |
---|
| 490 | case 233: return 130; |
---|
| 491 | case 234: return 136; |
---|
| 492 | case 235: return 137; |
---|
| 493 | case 236: return 141; |
---|
| 494 | case 237: return 161; |
---|
| 495 | case 238: return 140; |
---|
| 496 | case 239: return 139; |
---|
| 497 | case 240: return 208; |
---|
| 498 | case 241: return 164; |
---|
| 499 | case 242: return 149; |
---|
| 500 | case 243: return 162; |
---|
| 501 | case 244: return 147; |
---|
| 502 | case 245: return 228; |
---|
| 503 | case 246: return 148; |
---|
| 504 | case 247: return 246; |
---|
| 505 | case 248: return 155; |
---|
| 506 | case 249: return 151; |
---|
| 507 | case 250: return 163; |
---|
| 508 | case 251: return 150; |
---|
| 509 | case 252: return 129; |
---|
| 510 | case 253: return 236; |
---|
| 511 | case 254: return 231; |
---|
| 512 | case 255: return 152; |
---|
| 513 | } |
---|
| 514 | return 0; |
---|
| 515 | } |
---|
| 516 | #endif |
---|
| 517 | |
---|
[4432f2e] | 518 | static int add_unicode(int charset, char *p, int value) { |
---|
| 519 | if (value == 0) return 0; |
---|
[48e4121] | 520 | switch (charset) { |
---|
| 521 | case CHARSET_USASCII: |
---|
| 522 | if (value < 128) { |
---|
| 523 | *p = value; |
---|
| 524 | return 1; |
---|
| 525 | } |
---|
| 526 | break; |
---|
| 527 | case CHARSET_ISO_8859_1: |
---|
| 528 | #if (OS==RISCOS) |
---|
| 529 | case CHARSET_RISCOS31: /* RISC OS 3.1 has a few extras in 128-159 */ |
---|
| 530 | #endif |
---|
| 531 | if (value < 256) { |
---|
| 532 | *p = value; |
---|
| 533 | return 1; |
---|
| 534 | } |
---|
| 535 | #if (OS==RISCOS) |
---|
| 536 | /* !HACK! handle extras here */ |
---|
| 537 | #endif |
---|
| 538 | break; |
---|
| 539 | #if (OS==MSDOS) |
---|
| 540 | case CHARSET_DOSCP850: |
---|
| 541 | value = xlate_dos_cp850(value); |
---|
| 542 | if (value) { |
---|
| 543 | *p = value; |
---|
| 544 | return 1; |
---|
| 545 | } |
---|
| 546 | break; |
---|
| 547 | #endif |
---|
[4432f2e] | 548 | } |
---|
[f1a5201] | 549 | return 0; |
---|
[4432f2e] | 550 | } |
---|
| 551 | |
---|
| 552 | static int decode_entity(const char *entity, size_t len) { |
---|
[48e4121] | 553 | unsigned long value; |
---|
[4432f2e] | 554 | int i; |
---|
[48e4121] | 555 | |
---|
| 556 | if (len > 6) return 0; |
---|
| 557 | value = entity[0] - '0'; |
---|
| 558 | if (value >= 'a' - '0') { |
---|
| 559 | value += 36 - ('a' - '0'); |
---|
| 560 | } else if (value >= 'A' - '0') { |
---|
| 561 | value += 10 - ('A' - '0'); |
---|
| 562 | } |
---|
| 563 | for (i = 1; i < 6 && i < len; i++) { |
---|
| 564 | int c; |
---|
| 565 | c = toupper(entity[i]) - '0'; |
---|
| 566 | if (c >= 'A' - '0') c += 10 - ('A' - '0'); |
---|
| 567 | value = value * 36 + c; |
---|
| 568 | } |
---|
[4432f2e] | 569 | switch (value) { |
---|
[48e4121] | 570 | case 17477224u: return 198; /* AElig */ |
---|
| 571 | case 622057730u: return 193; /* Aacute */ |
---|
| 572 | case 17380344u: return 194; /* Acirc */ |
---|
| 573 | case 632809418u: return 192; /* Agrave */ |
---|
| 574 | case 18080044u: return 197; /* Aring */ |
---|
| 575 | case 654238130u: return 195; /* Atilde */ |
---|
| 576 | case 506253u: return 196; /* Auml */ |
---|
| 577 | case 746420205u: return 199; /* Ccedil */ |
---|
| 578 | case 19205u: return 208; /* ETH */ |
---|
| 579 | case 863922434u: return 201; /* Eacute */ |
---|
| 580 | case 24098808u: return 202; /* Ecirc */ |
---|
| 581 | case 874674122u: return 200; /* Egrave */ |
---|
| 582 | case 692877u: return 203; /* Euml */ |
---|
| 583 | case 1105787138u: return 205; /* Iacute */ |
---|
| 584 | case 30817272u: return 206; /* Icirc */ |
---|
| 585 | case 1116538826u: return 204; /* Igrave */ |
---|
| 586 | case 879501u: return 207; /* Iuml */ |
---|
| 587 | case 1440298418u: return 209; /* Ntilde */ |
---|
| 588 | case 1468584194u: return 211; /* Oacute */ |
---|
| 589 | case 40894968u: return 212; /* Ocirc */ |
---|
| 590 | case 1479335882u: return 210; /* Ograve */ |
---|
| 591 | case 1499211233u: return 216; /* Oslash */ |
---|
| 592 | case 1500764594u: return 213; /* Otilde */ |
---|
| 593 | case 1159437u: return 214; /* Ouml */ |
---|
| 594 | case 49534115u: return 222; /* THORN */ |
---|
| 595 | case 1831381250u: return 218; /* Uacute */ |
---|
| 596 | case 50972664u: return 219; /* Ucirc */ |
---|
| 597 | case 1842132938u: return 217; /* Ugrave */ |
---|
| 598 | case 1439373u: return 220; /* Uuml */ |
---|
| 599 | case 2073245954u: return 221; /* Yacute */ |
---|
| 600 | case 2194178306u: return 225; /* aacute */ |
---|
| 601 | case 61050360u: return 226; /* acirc */ |
---|
| 602 | case 61065986u: return 180; /* acute */ |
---|
| 603 | case 61147240u: return 230; /* aelig */ |
---|
| 604 | case 2204929994u: return 224; /* agrave */ |
---|
| 605 | case 61750060u: return 229; /* aring */ |
---|
| 606 | case 2226358706u: return 227; /* atilde */ |
---|
| 607 | case 1719309u: return 228; /* auml */ |
---|
| 608 | case 2284059123u: return 166; /* brvbar */ |
---|
| 609 | case 2318540781u: return 231; /* ccedil */ |
---|
| 610 | case 64496109u: return 184; /* cedil */ |
---|
| 611 | case 1791929u: return 162; /* cent */ |
---|
| 612 | case 1804966u: return 169; /* copy */ |
---|
| 613 | case 2349398399u: return 164; /* curren */ |
---|
| 614 | case 51064u: return 176; /* deg */ |
---|
| 615 | case 2389884098u: return 247; /* divide */ |
---|
| 616 | case 2436043010u: return 233; /* eacute */ |
---|
| 617 | case 67768824u: return 234; /* ecirc */ |
---|
| 618 | case 2446794698u: return 232; /* egrave */ |
---|
| 619 | case 52901u: return 240; /* eth */ |
---|
| 620 | case 1905933u: return 235; /* euml */ |
---|
| 621 | case 2524944998u: return 189; /* frac12 */ |
---|
| 622 | case 2524945000u: return 188; /* frac14 */ |
---|
| 623 | case 2524945072u: return 190; /* frac34 */ |
---|
| 624 | case 2677907714u: return 237; /* iacute */ |
---|
| 625 | case 74487288u: return 238; /* icirc */ |
---|
| 626 | case 74599509u: return 161; /* iexcl */ |
---|
| 627 | case 2688659402u: return 236; /* igrave */ |
---|
| 628 | case 2705600621u: return 191; /* iquest */ |
---|
| 629 | case 2092557u: return 239; /* iuml */ |
---|
| 630 | case 79443312u: return 171; /* laquo */ |
---|
| 631 | case 2252907u: return 175; /* macr */ |
---|
| 632 | case 81477924u: return 181; /* micro */ |
---|
| 633 | case 2933233805u: return 183; /* middot */ |
---|
| 634 | case 2301433u: return 160; /* nbsp */ |
---|
| 635 | case 64397u: return 172; /* not */ |
---|
| 636 | case 3012418994u: return 241; /* ntilde */ |
---|
| 637 | case 3040704770u: return 243; /* oacute */ |
---|
| 638 | case 84564984u: return 244; /* ocirc */ |
---|
| 639 | case 3051456458u: return 242; /* ograve */ |
---|
| 640 | case 2368275u: return 170; /* ordf */ |
---|
| 641 | case 2368282u: return 186; /* ordm */ |
---|
| 642 | case 3071331809u: return 248; /* oslash */ |
---|
| 643 | case 3072885170u: return 245; /* otilde */ |
---|
| 644 | case 2372493u: return 246; /* ouml */ |
---|
| 645 | case 2393398u: return 182; /* para */ |
---|
| 646 | case 3120483695u: return 177; /* plusmn */ |
---|
| 647 | case 86819881u: return 163; /* pound */ |
---|
| 648 | case 89521008u: return 187; /* raquo */ |
---|
| 649 | case 69208u: return 174; /* reg */ |
---|
| 650 | case 2538029u: return 167; /* sect */ |
---|
| 651 | case 70630u: return 173; /* shy */ |
---|
| 652 | case 2559205u: return 185; /* sup1 */ |
---|
| 653 | case 2559206u: return 178; /* sup2 */ |
---|
| 654 | case 2559207u: return 179; /* sup3 */ |
---|
| 655 | case 92360104u: return 223; /* szlig */ |
---|
| 656 | case 93204131u: return 254; /* thorn */ |
---|
| 657 | case 93247732u: return 215; /* times */ |
---|
| 658 | case 3403501826u: return 250; /* uacute */ |
---|
| 659 | case 94642680u: return 251; /* ucirc */ |
---|
| 660 | case 3414253514u: return 249; /* ugrave */ |
---|
| 661 | case 73389u: return 168; /* uml */ |
---|
| 662 | case 2652429u: return 252; /* uuml */ |
---|
| 663 | case 3645366530u: return 253; /* yacute */ |
---|
| 664 | case 78287u: return 165; /* yen */ |
---|
| 665 | case 2839053u: return 255; /* yuml */ |
---|
[4432f2e] | 666 | } |
---|
| 667 | return 0; |
---|
| 668 | } |
---|
| 669 | |
---|
[60f7018] | 670 | static void parse_msg_file( int charset_code ) { |
---|
| 671 | FILE *fh; |
---|
[4432f2e] | 672 | char estr[512], line[512]; |
---|
[60f7018] | 673 | int en; |
---|
| 674 | int c; |
---|
| 675 | bool fQuoted; |
---|
| 676 | #ifndef NO_ACCENTS |
---|
| 677 | char chOpenQuotes, chCloseQuotes; |
---|
| 678 | char *szSingles; |
---|
| 679 | char *szSingTab; |
---|
| 680 | char *szAccents; |
---|
| 681 | char *szLetters; |
---|
| 682 | char **pszTable; |
---|
| 683 | |
---|
| 684 | switch (charset_code) { |
---|
| 685 | case CHARSET_USASCII: { |
---|
| 686 | /* US ASCII */ |
---|
| 687 | chOpenQuotes = '\"'; |
---|
| 688 | chCloseQuotes = '\"'; |
---|
| 689 | szSingles = ""; |
---|
| 690 | szSingTab = NULL; |
---|
| 691 | szAccents = ""; |
---|
| 692 | szLetters = ""; |
---|
| 693 | pszTable = NULL; |
---|
| 694 | break; |
---|
| 695 | } |
---|
| 696 | case CHARSET_ISO_8859_1: { |
---|
| 697 | /* ISO 8859/1 (Latin 1) */ |
---|
| 698 | static char *my_pszTable[]={ |
---|
| 699 | "àèòÀìùÈÌÒÙ", |
---|
| 700 | "áéóÁíúÉÍÓÚýÝ", |
---|
| 701 | "âêôÂîûÊÎÔÛ", |
---|
| 702 | "äëöÄïüËÏÖÜÿ", |
---|
| 703 | "ã õÃ Õ ñÑ", |
---|
| 704 | NULL, |
---|
| 705 | NULL, |
---|
| 706 | NULL, |
---|
| 707 | NULL, |
---|
| 708 | NULL, |
---|
| 709 | NULL, |
---|
| 710 | " ç", |
---|
| 711 | " Ç", |
---|
| 712 | NULL, |
---|
| 713 | "ª º", |
---|
| 714 | "åæ", |
---|
| 715 | " Å Æ", |
---|
| 716 | " ß", |
---|
| 717 | NULL, |
---|
| 718 | NULL, |
---|
| 719 | " ø Ø" |
---|
| 720 | }; |
---|
| 721 | chOpenQuotes = '\"'; |
---|
| 722 | chCloseQuotes = '\"'; |
---|
| 723 | szSingles = ""; |
---|
| 724 | szSingTab = NULL; |
---|
| 725 | szAccents = "`'^\"~=.uvHtcCdbaAsOo/"; |
---|
| 726 | szLetters = "aeoAiuEIOUyYnNcCwWs"; |
---|
| 727 | pszTable = my_pszTable; |
---|
| 728 | break; |
---|
| 729 | } |
---|
| 730 | case CHARSET_RISCOS31: { |
---|
| 731 | /* Archimedes RISC OS 3.1 and above |
---|
| 732 | * ISO 8859/1 (Latin 1) + extensions in 128-159 */ |
---|
| 733 | static char *my_pszTable[]={ |
---|
| 734 | "àèòÀìùÈÌÒÙ", |
---|
| 735 | "áéóÁíúÉÍÓÚýÝ", |
---|
| 736 | "âêôÂîûÊÎÔÛ\x86\x85 \x82\x81", |
---|
| 737 | "äëöÄïüËÏÖÜÿ", |
---|
| 738 | "ã õÃ Õ ñÑ", |
---|
| 739 | NULL, |
---|
| 740 | NULL, |
---|
| 741 | NULL, |
---|
| 742 | NULL, |
---|
| 743 | NULL, |
---|
| 744 | NULL, |
---|
| 745 | " ç", |
---|
| 746 | " Ç", |
---|
| 747 | NULL, |
---|
| 748 | "ª º", |
---|
| 749 | "åæ", |
---|
| 750 | " Å Æ", |
---|
| 751 | " ß", |
---|
| 752 | " \x9a", |
---|
| 753 | " \x9b", |
---|
| 754 | " ø Ø" |
---|
| 755 | }; |
---|
| 756 | chOpenQuotes='\x94'; |
---|
| 757 | chCloseQuotes='\x95'; |
---|
| 758 | szSingles=""; |
---|
| 759 | szSingTab=NULL; |
---|
| 760 | szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
| 761 | szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
| 762 | pszTable = my_pszTable; |
---|
| 763 | break; |
---|
| 764 | } |
---|
| 765 | case CHARSET_DOSCP850: { |
---|
| 766 | /* MS DOS - Code page 850 */ |
---|
| 767 | static char *my_pszTable[]={ |
---|
| 768 | "\x85\x8A\x95·\x8D\x97Ô ãëìí", |
---|
| 769 | " \x82¢µ¡£\x90Öàé", |
---|
| 770 | "\x83\x88\x93¶\x8C\x96Ò×âê", |
---|
| 771 | "\x84\x89\x94\x8E\x8B\x81ÓØ\x99\x9A\x98", |
---|
| 772 | "Æ äÇ å ¤¥", |
---|
| 773 | NULL, |
---|
| 774 | NULL, |
---|
| 775 | NULL, |
---|
| 776 | NULL, |
---|
| 777 | NULL, |
---|
| 778 | NULL, |
---|
| 779 | " \x87", |
---|
| 780 | " \x80", |
---|
| 781 | NULL, |
---|
| 782 | "¦ §", |
---|
| 783 | "\x86\x91", |
---|
| 784 | " \x8F \x92", |
---|
| 785 | " á", |
---|
| 786 | NULL, |
---|
| 787 | NULL, |
---|
| 788 | " \x9B \x9D" |
---|
| 789 | }; |
---|
| 790 | chOpenQuotes='\"'; |
---|
| 791 | chCloseQuotes='\"'; |
---|
| 792 | szSingles="lLij"; |
---|
| 793 | szSingTab=" Õ"; |
---|
| 794 | szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
| 795 | szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
| 796 | pszTable = my_pszTable; |
---|
| 797 | break; |
---|
| 798 | } |
---|
| 799 | #if 0 |
---|
| 800 | /* MS DOS - PC-8 (code page 437?) */ |
---|
| 801 | static char chOpenQuotes='\"', chCloseQuotes='\"'; |
---|
| 802 | static char *szSingles=""; |
---|
| 803 | static char *szSingTab=NULL; |
---|
| 804 | static char *szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
| 805 | static char *szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
| 806 | static char *pszTable[]={ |
---|
| 807 | "\x85\x8A\x95 \x8D\x97", |
---|
| 808 | " \x82¢ ¡£\x90", |
---|
| 809 | "\x83\x88\x93 \x8C\x96", |
---|
| 810 | "\x84\x89\x94\x8E\x8B\x81 \x99\x9A\x98", |
---|
| 811 | " ¤¥", |
---|
| 812 | NULL, |
---|
| 813 | NULL, |
---|
| 814 | NULL, |
---|
| 815 | NULL, |
---|
| 816 | NULL, |
---|
| 817 | NULL, |
---|
| 818 | " \x87", |
---|
| 819 | " \x80", |
---|
| 820 | NULL, |
---|
| 821 | "¦ §", |
---|
| 822 | "\x86\x91", |
---|
| 823 | " \x8F \x92", |
---|
| 824 | " á", |
---|
| 825 | NULL, |
---|
| 826 | NULL, |
---|
| 827 | NULL |
---|
| 828 | }; |
---|
| 829 | |
---|
| 830 | #elif 0 |
---|
| 831 | /* MS DOS - PC-8 Denmark/Norway */ |
---|
| 832 | static char chOpenQuotes='\"', chCloseQuotes='\"'; |
---|
| 833 | static char *szSingles=""; |
---|
| 834 | static char *szSingTab=NULL; |
---|
| 835 | static char *szAccents="`'^\"~=.uvHtcCdbaAsOo/"; |
---|
| 836 | static char *szLetters="aeoAiuEIOUyYnNcCwWs"; |
---|
| 837 | static char *pszTable[]={ |
---|
| 838 | "\x85\x8A\x95 \x8D\x97", |
---|
| 839 | " \x82¢ ¡£\x90 ¬", |
---|
| 840 | "\x83\x88\x93 \x8C\x96", |
---|
| 841 | "\x84\x89\x94\x8E\x8B\x81 \x99\x9A\x98", |
---|
| 842 | "© ¦ª § ¤¥", |
---|
| 843 | NULL, |
---|
| 844 | NULL, |
---|
| 845 | NULL, |
---|
| 846 | NULL, |
---|
| 847 | NULL, |
---|
| 848 | NULL, |
---|
| 849 | " \x87", |
---|
| 850 | " \x80", |
---|
| 851 | NULL, |
---|
| 852 | NULL, |
---|
| 853 | "\x86\x91", |
---|
| 854 | " \x8F \x92", |
---|
| 855 | " á", |
---|
| 856 | NULL, |
---|
| 857 | NULL, |
---|
| 858 | NULL |
---|
| 859 | }; |
---|
| 860 | #elif 0 |
---|
| 861 | /* No special chars... */ |
---|
| 862 | # define NO_TEX |
---|
| 863 | #endif |
---|
| 864 | default: /*!HACK! do something -- no_tex variable version of NO_TEX ? */ |
---|
| 865 | printf("oops, bad charset...\n"); |
---|
| 866 | (void)0; |
---|
| 867 | } |
---|
| 868 | #endif |
---|
| 869 | |
---|
| 870 | #if 0 |
---|
| 871 | printf("opening error file\n"); |
---|
| 872 | printf("(%s %s)\n",pthMe,lfErrs); |
---|
| 873 | #endif |
---|
| 874 | fh=fopenWithPthAndExt( pthMe, lfErrs, "", "rb", NULL ); |
---|
| 875 | #if 0 |
---|
| 876 | printf("opened error file\n"); |
---|
| 877 | #endif |
---|
| 878 | if (!fh) { |
---|
| 879 | /* no point extracting this error, as it won't get used if file opens */ |
---|
| 880 | fprintf(STDERR, erg[3], szAppNameCopy ); |
---|
| 881 | fprintf(STDERR, "Can't open message file '%s' using path '%s'\n", |
---|
[a3e49dc] | 882 | lfErrs, pthMe); |
---|
[60f7018] | 883 | exit(EXIT_FAILURE); |
---|
| 884 | } |
---|
| 885 | |
---|
| 886 | { /* copy bootstrap erg[] which'll get overwritten by file entries */ |
---|
[a3e49dc] | 887 | const char **ergMalloc; |
---|
| 888 | erg = ergBootstrap; |
---|
| 889 | ergMalloc = osmalloc( enMac * ossizeof(char*) ); |
---|
| 890 | /* NULL marks end of list */ |
---|
| 891 | for ( en = 0 ; erg[en] ; en++ ) ergMalloc[en]=erg[en]; |
---|
| 892 | for ( ; en < enMac ; en++ ) ergMalloc[en] = szBadEn; |
---|
| 893 | erg = ergMalloc; |
---|
[60f7018] | 894 | } |
---|
| 895 | |
---|
| 896 | while (!feof( fh )) { |
---|
[4432f2e] | 897 | char *p; |
---|
| 898 | char *q; |
---|
| 899 | int exact; |
---|
[60f7018] | 900 | getline( line, ossizeof(line), fh ); |
---|
[4432f2e] | 901 | if ((exact = (strncmp(line, prefix, prefix_len) == 0)) || |
---|
| 902 | (prefix_root_len && strncmp(line, prefix_root, prefix_root_len) == 0)) { |
---|
| 903 | long val; |
---|
| 904 | val = strtol( line + (exact?prefix_len:prefix_root_len), &q, 0); |
---|
[60f7018] | 905 | if (val < 0 || val > (unsigned long)INT_MAX) { |
---|
| 906 | fprintf( STDERR, erg[3], szAppNameCopy ); |
---|
| 907 | fprintf( STDERR, erg[ (errno==ERANGE) ? 5 : 6 ] ); |
---|
| 908 | exit(EXIT_FAILURE); |
---|
| 909 | } |
---|
| 910 | en = (int)val; |
---|
| 911 | while (isspace(*q)) q++; |
---|
| 912 | |
---|
| 913 | p = q + strlen(q); |
---|
| 914 | while (p > q && isspace(p[-1])) p--; |
---|
| 915 | |
---|
| 916 | fQuoted = (p > q + 1 && *q == '\"' && *(p-1) == '\"'); |
---|
| 917 | if (fQuoted) { |
---|
| 918 | q++; |
---|
| 919 | p--; |
---|
| 920 | } |
---|
| 921 | *p = '\0'; |
---|
| 922 | |
---|
| 923 | c = 0; |
---|
| 924 | while (*q) { |
---|
| 925 | if (*q == '&') { |
---|
| 926 | if (*(q+1) == '#') { |
---|
[4432f2e] | 927 | if (isdigit(q[2])) { |
---|
[60f7018] | 928 | unsigned long value = strtoul( q+2, &q, 10); |
---|
| 929 | if (*q == ';') q++; |
---|
[4432f2e] | 930 | if (value < 127) { |
---|
[f1a5201] | 931 | estr[c++] = (char)value; |
---|
[4432f2e] | 932 | } else { |
---|
| 933 | c += add_unicode(charset_code, estr+c, value); |
---|
| 934 | } |
---|
[60f7018] | 935 | continue; |
---|
| 936 | } |
---|
[4432f2e] | 937 | } else if (isalnum(q[1])) { /* or isalpha? !HACK! */ |
---|
| 938 | /*const*/ char *entity; |
---|
[60f7018] | 939 | int entity_len; |
---|
[4432f2e] | 940 | int len; |
---|
[60f7018] | 941 | entity = q+1; |
---|
| 942 | q += 2; |
---|
| 943 | while (isalnum(*q)) q++; |
---|
| 944 | entity_len = q - entity; |
---|
| 945 | if (*q == ';') q++; |
---|
[4432f2e] | 946 | len = add_unicode(charset_code, estr+c, decode_entity(entity, entity_len)); |
---|
| 947 | if (len) { |
---|
| 948 | c += len; |
---|
| 949 | continue; |
---|
| 950 | } |
---|
[60f7018] | 951 | q = entity - 1; |
---|
| 952 | } |
---|
| 953 | } |
---|
| 954 | if (*q < 32 || *q >= 127) { |
---|
[4432f2e] | 955 | fprintf(STDERR, "Warning: literal character '%c' (value %d) " |
---|
| 956 | "in message %d\n", *q, (int)*q, en); |
---|
[60f7018] | 957 | } |
---|
| 958 | estr[c++] = *q++; |
---|
| 959 | } |
---|
| 960 | estr[c] = '\0'; |
---|
| 961 | |
---|
| 962 | if (en >= enMac) { |
---|
| 963 | int enTmp; |
---|
| 964 | enTmp = enMac; |
---|
| 965 | enMac = enMac<<1; |
---|
| 966 | erg = osrealloc( erg, enMac * ossizeof(char*) ); |
---|
| 967 | while (enTmp < enMac) erg[enTmp++] = szBadEn; |
---|
| 968 | } |
---|
[a3e49dc] | 969 | erg[en] = osstrdup(estr); |
---|
[60f7018] | 970 | /*printf("Error number %d: %s\n",en,erg[en]);*/ |
---|
| 971 | } |
---|
| 972 | } |
---|
| 973 | fclose(fh); |
---|
| 974 | } |
---|
| 975 | |
---|
| 976 | extern const char * FAR ReadErrorFile( const char *szAppName, const char *szEnvVar, |
---|
| 977 | const char *szLangVar, const char *argv0, |
---|
| 978 | const char *lfErrFile ) { |
---|
[4432f2e] | 979 | int c; |
---|
| 980 | char *szTmp; |
---|
[60f7018] | 981 | |
---|
[4432f2e] | 982 | lfErrs = osstrdup(lfErrFile); |
---|
[60f7018] | 983 | #ifdef HAVE_SIGNAL |
---|
[4432f2e] | 984 | init_signals(); |
---|
[60f7018] | 985 | #endif |
---|
[4432f2e] | 986 | /* This code *should* be completely bomb-proof even if strcpy |
---|
| 987 | * generates a signal |
---|
| 988 | */ |
---|
| 989 | szAppNameCopy = szAppName; /* ... in case the osstrdup() fails */ |
---|
| 990 | szAppNameCopy = osstrdup(szAppName); |
---|
| 991 | |
---|
| 992 | /* Look for env. var. "SURVEXHOME" or the like */ |
---|
| 993 | if (szEnvVar && *szEnvVar && (szTmp=getenv(szEnvVar))!=NULL && *szTmp) { |
---|
| 994 | pthMe = osstrdup(szTmp); |
---|
| 995 | } else if (argv0) { |
---|
| 996 | /* else try the path on argv[0] */ |
---|
| 997 | pthMe = PthFromFnm(argv0); |
---|
| 998 | } else { |
---|
| 999 | /* otherwise, forget it - go for the current directory */ |
---|
| 1000 | pthMe = ""; |
---|
| 1001 | } |
---|
[f1a5201] | 1002 | |
---|
[4432f2e] | 1003 | /* Look for env. var. "SURVEXLANG" or the like */ |
---|
| 1004 | if ((szTmp=getenv(szLangVar))==0 || !*szTmp) { |
---|
| 1005 | szTmp = DEFAULTLANG; |
---|
| 1006 | } |
---|
| 1007 | for (c = 0 ; c < 4 && szTmp[c] ; c++) prefix[c] = tolower(szTmp[c]); |
---|
| 1008 | prefix[c] = '\0'; |
---|
| 1009 | if (c == 4) { |
---|
| 1010 | if (strcmp(prefix, "engi") == 0) { |
---|
| 1011 | strcpy(prefix, "en"); |
---|
| 1012 | } else if (strcmp(prefix, "engu") == 0) { |
---|
[f1a5201] | 1013 | strcpy(prefix, "en-us"); |
---|
[4432f2e] | 1014 | } else if (strcmp(prefix, "fren") == 0) { |
---|
[f1a5201] | 1015 | strcpy(prefix, "fr"); |
---|
[4432f2e] | 1016 | } else if (strcmp(prefix, "germ") == 0) { |
---|
[f1a5201] | 1017 | strcpy(prefix, "de"); |
---|
[4432f2e] | 1018 | } else if (strcmp(prefix, "ital") == 0) { |
---|
[f1a5201] | 1019 | strcpy(prefix, "it"); |
---|
[4432f2e] | 1020 | } else if (strcmp(prefix, "span") == 0) { |
---|
[f1a5201] | 1021 | strcpy(prefix, "es"); |
---|
[4432f2e] | 1022 | } else if (strcmp(prefix, "cata") == 0) { |
---|
[f1a5201] | 1023 | strcpy(prefix, "ca"); |
---|
[4432f2e] | 1024 | } else if (strcmp(prefix, "port") == 0) { |
---|
[f1a5201] | 1025 | strcpy(prefix, "pt"); |
---|
[4432f2e] | 1026 | } else { |
---|
| 1027 | while (szTmp[c] && c < sizeof(prefix)) { |
---|
| 1028 | prefix[c] = tolower(szTmp[c]); |
---|
| 1029 | c++; |
---|
| 1030 | } |
---|
| 1031 | prefix[c] = '\0'; |
---|
| 1032 | } |
---|
| 1033 | } |
---|
| 1034 | strcat(prefix, ":"); |
---|
| 1035 | prefix_len = strlen(prefix); |
---|
[f1a5201] | 1036 | |
---|
[4432f2e] | 1037 | /* If the language is something like "en-us", fallback to "en" if we don't |
---|
| 1038 | * have an entry for en-us */ |
---|
| 1039 | szTmp = strchr(prefix, '-'); |
---|
| 1040 | if (szTmp) { |
---|
| 1041 | c = szTmp - prefix; |
---|
| 1042 | memcpy(prefix_root, prefix, c); |
---|
| 1043 | prefix_root[c++] = ':'; |
---|
| 1044 | prefix_root[c] = '\0'; |
---|
| 1045 | prefix_root_len = strlen(prefix_root); |
---|
| 1046 | } else { |
---|
| 1047 | prefix_root_len = 0; |
---|
| 1048 | } |
---|
[60f7018] | 1049 | |
---|
| 1050 | select_charset(default_charset()); |
---|
| 1051 | |
---|
| 1052 | if (erg[0]==szBadEn) { |
---|
| 1053 | fprintf(STDERR, erg[3], szAppName ); |
---|
| 1054 | /* no point extracting this message */ |
---|
| 1055 | fprintf(STDERR, "No messages in language '%s'\n",prefix); |
---|
| 1056 | exit(EXIT_FAILURE); |
---|
| 1057 | } |
---|
| 1058 | if (strcmp(MESSAGE_VERSION_MIN,erg[0])>0 || strcmp(VERSION,erg[0])<0) |
---|
| 1059 | /* a little tacky, but'll work */ |
---|
| 1060 | fatal(191,wr,MESSAGE_VERSION_MIN" - "VERSION,0); |
---|
| 1061 | |
---|
| 1062 | return pthMe; |
---|
| 1063 | } |
---|
| 1064 | |
---|
| 1065 | extern const char *msg( int en ) /* message may be overwritten by next call */ { |
---|
| 1066 | return ( (en<0||en>=enMac) ? szBadEn : erg[en] ); |
---|
| 1067 | } |
---|
| 1068 | |
---|
| 1069 | extern const char *msgPerm( int en ) /* returns persistent copy of message */ { |
---|
| 1070 | return ( (en<0||en>=enMac) ? szBadEn : erg[en] ); |
---|
| 1071 | } |
---|
| 1072 | |
---|
[4432f2e] | 1073 | static void FAR errdisp( int en, void (*fn)( const char *, int ), const char *arg, int n, |
---|
[60f7018] | 1074 | int type ) { |
---|
[4432f2e] | 1075 | fputnl( STDERR ); |
---|
| 1076 | fputnl( STDERR ); |
---|
| 1077 | fprintf( STDERR, erg[type], szAppNameCopy ); |
---|
| 1078 | fputs( msg(en), STDERR); |
---|
| 1079 | fputnl( STDERR ); |
---|
| 1080 | if (fn) (fn)(arg, n); |
---|
| 1081 | /* if (fn) (fn)( (arg ? arg : "(null)"), n);*/ |
---|
[60f7018] | 1082 | } |
---|
| 1083 | |
---|
| 1084 | extern void FAR warning( int en, void (*fn)( const char *, int ), const char *szArg, int n ) { |
---|
[4432f2e] | 1085 | cWarnings++; |
---|
| 1086 | errdisp( en, fn, szArg, n, 4 ); |
---|
[60f7018] | 1087 | } |
---|
| 1088 | |
---|
| 1089 | extern void FAR error( int en, void (*fn)( const char *, int ), const char *szArg, int n ) { |
---|
[4432f2e] | 1090 | cErrors++; |
---|
| 1091 | errdisp( en, fn, szArg, n, 3 ); |
---|
| 1092 | /* non-fatal errors now return... */ |
---|
[60f7018] | 1093 | } |
---|
| 1094 | |
---|
| 1095 | extern void FAR fatal( int en, void (*fn)( const char *, int ), const char *szArg, int n ) { |
---|
[4432f2e] | 1096 | errdisp( en, fn, szArg, n, 2 ); |
---|
| 1097 | exit(EXIT_FAILURE); |
---|
[60f7018] | 1098 | } |
---|
| 1099 | |
---|
| 1100 | #if 1 |
---|
| 1101 | /* Code to support switching character set at runtime (e.g. for a printer |
---|
| 1102 | * driver to support different character sets on screen and on the printer) |
---|
| 1103 | */ |
---|
| 1104 | typedef struct charset_li { |
---|
| 1105 | struct charset_li *next; |
---|
| 1106 | int code; |
---|
[a3e49dc] | 1107 | const char **erg; |
---|
[60f7018] | 1108 | } charset_li; |
---|
| 1109 | |
---|
| 1110 | static charset_li *charset_head = NULL; |
---|
| 1111 | |
---|
| 1112 | static int charset = CHARSET_BAD; |
---|
| 1113 | |
---|
| 1114 | int select_charset( int charset_code ) { |
---|
| 1115 | int old_charset = charset; |
---|
| 1116 | charset_li *p; |
---|
| 1117 | |
---|
[a3e49dc] | 1118 | /* printf( "select_charset(%d), old charset = %d\n", charset_code, charset ); */ |
---|
[60f7018] | 1119 | |
---|
| 1120 | charset = charset_code; |
---|
| 1121 | |
---|
| 1122 | /* check if we've already parsed messages for new charset */ |
---|
| 1123 | for( p = charset_head ; p ; p = p->next ) { |
---|
[a3e49dc] | 1124 | /* printf("%p: code %d erg %p\n",p,p->code,p->erg); */ |
---|
[60f7018] | 1125 | if (p->code == charset) { |
---|
| 1126 | erg = p->erg; |
---|
| 1127 | goto found; |
---|
| 1128 | } |
---|
| 1129 | } |
---|
| 1130 | |
---|
| 1131 | /* nope, got to reparse message file */ |
---|
[a3e49dc] | 1132 | parse_msg_file( charset_code ); |
---|
[60f7018] | 1133 | |
---|
| 1134 | /* add to list */ |
---|
| 1135 | p = osnew(charset_li); |
---|
| 1136 | /* p = osmalloc(256); */ |
---|
| 1137 | p->code = charset; |
---|
| 1138 | p->erg = erg; |
---|
| 1139 | p->next = charset_head; |
---|
| 1140 | charset_head = p; |
---|
| 1141 | |
---|
| 1142 | found: |
---|
| 1143 | return old_charset; |
---|
| 1144 | } |
---|
| 1145 | #endif |
---|