1 /*
2 * Copyright (c) 2016, Szymon Tomasz Stefanek
3 *
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
6 *
7 * This module contains functions for parsing and scanning C++ source files
8 */
9
10 #include "cxx_debug.h"
11
12 #ifdef CXX_DO_DEBUGGING
13
14 #include "trashbox.h"
15 #include "cxx_parser_internal.h"
16 #include "cxx_scope.h"
17
18 static void cxxDebugDumpToken0 (CXXToken *pToken,
19 struct circularRefChecker *pTokenChecker,
20 struct circularRefChecker *pChainChecker,
21 bool top_level);
22
cxxDebugDumpChain0(CXXTokenChain * pChain,struct circularRefChecker * pTokenChecker,struct circularRefChecker * pChainChecker,bool top_level)23 static void cxxDebugDumpChain0 (CXXTokenChain *pChain,
24 struct circularRefChecker *pTokenChecker,
25 struct circularRefChecker *pChainChecker,
26 bool top_level)
27 {
28 int backref;
29
30 if (top_level)
31 {
32 debugIndent ();
33 fprintf (stderr, "<chain ");
34 }
35 else if (pChain == NULL)
36 {
37 fprintf (stderr, "NULL\n");
38 return;
39 }
40 else
41 {
42 fprintf (stderr, "<");
43 }
44
45 backref = circularRefCheckerCheck (pChainChecker, pChain);
46 if (backref)
47 {
48 fprintf (stderr, "*C#%d>\n", backref);
49 return;
50 }
51
52 backref = circularRefCheckerGetCurrent (pChainChecker);
53
54 fprintf (stderr, "[%d %p&C#%d]\n", pChain->iCount, pChain, backref);
55
56 debugInc();
57 debugIndent ();
58 cxxDebugDumpToken0 (pChain->pHead, pTokenChecker, pChainChecker, false);
59 debugDec();
60
61 debugIndent ();
62 fprintf (stderr, ">\n");
63 }
64
cxxDebugDumpToken0(CXXToken * pToken,struct circularRefChecker * pTokenChecker,struct circularRefChecker * pChainChecker,bool top_level)65 static void cxxDebugDumpToken0 (CXXToken *pToken,
66 struct circularRefChecker *pTokenChecker,
67 struct circularRefChecker *pChainChecker,
68 bool top_level)
69 {
70 int backref;
71
72 if (top_level)
73 {
74 debugIndent ();
75 fprintf (stderr, "<token ");
76 }
77 else if (pToken == NULL)
78 {
79 fprintf (stderr, "NULL\n");
80 return;
81 }
82 else
83 {
84 fprintf (stderr, "<");
85 }
86
87 backref = circularRefCheckerCheck (pTokenChecker, pToken);
88 if (backref)
89 {
90 fprintf (stderr, "*T#%d>\n", backref);
91 return;
92 }
93
94 backref = circularRefCheckerGetCurrent (pTokenChecker);
95
96 fprintf (stderr, "\"%s\": [%s %p &T#%d]\n",
97 vStringValue (pToken->pszWord),
98 cxxDebugTypeDecode (pToken->eType), pToken, backref);
99
100 debugIndent ();
101 fprintf (stderr, " chain: ");
102 debugInc();
103 cxxDebugDumpChain0 (pToken->pChain, pTokenChecker, pTokenChecker, false);
104 debugDec();
105
106 debugIndent ();
107 fprintf (stderr, " next: ");
108 debugInc();
109 cxxDebugDumpToken0 (pToken->pNext, pTokenChecker, pTokenChecker, false);
110 debugDec();
111
112 debugIndent ();
113 fprintf (stderr, " prev: ");
114 debugInc();
115 cxxDebugDumpToken0 (pToken->pPrev, pTokenChecker, pTokenChecker, false);
116 debugDec();
117
118 debugIndent ();
119 fprintf (stderr, ">\n");
120 }
121
122 typedef void (* cxxDebugDumpCommonFunc)(void *,
123 struct circularRefChecker *,
124 struct circularRefChecker *,
125 bool);
cxxDebugDumpCommon(void * data,void (* func)(void *,struct circularRefChecker *,struct circularRefChecker *,bool))126 void cxxDebugDumpCommon (void *data,
127 void (* func)(void *,
128 struct circularRefChecker *,
129 struct circularRefChecker *,
130 bool))
131 {
132 static struct circularRefChecker *pTokenChecker;
133 static struct circularRefChecker *pChainChecker;
134
135 if (!pTokenChecker)
136 {
137 pTokenChecker = circularRefCheckerNew();
138 DEFAULT_TRASH_BOX(pTokenChecker, (TrashBoxDestroyItemProc)circularRefCheckerDestroy);
139 }
140
141 if (!pChainChecker)
142 {
143 pChainChecker = circularRefCheckerNew();
144 DEFAULT_TRASH_BOX(pChainChecker, (TrashBoxDestroyItemProc)circularRefCheckerDestroy);
145 }
146
147 func(data, pTokenChecker, pChainChecker, true);
148
149 circularRefCheckClear (pTokenChecker);
150 circularRefCheckClear (pChainChecker);
151 }
152
cxxDebugDumpToken(CXXToken * pToken)153 void cxxDebugDumpToken (CXXToken *pToken)
154 {
155 cxxDebugDumpCommon (pToken, (cxxDebugDumpCommonFunc)cxxDebugDumpToken0);
156 }
157
cxxDebugDumpChain(CXXTokenChain * pChain)158 void cxxDebugDumpChain (CXXTokenChain *pChain)
159 {
160 cxxDebugDumpCommon (pChain, (cxxDebugDumpCommonFunc)cxxDebugDumpChain0);
161 }
162
cxxDebugScopeDecode(enum CXXScopeType scope)163 const char* cxxDebugScopeDecode(enum CXXScopeType scope)
164 {
165 const char * table[] = {
166 [CXXScopeTypeFunction] = "function",
167 [CXXScopeTypeNamespace] = "namespace",
168 [CXXScopeTypeClass] = "class",
169 [CXXScopeTypeEnum] = "enum",
170 [CXXScopeTypeUnion] = "union",
171 [CXXScopeTypeStruct] = "struct",
172 [CXXScopeTypeVariable] = "variable",
173 [CXXScopeTypePrototype] = "prototype",
174 [CXXScopeTypeTypedef] = "typedef",
175 };
176 if (CXXScopeTypeLAST > scope)
177 return table[scope];
178 else
179 return NULL;
180 }
181
182 #endif
183