xref: /plan9/sys/src/cmd/aux/antiword/sectlist.c (revision 25b329d522281a8cdd35da0dcc08c3fc621059a9)
1 /*
2  * sectlist.c
3  * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL
4  *
5  * Description:
6  * Build, read and destroy list(s) of Word section information
7  */
8 
9 #include <stddef.h>
10 #include <string.h>
11 #include "antiword.h"
12 
13 
14 /*
15  * Private structure to hide the way the information
16  * is stored from the rest of the program
17  */
18 typedef struct section_mem_tag {
19 	section_block_type	tInfo;
20 	ULONG			ulCharPos;
21 	struct section_mem_tag	*pNext;
22 } section_mem_type;
23 
24 /* Variables needed to write the Section Information List */
25 static section_mem_type	*pAnchor = NULL;
26 static section_mem_type	*pSectionLast = NULL;
27 
28 
29 /*
30  * vDestroySectionInfoList - destroy the Section Information List
31  */
32 void
vDestroySectionInfoList(void)33 vDestroySectionInfoList(void)
34 {
35 	section_mem_type	*pCurr, *pNext;
36 
37 	DBG_MSG("vDestroySectionInfoList");
38 
39 	/* Free the Section Information List */
40 	pCurr = pAnchor;
41 	while (pCurr != NULL) {
42 		pNext = pCurr->pNext;
43 		pCurr = xfree(pCurr);
44 		pCurr = pNext;
45 	}
46 	pAnchor = NULL;
47 	/* Reset all control variables */
48 	pSectionLast = NULL;
49 } /* end of vDestroySectionInfoList */
50 
51 /*
52  * vAdd2SectionInfoList - Add an element to the Section Information List
53  */
54 void
vAdd2SectionInfoList(const section_block_type * pSection,ULONG ulCharPos)55 vAdd2SectionInfoList(const section_block_type *pSection, ULONG ulCharPos)
56 {
57 	section_mem_type	*pListMember;
58 
59 	fail(pSection == NULL);
60 
61 	/* Create list member */
62 	pListMember = xmalloc(sizeof(section_mem_type));
63 	/* Fill the list member */
64 	pListMember->tInfo = *pSection;
65 	pListMember->ulCharPos = ulCharPos;
66 	pListMember->pNext = NULL;
67 	/* Add the new member to the list */
68 	if (pAnchor == NULL) {
69 		pAnchor = pListMember;
70 	} else {
71 		fail(pSectionLast == NULL);
72 		pSectionLast->pNext = pListMember;
73 	}
74 	pSectionLast = pListMember;
75 } /* vAdd2SectionInfoList */
76 
77 /*
78  * vGetDefaultSection - fill the section struct with default values
79  */
80 void
vGetDefaultSection(section_block_type * pSection)81 vGetDefaultSection(section_block_type *pSection)
82 {
83 	(void)memset(pSection, 0, sizeof(*pSection));
84 	pSection->bNewPage = TRUE;
85 } /* end of vGetDefaultSection */
86 
87 /*
88  * vDefault2SectionInfoList - Add a default to the Section Information List
89  */
90 void
vDefault2SectionInfoList(ULONG ulCharPos)91 vDefault2SectionInfoList(ULONG ulCharPos)
92 {
93 	section_block_type	tSection;
94 
95 	vGetDefaultSection(&tSection);
96 	vAdd2SectionInfoList(&tSection, ulCharPos);
97 } /* end of vDefault2SectionInfoList */
98 
99 /*
100  * pGetSectionInfo - get the section information
101  */
102 const section_block_type *
pGetSectionInfo(const section_block_type * pOld,ULONG ulCharPos)103 pGetSectionInfo(const section_block_type *pOld, ULONG ulCharPos)
104 {
105 	const section_mem_type	*pCurr;
106 
107 	if (pOld == NULL || ulCharPos == 0) {
108 		if (pAnchor == NULL) {
109 			/* There are no records, make one */
110 			vDefault2SectionInfoList(0);
111 			fail(pAnchor == NULL);
112 		}
113 		/* The first record */
114 		NO_DBG_MSG("First record");
115 		return &pAnchor->tInfo;
116 	}
117 
118 	NO_DBG_HEX(ulCharPos);
119 	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
120 		NO_DBG_HEX(pCurr->ulCharPos);
121 		if (ulCharPos == pCurr->ulCharPos ||
122 		    ulCharPos + 1 == pCurr->ulCharPos) {
123 			NO_DBG_HEX(pCurr->ulCharPos);
124 			return &pCurr->tInfo;
125 		}
126 	}
127 	return pOld;
128 } /* end of pGetSectionInfo */
129 
130 /*
131  * tGetNumberOfSections - get the number of sections
132  */
133 size_t
tGetNumberOfSections(void)134 tGetNumberOfSections(void)
135 {
136 	const section_mem_type	*pCurr;
137 	size_t	tCounter;
138 
139 	for (tCounter = 0, pCurr = pAnchor;
140 	     pCurr != NULL;
141 	     tCounter++, pCurr = pCurr->pNext)
142 		;	/* Empty */
143 	return tCounter;
144 } /* end of tGetNumberOfSections */
145 
146 /*
147  * ucGetSepHdrFtrSpecification - get the Heder/footer specification
148  */
149 UCHAR
ucGetSepHdrFtrSpecification(size_t tSectionNumber)150 ucGetSepHdrFtrSpecification(size_t tSectionNumber)
151 {
152 	const section_mem_type	*pCurr;
153 	size_t	tIndex;
154 
155 	for (tIndex = 0, pCurr = pAnchor;
156 	     tIndex < tSectionNumber && pCurr != NULL;
157 	     tIndex++, pCurr = pCurr->pNext)
158 		;	/* Empty */
159 	if (pCurr == NULL) {
160 		DBG_DEC(tSectionNumber);
161 		DBG_FIXME();
162 		return 0x00;
163 	}
164 	return pCurr->tInfo.ucHdrFtrSpecification;
165 } /* end of ucGetSepHdrFtrSpecification */
166