19ed22506SFrank Fesevur /*
29ed22506SFrank Fesevur * Copyright (c) 1999-2002, Darren Hiebert
39ed22506SFrank Fesevur * Copyright 2009-2011 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
49ed22506SFrank Fesevur *
59ed22506SFrank Fesevur * This source code is released for free distribution under the terms of the
60ce38835Sviccuad * GNU General Public License version 2 or (at your option) any later version.
79ed22506SFrank Fesevur *
89ed22506SFrank Fesevur * Defines external interface to scope nesting levels for tags.
99ed22506SFrank Fesevur */
109ed22506SFrank Fesevur
119ed22506SFrank Fesevur /*
129ed22506SFrank Fesevur * INCLUDE FILES
139ed22506SFrank Fesevur */
149ed22506SFrank Fesevur #include "general.h" /* must always come first */
159ed22506SFrank Fesevur
169ed22506SFrank Fesevur #include "debug.h"
1714781660SMasatake YAMATO #include "entry.h"
189ed22506SFrank Fesevur #include "routines.h"
199ed22506SFrank Fesevur #include "nestlevel.h"
209ed22506SFrank Fesevur
2149c6e400SMasatake YAMATO #include <string.h>
2249c6e400SMasatake YAMATO
23090afdd9SMasatake YAMATO /* TODO: Alignment */
24090afdd9SMasatake YAMATO #define NL_SIZE(nls) (sizeof(NestingLevel) + (nls)->userDataSize)
25090afdd9SMasatake YAMATO #define NL_NTH(nls,n) (NestingLevel *)(((char *)((nls)->levels)) + ((n) * NL_SIZE (nls)))
26090afdd9SMasatake YAMATO
279ed22506SFrank Fesevur /*
289ed22506SFrank Fesevur * FUNCTION DEFINITIONS
299ed22506SFrank Fesevur */
309ed22506SFrank Fesevur
nestingLevelsNewFull(size_t userDataSize,void (* deleteUserData)(NestingLevel *,void *))31526f5c1fSMasatake YAMATO extern NestingLevels *nestingLevelsNewFull(size_t userDataSize,
32*2e3d0c31SMasatake YAMATO void (* deleteUserData)(NestingLevel *, void *))
339ed22506SFrank Fesevur {
349ed22506SFrank Fesevur NestingLevels *nls = xCalloc (1, NestingLevels);
35090afdd9SMasatake YAMATO nls->userDataSize = userDataSize;
36526f5c1fSMasatake YAMATO nls->deleteUserData = deleteUserData;
379ed22506SFrank Fesevur return nls;
389ed22506SFrank Fesevur }
399ed22506SFrank Fesevur
nestingLevelsNew(size_t userDataSize)40526f5c1fSMasatake YAMATO extern NestingLevels *nestingLevelsNew(size_t userDataSize)
41526f5c1fSMasatake YAMATO {
42526f5c1fSMasatake YAMATO return nestingLevelsNewFull (userDataSize, NULL);
43526f5c1fSMasatake YAMATO }
44526f5c1fSMasatake YAMATO
nestingLevelsFreeFull(NestingLevels * nls,void * ctxData)45*2e3d0c31SMasatake YAMATO extern void nestingLevelsFreeFull(NestingLevels *nls, void *ctxData)
469ed22506SFrank Fesevur {
479ed22506SFrank Fesevur int i;
48090afdd9SMasatake YAMATO NestingLevel *nl;
49090afdd9SMasatake YAMATO
50526f5c1fSMasatake YAMATO for (i = 0; i < nls->n; i++)
51090afdd9SMasatake YAMATO {
52090afdd9SMasatake YAMATO nl = NL_NTH(nls, i);
53526f5c1fSMasatake YAMATO if (nls->deleteUserData)
54*2e3d0c31SMasatake YAMATO nls->deleteUserData (nl, ctxData);
55090afdd9SMasatake YAMATO nl->corkIndex = CORK_NIL;
56090afdd9SMasatake YAMATO }
579ed22506SFrank Fesevur if (nls->levels) eFree(nls->levels);
589ed22506SFrank Fesevur eFree(nls);
599ed22506SFrank Fesevur }
609ed22506SFrank Fesevur
nestingLevelsPush(NestingLevels * nls,int corkIndex)61885fbc2cSMasatake YAMATO extern NestingLevel * nestingLevelsPush(NestingLevels *nls, int corkIndex)
629ed22506SFrank Fesevur {
639ed22506SFrank Fesevur NestingLevel *nl = NULL;
649ed22506SFrank Fesevur
659ed22506SFrank Fesevur if (nls->n >= nls->allocated)
669ed22506SFrank Fesevur {
679ed22506SFrank Fesevur nls->allocated++;
68090afdd9SMasatake YAMATO nls->levels = eRealloc(nls->levels,
69090afdd9SMasatake YAMATO nls->allocated * NL_SIZE (nls));
709ed22506SFrank Fesevur }
71090afdd9SMasatake YAMATO nl = NL_NTH(nls, nls->n);
729ed22506SFrank Fesevur nls->n++;
739ed22506SFrank Fesevur
74885fbc2cSMasatake YAMATO nl->corkIndex = corkIndex;
7549c6e400SMasatake YAMATO if (nls->userDataSize > 0)
7649c6e400SMasatake YAMATO memset (nl->userData, 0, nls->userDataSize);
7749c6e400SMasatake YAMATO
78cd4bad4cSMasatake YAMATO return nl;
799ed22506SFrank Fesevur }
809ed22506SFrank Fesevur
nestingLevelsTruncate(NestingLevels * nls,int depth,int corkIndex)81885fbc2cSMasatake YAMATO extern NestingLevel *nestingLevelsTruncate(NestingLevels *nls, int depth, int corkIndex)
8215c1c1c3SMasatake YAMATO {
8315c1c1c3SMasatake YAMATO NestingLevel *nl;
8415c1c1c3SMasatake YAMATO
8515c1c1c3SMasatake YAMATO nls->n = depth;
8615c1c1c3SMasatake YAMATO nl = nestingLevelsGetCurrent(nls);
87885fbc2cSMasatake YAMATO nl->corkIndex = corkIndex;
8815c1c1c3SMasatake YAMATO return nl;
8915c1c1c3SMasatake YAMATO }
9015c1c1c3SMasatake YAMATO
9115c1c1c3SMasatake YAMATO
nestingLevelsPopFull(NestingLevels * nls,void * ctxData)92*2e3d0c31SMasatake YAMATO extern void nestingLevelsPopFull(NestingLevels *nls, void *ctxData)
939ed22506SFrank Fesevur {
94885fbc2cSMasatake YAMATO NestingLevel *nl = nestingLevelsGetCurrent(nls);
959ed22506SFrank Fesevur
969ed22506SFrank Fesevur Assert (nl != NULL);
97526f5c1fSMasatake YAMATO if (nls->deleteUserData)
98*2e3d0c31SMasatake YAMATO nls->deleteUserData (nl, ctxData);
99885fbc2cSMasatake YAMATO nl->corkIndex = CORK_NIL;
1009ed22506SFrank Fesevur nls->n--;
1019ed22506SFrank Fesevur }
1029ed22506SFrank Fesevur
nestingLevelsGetNthFromRoot(const NestingLevels * nls,int n)1030f753a22SMasatake YAMATO extern NestingLevel *nestingLevelsGetNthFromRoot (const NestingLevels *nls, int n)
104090afdd9SMasatake YAMATO {
105090afdd9SMasatake YAMATO Assert (nls != NULL);
106090afdd9SMasatake YAMATO if (nls->n > n && n >= 0)
107090afdd9SMasatake YAMATO return NL_NTH(nls, n);
108090afdd9SMasatake YAMATO else
109090afdd9SMasatake YAMATO return NULL;
110090afdd9SMasatake YAMATO }
111090afdd9SMasatake YAMATO
nestingLevelsGetNthParent(const NestingLevels * nls,int n)1120f753a22SMasatake YAMATO extern NestingLevel *nestingLevelsGetNthParent (const NestingLevels *nls, int n)
1130f753a22SMasatake YAMATO {
1140f753a22SMasatake YAMATO Assert (nls != NULL);
1150f753a22SMasatake YAMATO return nestingLevelsGetNthFromRoot (nls, nls->n - 1 - n);
1160f753a22SMasatake YAMATO }
1170f753a22SMasatake YAMATO
nestingLevelGetUserData(const NestingLevel * nl)118090afdd9SMasatake YAMATO extern void *nestingLevelGetUserData (const NestingLevel *nl)
119090afdd9SMasatake YAMATO {
120090afdd9SMasatake YAMATO return (void *)nl->userData;
121090afdd9SMasatake YAMATO }
122