3 * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
6 * Miscellaneous functions
15 #include "DeskLib:SWI.h"
18 #include <sys/types.h>
22 #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
29 #if !defined(__riscos)
31 * szGetHomeDirectory - get the name of the home directory
34 szGetHomeDirectory(void)
39 szHome
= decc$
translate_vms(getenv("HOME"));
40 #elif defined(__Plan9__)
41 szHome
= getenv("home");
43 szHome
= getenv("HOME");
46 if (szHome
== NULL
|| szHome
[0] == '\0') {
47 #if defined(N_PLAT_NLM)
52 werr(0, "I can't find the name of your HOME directory");
57 } /* end of szGetHomeDirectory */
60 * szGetAntiwordDirectory - get the name of the Antiword directory
63 szGetAntiwordDirectory(void)
66 return decc$
translate_vms(getenv("ANTIWORDHOME"));
68 return getenv("ANTIWORDHOME");
70 } /* end of szGetAntiwordDirectory */
71 #endif /* !__riscos */
74 * Get the size of the specified file.
75 * Returns -1 if the file does not exist or is not a proper file.
78 lGetFilesize(const char *szFilename
)
84 e
= SWI(2, 5, SWI_OS_File
| XOS_Bit
,
86 &iType
, NULL
, NULL
, NULL
, &iSize
);
88 werr(0, "Get Filesize error %d: %s",
89 e
->errnum
, e
->errmess
);
93 /* It's not a proper file or the file does not exist */
101 if (stat(szFilename
, &tBuffer
) != 0) {
102 werr(0, "Get Filesize error %d", errno
);
105 if (!S_ISREG(tBuffer
.st_mode
)) {
106 /* It's not a regular file */
109 return (long)tBuffer
.st_size
;
110 #endif /* __riscos */
111 } /* end of lGetFilesize */
115 vPrintBlock(const char *szFile
, int iLine
,
116 const UCHAR
*aucBlock
, size_t tLength
)
120 fail(szFile
== NULL
|| iLine
< 0 || aucBlock
== NULL
);
122 fprintf(stderr
, "%s[%3d]:\n", szFile
, iLine
);
123 for (i
= 0; i
< 32; i
++) {
124 if (16 * i
>= (int)tLength
) {
127 fprintf(stderr
, "%03x: ", (unsigned int)(16 * i
));
128 for (j
= 0; j
< 16; j
++) {
129 if (16 * i
+ j
< (int)tLength
) {
130 fprintf(stderr
, "%02x ",
131 (unsigned int)aucBlock
[16 * i
+ j
]);
134 fprintf(stderr
, "\n");
136 } /* end of vPrintBlock */
139 vPrintUnicode(const char *szFile
, int iLine
, const UCHAR
*aucUni
, size_t tLen
)
145 tLen
/= 2; /* Length in bytes to length in characters */
146 szASCII
= xmalloc(tLen
+ 1);
147 (void)unincpy(szASCII
, aucUni
, tLen
);
148 szASCII
[tLen
] = '\0';
149 (void)fprintf(stderr
, "%s[%3d]: %.*s\n",
150 szFile
, iLine
, (int)tLen
, szASCII
);
151 szASCII
= xfree(szASCII
);
152 } /* end of vPrintUnicode */
155 bCheckDoubleLinkedList(output_type
*pAnchor
)
157 output_type
*pCurr
, *pLast
;
162 for (pCurr
= pAnchor
; pCurr
!= NULL
; pCurr
= pCurr
->pNext
) {
167 for (pCurr
= pLast
; pCurr
!= NULL
; pCurr
= pCurr
->pPrev
) {
171 DBG_DEC_C(iInList
!= 0, iInList
);
172 return pAnchor
== pLast
&& iInList
== 0;
173 } /* end of bCheckDoubleLinkedList */
178 * This function reads the specified number of bytes from the specified file,
179 * starting from the specified offset.
180 * Returns TRUE when successfull, otherwise FALSE
183 bReadBytes(UCHAR
*aucBytes
, size_t tMemb
, ULONG ulOffset
, FILE *pFile
)
185 fail(aucBytes
== NULL
|| pFile
== NULL
|| ulOffset
> (ULONG
)LONG_MAX
);
187 if (ulOffset
> (ULONG
)LONG_MAX
) {
190 if (fseek(pFile
, (long)ulOffset
, SEEK_SET
) != 0) {
193 if (fread(aucBytes
, sizeof(UCHAR
), tMemb
, pFile
) != tMemb
) {
197 } /* end of bReadBytes */
201 * This function fills the specified buffer with the specified number of bytes,
202 * starting at the specified offset within the Big/Small Block Depot.
204 * Returns TRUE when successful, otherwise FALSE
207 bReadBuffer(FILE *pFile
, ULONG ulStartBlock
,
208 const ULONG
*aulBlockDepot
, size_t tBlockDepotLen
, size_t tBlockSize
,
209 UCHAR
*aucBuffer
, ULONG ulOffset
, size_t tToRead
)
211 ULONG ulBegin
, ulIndex
;
215 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
216 fail(aulBlockDepot
== NULL
);
217 fail(tBlockSize
!= BIG_BLOCK_SIZE
&& tBlockSize
!= SMALL_BLOCK_SIZE
);
218 fail(aucBuffer
== NULL
);
221 for (ulIndex
= ulStartBlock
;
222 ulIndex
!= END_OF_CHAIN
&& tToRead
!= 0;
223 ulIndex
= aulBlockDepot
[ulIndex
]) {
224 if (ulIndex
>= (ULONG
)tBlockDepotLen
) {
226 DBG_DEC(tBlockDepotLen
);
227 if (tBlockSize
>= BIG_BLOCK_SIZE
) {
228 werr(1, "The Big Block Depot is damaged");
230 werr(1, "The Small Block Depot is damaged");
233 if (ulOffset
>= (ULONG
)tBlockSize
) {
234 ulOffset
-= tBlockSize
;
237 ulBegin
= ulDepotOffset(ulIndex
, tBlockSize
) + ulOffset
;
238 tLen
= min(tBlockSize
- (size_t)ulOffset
, tToRead
);
240 if (!bReadBytes(aucBuffer
, tLen
, ulBegin
, pFile
)) {
241 werr(0, "Read big block 0x%lx not possible", ulBegin
);
247 DBG_DEC_C(tToRead
!= 0, tToRead
);
249 } /* end of bReadBuffer */
252 * Convert a Word colornumber into a true color for use in a drawfile
254 * Returns the true color
257 ulColor2Color(UCHAR ucFontColor
)
259 static const ULONG aulColorTable
[] = {
260 /* 0 */ 0x00000000UL
, /* Automatic */
261 /* 1 */ 0x00000000UL
, /* Black */
262 /* 2 */ 0xff000000UL
, /* Blue */
263 /* 3 */ 0xffff0000UL
, /* Turquoise */
264 /* 4 */ 0x00ff0000UL
, /* Bright Green */
265 /* 5 */ 0xff00ff00UL
, /* Pink */
266 /* 6 */ 0x0000ff00UL
, /* Red */
267 /* 7 */ 0x00ffff00UL
, /* Yellow */
268 /* 8 */ 0xffffff00UL
, /* White */
269 /* 9 */ 0x80000000UL
, /* Dark Blue */
270 /* 10 */ 0x80800000UL
, /* Teal */
271 /* 11 */ 0x00800000UL
, /* Green */
272 /* 12 */ 0x80008000UL
, /* Violet */
273 /* 13 */ 0x00008000UL
, /* Dark Red */
274 /* 14 */ 0x00808000UL
, /* Dark Yellow */
275 /* 15 */ 0x80808000UL
, /* Gray 50% */
276 /* 16 */ 0xc0c0c000UL
, /* Gray 25% */
278 if ((size_t)ucFontColor
>= elementsof(aulColorTable
)) {
279 return aulColorTable
[0];
281 return aulColorTable
[(int)ucFontColor
];
282 } /* end of ulColor2Color */
285 * iFindSplit - find a place to split the string
287 * returns the index of the split character or -1 if no split found.
290 iFindSplit(const char *szString
, size_t tStringLen
)
294 if (tStringLen
== 0) {
297 tSplit
= tStringLen
- 1;
298 while (tSplit
>= 1) {
299 if (szString
[tSplit
] == ' ' ||
300 (szString
[tSplit
] == '-' && szString
[tSplit
- 1] != ' ')) {
306 } /* end of iFindSplit */
309 * pSplitList - split the specified list in a printable part and a leftover part
311 * returns the pointer to the leftover part
314 pSplitList(output_type
*pAnchor
)
316 output_type
*pCurr
, *pLeftOver
;
319 fail(pAnchor
== NULL
);
321 for (pCurr
= pAnchor
; pCurr
->pNext
!= NULL
; pCurr
= pCurr
->pNext
)
324 for (; pCurr
!= NULL
; pCurr
= pCurr
->pPrev
) {
325 iIndex
= iFindSplit(pCurr
->szStorage
, pCurr
->tNextFree
);
331 if (pCurr
== NULL
|| iIndex
< 0) {
332 /* No split, no leftover */
335 /* Split over the iIndex-th character */
336 NO_DBG_MSG("pLeftOver");
337 pLeftOver
= xmalloc(sizeof(*pLeftOver
));
338 fail(pCurr
->tNextFree
< (size_t)iIndex
);
339 pLeftOver
->tStorageSize
= pCurr
->tNextFree
- (size_t)iIndex
;
340 pLeftOver
->szStorage
= xmalloc(pLeftOver
->tStorageSize
);
341 pLeftOver
->tNextFree
= pCurr
->tNextFree
- (size_t)iIndex
- 1;
342 (void)strncpy(pLeftOver
->szStorage
,
343 pCurr
->szStorage
+ iIndex
+ 1, pLeftOver
->tNextFree
);
344 pLeftOver
->szStorage
[pLeftOver
->tNextFree
] = '\0';
345 NO_DBG_MSG(pLeftOver
->szStorage
);
346 pLeftOver
->ucFontColor
= pCurr
->ucFontColor
;
347 pLeftOver
->usFontStyle
= pCurr
->usFontStyle
;
348 pLeftOver
->tFontRef
= pCurr
->tFontRef
;
349 pLeftOver
->usFontSize
= pCurr
->usFontSize
;
350 pLeftOver
->lStringWidth
= lComputeStringWidth(
351 pLeftOver
->szStorage
,
352 pLeftOver
->tNextFree
,
354 pLeftOver
->usFontSize
);
355 pLeftOver
->pPrev
= NULL
;
356 pLeftOver
->pNext
= pCurr
->pNext
;
357 if (pLeftOver
->pNext
!= NULL
) {
358 pLeftOver
->pNext
->pPrev
= pLeftOver
;
360 fail(!bCheckDoubleLinkedList(pLeftOver
));
362 NO_DBG_MSG("pAnchor");
363 NO_DBG_HEX(pCurr
->szStorage
[iIndex
]);
364 while (iIndex
>= 0 && isspace((int)(UCHAR
)pCurr
->szStorage
[iIndex
])) {
367 pCurr
->tNextFree
= (size_t)iIndex
+ 1;
368 pCurr
->szStorage
[pCurr
->tNextFree
] = '\0';
369 NO_DBG_MSG(pCurr
->szStorage
);
370 pCurr
->lStringWidth
= lComputeStringWidth(
376 fail(!bCheckDoubleLinkedList(pAnchor
));
379 } /* end of pSplitList */
382 * tNumber2Roman - convert a number to Roman Numerals
384 * returns the number of characters written
387 tNumber2Roman(UINT uiNumber
, BOOL bUpperCase
, char *szOutput
)
390 UINT uiNextVal
, uiValue
;
392 fail(szOutput
== NULL
);
394 uiNumber
%= 4000; /* Very high numbers can't be represented */
401 p
= bUpperCase
? "M\2D\5C\2L\5X\2V\5I" : "m\2d\5c\2l\5x\2v\5i";
404 while (uiNumber
>= uiValue
) {
410 fail(outp
< szOutput
);
411 return (size_t)(outp
- szOutput
);
414 uiNextVal
= uiValue
/ (UINT
)(UCHAR
)*q
;
415 if ((int)*q
== 2) { /* magic */
416 uiNextVal
/= (UINT
)(UCHAR
)*(q
+= 2);
418 if (uiNumber
+ uiNextVal
>= uiValue
) {
420 uiNumber
+= uiNextVal
;
423 uiValue
/= (UINT
)(UCHAR
)(*p
++);
426 } /* end of tNumber2Roman */
429 * iNumber2Alpha - convert a number to alphabetic "numbers"
431 * returns the number of characters written
434 tNumber2Alpha(UINT uiNumber
, BOOL bUpperCase
, char *szOutput
)
439 fail(szOutput
== NULL
);
447 uiTmp
= (UINT
)(bUpperCase
? 'A': 'a');
448 if (uiNumber
<= 26) {
450 *outp
++ = (char)(uiTmp
+ uiNumber
);
451 } else if (uiNumber
<= 26U + 26U*26U) {
453 *outp
++ = (char)(uiTmp
+ uiNumber
/ 26);
454 *outp
++ = (char)(uiTmp
+ uiNumber
% 26);
455 } else if (uiNumber
<= 26U + 26U*26U + 26U*26U*26U) {
456 uiNumber
-= 26 + 26*26 + 1;
457 *outp
++ = (char)(uiTmp
+ uiNumber
/ (26*26));
458 *outp
++ = (char)(uiTmp
+ uiNumber
/ 26 % 26);
459 *outp
++ = (char)(uiTmp
+ uiNumber
% 26);
462 fail(outp
< szOutput
);
463 return (size_t)(outp
- szOutput
);
464 } /* end of tNumber2Alpha */
467 * unincpy - copy a counted Unicode string to an single-byte string
470 unincpy(char *s1
, const UCHAR
*s2
, size_t n
)
477 for (pcDest
= s1
, tLen
= 0; tLen
< n
; pcDest
++, tLen
++) {
478 usUni
= usGetWord(tLen
* 2, s2
);
482 ulChar
= ulTranslateCharacters(usUni
, 0, 8,
483 conversion_unknown
, encoding_neutral
, FALSE
);
484 if (ulChar
== IGNORE_CHARACTER
) {
487 *pcDest
= (char)ulChar
;
489 for (; tLen
< n
; tLen
++) {
493 } /* end of unincpy */
496 * unilen - calculate the length of a Unicode string
498 * returns the length in bytes
501 unilen(const UCHAR
*s
)
508 usUni
= usGetWord(tLen
, s
);
514 } /* end of unilen */
517 * szBaseName - get the basename of the specified filename
520 szBasename(const char *szFilename
)
524 fail(szFilename
== NULL
);
526 if (szFilename
== NULL
|| szFilename
[0] == '\0') {
530 szTmp
= strrchr(szFilename
, FILE_SEPARATOR
[0]);
535 } /* end of szBasename */
538 * lComputeLeading - compute the leading
540 * NOTE: the fontsize is specified in half points
542 * Returns the leading in drawunits
545 lComputeLeading(USHORT usFontSize
)
549 lLeading
= (long)usFontSize
* 500L;
550 if (usFontSize
< 18) { /* Small text: 112% */
552 } else if (usFontSize
< 28) { /* Normal text: 124% */
554 } else if (usFontSize
< 48) { /* Small headlines: 104% */
556 } else { /* Large headlines: 100% */
559 lLeading
= lMilliPoints2DrawUnits(lLeading
);
563 } /* end of lComputeLeading */
566 * Convert a UCS character to an UTF-8 string
568 * Returns the string length of the result
571 tUcs2Utf8(ULONG ulChar
, char *szResult
, size_t tMaxResultLen
)
573 if (szResult
== NULL
|| tMaxResultLen
== 0) {
577 if (ulChar
< 0x80 && tMaxResultLen
>= 2) {
578 szResult
[0] = (char)ulChar
;
582 if (ulChar
< 0x800 && tMaxResultLen
>= 3) {
583 szResult
[0] = (char)(0xc0 | ulChar
>> 6);
584 szResult
[1] = (char)(0x80 | (ulChar
& 0x3f));
588 if (ulChar
< 0x10000 && tMaxResultLen
>= 4) {
589 szResult
[0] = (char)(0xe0 | ulChar
>> 12);
590 szResult
[1] = (char)(0x80 | (ulChar
>> 6 & 0x3f));
591 szResult
[2] = (char)(0x80 | (ulChar
& 0x3f));
595 if (ulChar
< 0x200000 && tMaxResultLen
>= 5) {
596 szResult
[0] = (char)(0xf0 | ulChar
>> 18);
597 szResult
[1] = (char)(0x80 | (ulChar
>> 12 & 0x3f));
598 szResult
[2] = (char)(0x80 | (ulChar
>> 6 & 0x3f));
599 szResult
[3] = (char)(0x80 | (ulChar
& 0x3f));
605 } /* end of tUcs2Utf8 */
608 * vGetBulletValue - get the bullet value for the conversing type and encoding
611 vGetBulletValue(conversion_type eConversionType
, encoding_type eEncoding
,
612 char *szResult
, size_t tMaxResultLen
)
614 fail(szResult
== NULL
);
615 fail(tMaxResultLen
< 2);
617 if (eEncoding
== encoding_utf_8
) {
618 (void)tUcs2Utf8(UNICODE_BULLET
, szResult
, tMaxResultLen
);
620 szResult
[0] = (char)ucGetBulletCharacter(eConversionType
,
624 } /* end of vGetBulletValue */
627 * bAllZero - are all bytes zero?
630 bAllZero(const UCHAR
*aucBytes
, size_t tLength
)
634 if (aucBytes
== NULL
|| tLength
== 0) {
638 for (tIndex
= 0; tIndex
< tLength
; tIndex
++) {
639 if (aucBytes
[tIndex
] != 0) {
644 } /* end of bAllZero */
646 #if !defined(__riscos)
648 * GetCodesetFromLocale - get the codeset from the current locale
650 * Original version: Copyright (C) 1999 Bruno Haible
652 * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
654 * Returns TRUE when sucessful, otherwise FALSE
657 bGetCodesetFromLocale(char *szCodeset
, size_t tMaxCodesetLength
, BOOL
*pbEuro
)
660 const char *szLocale
;
666 if (pbEuro
!= NULL
) {
667 *pbEuro
= FALSE
; /* Until proven otherwise */
669 if (szCodeset
== NULL
|| tMaxCodesetLength
== 0) {
674 if (tMaxCodesetLength
< 2 + sizeof(int) * 3 + 1) {
675 DBG_DEC(tMaxCodesetLength
);
676 DBG_DEC(2 + sizeof(int) * 3 + 1);
679 /* Get the active codepage from DOS */
680 sprintf(szCodeset
, "cp%d", iGetCodepage());
683 /* Get the locale from the environment */
684 szLocale
= getenv("LC_ALL");
685 if (szLocale
== NULL
|| szLocale
[0] == '\0') {
686 szLocale
= getenv("LC_CTYPE");
687 if (szLocale
== NULL
|| szLocale
[0] == '\0') {
688 szLocale
= getenv("LANG");
691 if (szLocale
== NULL
|| szLocale
[0] == '\0') {
692 /* No locale, so no codeset name and no modifier */
696 pcTmp
= strchr(szLocale
, '.');
698 /* No codeset name */
701 /* Copy the codeset name */
703 for (tIndex
= 0; tIndex
< tMaxCodesetLength
; tIndex
++) {
704 if (*pcTmp
== '@' || *pcTmp
== '+' ||
705 *pcTmp
== ',' || *pcTmp
== '_' ||
707 szCodeset
[tIndex
] = '\0';
710 szCodeset
[tIndex
] = *pcTmp
;
713 szCodeset
[tMaxCodesetLength
- 1] = '\0';
715 if (pbEuro
== NULL
) {
716 /* No need to get the modifier */
719 pcTmp
= strchr(szLocale
, '@');
721 /* Copy the modifier */
723 for (tIndex
= 0; tIndex
< sizeof(szModifier
); tIndex
++) {
724 if (*pcTmp
== '+' || *pcTmp
== ',' ||
725 *pcTmp
== '_' || *pcTmp
== '\0') {
726 szModifier
[tIndex
] = '\0';
729 szModifier
[tIndex
] = *pcTmp
;
732 szModifier
[sizeof(szModifier
) - 1] = '\0';
733 *pbEuro
= STRCEQ(szModifier
, "Euro");
737 } /* end of bGetCodesetFromLocale */
740 * GetNormalizedCodeset - get the normalized codeset from the current locale
742 * Returns TRUE when sucessful, otherwise FALSE
745 bGetNormalizedCodeset(char *szCodeset
, size_t tMaxCodesetLength
, BOOL
*pbEuro
)
750 char *szTmp
, *szCodesetNorm
;
752 if (pbEuro
!= NULL
) {
753 *pbEuro
= FALSE
; /* Until proven otherwise */
755 if (szCodeset
== NULL
|| tMaxCodesetLength
< 4) {
759 /* Get the codeset name */
760 szTmp
= xmalloc(tMaxCodesetLength
- 3);
761 if (!bGetCodesetFromLocale(szTmp
, tMaxCodesetLength
- 3, pbEuro
)) {
762 szTmp
= xfree(szTmp
);
765 /* Normalize the codeset name */
766 szCodesetNorm
= xmalloc(tMaxCodesetLength
- 3);
768 pcDest
= szCodesetNorm
;
769 for (pcSrc
= szTmp
; *pcSrc
!= '\0'; pcSrc
++) {
770 if (isalnum(*pcSrc
)) {
771 *pcDest
= tolower(*pcSrc
);
772 if (!isdigit(*pcDest
)) {
779 DBG_MSG(szCodesetNorm
);
780 /* Add "iso" when szCodesetNorm contains all digits */
781 if (bOnlyDigits
&& szCodesetNorm
[0] != '\0') {
782 fail(strlen(szCodesetNorm
) + 3 >= tMaxCodesetLength
);
783 sprintf(szCodeset
, "iso%s", szCodesetNorm
);
785 fail(strlen(szCodesetNorm
) >= tMaxCodesetLength
);
786 strncpy(szCodeset
, szCodesetNorm
, pcDest
- szCodesetNorm
+ 1);
787 szCodeset
[tMaxCodesetLength
- 1] = '\0';
790 /* Clean up and leave */
791 szCodesetNorm
= xfree(szCodesetNorm
);
792 szTmp
= xfree(szTmp
);
794 } /* end of bGetNormalizedCodeset */
797 * szGetDefaultMappingFile - get the default mapping file
799 * Returns the basename of the default mapping file
802 szGetDefaultMappingFile(void)
804 static const struct {
805 const char *szCodeset
;
806 const char *szMappingFile
;
807 } atMappingFile
[] = {
808 { "iso88591", MAPPING_FILE_8859_1
},
809 { "iso88592", MAPPING_FILE_8859_2
},
810 { "iso88593", "8859-3.txt" },
811 { "iso88594", "8859-4.txt" },
812 { "iso88595", "8859-5.txt" },
813 { "iso88596", MAPPING_FILE_8859_5
},
814 { "iso88597", "8859-7.txt" },
815 { "iso88598", "8859-8.txt" },
816 { "iso88599", "8859-9.txt" },
817 { "iso885910", "8859-10.txt" },
818 { "iso885913", "8859-13.txt" },
819 { "iso885914", "8859-14.txt" },
820 { "iso885915", MAPPING_FILE_8859_15
},
821 { "iso885916", "8859-16.txt" },
822 { "koi8r", MAPPING_FILE_KOI8_R
},
823 { "koi8u", MAPPING_FILE_KOI8_U
},
824 { "utf8", MAPPING_FILE_UTF_8
},
825 { "cp437", MAPPING_FILE_CP437
},
826 { "cp850", "cp850.txt" },
827 { "cp852", MAPPING_FILE_CP852
},
828 { "cp862", "cp862.txt" },
829 { "cp864", "cp864.txt" },
830 { "cp866", MAPPING_FILE_CP866
},
831 { "cp1250", MAPPING_FILE_CP1250
},
832 { "cp1251", MAPPING_FILE_CP1251
},
833 { "cp1252", "cp1252.txt" },
841 /* Get the normalized codeset name */
842 if (!bGetNormalizedCodeset(szCodeset
, sizeof(szCodeset
), &bEuro
)) {
843 return MAPPING_FILE_8859_1
;
845 if (szCodeset
[0] == '\0') {
847 /* Default mapping file (with Euro sign) */
848 return MAPPING_FILE_8859_15
;
850 /* Default mapping file (without Euro sign) */
851 return MAPPING_FILE_8859_1
;
854 /* Find the name in the table */
855 for (tIndex
= 0; tIndex
< elementsof(atMappingFile
); tIndex
++) {
856 if (STREQ(atMappingFile
[tIndex
].szCodeset
, szCodeset
)) {
857 return atMappingFile
[tIndex
].szMappingFile
;
860 /* Default default mapping file */
862 return MAPPING_FILE_CP437
;
864 return MAPPING_FILE_8859_1
;
866 } /* end of szGetDefaultMappingFile */
867 #endif /* !__riscos */
870 * tConvertDTTM - convert Windows Date and Time format
872 * returns Unix time_t or -1
875 tConvertDTTM(ULONG ulDTTM
)
883 memset(&tTime
, 0, sizeof(tTime
));
884 tTime
.tm_min
= (int)(ulDTTM
& 0x0000003f);
885 tTime
.tm_hour
= (int)((ulDTTM
& 0x000007c0) >> 6);
886 tTime
.tm_mday
= (int)((ulDTTM
& 0x0000f800) >> 11);
887 tTime
.tm_mon
= (int)((ulDTTM
& 0x000f0000) >> 16);
888 tTime
.tm_year
= (int)((ulDTTM
& 0x1ff00000) >> 20);
890 tTime
.tm_mon
--; /* From 01-12 to 00-11 */
891 tResult
= mktime(&tTime
);
892 NO_DBG_MSG(ctime(&tResult
));
894 } /* end of tConvertDTTM */