diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/misc_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/misc_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,910 +0,0 @@ - - -
- -00001 /* -00002 * misc.c -00003 * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL -00004 * -00005 * Description: -00006 * Miscellaneous functions -00007 */ -00008 -00009 #include <stdio.h> -00010 #include <stdlib.h> -00011 #include <string.h> -00012 #include <ctype.h> -00013 #include <time.h> -00014 #if defined(__riscos) -00015 #include "DeskLib:SWI.h" -00016 #else -00017 #include <errno.h> -00018 #include <sys/types.h> -00019 #include <sys/stat.h> -00020 #endif /* __riscos */ -00021 #if !defined(S_ISREG) -00022 #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) -00023 #endif /* !S_ISREG */ -00024 #include "antiword.h" -00025 #if defined(__vms) -00026 #include <unixlib.h> -00027 #endif -00028 -00029 #if !defined(__riscos) -00030 /* -00031 * szGetHomeDirectory - get the name of the home directory -00032 */ -00033 const char * -00034 szGetHomeDirectory(void) -00035 { -00036 const char *szHome; -00037 -00038 #if defined(__vms) -00039 szHome = decc$translate_vms(getenv("HOME")); -00040 #elif defined(__Plan9__) -00041 szHome = getenv("home"); -00042 #else -00043 szHome = getenv("HOME"); -00044 #endif /* __vms */ -00045 -00046 if (szHome == NULL || szHome[0] == '\0') { -00047 #if defined(N_PLAT_NLM) -00048 szHome = "SYS:"; -00049 #elif defined(__dos) -00050 szHome = "C:"; -00051 #else -00052 werr(0, "I can't find the name of your HOME directory"); -00053 szHome = ""; -00054 #endif /* __dos */ -00055 } -00056 return szHome; -00057 } /* end of szGetHomeDirectory */ -00058 -00059 /* -00060 * szGetAntiwordDirectory - get the name of the Antiword directory -00061 */ -00062 const char * -00063 szGetAntiwordDirectory(void) -00064 { -00065 #if defined(__vms) -00066 return decc$translate_vms(getenv("ANTIWORDHOME")); -00067 #else -00068 return getenv("ANTIWORDHOME"); -00069 #endif /* __vms */ -00070 } /* end of szGetAntiwordDirectory */ -00071 #endif /* !__riscos */ -00072 -00073 /* -00074 * Get the size of the specified file. -00075 * Returns -1 if the file does not exist or is not a proper file. -00076 */ -00077 long -00078 lGetFilesize(const char *szFilename) -00079 { -00080 #if defined(__riscos) -00081 os_error *e; -00082 int iType, iSize; -00083 -00084 e = SWI(2, 5, SWI_OS_File | XOS_Bit, -00085 17, szFilename, -00086 &iType, NULL, NULL, NULL, &iSize); -00087 if (e != NULL) { -00088 werr(0, "Get Filesize error %d: %s", -00089 e->errnum, e->errmess); -00090 return -1; -00091 } -00092 if (iType != 1) { -00093 /* It's not a proper file or the file does not exist */ -00094 return -1; -00095 } -00096 return (long)iSize; -00097 #else -00098 struct stat tBuffer; -00099 -00100 errno = 0; -00101 if (stat(szFilename, &tBuffer) != 0) { -00102 werr(0, "Get Filesize error %d", errno); -00103 return -1; -00104 } -00105 if (!S_ISREG(tBuffer.st_mode)) { -00106 /* It's not a regular file */ -00107 return -1; -00108 } -00109 return (long)tBuffer.st_size; -00110 #endif /* __riscos */ -00111 } /* end of lGetFilesize */ -00112 -00113 #if defined(DEBUG) -00114 void -00115 vPrintBlock(const char *szFile, int iLine, -00116 const UCHAR *aucBlock, size_t tLength) -00117 { -00118 int i, j; -00119 -00120 fail(szFile == NULL || iLine < 0 || aucBlock == NULL); -00121 -00122 fprintf(stderr, "%s[%3d]:\n", szFile, iLine); -00123 for (i = 0; i < 32; i++) { -00124 if (16 * i >= (int)tLength) { -00125 return; -00126 } -00127 fprintf(stderr, "%03x: ", (unsigned int)(16 * i)); -00128 for (j = 0; j < 16; j++) { -00129 if (16 * i + j < (int)tLength) { -00130 fprintf(stderr, "%02x ", -00131 (unsigned int)aucBlock[16 * i + j]); -00132 } -00133 } -00134 fprintf(stderr, "\n"); -00135 } -00136 } /* end of vPrintBlock */ -00137 -00138 void -00139 vPrintUnicode(const char *szFile, int iLine, const UCHAR *aucUni, size_t tLen) -00140 { -00141 char *szASCII; -00142 -00143 fail(tLen % 2 != 0); -00144 -00145 tLen /= 2; /* Length in bytes to length in characters */ -00146 szASCII = xmalloc(tLen + 1); -00147 (void)unincpy(szASCII, aucUni, tLen); -00148 szASCII[tLen] = '\0'; -00149 (void)fprintf(stderr, "%s[%3d]: %.*s\n", -00150 szFile, iLine, (int)tLen, szASCII); -00151 szASCII = xfree(szASCII); -00152 } /* end of vPrintUnicode */ -00153 -00154 BOOL -00155 bCheckDoubleLinkedList(output_type *pAnchor) -00156 { -00157 output_type *pCurr, *pLast; -00158 int iInList; -00159 -00160 pLast = pAnchor; -00161 iInList = 0; -00162 for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { -00163 pLast = pCurr; -00164 iInList++; -00165 } -00166 NO_DBG_DEC(iInList); -00167 for (pCurr = pLast; pCurr != NULL; pCurr = pCurr->pPrev) { -00168 pLast = pCurr; -00169 iInList--; -00170 } -00171 DBG_DEC_C(iInList != 0, iInList); -00172 return pAnchor == pLast && iInList == 0; -00173 } /* end of bCheckDoubleLinkedList */ -00174 #endif /* DEBUG */ -00175 -00176 /* -00177 * bReadBytes -00178 * This function reads the specified number of bytes from the specified file, -00179 * starting from the specified offset. -00180 * Returns TRUE when successfull, otherwise FALSE -00181 */ -00182 BOOL -00183 bReadBytes(UCHAR *aucBytes, size_t tMemb, ULONG ulOffset, FILE *pFile) -00184 { -00185 fail(aucBytes == NULL || pFile == NULL || ulOffset > (ULONG)LONG_MAX); -00186 -00187 if (ulOffset > (ULONG)LONG_MAX) { -00188 return FALSE; -00189 } -00190 if (fseek(pFile, (long)ulOffset, SEEK_SET) != 0) { -00191 return FALSE; -00192 } -00193 if (fread(aucBytes, sizeof(UCHAR), tMemb, pFile) != tMemb) { -00194 return FALSE; -00195 } -00196 return TRUE; -00197 } /* end of bReadBytes */ -00198 -00199 /* -00200 * bReadBuffer -00201 * This function fills the specified buffer with the specified number of bytes, -00202 * starting at the specified offset within the Big/Small Block Depot. -00203 * -00204 * Returns TRUE when successful, otherwise FALSE -00205 */ -00206 BOOL -00207 bReadBuffer(FILE *pFile, ULONG ulStartBlock, -00208 const ULONG *aulBlockDepot, size_t tBlockDepotLen, size_t tBlockSize, -00209 UCHAR *aucBuffer, ULONG ulOffset, size_t tToRead) -00210 { -00211 ULONG ulBegin, ulIndex; -00212 size_t tLen; -00213 -00214 fail(pFile == NULL); -00215 fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); -00216 fail(aulBlockDepot == NULL); -00217 fail(tBlockSize != BIG_BLOCK_SIZE && tBlockSize != SMALL_BLOCK_SIZE); -00218 fail(aucBuffer == NULL); -00219 fail(tToRead == 0); -00220 -00221 for (ulIndex = ulStartBlock; -00222 ulIndex != END_OF_CHAIN && tToRead != 0; -00223 ulIndex = aulBlockDepot[ulIndex]) { -00224 if (ulIndex >= (ULONG)tBlockDepotLen) { -00225 DBG_DEC(ulIndex); -00226 DBG_DEC(tBlockDepotLen); -00227 if (tBlockSize >= BIG_BLOCK_SIZE) { -00228 werr(1, "The Big Block Depot is damaged"); -00229 } else { -00230 werr(1, "The Small Block Depot is damaged"); -00231 } -00232 } -00233 if (ulOffset >= (ULONG)tBlockSize) { -00234 ulOffset -= tBlockSize; -00235 continue; -00236 } -00237 ulBegin = ulDepotOffset(ulIndex, tBlockSize) + ulOffset; -00238 tLen = min(tBlockSize - (size_t)ulOffset, tToRead); -00239 ulOffset = 0; -00240 if (!bReadBytes(aucBuffer, tLen, ulBegin, pFile)) { -00241 werr(0, "Read big block 0x%lx not possible", ulBegin); -00242 return FALSE; -00243 } -00244 aucBuffer += tLen; -00245 tToRead -= tLen; -00246 } -00247 DBG_DEC_C(tToRead != 0, tToRead); -00248 return tToRead == 0; -00249 } /* end of bReadBuffer */ -00250 -00251 /* -00252 * Convert a Word colornumber into a true color for use in a drawfile -00253 * -00254 * Returns the true color -00255 */ -00256 ULONG -00257 ulColor2Color(UCHAR ucFontColor) -00258 { -00259 static const ULONG aulColorTable[] = { -00260 /* 0 */ 0x00000000UL, /* Automatic */ -00261 /* 1 */ 0x00000000UL, /* Black */ -00262 /* 2 */ 0xff000000UL, /* Blue */ -00263 /* 3 */ 0xffff0000UL, /* Turquoise */ -00264 /* 4 */ 0x00ff0000UL, /* Bright Green */ -00265 /* 5 */ 0xff00ff00UL, /* Pink */ -00266 /* 6 */ 0x0000ff00UL, /* Red */ -00267 /* 7 */ 0x00ffff00UL, /* Yellow */ -00268 /* 8 */ 0xffffff00UL, /* White */ -00269 /* 9 */ 0x80000000UL, /* Dark Blue */ -00270 /* 10 */ 0x80800000UL, /* Teal */ -00271 /* 11 */ 0x00800000UL, /* Green */ -00272 /* 12 */ 0x80008000UL, /* Violet */ -00273 /* 13 */ 0x00008000UL, /* Dark Red */ -00274 /* 14 */ 0x00808000UL, /* Dark Yellow */ -00275 /* 15 */ 0x80808000UL, /* Gray 50% */ -00276 /* 16 */ 0xc0c0c000UL, /* Gray 25% */ -00277 }; -00278 if ((size_t)ucFontColor >= elementsof(aulColorTable)) { -00279 return aulColorTable[0]; -00280 } -00281 return aulColorTable[(int)ucFontColor]; -00282 } /* end of ulColor2Color */ -00283 -00284 /* -00285 * iFindSplit - find a place to split the string -00286 * -00287 * returns the index of the split character or -1 if no split found. -00288 */ -00289 static int -00290 iFindSplit(const char *szString, size_t tStringLen) -00291 { -00292 size_t tSplit; -00293 -00294 if (tStringLen == 0) { -00295 return -1; -00296 } -00297 tSplit = tStringLen - 1; -00298 while (tSplit >= 1) { -00299 if (szString[tSplit] == ' ' || -00300 (szString[tSplit] == '-' && szString[tSplit - 1] != ' ')) { -00301 return (int)tSplit; -00302 } -00303 tSplit--; -00304 } -00305 return -1; -00306 } /* end of iFindSplit */ -00307 -00308 /* -00309 * pSplitList - split the specified list in a printable part and a leftover part -00310 * -00311 * returns the pointer to the leftover part -00312 */ -00313 output_type * -00314 pSplitList(output_type *pAnchor) -00315 { -00316 output_type *pCurr, *pLeftOver; -00317 int iIndex; -00318 -00319 fail(pAnchor == NULL); -00320 -00321 for (pCurr = pAnchor; pCurr->pNext != NULL; pCurr = pCurr->pNext) -00322 ; /* EMPTY */ -00323 iIndex = -1; -00324 for (; pCurr != NULL; pCurr = pCurr->pPrev) { -00325 iIndex = iFindSplit(pCurr->szStorage, pCurr->tNextFree); -00326 if (iIndex >= 0) { -00327 break; -00328 } -00329 } -00330 -00331 if (pCurr == NULL || iIndex < 0) { -00332 /* No split, no leftover */ -00333 return NULL; -00334 } -00335 /* Split over the iIndex-th character */ -00336 NO_DBG_MSG("pLeftOver"); -00337 pLeftOver = xmalloc(sizeof(*pLeftOver)); -00338 fail(pCurr->tNextFree < (size_t)iIndex); -00339 pLeftOver->tStorageSize = pCurr->tNextFree - (size_t)iIndex; -00340 pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize); -00341 pLeftOver->tNextFree = pCurr->tNextFree - (size_t)iIndex - 1; -00342 (void)strncpy(pLeftOver->szStorage, -00343 pCurr->szStorage + iIndex + 1, pLeftOver->tNextFree); -00344 pLeftOver->szStorage[pLeftOver->tNextFree] = '\0'; -00345 NO_DBG_MSG(pLeftOver->szStorage); -00346 pLeftOver->ucFontColor = pCurr->ucFontColor; -00347 pLeftOver->usFontStyle = pCurr->usFontStyle; -00348 pLeftOver->tFontRef = pCurr->tFontRef; -00349 pLeftOver->usFontSize = pCurr->usFontSize; -00350 pLeftOver->lStringWidth = lComputeStringWidth( -00351 pLeftOver->szStorage, -00352 pLeftOver->tNextFree, -00353 pLeftOver->tFontRef, -00354 pLeftOver->usFontSize); -00355 pLeftOver->pPrev = NULL; -00356 pLeftOver->pNext = pCurr->pNext; -00357 if (pLeftOver->pNext != NULL) { -00358 pLeftOver->pNext->pPrev = pLeftOver; -00359 } -00360 fail(!bCheckDoubleLinkedList(pLeftOver)); -00361 -00362 NO_DBG_MSG("pAnchor"); -00363 NO_DBG_HEX(pCurr->szStorage[iIndex]); -00364 while (iIndex >= 0 && isspace((int)(UCHAR)pCurr->szStorage[iIndex])) { -00365 iIndex--; -00366 } -00367 pCurr->tNextFree = (size_t)iIndex + 1; -00368 pCurr->szStorage[pCurr->tNextFree] = '\0'; -00369 NO_DBG_MSG(pCurr->szStorage); -00370 pCurr->lStringWidth = lComputeStringWidth( -00371 pCurr->szStorage, -00372 pCurr->tNextFree, -00373 pCurr->tFontRef, -00374 pCurr->usFontSize); -00375 pCurr->pNext = NULL; -00376 fail(!bCheckDoubleLinkedList(pAnchor)); -00377 -00378 return pLeftOver; -00379 } /* end of pSplitList */ -00380 -00381 /* -00382 * tNumber2Roman - convert a number to Roman Numerals -00383 * -00384 * returns the number of characters written -00385 */ -00386 size_t -00387 tNumber2Roman(UINT uiNumber, BOOL bUpperCase, char *szOutput) -00388 { -00389 char *outp, *p, *q; -00390 UINT uiNextVal, uiValue; -00391 -00392 fail(szOutput == NULL); -00393 -00394 uiNumber %= 4000; /* Very high numbers can't be represented */ -00395 if (uiNumber == 0) { -00396 szOutput[0] = '\0'; -00397 return 0; -00398 } -00399 -00400 outp = szOutput; -00401 p = bUpperCase ? "M\2D\5C\2L\5X\2V\5I" : "m\2d\5c\2l\5x\2v\5i"; -00402 uiValue = 1000; -00403 for (;;) { -00404 while (uiNumber >= uiValue) { -00405 *outp++ = *p; -00406 uiNumber -= uiValue; -00407 } -00408 if (uiNumber == 0) { -00409 *outp = '\0'; -00410 fail(outp < szOutput); -00411 return (size_t)(outp - szOutput); -00412 } -00413 q = p + 1; -00414 uiNextVal = uiValue / (UINT)(UCHAR)*q; -00415 if ((int)*q == 2) { /* magic */ -00416 uiNextVal /= (UINT)(UCHAR)*(q += 2); -00417 } -00418 if (uiNumber + uiNextVal >= uiValue) { -00419 *outp++ = *++q; -00420 uiNumber += uiNextVal; -00421 } else { -00422 p++; -00423 uiValue /= (UINT)(UCHAR)(*p++); -00424 } -00425 } -00426 } /* end of tNumber2Roman */ -00427 -00428 /* -00429 * iNumber2Alpha - convert a number to alphabetic "numbers" -00430 * -00431 * returns the number of characters written -00432 */ -00433 size_t -00434 tNumber2Alpha(UINT uiNumber, BOOL bUpperCase, char *szOutput) -00435 { -00436 char *outp; -00437 UINT uiTmp; -00438 -00439 fail(szOutput == NULL); -00440 -00441 if (uiNumber == 0) { -00442 szOutput[0] = '\0'; -00443 return 0; -00444 } -00445 -00446 outp = szOutput; -00447 uiTmp = (UINT)(bUpperCase ? 'A': 'a'); -00448 if (uiNumber <= 26) { -00449 uiNumber -= 1; -00450 *outp++ = (char)(uiTmp + uiNumber); -00451 } else if (uiNumber <= 26U + 26U*26U) { -00452 uiNumber -= 26 + 1; -00453 *outp++ = (char)(uiTmp + uiNumber / 26); -00454 *outp++ = (char)(uiTmp + uiNumber % 26); -00455 } else if (uiNumber <= 26U + 26U*26U + 26U*26U*26U) { -00456 uiNumber -= 26 + 26*26 + 1; -00457 *outp++ = (char)(uiTmp + uiNumber / (26*26)); -00458 *outp++ = (char)(uiTmp + uiNumber / 26 % 26); -00459 *outp++ = (char)(uiTmp + uiNumber % 26); -00460 } -00461 *outp = '\0'; -00462 fail(outp < szOutput); -00463 return (size_t)(outp - szOutput); -00464 } /* end of tNumber2Alpha */ -00465 -00466 /* -00467 * unincpy - copy a counted Unicode string to an single-byte string -00468 */ -00469 char * -00470 unincpy(char *s1, const UCHAR *s2, size_t n) -00471 { -00472 char *pcDest; -00473 ULONG ulChar; -00474 size_t tLen; -00475 USHORT usUni; -00476 -00477 for (pcDest = s1, tLen = 0; tLen < n; pcDest++, tLen++) { -00478 usUni = usGetWord(tLen * 2, s2); -00479 if (usUni == 0) { -00480 break; -00481 } -00482 ulChar = ulTranslateCharacters(usUni, 0, 8, -00483 conversion_unknown, encoding_neutral, FALSE); -00484 if (ulChar == IGNORE_CHARACTER) { -00485 ulChar = (ULONG)'?'; -00486 } -00487 *pcDest = (char)ulChar; -00488 } -00489 for (; tLen < n; tLen++) { -00490 *pcDest++ = '\0'; -00491 } -00492 return s1; -00493 } /* end of unincpy */ -00494 -00495 /* -00496 * unilen - calculate the length of a Unicode string -00497 * -00498 * returns the length in bytes -00499 */ -00500 size_t -00501 unilen(const UCHAR *s) -00502 { -00503 size_t tLen; -00504 USHORT usUni; -00505 -00506 tLen = 0; -00507 for (;;) { -00508 usUni = usGetWord(tLen, s); -00509 if (usUni == 0) { -00510 return tLen; -00511 } -00512 tLen += 2; -00513 } -00514 } /* end of unilen */ -00515 -00516 /* -00517 * szBaseName - get the basename of the specified filename -00518 */ -00519 const char * -00520 szBasename(const char *szFilename) -00521 { -00522 const char *szTmp; -00523 -00524 fail(szFilename == NULL); -00525 -00526 if (szFilename == NULL || szFilename[0] == '\0') { -00527 return "null"; -00528 } -00529 -00530 szTmp = strrchr(szFilename, FILE_SEPARATOR[0]); -00531 if (szTmp == NULL) { -00532 return szFilename; -00533 } -00534 return ++szTmp; -00535 } /* end of szBasename */ -00536 -00537 /* -00538 * lComputeLeading - compute the leading -00539 * -00540 * NOTE: the fontsize is specified in half points -00541 * -00542 * Returns the leading in drawunits -00543 */ -00544 long -00545 lComputeLeading(USHORT usFontSize) -00546 { -00547 long lLeading; -00548 -00549 lLeading = (long)usFontSize * 500L; -00550 if (usFontSize < 18) { /* Small text: 112% */ -00551 lLeading *= 112; -00552 } else if (usFontSize < 28) { /* Normal text: 124% */ -00553 lLeading *= 124; -00554 } else if (usFontSize < 48) { /* Small headlines: 104% */ -00555 lLeading *= 104; -00556 } else { /* Large headlines: 100% */ -00557 lLeading *= 100; -00558 } -00559 lLeading = lMilliPoints2DrawUnits(lLeading); -00560 lLeading += 50; -00561 lLeading /= 100; -00562 return lLeading; -00563 } /* end of lComputeLeading */ -00564 -00565 /* -00566 * Convert a UCS character to an UTF-8 string -00567 * -00568 * Returns the string length of the result -00569 */ -00570 size_t -00571 tUcs2Utf8(ULONG ulChar, char *szResult, size_t tMaxResultLen) -00572 { -00573 if (szResult == NULL || tMaxResultLen == 0) { -00574 return 0; -00575 } -00576 -00577 if (ulChar < 0x80 && tMaxResultLen >= 2) { -00578 szResult[0] = (char)ulChar; -00579 szResult[1] = '\0'; -00580 return 1; -00581 } -00582 if (ulChar < 0x800 && tMaxResultLen >= 3) { -00583 szResult[0] = (char)(0xc0 | ulChar >> 6); -00584 szResult[1] = (char)(0x80 | (ulChar & 0x3f)); -00585 szResult[2] = '\0'; -00586 return 2; -00587 } -00588 if (ulChar < 0x10000 && tMaxResultLen >= 4) { -00589 szResult[0] = (char)(0xe0 | ulChar >> 12); -00590 szResult[1] = (char)(0x80 | (ulChar >> 6 & 0x3f)); -00591 szResult[2] = (char)(0x80 | (ulChar & 0x3f)); -00592 szResult[3] = '\0'; -00593 return 3; -00594 } -00595 if (ulChar < 0x200000 && tMaxResultLen >= 5) { -00596 szResult[0] = (char)(0xf0 | ulChar >> 18); -00597 szResult[1] = (char)(0x80 | (ulChar >> 12 & 0x3f)); -00598 szResult[2] = (char)(0x80 | (ulChar >> 6 & 0x3f)); -00599 szResult[3] = (char)(0x80 | (ulChar & 0x3f)); -00600 szResult[4] = '\0'; -00601 return 4; -00602 } -00603 szResult[0] = '\0'; -00604 return 0; -00605 } /* end of tUcs2Utf8 */ -00606 -00607 /* -00608 * vGetBulletValue - get the bullet value for the conversing type and encoding -00609 */ -00610 void -00611 vGetBulletValue(conversion_type eConversionType, encoding_type eEncoding, -00612 char *szResult, size_t tMaxResultLen) -00613 { -00614 fail(szResult == NULL); -00615 fail(tMaxResultLen < 2); -00616 -00617 if (eEncoding == encoding_utf_8) { -00618 (void)tUcs2Utf8(UNICODE_BULLET, szResult, tMaxResultLen); -00619 } else { -00620 szResult[0] = (char)ucGetBulletCharacter(eConversionType, -00621 eEncoding); -00622 szResult[1] = '\0'; -00623 } -00624 } /* end of vGetBulletValue */ -00625 -00626 /* -00627 * bAllZero - are all bytes zero? -00628 */ -00629 BOOL -00630 bAllZero(const UCHAR *aucBytes, size_t tLength) -00631 { -00632 size_t tIndex; -00633 -00634 if (aucBytes == NULL || tLength == 0) { -00635 return TRUE; -00636 } -00637 -00638 for (tIndex = 0; tIndex < tLength; tIndex++) { -00639 if (aucBytes[tIndex] != 0) { -00640 return FALSE; -00641 } -00642 } -00643 return TRUE; -00644 } /* end of bAllZero */ -00645 -00646 #if !defined(__riscos) -00647 /* -00648 * GetCodesetFromLocale - get the codeset from the current locale -00649 * -00650 * Original version: Copyright (C) 1999 Bruno Haible -00651 * Syntax: -00652 * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]] -00653 * -00654 * Returns TRUE when sucessful, otherwise FALSE -00655 */ -00656 static BOOL -00657 bGetCodesetFromLocale(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro) -00658 { -00659 #if !defined(__dos) -00660 const char *szLocale; -00661 const char *pcTmp; -00662 size_t tIndex; -00663 char szModifier[6]; -00664 #endif /* __dos */ -00665 -00666 if (pbEuro != NULL) { -00667 *pbEuro = FALSE; /* Until proven otherwise */ -00668 } -00669 if (szCodeset == NULL || tMaxCodesetLength == 0) { -00670 return FALSE; -00671 } -00672 -00673 #if defined(__dos) -00674 if (tMaxCodesetLength < 2 + sizeof(int) * 3 + 1) { -00675 DBG_DEC(tMaxCodesetLength); -00676 DBG_DEC(2 + sizeof(int) * 3 + 1); -00677 return FALSE; -00678 } -00679 /* Get the active codepage from DOS */ -00680 sprintf(szCodeset, "cp%d", iGetCodepage()); -00681 DBG_MSG(szCodeset); -00682 #else -00683 /* Get the locale from the environment */ -00684 szLocale = getenv("LC_ALL"); -00685 if (szLocale == NULL || szLocale[0] == '\0') { -00686 szLocale = getenv("LC_CTYPE"); -00687 if (szLocale == NULL || szLocale[0] == '\0') { -00688 szLocale = getenv("LANG"); -00689 } -00690 } -00691 if (szLocale == NULL || szLocale[0] == '\0') { -00692 /* No locale, so no codeset name and no modifier */ -00693 return FALSE; -00694 } -00695 DBG_MSG(szLocale); -00696 pcTmp = strchr(szLocale, '.'); -00697 if (pcTmp == NULL) { -00698 /* No codeset name */ -00699 szCodeset[0] = '\0'; -00700 } else { -00701 /* Copy the codeset name */ -00702 pcTmp++; -00703 for (tIndex = 0; tIndex < tMaxCodesetLength; tIndex++) { -00704 if (*pcTmp == '@' || *pcTmp == '+' || -00705 *pcTmp == ',' || *pcTmp == '_' || -00706 *pcTmp == '\0') { -00707 szCodeset[tIndex] = '\0'; -00708 break; -00709 } -00710 szCodeset[tIndex] = *pcTmp; -00711 pcTmp++; -00712 } -00713 szCodeset[tMaxCodesetLength - 1] = '\0'; -00714 } -00715 if (pbEuro == NULL) { -00716 /* No need to get the modifier */ -00717 return TRUE; -00718 } -00719 pcTmp = strchr(szLocale, '@'); -00720 if (pcTmp != NULL) { -00721 /* Copy the modifier */ -00722 pcTmp++; -00723 for (tIndex = 0; tIndex < sizeof(szModifier); tIndex++) { -00724 if (*pcTmp == '+' || *pcTmp == ',' || -00725 *pcTmp == '_' || *pcTmp == '\0') { -00726 szModifier[tIndex] = '\0'; -00727 break; -00728 } -00729 szModifier[tIndex] = *pcTmp; -00730 pcTmp++; -00731 } -00732 szModifier[sizeof(szModifier) - 1] = '\0'; -00733 *pbEuro = STRCEQ(szModifier, "Euro"); -00734 } -00735 #endif /* __dos */ -00736 return TRUE; -00737 } /* end of bGetCodesetFromLocale */ -00738 -00739 /* -00740 * GetNormalizedCodeset - get the normalized codeset from the current locale -00741 * -00742 * Returns TRUE when sucessful, otherwise FALSE -00743 */ -00744 BOOL -00745 bGetNormalizedCodeset(char *szCodeset, size_t tMaxCodesetLength, BOOL *pbEuro) -00746 { -00747 BOOL bOnlyDigits; -00748 const char *pcSrc; -00749 char *pcDest; -00750 char *szTmp, *szCodesetNorm; -00751 -00752 if (pbEuro != NULL) { -00753 *pbEuro = FALSE; /* Until proven otherwise */ -00754 } -00755 if (szCodeset == NULL || tMaxCodesetLength < 4) { -00756 return FALSE; -00757 } -00758 -00759 /* Get the codeset name */ -00760 szTmp = xmalloc(tMaxCodesetLength - 3); -00761 if (!bGetCodesetFromLocale(szTmp, tMaxCodesetLength - 3, pbEuro)) { -00762 szTmp = xfree(szTmp); -00763 return FALSE; -00764 } -00765 /* Normalize the codeset name */ -00766 szCodesetNorm = xmalloc(tMaxCodesetLength - 3); -00767 bOnlyDigits = TRUE; -00768 pcDest = szCodesetNorm; -00769 for (pcSrc = szTmp; *pcSrc != '\0'; pcSrc++) { -00770 if (isalnum(*pcSrc)) { -00771 *pcDest = tolower(*pcSrc); -00772 if (!isdigit(*pcDest)) { -00773 bOnlyDigits = FALSE; -00774 } -00775 pcDest++; -00776 } -00777 } -00778 *pcDest = '\0'; -00779 DBG_MSG(szCodesetNorm); -00780 /* Add "iso" when szCodesetNorm contains all digits */ -00781 if (bOnlyDigits && szCodesetNorm[0] != '\0') { -00782 fail(strlen(szCodesetNorm) + 3 >= tMaxCodesetLength); -00783 sprintf(szCodeset, "iso%s", szCodesetNorm); -00784 } else { -00785 fail(strlen(szCodesetNorm) >= tMaxCodesetLength); -00786 strncpy(szCodeset, szCodesetNorm, pcDest - szCodesetNorm + 1); -00787 szCodeset[tMaxCodesetLength - 1] = '\0'; -00788 } -00789 DBG_MSG(szCodeset); -00790 /* Clean up and leave */ -00791 szCodesetNorm = xfree(szCodesetNorm); -00792 szTmp = xfree(szTmp); -00793 return TRUE; -00794 } /* end of bGetNormalizedCodeset */ -00795 -00796 /* -00797 * szGetDefaultMappingFile - get the default mapping file -00798 * -00799 * Returns the basename of the default mapping file -00800 */ -00801 const char * -00802 szGetDefaultMappingFile(void) -00803 { -00804 static const struct { -00805 const char *szCodeset; -00806 const char *szMappingFile; -00807 } atMappingFile[] = { -00808 { "iso88591", MAPPING_FILE_8859_1 }, -00809 { "iso88592", MAPPING_FILE_8859_2 }, -00810 { "iso88593", "8859-3.txt" }, -00811 { "iso88594", "8859-4.txt" }, -00812 { "iso88595", "8859-5.txt" }, -00813 { "iso88596", MAPPING_FILE_8859_5 }, -00814 { "iso88597", "8859-7.txt" }, -00815 { "iso88598", "8859-8.txt" }, -00816 { "iso88599", "8859-9.txt" }, -00817 { "iso885910", "8859-10.txt" }, -00818 { "iso885913", "8859-13.txt" }, -00819 { "iso885914", "8859-14.txt" }, -00820 { "iso885915", MAPPING_FILE_8859_15 }, -00821 { "iso885916", "8859-16.txt" }, -00822 { "koi8r", MAPPING_FILE_KOI8_R }, -00823 { "koi8u", MAPPING_FILE_KOI8_U }, -00824 { "utf8", MAPPING_FILE_UTF_8 }, -00825 { "cp437", MAPPING_FILE_CP437 }, -00826 { "cp850", "cp850.txt" }, -00827 { "cp852", MAPPING_FILE_CP852 }, -00828 { "cp862", "cp862.txt" }, -00829 { "cp864", "cp864.txt" }, -00830 { "cp866", MAPPING_FILE_CP866 }, -00831 { "cp1250", MAPPING_FILE_CP1250 }, -00832 { "cp1251", MAPPING_FILE_CP1251 }, -00833 { "cp1252", "cp1252.txt" }, -00834 }; -00835 size_t tIndex; -00836 BOOL bEuro; -00837 char szCodeset[20]; -00838 -00839 szCodeset[0] = '\0'; -00840 bEuro = FALSE; -00841 /* Get the normalized codeset name */ -00842 if (!bGetNormalizedCodeset(szCodeset, sizeof(szCodeset), &bEuro)) { -00843 return MAPPING_FILE_8859_1; -00844 } -00845 if (szCodeset[0] == '\0') { -00846 if (bEuro) { -00847 /* Default mapping file (with Euro sign) */ -00848 return MAPPING_FILE_8859_15; -00849 } else { -00850 /* Default mapping file (without Euro sign) */ -00851 return MAPPING_FILE_8859_1; -00852 } -00853 } -00854 /* Find the name in the table */ -00855 for (tIndex = 0; tIndex < elementsof(atMappingFile); tIndex++) { -00856 if (STREQ(atMappingFile[tIndex].szCodeset, szCodeset)) { -00857 return atMappingFile[tIndex].szMappingFile; -00858 } -00859 } -00860 /* Default default mapping file */ -00861 #if defined(__dos) -00862 return MAPPING_FILE_CP437; -00863 #else -00864 return MAPPING_FILE_8859_1; -00865 #endif /* __dos */ -00866 } /* end of szGetDefaultMappingFile */ -00867 #endif /* !__riscos */ -00868 -00869 /* -00870 * tConvertDTTM - convert Windows Date and Time format -00871 * -00872 * returns Unix time_t or -1 -00873 */ -00874 time_t -00875 tConvertDTTM(ULONG ulDTTM) -00876 { -00877 struct tm tTime; -00878 time_t tResult; -00879 -00880 if (ulDTTM == 0) { -00881 return (time_t)-1; -00882 } -00883 memset(&tTime, 0, sizeof(tTime)); -00884 tTime.tm_min = (int)(ulDTTM & 0x0000003f); -00885 tTime.tm_hour = (int)((ulDTTM & 0x000007c0) >> 6); -00886 tTime.tm_mday = (int)((ulDTTM & 0x0000f800) >> 11); -00887 tTime.tm_mon = (int)((ulDTTM & 0x000f0000) >> 16); -00888 tTime.tm_year = (int)((ulDTTM & 0x1ff00000) >> 20); -00889 tTime.tm_isdst = -1; -00890 tTime.tm_mon--; /* From 01-12 to 00-11 */ -00891 tResult = mktime(&tTime); -00892 NO_DBG_MSG(ctime(&tResult)); -00893 return tResult; -00894 } /* end of tConvertDTTM */ -