⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listlist.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * listlist.c * Copyright (C) 2002,2003 A.J. van Os; Released under GPL * * Description: * Build, read and destroy a list of Word list information * * Note: * This list only exists when the Word document is saved by Word 8 or later */#include "antiword.h"/* * Private structure to hide the way the information * is stored from the rest of the program */typedef struct list_desc_tag {	list_block_type		tInfo;	ULONG			ulListID;	USHORT			usIstd;	UCHAR			ucListLevel;	struct list_desc_tag	*pNext;} list_desc_type;typedef struct list_value_tag {	USHORT			usValue;	USHORT			usListIndex;	UCHAR			ucListLevel;	struct list_value_tag	*pNext;} list_value_type;/* Variables needed to describe the LFO list (pllfo) */static ULONG		*aulLfoList = NULL;static USHORT		usLfoLen = 0;/* Variables needed to write the List Information List */static list_desc_type	*pAnchor = NULL;static list_desc_type	*pBlockLast = NULL;/* Variable needed for numbering new lists */static list_value_type	*pValues = NULL;/* Variables needed for numbering old lists */static int	iOldListSeqNumber = 0;static USHORT	usOldListValue = 0;/* * vDestroyListInfoList - destroy the List Information List */voidvDestroyListInfoList(void){	list_desc_type	*pCurr, *pNext;	list_value_type	*pValueCurr, *pValueNext;	DBG_MSG("vDestroyListInfoList");	/* Free the LFO list */	usLfoLen = 0;	aulLfoList = xfree(aulLfoList);	/* Free the List Information List */	pCurr = pAnchor;	while (pCurr != NULL) {		pNext = pCurr->pNext;		pCurr = xfree(pCurr);		pCurr = pNext;	}	pAnchor = NULL;	/* Reset all control variables */	pBlockLast = NULL;	/* Free the values list */	pValueCurr = pValues;	while (pValueCurr != NULL) {		pValueNext = pValueCurr->pNext;		pValueCurr = xfree(pValueCurr);		pValueCurr = pValueNext;	}	pValues = NULL;	/* Reset the values for the old lists */	iOldListSeqNumber = 0;	usOldListValue = 0;} /* end of vDestroyListInfoList *//* * vBuildLfoList - build the LFO list (pllfo) */voidvBuildLfoList(const UCHAR *aucBuffer, size_t tBufLen){	size_t	tRecords;	int	iIndex;	fail(aucBuffer == NULL);	if (tBufLen < 4) {		return;	}	tRecords = (size_t)ulGetLong(0, aucBuffer);	NO_DBG_DEC(tRecords);	if (4 + 16 * tRecords > tBufLen || tRecords >= 0x7fff) {		/* Just a sanity check */		DBG_DEC(tRecords);		DBG_DEC(4 + 16 * tRecords);		DBG_DEC(tBufLen);		return;	}	aulLfoList = xcalloc(tRecords, sizeof(ULONG));	for (iIndex = 0; iIndex < (int)tRecords; iIndex++) {		aulLfoList[iIndex] = ulGetLong(4 + 16 * iIndex, aucBuffer);		NO_DBG_HEX(aulLfoList[iIndex]);	}	usLfoLen = (USHORT)tRecords;} /* end of vBuildLfoList *//* * vAdd2ListInfoList - add an element to the List Information list */voidvAdd2ListInfoList(ULONG ulListID, USHORT usIstd, UCHAR ucListLevel,	const list_block_type *pListBlock){	list_desc_type	*pListMember;	fail(pListBlock == NULL);	NO_DBG_HEX(ulListID);	NO_DBG_DEC(usIstd);	NO_DBG_DEC(ucListLevel);	NO_DBG_DEC(pListBlock->ulStartAt);	NO_DBG_DEC(pListBlock->bNoRestart);	NO_DBG_DEC(pListBlock->sLeftIndent);	NO_DBG_HEX(pListBlock->ucNFC);	NO_DBG_HEX(pListBlock->usListChar);	/* Create list member */	pListMember = xmalloc(sizeof(list_desc_type));	/* Fill the list member */	pListMember->tInfo = *pListBlock;	pListMember->ulListID = ulListID;	pListMember->usIstd = usIstd;	pListMember->ucListLevel = ucListLevel;	pListMember->pNext = NULL;	/* Correct the values where needed */	if (pListMember->tInfo.ulStartAt > 0xffff) {		DBG_DEC(pListMember->tInfo.ulStartAt);		pListMember->tInfo.ulStartAt = 1;	}	/* Add the new member to the list */	if (pAnchor == NULL) {		pAnchor = pListMember;	} else {		fail(pBlockLast == NULL);		pBlockLast->pNext = pListMember;	}	pBlockLast = pListMember;} /* end of vAdd2ListInfoList *//* * Get a matching record from the List Information List * * Returns NULL if no matching records is found */const list_block_type *pGetListInfo(USHORT usListIndex, UCHAR ucListLevel){	list_desc_type	*pCurr;	list_block_type	*pNearMatch;	ULONG	ulListID;	if (usListIndex == 0) {		return NULL;	}	if (usListIndex - 1 >= usLfoLen || ucListLevel > 8) {		DBG_DEC(usListIndex);		DBG_DEC(ucListLevel);		return NULL;	}	fail(aulLfoList == NULL);	ulListID = aulLfoList[usListIndex - 1];	NO_DBG_HEX(ulListID);	pNearMatch = NULL;	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {		if (pCurr->ulListID != ulListID) {			/* No match */			continue;		}		if (pCurr->ucListLevel == ucListLevel) {			/* Exact match */			return &pCurr->tInfo;		}		if (pCurr->ucListLevel == 0) {			/* Near match */			pNearMatch = &pCurr->tInfo;		}	}	/* No exact match, use a near match if any */	return pNearMatch;} /* end of pGetListInfo *//* * Get a matching record from the List Information List * * Returns NULL if no matching records is found */const list_block_type *pGetListInfoByIstd(USHORT usIstd){	list_desc_type	*pCurr;	if (usIstd == ISTD_INVALID || usIstd == STI_NIL || usIstd == STI_USER) {		return NULL;	}	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {		if (pCurr->usIstd == usIstd) {			return &pCurr->tInfo;		}	}	return NULL;} /* end of pGetListInfoByIstd *//* * vRestartListValues - reset the less significant list levels */static voidvRestartListValues(USHORT usListIndex, UCHAR ucListLevel){	list_value_type	*pPrev, *pCurr, *pNext;	int		iCounter;	iCounter = 0;	pPrev = NULL;	pCurr = pValues;	while (pCurr != NULL) {		if (pCurr->usListIndex != usListIndex ||		    pCurr->ucListLevel <= ucListLevel) {			pPrev = pCurr;			pCurr = pCurr->pNext;			continue;		}		/* Reset the level by deleting the record */		pNext = pCurr->pNext;		if (pPrev == NULL) {			pValues = pNext;		} else {			pPrev->pNext = pNext;		}		DBG_DEC(pCurr->usListIndex);		DBG_DEC(pCurr->ucListLevel);		pCurr = xfree(pCurr);		pCurr = pNext;		iCounter++;	}	DBG_DEC_C(iCounter > 0, iCounter);} /* end of vRestartListValues *//* * usGetListValue - Get the current value of the given list * * Returns the value of the given list */USHORTusGetListValue(int iListSeqNumber, int iWordVersion,	const style_block_type *pStyle){	list_value_type	*pCurr;	USHORT		usValue;	fail(iListSeqNumber < 0);	fail(iListSeqNumber < iOldListSeqNumber);	fail(iWordVersion < 0);	fail(pStyle == NULL);	if (iListSeqNumber <= 0) {		return 0;	}	if (iWordVersion < 8) {		/* Old style list */		if (iListSeqNumber == iOldListSeqNumber ||		    (iListSeqNumber == iOldListSeqNumber + 1 &&		     eGetNumType(pStyle->ucNumLevel) == level_type_sequence)) {			if (!pStyle->bNumPause) {				usOldListValue++;			}		} else {			usOldListValue = pStyle->usStartAt;		}		iOldListSeqNumber = iListSeqNumber;		return usOldListValue;	}	/* New style list */	if (pStyle->usListIndex == 0 ||	    pStyle->usListIndex - 1 >= usLfoLen ||	    pStyle->ucListLevel > 8) {		/* Out of range; no need to search */		return 0;	}	for (pCurr = pValues; pCurr != NULL; pCurr = pCurr->pNext) {		if (pCurr->usListIndex == pStyle->usListIndex &&		    pCurr->ucListLevel == pStyle->ucListLevel) {			/* Record found; increment and return the value */			pCurr->usValue++;			usValue = pCurr->usValue;			if (!pStyle->bNoRestart) {				vRestartListValues(pStyle->usListIndex,						pStyle->ucListLevel);			}			return usValue;		}	}	/* Record not found; create it and add it to the front of the list */	pCurr = xmalloc(sizeof(list_value_type));	pCurr->usValue = pStyle->usStartAt;	pCurr->usListIndex = pStyle->usListIndex;	pCurr->ucListLevel = pStyle->ucListLevel;	pCurr->pNext = pValues;	pValues = pCurr;	usValue = pCurr->usValue;	if (!pStyle->bNoRestart) {		vRestartListValues(pStyle->usListIndex, pStyle->ucListLevel);	}	return usValue;} /* end of usGetListValue */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -