diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/misc_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/misc_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,910 @@ + + +
+ +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 */ +