Mercurial > dwindows
comparison dwcompat.c @ 1594:6baf177f335c
Rename compat.c/h dwcompat.c/h and configure option to --with-dwcompat.
There are several other projects that include compat.c and compat.h...
To avoid conflicts make sure the header and source files match the library.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Thu, 23 Feb 2012 12:44:15 +0000 |
parents | compat.c@007ed833ac79 |
children | 71e0a3ad07f7 |
comparison
equal
deleted
inserted
replaced
1593:19af25f71e1f | 1594:6baf177f335c |
---|---|
1 /* $Id$ */ | |
2 | |
3 #include "dwcompat.h" | |
4 #include "dw.h" | |
5 #if defined(__OS2__) || defined(__WIN32__) | |
6 #include <share.h> | |
7 #endif | |
8 | |
9 #if defined(__UNIX__) || defined(__MAC__) | |
10 #if defined(__FreeBSD__) || defined(__MAC__) | |
11 #include <sys/param.h> | |
12 #include <sys/ucred.h> | |
13 #include <sys/mount.h> | |
14 #elif defined(__sun__) | |
15 #include <sys/mnttab.h> | |
16 #include <sys/param.h> | |
17 #include <sys/mount.h> | |
18 #include <sys/statvfs.h> | |
19 #else | |
20 #include <mntent.h> | |
21 #include <sys/vfs.h> | |
22 #endif | |
23 #endif | |
24 #include <time.h> | |
25 #include <errno.h> | |
26 | |
27 #if defined(__UNIX__) || defined(__MAC__) | |
28 void msleep(long period) | |
29 { | |
30 #ifdef __sun__ | |
31 /* usleep() isn't threadsafe on Solaris */ | |
32 struct timespec req; | |
33 | |
34 req.tv_sec = 0; | |
35 if(period >= 1000) | |
36 { | |
37 req.tv_sec = (int)(period / 1000); | |
38 period -= (req.tv_sec * 1000); | |
39 } | |
40 req.tv_nsec = period * 10000000; | |
41 | |
42 nanosleep(&req, NULL); | |
43 #else | |
44 usleep((int)(period * 1000)); | |
45 #endif | |
46 } | |
47 #endif | |
48 | |
49 int API makedir(char *path) | |
50 { | |
51 #if defined(__IBMC__) || defined(__WATCOMC__) || (defined(__WIN32__) && !defined(__CYGWIN32__)) | |
52 return mkdir(path); | |
53 #else | |
54 return mkdir(path,S_IRWXU); | |
55 #endif | |
56 } | |
57 | |
58 char * API vargs(char *buf, int len, char *format, ...) | |
59 { | |
60 va_list args; | |
61 | |
62 va_start(args, format); | |
63 #ifdef HAVE_VSNPRINTF | |
64 vsnprintf(buf, len, format, args); | |
65 #else | |
66 len = len; | |
67 vsprintf(buf, format, args); | |
68 #endif | |
69 va_end(args); | |
70 | |
71 return buf; | |
72 } | |
73 | |
74 long double API drivefree(int drive) | |
75 { | |
76 #if defined(__EMX__) || defined(__OS2__) | |
77 ULONG aulFSInfoBuf[40] = {0}; | |
78 APIRET rc = NO_ERROR; | |
79 | |
80 DosError(FERR_DISABLEHARDERR); | |
81 rc = DosQueryFSInfo(drive, | |
82 FSIL_ALLOC, | |
83 (PVOID)aulFSInfoBuf, | |
84 sizeof(aulFSInfoBuf)); | |
85 | |
86 DosError(FERR_ENABLEHARDERR); | |
87 if (rc != NO_ERROR) | |
88 return 0; | |
89 | |
90 return (long double)((double)aulFSInfoBuf[3] * (double)aulFSInfoBuf[1] * (double)aulFSInfoBuf[4]); | |
91 #elif defined(__WIN32__) || defined(WINNT) | |
92 char buffer[10] = "C:\\"; | |
93 DWORD spc, bps, fc, tc; | |
94 | |
95 buffer[0] = drive + 'A' - 1; | |
96 | |
97 if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0) | |
98 return 0; | |
99 | |
100 return (long double)((double)spc*(double)bps*(double)fc); | |
101 #elif defined(__FreeBSD__) || defined(__MAC__) | |
102 struct statfs *fsp; | |
103 int entries, index = 1; | |
104 | |
105 entries = getmntinfo (&fsp, MNT_NOWAIT); | |
106 | |
107 for (; entries-- > 0; fsp++) | |
108 { | |
109 if(index == drive) | |
110 return (long double)((double)fsp->f_bsize * (double)fsp->f_bavail); | |
111 index++; | |
112 } | |
113 return 0; | |
114 #elif defined(__sun__) | |
115 FILE *fp = fopen("/etc/mnttab", "r"); | |
116 struct mnttab mnt; | |
117 struct statvfs sfs; | |
118 int index = 1; | |
119 | |
120 if(fp) | |
121 { | |
122 while((getmntent(fp, &mnt) == 0)) | |
123 { | |
124 if(index == drive) | |
125 { | |
126 long double size = 0; | |
127 | |
128 if(mnt.mnt_mountp) | |
129 { | |
130 if(!statvfs(mnt.mnt_mountp, &sfs)) | |
131 { | |
132 size = (long double)((double)sfs.f_bsize * (double)sfs.f_bavail); | |
133 } | |
134 } | |
135 fclose(fp); | |
136 return size; | |
137 } | |
138 index++; | |
139 } | |
140 fclose(fp); | |
141 } | |
142 return 0; | |
143 #else | |
144 FILE *fp = setmntent(MOUNTED, "r"); | |
145 struct mntent mnt; | |
146 struct statfs sfs; | |
147 char buffer[1024]; | |
148 int index = 1; | |
149 | |
150 if(fp) | |
151 { | |
152 while(getmntent_r(fp, &mnt, buffer, sizeof(buffer))) | |
153 { | |
154 if(index == drive) | |
155 { | |
156 long double size = 0; | |
157 | |
158 if(mnt.mnt_dir) | |
159 { | |
160 if(!statfs(mnt.mnt_dir, &sfs)) | |
161 { | |
162 size = (long double)((double)sfs.f_bsize * (double)sfs.f_bavail); | |
163 } | |
164 } | |
165 endmntent(fp); | |
166 return size; | |
167 } | |
168 index++; | |
169 } | |
170 endmntent(fp); | |
171 } | |
172 return 0; | |
173 #endif | |
174 } | |
175 | |
176 long double API drivesize(int drive) | |
177 { | |
178 #if defined(__EMX__) || defined(__OS2__) | |
179 ULONG aulFSInfoBuf[40] = {0}; | |
180 APIRET rc = NO_ERROR; | |
181 | |
182 DosError(FERR_DISABLEHARDERR); | |
183 rc = DosQueryFSInfo(drive, | |
184 FSIL_ALLOC, | |
185 (PVOID)aulFSInfoBuf, | |
186 sizeof(aulFSInfoBuf)); | |
187 | |
188 DosError(FERR_ENABLEHARDERR); | |
189 if (rc != NO_ERROR) | |
190 return 0; | |
191 | |
192 return (long double)((double)aulFSInfoBuf[2] * (double)aulFSInfoBuf[1] * (double)aulFSInfoBuf[4]); | |
193 #elif defined(__WIN32__) || defined(WINNT) | |
194 char buffer[10] = "C:\\"; | |
195 DWORD spc, bps, fc, tc; | |
196 | |
197 buffer[0] = drive + 'A' - 1; | |
198 | |
199 if(GetDiskFreeSpace(buffer, &spc, &bps, &fc, &tc) == 0) | |
200 return 0; | |
201 | |
202 return (long double)((double)spc*(double)bps*(double)tc); | |
203 #elif defined(__FreeBSD__) || defined(__MAC__) | |
204 struct statfs *fsp; | |
205 int entries, index = 1; | |
206 | |
207 entries = getmntinfo (&fsp, MNT_NOWAIT); | |
208 | |
209 for (; entries-- > 0; fsp++) | |
210 { | |
211 if(index == drive) | |
212 return (long double)((double)fsp->f_bsize * (double)fsp->f_blocks); | |
213 index++; | |
214 } | |
215 return 0; | |
216 #elif defined(__sun__) | |
217 FILE *fp = fopen("/etc/mnttab", "r"); | |
218 struct mnttab mnt; | |
219 struct statvfs sfs; | |
220 int index = 1; | |
221 | |
222 if(fp) | |
223 { | |
224 while(getmntent(fp, &mnt) == 0) | |
225 { | |
226 if(index == drive) | |
227 { | |
228 long double size = 0; | |
229 | |
230 if(mnt.mnt_mountp) | |
231 { | |
232 if(!statvfs(mnt.mnt_mountp, &sfs)) | |
233 { | |
234 size = (long double)((double)sfs.f_bsize * (double)sfs.f_blocks); | |
235 } | |
236 } | |
237 fclose(fp); | |
238 return size; | |
239 } | |
240 index++; | |
241 } | |
242 fclose(fp); | |
243 } | |
244 return 0; | |
245 #else | |
246 FILE *fp = setmntent(MOUNTED, "r"); | |
247 struct mntent mnt; | |
248 char buffer[1024]; | |
249 struct statfs sfs; | |
250 int index = 1; | |
251 | |
252 if(fp) | |
253 { | |
254 while(getmntent_r(fp, &mnt, buffer, sizeof(buffer))) | |
255 { | |
256 if(index == drive) | |
257 { | |
258 long double size = 0; | |
259 | |
260 if(mnt.mnt_dir) | |
261 { | |
262 if(!statfs(mnt.mnt_dir, &sfs)) | |
263 { | |
264 size = (long double)((double)sfs.f_bsize * (double)sfs.f_blocks); | |
265 } | |
266 } | |
267 endmntent(fp); | |
268 return size; | |
269 } | |
270 index++; | |
271 } | |
272 endmntent(fp); | |
273 } | |
274 return 0; | |
275 #endif | |
276 } | |
277 | |
278 int API isdrive(int drive) | |
279 { | |
280 #if defined(__EMX__) || defined(__OS2__) | |
281 APIRET rc = NO_ERROR; | |
282 FSINFO volinfo; | |
283 | |
284 DosError(FERR_DISABLEHARDERR); | |
285 rc = DosQueryFSInfo(drive, | |
286 FSIL_VOLSER, | |
287 (PVOID)&volinfo, | |
288 sizeof(FSINFO)); | |
289 | |
290 DosError(FERR_ENABLEHARDERR); | |
291 if (rc == NO_ERROR) | |
292 return 1; | |
293 | |
294 #elif defined(__WIN32__) || defined(WINNT) | |
295 char buffer[10] = "C:\\", volname[100]; | |
296 DWORD spc, bps, fc; | |
297 | |
298 buffer[0] = drive + 'A' - 1; | |
299 | |
300 if(GetVolumeInformation(buffer, volname, 100, &spc, &bps, &fc, NULL, 0) != 0) | |
301 return 1; | |
302 #elif defined(__FreeBSD__) || defined(__MAC__) | |
303 struct statfs *fsp; | |
304 int entries, index = 1; | |
305 | |
306 entries = getmntinfo (&fsp, MNT_NOWAIT); | |
307 | |
308 for (; entries-- > 0; fsp++) | |
309 { | |
310 if(index == drive && fsp->f_blocks) | |
311 return 1; | |
312 index++; | |
313 } | |
314 return 0; | |
315 #elif defined(__sun__) | |
316 FILE *fp = fopen("/etc/mnttab", "r"); | |
317 struct mnttab mnt; | |
318 struct statvfs sfs; | |
319 int index = 1; | |
320 | |
321 if(fp) | |
322 { | |
323 while(getmntent(fp, &mnt) == 0) | |
324 { | |
325 if(index == drive) | |
326 { | |
327 fclose(fp); | |
328 if(mnt.mnt_mountp) | |
329 { | |
330 if(!statvfs(mnt.mnt_mountp, &sfs) && sfs.f_blocks) | |
331 return 1; | |
332 } | |
333 return 0; | |
334 } | |
335 index++; | |
336 } | |
337 fclose(fp); | |
338 } | |
339 #else | |
340 FILE *fp = setmntent(MOUNTED, "r"); | |
341 struct mntent mnt; | |
342 char buffer[1024]; | |
343 struct statfs sfs; | |
344 int index = 1; | |
345 | |
346 if(fp) | |
347 { | |
348 while(getmntent_r(fp, &mnt, buffer, sizeof(buffer))) | |
349 { | |
350 if(index == drive) | |
351 { | |
352 endmntent(fp); | |
353 if(mnt.mnt_dir) | |
354 { | |
355 if(!statfs(mnt.mnt_dir, &sfs) && sfs.f_blocks) | |
356 { | |
357 return 1; | |
358 } | |
359 } | |
360 return 0; | |
361 } | |
362 index++; | |
363 } | |
364 endmntent(fp); | |
365 } | |
366 #endif | |
367 return 0; | |
368 } | |
369 | |
370 void API getfsname(int drive, char *buf, int len) | |
371 { | |
372 #if defined(__UNIX__) || defined(__MAC__) | |
373 #if defined(__FreeBSD__) || defined(__MAC__) | |
374 struct statfs *fsp; | |
375 int entries, index = 1; | |
376 | |
377 strncpy(buf, "Unknown", len); | |
378 | |
379 entries = getmntinfo (&fsp, MNT_NOWAIT); | |
380 | |
381 for (; entries-- > 0; fsp++) | |
382 { | |
383 if(index == drive) | |
384 strncpy(buf, fsp->f_mntonname, len); | |
385 index++; | |
386 } | |
387 #elif defined(__sun__) | |
388 FILE *fp = fopen("/etc/mnttab", "r"); | |
389 struct mnttab mnt; | |
390 int index = 1; | |
391 | |
392 strncpy(buf, "Unknown", len); | |
393 | |
394 if(fp) | |
395 { | |
396 while(getmntent(fp, &mnt) == 0) | |
397 { | |
398 if(index == drive && mnt.mnt_mountp) | |
399 strncpy(buf, mnt.mnt_mountp, len); | |
400 index++; | |
401 } | |
402 fclose(fp); | |
403 } | |
404 #else | |
405 FILE *fp = setmntent(MOUNTED, "r"); | |
406 struct mntent mnt; | |
407 char buffer[1024]; | |
408 int index = 1; | |
409 | |
410 strncpy(buf, "Unknown", len); | |
411 | |
412 if(fp) | |
413 { | |
414 while(getmntent_r(fp, &mnt, buffer, sizeof(buffer))) | |
415 { | |
416 if(index == drive && mnt.mnt_dir) | |
417 strncpy(buf, mnt.mnt_dir, len); | |
418 index++; | |
419 } | |
420 endmntent(fp); | |
421 } | |
422 #endif | |
423 #elif defined(__OS2__) | |
424 /* No snprintf() on OS/2 ??? */ | |
425 len = len; | |
426 sprintf(buf, "Drive %c", (char)drive + 'A' - 1); | |
427 #else | |
428 _snprintf(buf, len, "Drive %c", (char)drive + 'A' - 1); | |
429 #endif | |
430 } | |
431 | |
432 void API setfileinfo(char *filename, char *url, char *logfile) | |
433 { | |
434 time_t ltime; | |
435 struct tm *tm; | |
436 char buffer[200], timebuf[200]; | |
437 #ifdef __OS2__ | |
438 const unsigned fea2listsize = 6000; | |
439 char *pData; | |
440 EAOP2 eaop2; | |
441 PFEA2 pFEA2; | |
442 #else | |
443 FILE *urlfile; | |
444 #endif | |
445 | |
446 ltime = time(NULL); | |
447 | |
448 tm = localtime(<ime); | |
449 | |
450 strftime(timebuf, 200, "%c", tm); | |
451 | |
452 sprintf(buffer, "%s %s", url, timebuf); | |
453 | |
454 #ifdef __OS2__ | |
455 logfile = logfile; | |
456 eaop2.fpGEA2List = 0; | |
457 eaop2.fpFEA2List = (PFEA2LIST)malloc(fea2listsize); | |
458 pFEA2 = &eaop2.fpFEA2List->list[0]; | |
459 | |
460 pFEA2->fEA = 0; | |
461 /* .COMMENTS is 9 characters long */ | |
462 pFEA2->cbName = 9; | |
463 | |
464 /* space for the type and length field. */ | |
465 pFEA2->cbValue = strlen(buffer)+2*sizeof(USHORT); | |
466 | |
467 strcpy(pFEA2->szName, ".COMMENTS"); | |
468 pData = pFEA2->szName+pFEA2->cbName+1; | |
469 /* data begins at first byte after the name */ | |
470 | |
471 *(USHORT*)pData = EAT_ASCII; /* type */ | |
472 *((USHORT*)pData+1) = strlen(buffer); /* length */ | |
473 strcpy(pData+2*sizeof(USHORT), buffer);/* content */ | |
474 | |
475 pFEA2->oNextEntryOffset = 0; | |
476 | |
477 eaop2.fpFEA2List->cbList = ((PCHAR)pData+2*sizeof(USHORT)+ | |
478 pFEA2->cbValue)-((PCHAR)eaop2.fpFEA2List); | |
479 | |
480 DosSetPathInfo((PSZ)filename, | |
481 FIL_QUERYEASIZE, | |
482 &eaop2, | |
483 sizeof(eaop2), | |
484 0); | |
485 | |
486 free((void *)eaop2.fpFEA2List); | |
487 #else | |
488 | |
489 if((urlfile = fopen(logfile, "a"))!=NULL) | |
490 { | |
491 fprintf(urlfile, "%s\n", buffer); | |
492 fclose(urlfile); | |
493 } | |
494 #endif | |
495 } | |
496 | |
497 #if defined(__OS2__) || defined(__WIN32__) | |
498 typedef struct _fsinfo { | |
499 FILE *fp; | |
500 int fd; | |
501 } FSInfo; | |
502 | |
503 FSInfo *FSIRoot = NULL; | |
504 | |
505 #define FSI_MAX 100 | |
506 #endif | |
507 | |
508 /* Sharable fopen() and fclose() calls. */ | |
509 FILE * API fsopen(char *path, char *modes) | |
510 { | |
511 #if (defined(__OS2__) && !defined(__WATCOMC__)) || defined(__WIN32__) | |
512 int z; | |
513 | |
514 if(!FSIRoot) | |
515 FSIRoot = calloc(sizeof(struct _fsinfo), FSI_MAX); | |
516 | |
517 for(z=0;z<FSI_MAX;z++) | |
518 { | |
519 if(FSIRoot[z].fd < 1) | |
520 { | |
521 int s, sopenmode = 0, wrmode = 0; | |
522 | |
523 /* Check the flags passed */ | |
524 for(s=0;s<3;s++) | |
525 { | |
526 if(modes[s] == 'b') | |
527 sopenmode |= O_BINARY; | |
528 if(modes[s] == 'r') | |
529 wrmode |= O_RDONLY; | |
530 if(modes[s] == 'w') | |
531 wrmode |= O_WRONLY; | |
532 if(modes[s] == 'a') | |
533 sopenmode |= O_APPEND; | |
534 if(modes[s] == 't') | |
535 sopenmode |= O_TEXT; | |
536 } | |
537 | |
538 /* Check the read/write request */ | |
539 if((wrmode & O_RDONLY) && (wrmode & O_WRONLY)) | |
540 sopenmode |= O_RDWR; | |
541 else | |
542 sopenmode |= wrmode; | |
543 FSIRoot[z].fd = _sopen(path, sopenmode, SH_DENYNO, S_IREAD|S_IWRITE); | |
544 if(FSIRoot[z].fd > 0) | |
545 { | |
546 FSIRoot[z].fp = fdopen(FSIRoot[z].fd, modes); | |
547 | |
548 return FSIRoot[z].fp; | |
549 } | |
550 } | |
551 } | |
552 return NULL; | |
553 #else | |
554 return fopen(path, modes); | |
555 #endif | |
556 } | |
557 | |
558 int API fsclose(FILE *fp) | |
559 { | |
560 #if defined(__OS2__) || defined(__WIN32__) | |
561 if(FSIRoot) | |
562 { | |
563 | |
564 int z; | |
565 for(z=0;z<FSI_MAX;z++) | |
566 { | |
567 if(fp == FSIRoot[z].fp) | |
568 { | |
569 int ret = fclose(fp); | |
570 close(FSIRoot[z].fd); | |
571 FSIRoot[z].fd = 0; | |
572 FSIRoot[z].fp = NULL; | |
573 return ret; | |
574 } | |
575 } | |
576 } | |
577 #endif | |
578 return fclose(fp); | |
579 } | |
580 | |
581 char * API fsgets(char *str, int size, FILE *stream) | |
582 { | |
583 return fgets(str, size, stream); | |
584 } | |
585 | |
586 int API fsseek(FILE *stream, long offset, int whence) | |
587 { | |
588 return fseek(stream, offset, whence); | |
589 } | |
590 | |
591 void API nice_strformat(char *dest, long double val, int dec) | |
592 { | |
593 char formatbuf[10]; | |
594 char format = 0; | |
595 double printval; | |
596 | |
597 /* 1024 ^ 3 = Gigabytes */ | |
598 if(val >= 1073741824L) | |
599 { | |
600 printval = val/(1073741824L); | |
601 format = 'G'; | |
602 } | |
603 /* 1024 ^ 2 = Megabytes */ | |
604 else if(val >= 1048576) | |
605 { | |
606 printval = val/(1048576); | |
607 format = 'M'; | |
608 } | |
609 /* 1024 = Kilobytes */ | |
610 else if(val > 1024) | |
611 { | |
612 printval = val/1024; | |
613 format = 'K'; | |
614 } | |
615 else | |
616 printval = val; | |
617 | |
618 /* Generate the format string */ | |
619 sprintf(formatbuf, "%%.%df%c", dec, format); | |
620 /* Create the pretty value */ | |
621 sprintf(dest, formatbuf, printval); | |
622 } | |
623 | |
624 /* Update the current working directory based on the | |
625 * path of the executable being executed. | |
626 */ | |
627 void API initdir(int argc, char *argv[]) | |
628 { | |
629 if(argc > 0) | |
630 { | |
631 char *tmpdir = strdup(argv[0]); | |
632 int z, len = (int)strlen(argv[0]); | |
633 | |
634 for(z=len;z > -1;z--) | |
635 { | |
636 if(tmpdir[z] == '/') | |
637 { | |
638 tmpdir[z+1] = 0; | |
639 setpath(tmpdir); | |
640 free(tmpdir); | |
641 return; | |
642 } | |
643 } | |
644 free(tmpdir); | |
645 } | |
646 } | |
647 | |
648 /* | |
649 * Sets the current directory (and drive) information. | |
650 * Parameters: | |
651 * path: A buffer containing the new path. | |
652 * Returns: | |
653 * -1 on error. | |
654 */ | |
655 int API setpath(char *path) | |
656 { | |
657 #if defined(__OS2__) || defined(__WIN32__) | |
658 if(strlen(path) > 2) | |
659 { | |
660 if(path[1] == ':') | |
661 { | |
662 char drive = toupper(path[0]); | |
663 _chdrive((drive - 'A')+1); | |
664 } | |
665 } | |
666 #endif | |
667 return chdir(path); | |
668 } | |
669 | |
670 static int locale_number = -1, locale_count = 0; | |
671 static char **locale_text = NULL; | |
672 | |
673 void _compat_free_locale(void) | |
674 { | |
675 if(locale_text) | |
676 { | |
677 int z; | |
678 | |
679 for(z=0;z<locale_count;z++) | |
680 { | |
681 if(locale_text[z]) | |
682 free(locale_text[z]); | |
683 } | |
684 free(locale_text); | |
685 locale_text = NULL; | |
686 } | |
687 } | |
688 | |
689 int _stripcrlf(char *buf) | |
690 { | |
691 int z, len = (int)strlen(buf); | |
692 | |
693 for(z=0;z<len;z++) | |
694 { | |
695 if(buf[z] == '\r' || buf[z] == '\n') | |
696 { | |
697 buf[z] = 0; | |
698 return 1; | |
699 } | |
700 } | |
701 return 1; | |
702 } | |
703 | |
704 #ifdef __WIN32__ | |
705 #define LOCALE_CHARACTERS 62 | |
706 static char locale_table[LOCALE_CHARACTERS * 2] = { | |
707 0xc0, 0xb7, 0xc1, 0xb5, 0xc2, 0xb6, 0xc3, 0xc7, 0xc4, 0x8e, 0xc5, 0x8f, | |
708 0xc6, 0x92, 0xc7, 0x80, 0xc8, 0xd4, 0xc9, 0x90, 0xcb, 0xd3, 0xcc, 0xde, | |
709 0xcd, 0xd6, 0xce, 0xd7, 0xcf, 0xd8, 0xd0, 0xd1, 0xd1, 0xa5, 0xd2, 0xe3, | |
710 0xd3, 0xe0, 0xd4, 0xe2, 0xd5, 0xe5, 0xd6, 0x99, 0xd8, 0x9d, 0xd9, 0xeb, | |
711 0xda, 0xe9, 0xdb, 0xea, 0xdc, 0x9a, 0xde, 0xed, 0xde, 0xe8, 0xdf, 0xe1, | |
712 0xe0, 0x85, 0xe1, 0xa0, 0xe2, 0x83, 0xe3, 0xc6, 0xe4, 0x84, 0xe5, 0x86, | |
713 0xe6, 0x91, 0xe7, 0x87, 0xe8, 0x8a, 0xe9, 0x82, 0xea, 0x88, 0xeb, 0x89, | |
714 0xec, 0x8d, 0xed, 0xa1, 0xee, 0x8c, 0xef, 0x8b, 0xf0, 0xd0, 0xf1, 0xa4, | |
715 0xf2, 0x95, 0xf3, 0xa3, 0xf4, 0x93, 0xf5, 0xe4, 0xf6, 0x94, 0xf7, 0xf6, | |
716 0xf8, 0x9b, 0xf9, 0x97, 0xfa, 0xa3, 0xfb, 0x96, 0xfc, 0x81, 0xfd, 0xec, | |
717 0xfe, 0xe7, 0xff, 0x9e | |
718 | |
719 }; | |
720 | |
721 char locale_convert(int codepage, char c) | |
722 { | |
723 int z; | |
724 | |
725 for(z=0;z<LOCALE_CHARACTERS;z++) | |
726 { | |
727 if(locale_table[(z*2)+1] == c) | |
728 return locale_table[z*2]; | |
729 } | |
730 return c; | |
731 } | |
732 #endif | |
733 | |
734 /* Initialize the locale engine | |
735 * Returns: TRUE on success, FALSE on failure. | |
736 */ | |
737 int API locale_init(char *filename, int my_locale) | |
738 { | |
739 FILE *fp = fopen(filename, FOPEN_READ_TEXT); | |
740 static char text[1025]; | |
741 int count = 0; | |
742 | |
743 _compat_free_locale(); | |
744 | |
745 if(fp) | |
746 { | |
747 if(fgets(text, 1024, fp) && strncasecmp(text, "MESSAGES=", 9) == 0 && (count = atoi(&text[9])) > 0) | |
748 { | |
749 int current = -1; | |
750 | |
751 locale_text = calloc(count, sizeof(char *)); | |
752 | |
753 while(!feof(fp)) | |
754 { | |
755 if(fgets(text, 1024, fp) && _stripcrlf(text) && | |
756 strncasecmp(text, "LOCALE=", 7) == 0) | |
757 { | |
758 if(current > -1) | |
759 { | |
760 fclose(fp); | |
761 locale_count = count; | |
762 locale_number = my_locale; | |
763 return 1; | |
764 } | |
765 if(atoi(&text[7]) == my_locale) | |
766 current = 0; | |
767 } | |
768 else if(current > -1 && current < count) | |
769 { | |
770 /* Use defaults on blank lines */ | |
771 if(text[0]) | |
772 { | |
773 int x = 0, z, len = (int)strlen(text); | |
774 | |
775 locale_text[current] = calloc(1, len + 1); | |
776 | |
777 for(z=0;z<len;z++) | |
778 { | |
779 if(text[z] == '\\' && (text[z+1] == 'r' || text[z+1] == 'n' | |
780 || text[z+1] == '\"' || text[z+1] == '\'')) | |
781 { | |
782 switch(text[z+1]) | |
783 { | |
784 case 'r': | |
785 locale_text[current][x] = '\r'; | |
786 break; | |
787 case 'n': | |
788 locale_text[current][x] = '\n'; | |
789 break; | |
790 case '\"': | |
791 locale_text[current][x] = '\"'; | |
792 break; | |
793 case '\'': | |
794 locale_text[current][x] = '\''; | |
795 break; | |
796 } | |
797 x++; | |
798 z++; | |
799 } | |
800 else | |
801 { | |
802 #ifdef __WIN32__ | |
803 locale_text[current][x] = locale_convert(1252, text[z]); | |
804 #else | |
805 locale_text[current][x] = text[z]; | |
806 #endif | |
807 x++; | |
808 } | |
809 } | |
810 } | |
811 current++; | |
812 } | |
813 } | |
814 } | |
815 fclose(fp); | |
816 } | |
817 if(locale_text && count) | |
818 { | |
819 locale_count = count; | |
820 locale_number = my_locale; | |
821 return 1; | |
822 } | |
823 return 0; | |
824 } | |
825 | |
826 /* Retrieve a localized string if available */ | |
827 char * API locale_string(char *default_text, int message) | |
828 { | |
829 if(locale_number > -1 && message < locale_count && message > -1 && locale_text[message]) | |
830 return locale_text[message]; | |
831 return default_text; | |
832 } | |
833 |