/* * sectlist.c * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL * * Description: * Build, read and destroy list(s) of Word section information */ #include #include #include "antiword.h" /* * Private structure to hide the way the information * is stored from the rest of the program */ typedef struct section_mem_tag { section_block_type tInfo; ULONG ulCharPos; struct section_mem_tag *pNext; } section_mem_type; /* Variables needed to write the Section Information List */ static section_mem_type *pAnchor = NULL; static section_mem_type *pSectionLast = NULL; /* * vDestroySectionInfoList - destroy the Section Information List */ void vDestroySectionInfoList(void) { section_mem_type *pCurr, *pNext; DBG_MSG("vDestroySectionInfoList"); /* Free the Section Information List */ pCurr = pAnchor; while (pCurr != NULL) { pNext = pCurr->pNext; pCurr = xfree(pCurr); pCurr = pNext; } pAnchor = NULL; /* Reset all control variables */ pSectionLast = NULL; } /* end of vDestroySectionInfoList */ /* * vAdd2SectionInfoList - Add an element to the Section Information List */ void vAdd2SectionInfoList(const section_block_type *pSection, ULONG ulCharPos) { section_mem_type *pListMember; fail(pSection == NULL); /* Create list member */ pListMember = xmalloc(sizeof(section_mem_type)); /* Fill the list member */ pListMember->tInfo = *pSection; pListMember->ulCharPos = ulCharPos; pListMember->pNext = NULL; /* Add the new member to the list */ if (pAnchor == NULL) { pAnchor = pListMember; } else { fail(pSectionLast == NULL); pSectionLast->pNext = pListMember; } pSectionLast = pListMember; } /* vAdd2SectionInfoList */ /* * vGetDefaultSection - fill the section struct with default values */ void vGetDefaultSection(section_block_type *pSection) { (void)memset(pSection, 0, sizeof(*pSection)); pSection->bNewPage = TRUE; } /* end of vGetDefaultSection */ /* * vDefault2SectionInfoList - Add a default to the Section Information List */ void vDefault2SectionInfoList(ULONG ulCharPos) { section_block_type tSection; vGetDefaultSection(&tSection); vAdd2SectionInfoList(&tSection, ulCharPos); } /* end of vDefault2SectionInfoList */ /* * pGetSectionInfo - get the section information */ const section_block_type * pGetSectionInfo(const section_block_type *pOld, ULONG ulCharPos) { const section_mem_type *pCurr; if (pOld == NULL || ulCharPos == 0) { if (pAnchor == NULL) { /* There are no records, make one */ vDefault2SectionInfoList(0); fail(pAnchor == NULL); } /* The first record */ NO_DBG_MSG("First record"); return &pAnchor->tInfo; } NO_DBG_HEX(ulCharPos); for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { NO_DBG_HEX(pCurr->ulCharPos); if (ulCharPos == pCurr->ulCharPos || ulCharPos + 1 == pCurr->ulCharPos) { NO_DBG_HEX(pCurr->ulCharPos); return &pCurr->tInfo; } } return pOld; } /* end of pGetSectionInfo */ /* * tGetNumberOfSections - get the number of sections */ size_t tGetNumberOfSections(void) { const section_mem_type *pCurr; size_t tCounter; for (tCounter = 0, pCurr = pAnchor; pCurr != NULL; tCounter++, pCurr = pCurr->pNext) ; /* Empty */ return tCounter; } /* end of tGetNumberOfSections */ /* * ucGetSepHdrFtrSpecification - get the Heder/footer specification */ UCHAR ucGetSepHdrFtrSpecification(size_t tSectionNumber) { const section_mem_type *pCurr; size_t tIndex; for (tIndex = 0, pCurr = pAnchor; tIndex < tSectionNumber && pCurr != NULL; tIndex++, pCurr = pCurr->pNext) ; /* Empty */ if (pCurr == NULL) { DBG_DEC(tSectionNumber); DBG_FIXME(); return 0x00; } return pCurr->tInfo.ucHdrFtrSpecification; } /* end of ucGetSepHdrFtrSpecification */