1 /*
2 * Copyright (c) 1999-2002, Darren Hiebert
3 * Copyright 2009-2011 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
4 *
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License version 2 or (at your option) any later version.
7 *
8 * Defines external interface to scope nesting levels for tags.
9 */
10
11 /*
12 * INCLUDE FILES
13 */
14 #include "general.h" /* must always come first */
15
16 #include "main.h"
17 #include "debug.h"
18 #include "routines.h"
19 #include "nestlevel.h"
20
21 /* TODO: Alignment */
22 #define NL_SIZE(nls) (sizeof(NestingLevel) + (nls)->userDataSize)
23 #define NL_NTH(nls,n) (NestingLevel *)(((char *)((nls)->levels)) + ((n) * NL_SIZE (nls)))
24
25 /*
26 * FUNCTION DEFINITIONS
27 */
28
nestingLevelsNew(size_t userDataSize)29 extern NestingLevels *nestingLevelsNew(size_t userDataSize)
30 {
31 NestingLevels *nls = xCalloc (1, NestingLevels);
32 nls->userDataSize = userDataSize;
33 return nls;
34 }
35
nestingLevelsFree(NestingLevels * nls)36 extern void nestingLevelsFree(NestingLevels *nls)
37 {
38 int i;
39 NestingLevel *nl;
40
41 for (i = 0; i < nls->allocated; i++)
42 {
43 nl = NL_NTH(nls, i);
44 nl->corkIndex = CORK_NIL;
45 }
46 if (nls->levels) eFree(nls->levels);
47 eFree(nls);
48 }
49
nestingLevelsPush(NestingLevels * nls,int corkIndex)50 extern NestingLevel * nestingLevelsPush(NestingLevels *nls, int corkIndex)
51 {
52 NestingLevel *nl = NULL;
53
54 if (nls->n >= nls->allocated)
55 {
56 nls->allocated++;
57 nls->levels = eRealloc(nls->levels,
58 nls->allocated * NL_SIZE (nls));
59 }
60 nl = NL_NTH(nls, nls->n);
61 nls->n++;
62
63 nl->corkIndex = corkIndex;
64 return nl;
65 }
66
nestingLevelsTruncate(NestingLevels * nls,int depth,int corkIndex)67 extern NestingLevel *nestingLevelsTruncate(NestingLevels *nls, int depth, int corkIndex)
68 {
69 NestingLevel *nl;
70
71 nls->n = depth;
72 nl = nestingLevelsGetCurrent(nls);
73 nl->corkIndex = corkIndex;
74 return nl;
75 }
76
77
nestingLevelsPop(NestingLevels * nls)78 extern void nestingLevelsPop(NestingLevels *nls)
79 {
80 NestingLevel *nl = nestingLevelsGetCurrent(nls);
81
82 Assert (nl != NULL);
83 nl->corkIndex = CORK_NIL;
84 nls->n--;
85 }
86
nestingLevelsGetCurrent(const NestingLevels * nls)87 extern NestingLevel *nestingLevelsGetCurrent(const NestingLevels *nls)
88 {
89 Assert (nls != NULL);
90
91 if (nls->n < 1)
92 return NULL;
93
94 return NL_NTH(nls, (nls->n - 1));
95 }
96
nestingLevelsGetNth(const NestingLevels * nls,int n)97 extern NestingLevel *nestingLevelsGetNth(const NestingLevels *nls, int n)
98 {
99 Assert (nls != NULL);
100 if (nls->n > n && n >= 0)
101 return NL_NTH(nls, n);
102 else
103 return NULL;
104 }
105
nestingLevelGetUserData(const NestingLevel * nl)106 extern void *nestingLevelGetUserData (const NestingLevel *nl)
107 {
108 return (void *)nl->userData;
109 }
110