Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* texrefs.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS */ |
||
6 | /* */ |
||
7 | /* TeX Convertes: Label/Citation Bookkeeping */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include <stdlib.h> |
||
12 | #include <string.h> |
||
13 | #include "strutil.h" |
||
14 | #include "texutil.h" |
||
15 | #include "texrefs.h" |
||
16 | |||
17 | /*--------------------------------------------------------------------------*/ |
||
18 | |||
19 | typedef struct sRefSave |
||
20 | { |
||
21 | struct sRefSave *pNext; |
||
22 | char *pRefName, *pValue; |
||
23 | } tRefSave, *tpRefSave; |
||
24 | |||
25 | /*--------------------------------------------------------------------------*/ |
||
26 | |||
27 | static tpRefSave pFirstRefSave, pFirstCiteSave; |
||
28 | |||
29 | /*!------------------------------------------------------------------------ |
||
30 | * \fn AddList(tpRefSave *ppList, const char *pDescr, const char *pName, const char *pValue) |
||
31 | * \brief add/update list |
||
32 | * \param ppList list root |
||
33 | * \param pDescr type of list contents |
||
34 | * \param pName name of label |
||
35 | * \param pValue value of label |
||
36 | * ------------------------------------------------------------------------ */ |
||
37 | |||
38 | static void AddList(tpRefSave *ppList, const char *pDescr, const char *pName, const char *pValue) |
||
39 | { |
||
40 | tpRefSave pRun, pPrev, pNeu; |
||
41 | int cmp = -1; |
||
42 | char err[200]; |
||
43 | |||
44 | for (pRun = *ppList, pPrev = NULL; pRun; pPrev = pRun, pRun = pRun->pNext) |
||
45 | if ((cmp = strcmp(pRun->pRefName, pName)) >= 0) |
||
46 | break; |
||
47 | |||
48 | if (pRun && !cmp) |
||
49 | { |
||
50 | if (strcmp(pRun->pValue, pValue)) |
||
51 | { |
||
52 | as_snprintf(err, sizeof(err), "value of %s '%s' has changed", pDescr, pName); |
||
53 | tex_warning(err); |
||
54 | DoRepass = True; |
||
55 | free(pRun->pValue); |
||
56 | pRun->pValue = as_strdup(pValue); |
||
57 | } |
||
58 | } |
||
59 | else |
||
60 | { |
||
61 | pNeu = (tpRefSave) malloc(sizeof(*pNeu)); |
||
62 | pNeu->pRefName = as_strdup(pName); |
||
63 | pNeu->pValue = as_strdup(pValue); |
||
64 | pNeu->pNext = pRun; |
||
65 | if (!pPrev) |
||
66 | *ppList = pNeu; |
||
67 | else |
||
68 | pPrev->pNext = pNeu; |
||
69 | } |
||
70 | } |
||
71 | |||
72 | /*!------------------------------------------------------------------------ |
||
73 | * \fn GetList(tpRefSave *pList, const char *pDescr, const char *pName, char *pDest) |
||
74 | * \brief retrieve value of label |
||
75 | * \param pList list to search |
||
76 | * \param pDescr type of list contents |
||
77 | * \param pName name of label |
||
78 | * \param pDest result buffer |
||
79 | * ------------------------------------------------------------------------ */ |
||
80 | |||
81 | static void GetList(tpRefSave pList, const char *pDescr, const char *pName, char *pDest) |
||
82 | { |
||
83 | tpRefSave pRun; |
||
84 | char err[200]; |
||
85 | |||
86 | for (pRun = pList; pRun; pRun = pRun->pNext) |
||
87 | if (!strcmp(pName, pRun->pRefName)) |
||
88 | break; |
||
89 | |||
90 | if (!pRun) |
||
91 | { |
||
92 | as_snprintf(err, sizeof(err), "undefined %s '%s'", pDescr, pName); |
||
93 | tex_warning(err); DoRepass = True; |
||
94 | } |
||
95 | strcpy(pDest, !pRun ? "???" : pRun->pValue); |
||
96 | } |
||
97 | |||
98 | /*!------------------------------------------------------------------------ |
||
99 | * \fn FreeList(tpRefSave *ppList) |
||
100 | * \brief free list of references |
||
101 | * \param ppList list to free |
||
102 | * ------------------------------------------------------------------------ */ |
||
103 | |||
104 | static void FreeList(tpRefSave *ppList) |
||
105 | { |
||
106 | while (*ppList) |
||
107 | { |
||
108 | tpRefSave pOld = *ppList; |
||
109 | *ppList = pOld->pNext; |
||
110 | |||
111 | free(pOld->pValue); |
||
112 | free(pOld->pRefName); |
||
113 | free(pOld); |
||
114 | } |
||
115 | } |
||
116 | |||
117 | /*!------------------------------------------------------------------------ |
||
118 | * \fn PrintList(const char *pFileName, tpRefSave pList, const char *pDescr) |
||
119 | * \brief save list to file |
||
120 | * \param pFileName file to write label list to |
||
121 | * \param pList list to dump |
||
122 | * \param pDescr type of list contents |
||
123 | * ------------------------------------------------------------------------ */ |
||
124 | |||
125 | void PrintList(const char *pName, tpRefSave pList, const char *pDescr) |
||
126 | { |
||
127 | tpRefSave pRun; |
||
128 | FILE *pFile = fopen(pName, "a"); |
||
129 | |||
130 | if (!pFile) |
||
131 | perror(pName); |
||
132 | |||
133 | for (pRun = pList; pRun; pRun = pRun->pNext) |
||
134 | fprintf(pFile, "%s %s %s\n", pDescr, pRun->pRefName, pRun->pValue); |
||
135 | fclose(pFile); |
||
136 | } |
||
137 | |||
138 | /*!------------------------------------------------------------------------ |
||
139 | * \fn InitLabels(void) |
||
140 | * \brief reset list of labels |
||
141 | * ------------------------------------------------------------------------ */ |
||
142 | |||
143 | void InitLabels(void) |
||
144 | { |
||
145 | pFirstRefSave = NULL; |
||
146 | } |
||
147 | |||
148 | /*!------------------------------------------------------------------------ |
||
149 | * \fn AddLabel(const char *pName, const char *pValue) |
||
150 | * \brief add/update label |
||
151 | * \param pName name of label |
||
152 | * \param pValue value of label |
||
153 | * ------------------------------------------------------------------------ */ |
||
154 | |||
155 | void AddLabel(const char *pName, const char *pValue) |
||
156 | { |
||
157 | AddList(&pFirstRefSave, "label", pName, pValue); |
||
158 | } |
||
159 | |||
160 | /*!------------------------------------------------------------------------ |
||
161 | * \fn GetLabel(const char *pName, char *pDest) |
||
162 | * \brief retrieve value of label |
||
163 | * \param pName name of label |
||
164 | * \param pDest result buffer |
||
165 | * ------------------------------------------------------------------------ */ |
||
166 | |||
167 | void GetLabel(const char *pName, char *pDest) |
||
168 | { |
||
169 | GetList(pFirstRefSave, "label", pName, pDest); |
||
170 | } |
||
171 | |||
172 | /*!------------------------------------------------------------------------ |
||
173 | * \fn PrintLabels(const char *pFileName) |
||
174 | * \brief save label list to file |
||
175 | * \param pFileName file to write label list to |
||
176 | * ------------------------------------------------------------------------ */ |
||
177 | |||
178 | void PrintLabels(const char *pFileName) |
||
179 | { |
||
180 | PrintList(pFileName, pFirstRefSave, "Label"); |
||
181 | } |
||
182 | |||
183 | /*!------------------------------------------------------------------------ |
||
184 | * \fn FreeLabels(void) |
||
185 | * \brief free list of labels |
||
186 | * ------------------------------------------------------------------------ */ |
||
187 | |||
188 | void FreeLabels(void) |
||
189 | { |
||
190 | FreeList(&pFirstRefSave); |
||
191 | } |
||
192 | |||
193 | /*!------------------------------------------------------------------------ |
||
194 | * \fn InitCites(void) |
||
195 | * \brief reset list of citations |
||
196 | * ------------------------------------------------------------------------ */ |
||
197 | |||
198 | void InitCites(void) |
||
199 | { |
||
200 | pFirstCiteSave = NULL; |
||
201 | } |
||
202 | |||
203 | /*!------------------------------------------------------------------------ |
||
204 | * \fn AddCite(const char *pName, const char *pValue) |
||
205 | * \brief add/update citation |
||
206 | * \param pName name of citation |
||
207 | * \param pValue value of citation |
||
208 | * ------------------------------------------------------------------------ */ |
||
209 | |||
210 | void AddCite(const char *pName, const char *pValue) |
||
211 | { |
||
212 | AddList(&pFirstCiteSave, "citation", pName, pValue); |
||
213 | } |
||
214 | |||
215 | /*!------------------------------------------------------------------------ |
||
216 | * \fn GetCite(char *pName, char *pDest) |
||
217 | * \brief retrieve value of citation |
||
218 | * \param pName name of citation |
||
219 | * \param pDest result buffer |
||
220 | * \return |
||
221 | * ------------------------------------------------------------------------ */ |
||
222 | |||
223 | void GetCite(char *pName, char *pDest) |
||
224 | { |
||
225 | GetList(pFirstCiteSave, "citation", pName, pDest); |
||
226 | } |
||
227 | |||
228 | /*!------------------------------------------------------------------------ |
||
229 | * \fn PrintCites(const char *pFileName) |
||
230 | * \brief save list of citations to file |
||
231 | * \param pFileName destination file name |
||
232 | * ------------------------------------------------------------------------ */ |
||
233 | |||
234 | void PrintCites(const char *pFileName) |
||
235 | { |
||
236 | PrintList(pFileName, pFirstCiteSave, "Citation"); |
||
237 | } |
||
238 | |||
239 | /*!------------------------------------------------------------------------ |
||
240 | * \fn FreeCites(void) |
||
241 | * \brief free list of citations |
||
242 | * ------------------------------------------------------------------------ */ |
||
243 | |||
244 | void FreeCites(void) |
||
245 | { |
||
246 | FreeList(&pFirstCiteSave); |
||
247 | } |