xref: /Universal-ctags/main/nestlevel.c (revision 2e3d0c314e7498083e1f0b52a426b201f083cbb4)
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 "debug.h"
17 #include "entry.h"
18 #include "routines.h"
19 #include "nestlevel.h"
20 
21 #include <string.h>
22 
23 /* TODO: Alignment */
24 #define NL_SIZE(nls) (sizeof(NestingLevel) + (nls)->userDataSize)
25 #define NL_NTH(nls,n) (NestingLevel *)(((char *)((nls)->levels)) + ((n) * NL_SIZE (nls)))
26 
27 /*
28 *   FUNCTION DEFINITIONS
29 */
30 
nestingLevelsNewFull(size_t userDataSize,void (* deleteUserData)(NestingLevel *,void *))31 extern NestingLevels *nestingLevelsNewFull(size_t userDataSize,
32 										   void (* deleteUserData)(NestingLevel *, void *))
33 {
34 	NestingLevels *nls = xCalloc (1, NestingLevels);
35 	nls->userDataSize = userDataSize;
36 	nls->deleteUserData = deleteUserData;
37 	return nls;
38 }
39 
nestingLevelsNew(size_t userDataSize)40 extern NestingLevels *nestingLevelsNew(size_t userDataSize)
41 {
42 	return nestingLevelsNewFull (userDataSize, NULL);
43 }
44 
nestingLevelsFreeFull(NestingLevels * nls,void * ctxData)45 extern void nestingLevelsFreeFull(NestingLevels *nls, void *ctxData)
46 {
47 	int i;
48 	NestingLevel *nl;
49 
50 	for (i = 0; i < nls->n; i++)
51 	{
52 		nl = NL_NTH(nls, i);
53 		if (nls->deleteUserData)
54 			nls->deleteUserData (nl, ctxData);
55 		nl->corkIndex = CORK_NIL;
56 	}
57 	if (nls->levels) eFree(nls->levels);
58 	eFree(nls);
59 }
60 
nestingLevelsPush(NestingLevels * nls,int corkIndex)61 extern NestingLevel * nestingLevelsPush(NestingLevels *nls, int corkIndex)
62 {
63 	NestingLevel *nl = NULL;
64 
65 	if (nls->n >= nls->allocated)
66 	{
67 		nls->allocated++;
68 		nls->levels = eRealloc(nls->levels,
69 				       nls->allocated * NL_SIZE (nls));
70 	}
71 	nl = NL_NTH(nls, nls->n);
72 	nls->n++;
73 
74 	nl->corkIndex = corkIndex;
75 	if (nls->userDataSize > 0)
76 		memset (nl->userData, 0, nls->userDataSize);
77 
78 	return nl;
79 }
80 
nestingLevelsTruncate(NestingLevels * nls,int depth,int corkIndex)81 extern NestingLevel *nestingLevelsTruncate(NestingLevels *nls, int depth, int corkIndex)
82 {
83 	NestingLevel *nl;
84 
85 	nls->n = depth;
86 	nl = nestingLevelsGetCurrent(nls);
87 	nl->corkIndex = corkIndex;
88 	return nl;
89 }
90 
91 
nestingLevelsPopFull(NestingLevels * nls,void * ctxData)92 extern void nestingLevelsPopFull(NestingLevels *nls, void *ctxData)
93 {
94 	NestingLevel *nl = nestingLevelsGetCurrent(nls);
95 
96 	Assert (nl != NULL);
97 	if (nls->deleteUserData)
98 		nls->deleteUserData (nl, ctxData);
99 	nl->corkIndex = CORK_NIL;
100 	nls->n--;
101 }
102 
nestingLevelsGetNthFromRoot(const NestingLevels * nls,int n)103 extern NestingLevel *nestingLevelsGetNthFromRoot (const NestingLevels *nls, int n)
104 {
105 	Assert (nls != NULL);
106 	if (nls->n > n && n >= 0)
107 		return  NL_NTH(nls, n);
108 	else
109 		return NULL;
110 }
111 
nestingLevelsGetNthParent(const NestingLevels * nls,int n)112 extern NestingLevel *nestingLevelsGetNthParent (const NestingLevels *nls, int n)
113 {
114 	Assert (nls != NULL);
115 	return nestingLevelsGetNthFromRoot (nls, nls->n - 1 - n);
116 }
117 
nestingLevelGetUserData(const NestingLevel * nl)118 extern void *nestingLevelGetUserData (const NestingLevel *nl)
119 {
120 	return (void *)nl->userData;
121 }
122