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 @@ + + + + +TB9.2 Example Applications: examples/PIPS/antiword/src/misc.c Source File + + + + + +

examples/PIPS/antiword/src/misc.c

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 */
+
+
Generated by  + +doxygen 1.6.2
+ +