📄 misc.c
字号:
/* * misc.c * Copyright (C) 1998-2001 A.J. van Os; Released under GPL * * Description: * misc. functions */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <time.h>#if defined(__riscos)#include "kernel.h"#include "swis.h"#else#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#if defined(__dos)#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)#endif /* __dos */#endif /* __riscos */#if defined(WIN32)#include "windows.h"#endif // WIN32#include "antiword.h"static BOOL bWord6MacFile = FALSE;#if !defined(__riscos)/* * szGetHomeDirectory - get the name of the home directory */const char *szGetHomeDirectory(void){ static char homedir[256]; const char *szHome; szHome = getenv("HOME"); if (szHome == NULL || szHome[0] == '\0') {#if defined(WIN32) (void)GetCurrentDirectory(255, &homedir[0]); szHome = &homedir[0];#else#if defined(__dos) szHome = "C:"; #else werr(0, "I can't find the name of your HOME directory"); szHome = "";#endif /* __dos */#endif // WIN32 } return szHome;} /* end of szGetHomeDirectory */#endif /* !__riscos *//* * Get the size of the given file. * Returns -1 if the file does not exist or is not a proper file. */longlGetFilesize(const char *szFilename){#if defined(__riscos) _kernel_swi_regs regs; _kernel_oserror *e; (void)memset(®s, 0, sizeof(regs)); regs.r[0] = 17; regs.r[1] = (int)szFilename; e = _kernel_swi(OS_File, ®s, ®s); if (e != NULL) { werr(0, "Get Filesize error %d: %s", e->errnum, e->errmess); return -1; } if (regs.r[0] != 1) { /* It's not a proper file or the file does not exist */ return -1; } return (long)regs.r[4];#else struct stat tBuffer; if (stat(szFilename, &tBuffer) != 0) { werr(0, "Get Filesize error %d", errno); return -1; } if (!S_ISREG(tBuffer.st_mode)) { /* It's not a regular file */ return -1; } return (long)tBuffer.st_size;#endif /* __riscos */} /* end of lGetFilesize */#if defined(DEBUG)voidvPrintBlock(const char *szFile, int iLine, const unsigned char *aucBlock, size_t tLength){ int i, j; fail(szFile == NULL || iLine < 0 || aucBlock == NULL); fprintf(stderr, "%s[%3d]:\n", szFile, iLine); for (i = 0; i < 32; i++) { if (16 * i >= (int)tLength) { return; } fprintf(stderr, "%03x: ", 16 * i); for (j = 0; j < 16; j++) { if (16 * i + j < (int)tLength) { fprintf(stderr, "%02x ", aucBlock[16 * i + j]); } } fprintf(stderr, "\n"); }} /* end of vPrintBlock */voidvPrintUnicode(const char *szFile, int iLine, const char *s){ size_t tLen; char *szASCII; tLen = unilen(s) / 2; szASCII = xmalloc(tLen + 1); (void)unincpy(szASCII, s, tLen); szASCII[tLen] = '\0'; (void)fprintf(stderr, "%s[%3d]: %.240s\n", szFile, iLine, szASCII); szASCII = xfree(szASCII);} /* end of vPrintUnicode */BOOLbCheckDoubleLinkedList(output_type *pAnchor){ output_type *pCurr, *pLast; int iInList; pLast = pAnchor; iInList = 0; for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { pLast = pCurr; iInList++; } NO_DBG_DEC(iInList); for (pCurr = pLast; pCurr != NULL; pCurr = pCurr->pPrev) { pLast = pCurr; iInList--; } DBG_DEC_C(iInList != 0, iInList); return pAnchor == pLast && iInList == 0;} /* end of bCheckDoubleLinkedList */#endif /* DEBUG *//* * bReadBytes * This function reads the given number of bytes from the given file, * starting from the given offset. * Returns TRUE when successfull, otherwise FALSE */BOOLbReadBytes(unsigned char *aucBytes, size_t tMemb, long lOffset, FILE *pFile){ fail(aucBytes == NULL || pFile == NULL || lOffset < 0); if (fseek(pFile, lOffset, SEEK_SET) != 0) { return FALSE; } if (fread(aucBytes, sizeof(unsigned char), tMemb, pFile) != tMemb) { return FALSE; } return TRUE;} /* end of bReadBytes *//* * bReadBuffer * This function fills the given buffer with the given number of bytes, * starting at the given offset within the Big/Small Block Depot. * * Returns TRUE when successful, otherwise FALSE */BOOLbReadBuffer(FILE *pFile, long lStartBlock, const long *alBlockDepot, size_t tBlockDepotLen, size_t tBlockSize, unsigned char *aucBuffer, long lOffset, size_t tToRead){ long lBegin, lIndex; size_t tLen; fail(pFile == NULL); fail(lStartBlock < 0); fail(alBlockDepot == NULL); fail(tBlockSize != BIG_BLOCK_SIZE && tBlockSize != SMALL_BLOCK_SIZE); fail(aucBuffer == NULL); fail(tToRead == 0); for (lIndex = lStartBlock; lIndex != END_OF_CHAIN && tToRead != 0; lIndex = alBlockDepot[lIndex]) { if (lIndex < 0 || lIndex >= (long)tBlockDepotLen) { if (tBlockSize >= BIG_BLOCK_SIZE) { werr(1, "The Big Block Depot is corrupt"); } else { werr(1, "The Small Block Depot is corrupt"); } } if (lOffset >= (long)tBlockSize) { lOffset -= (long)tBlockSize; continue; } lBegin = lDepotOffset(lIndex, tBlockSize) + lOffset; tLen = min(tBlockSize - (size_t)lOffset, tToRead); lOffset = 0; if (!bReadBytes(aucBuffer, tLen, lBegin, pFile)) { werr(0, "Read big block %ld not possible", lBegin); return FALSE; } aucBuffer += tLen; tToRead -= tLen; } DBG_DEC_C(tToRead != 0, tToRead); return tToRead == 0;} /* end of bReadBuffer *//* * Translate a Word colornumber into a true color for use in a drawfile * * Returns the true color */unsigned intuiColor2Color(int iWordColor){ static const unsigned int auiColorTable[] = { /* 0 */ 0x00000000U, /* Automatic */ /* 1 */ 0x00000000U, /* Black */ /* 2 */ 0xff000000U, /* Blue */ /* 3 */ 0xffff0000U, /* Turquoise */ /* 4 */ 0x00ff0000U, /* Bright Green */ /* 5 */ 0xff00ff00U, /* Pink */ /* 6 */ 0x0000ff00U, /* Red */ /* 7 */ 0x00ffff00U, /* Yellow */ /* 8 */ 0xffffff00U, /* White */ /* 9 */ 0x80000000U, /* Dark Blue */ /* 10 */ 0x80800000U, /* Teal */ /* 11 */ 0x00800000U, /* Green */ /* 12 */ 0x80008000U, /* Violet */ /* 13 */ 0x00008000U, /* Dark Red */ /* 14 */ 0x00808000U, /* Dark Yellow */ /* 15 */ 0x80808000U, /* Gray 50% */ /* 16 */ 0xc0c0c000U, /* Gray 25% */ }; if (iWordColor < 0 || iWordColor >= (int)elementsof(auiColorTable)) { return auiColorTable[0]; } return auiColorTable[iWordColor];} /* end of uiColor2Color *//* * iFindSplit - find a place to split the string * * returns the index of the split character or -1 if no split found. */static intiFindSplit(const char *szString, int iStringLen){ int iSplit; iSplit = iStringLen - 1; while (iSplit >= 1) { if (szString[iSplit] == ' ' || (szString[iSplit] == '-' && szString[iSplit - 1] != ' ')) { return iSplit; } iSplit--; } return -1;} /* end of iFindSplit *//* * pSplitList - split the given list in a printable part and a leftover part * * returns the pointer to the leftover part */output_type *pSplitList(output_type *pAnchor){ output_type *pCurr, *pLeftOver; int iIndex; fail(pAnchor == NULL); for (pCurr = pAnchor; pCurr->pNext != NULL; pCurr = pCurr->pNext) ; /* EMPTY */ iIndex = -1; for (; pCurr != NULL; pCurr = pCurr->pPrev) { iIndex = iFindSplit(pCurr->szStorage, pCurr->iNextFree); if (iIndex >= 0) { break; } } if (pCurr == NULL || iIndex < 0) { /* No split, no leftover */ return NULL; } /* Split over the iIndex-th character */ NO_DBG_MSG("pLeftOver"); pLeftOver = xmalloc(sizeof(*pLeftOver)); pLeftOver->tStorageSize = (size_t)(pCurr->iNextFree - iIndex); pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize); pLeftOver->iNextFree = pCurr->iNextFree - iIndex - 1; (void)strncpy(pLeftOver->szStorage, pCurr->szStorage + iIndex + 1, (size_t)pLeftOver->iNextFree); pLeftOver->szStorage[pLeftOver->iNextFree] = '\0'; NO_DBG_MSG(pLeftOver->szStorage); pLeftOver->iColor = pCurr->iColor; pLeftOver->ucFontstyle = pCurr->ucFontstyle; pLeftOver->tFontRef = pCurr->tFontRef; pLeftOver->sFontsize = pCurr->sFontsize; pLeftOver->lStringWidth = lComputeStringWidth( pLeftOver->szStorage, pLeftOver->iNextFree, pLeftOver->tFontRef, pLeftOver->sFontsize); pLeftOver->pPrev = NULL; pLeftOver->pNext = pCurr->pNext; if (pLeftOver->pNext != NULL) { pLeftOver->pNext->pPrev = pLeftOver; } fail(!bCheckDoubleLinkedList(pLeftOver)); NO_DBG_MSG("pAnchor"); NO_DBG_HEX(pCurr->szStorage[iIndex]); while (iIndex >= 0 && isspace(pCurr->szStorage[iIndex])) { iIndex--; } pCurr->iNextFree = iIndex + 1; pCurr->szStorage[pCurr->iNextFree] = '\0'; NO_DBG_MSG(pCurr->szStorage); pCurr->lStringWidth = lComputeStringWidth( pCurr->szStorage, pCurr->iNextFree, pCurr->tFontRef, pCurr->sFontsize); pCurr->pNext = NULL; fail(!bCheckDoubleLinkedList(pAnchor)); return pLeftOver;} /* end of pSplitList *//* * iInteger2Roman - convert an integer to Roman Numerals * * returns the number of characters written */intiInteger2Roman(int iNumber, BOOL bUpperCase, char *szOutput){ char *outp, *p, *q; int iNextVal, iValue; fail(szOutput == NULL); if (iNumber <= 0 || iNumber >= 4000) { szOutput[0] = '\0'; return 0; } outp = szOutput; p = bUpperCase ? "M\2D\5C\2L\5X\2V\5I" : "m\2d\5c\2l\5x\2v\5i"; iValue = 1000; for (;;) { while (iNumber >= iValue) { *outp++ = *p; iNumber -= iValue; } if (iNumber <= 0) { *outp = '\0'; return outp - szOutput; } q = p + 1; iNextVal = iValue / (int)*q; if ((int)*q == 2) { /* magic */ iNextVal /= (int)*(q += 2); } if (iNumber + iNextVal >= iValue) { *outp++ = *++q; iNumber += iNextVal; } else { p++; iValue /= (int)(*p++); } }} /* end of iInteger2Roman *//* * iInteger2Alpha - convert an integer to Alphabetic "numbers" * * returns the number of characters written */intiInteger2Alpha(int iNumber, BOOL bUpperCase, char *szOutput){ char *outp; int iTmp; fail(szOutput == NULL); outp = szOutput; iTmp = bUpperCase ? 'A': 'a'; if (iNumber <= 26) { iNumber -= 1; *outp++ = (char)(iTmp + iNumber); } else if (iNumber <= 26 + 26*26) { iNumber -= 26 + 1; *outp++ = (char)(iTmp + iNumber / 26); *outp++ = (char)(iTmp + iNumber % 26); } else if (iNumber <= 26 + 26*26 + 26*26*26) { iNumber -= 26 + 26*26 + 1; *outp++ = (char)(iTmp + iNumber / (26*26)); *outp++ = (char)(iTmp + iNumber / 26 % 26); *outp++ = (char)(iTmp + iNumber % 26); } *outp = '\0'; return outp - szOutput;} /* end of iInteger2Alpha *//* * unincpy - copy a counted Unicode string to an single-byte string */char *unincpy(char *s1, const char *s2, size_t n){ char *dest; unsigned long ulChar; size_t len; unsigned short usUni; for (dest = s1, len = 0; len < n; dest++, len++) { usUni = usGetWord(len * 2, s2); if (usUni == 0) { break; } ulChar = ulTranslateCharacters(usUni, 0, FALSE, FALSE); if (ulChar == IGNORE_CHARACTER) { ulChar = (unsigned long)'?'; } *dest = (char)ulChar; } for (; len < n; len++) { *dest++ = '\0'; } return s1;} /* end of unincpy *//* * unilen - calculate the length of a Unicode string */size_tunilen(const char *s){ size_t tLen; unsigned short usUni; tLen = 0; for (;;) { usUni = usGetWord(tLen * 2, s); if (usUni == 0) { return tLen; } tLen += 2; }} /* end of unilen *//* * szBaseName - get the basename of the given filename */const char *szBasename(const char *szFilename){ const char *szTmp; fail(szFilename == NULL); if (szFilename == NULL || szFilename[0] == '\0') { return "null"; } szTmp = strrchr(szFilename, FILE_SEPARATOR[0]); if (szTmp == NULL) { return szFilename; } return ++szTmp;} /* end of szBasename *//* * iGetVersionNumber - get the Word version number from the header * * Returns the version number or -1 when unknown */intiGetVersionNumber(const unsigned char *aucHeader){ unsigned short usFib, usChse; usFib = usGetWord(0x02, aucHeader); DBG_DEC(usFib); if (usFib < 101) { /* This file is from a version of Word older than Word 6 */ return -1; } usChse = usGetWord(0x14, aucHeader); DBG_DEC(usChse); bWord6MacFile = FALSE; switch (usFib) { case 101: case 102: DBG_MSG("Word 6 for Windows"); return 6; case 103: case 104: switch (usChse) { case 0: DBG_MSG("Word 7 for Win95"); return 7; case 256: DBG_MSG("Word 6 for Macintosh"); bWord6MacFile = TRUE; return 6; default: DBG_FIXME(); if (ucGetByte(0x05, aucHeader) == 0xe0) { DBG_MSG("Word 7 for Win95"); return 7; } DBG_MSG("Word 6 for Macintosh"); bWord6MacFile = TRUE; return 6; } default: DBG_MSG_C(usChse != 256, "Word97 for Win95/98/NT"); DBG_MSG_C(usChse == 256, "Word98 for Macintosh"); return 8; }} /* end of iGetVersionNumber *//* * TRUE if the current file was made by Word 6 on an Apple Macintosh, * otherwise FALSE. * This function hides the methode of how to find out from the rest of the * program. */BOOLbIsWord6MacFile(void){ return bWord6MacFile;} /* end of bIsWord6MacFile *//* * lComputeLeading - compute the leading * * NOTE: the fontsize is given in half points * * Returns the leading in drawunits */longlComputeLeading(int iFontsize){ long lLeading; lLeading = iFontsize * 500L; if (iFontsize < 18) { /* Small text: 112% */ lLeading *= 112; } else if (iFontsize < 28) { /* Normal text: 124% */ lLeading *= 124; } else if (iFontsize < 48) { /* Small headlines: 104% */ lLeading *= 104; } else { /* Large headlines: 100% */ lLeading *= 100; } lLeading = lMilliPoints2DrawUnits(lLeading); lLeading += 50; lLeading /= 100; return lLeading;} /* end of lComputeLeading */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -