VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/VDScriptAst.cpp@ 78392

Last change on this file since 78392 was 77232, checked in by vboxsync, 6 years ago

Storage/QED+QCOW: It is not allowed to mix RTStrDup, RTMemAlloc and RTStrFree, you must stick to one allocator type. Strings must be sanitized or coverted after loading.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.4 KB
Line 
1/* $Id: VDScriptAst.cpp 77232 2019-02-09 01:55:37Z vboxsync $ */
2/** @file
3 * VBox HDD container test utility - scripting engine AST node related functions.
4 */
5
6/*
7 * Copyright (C) 2013-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#define LOGGROUP LOGGROUP_DEFAULT
18#include <iprt/list.h>
19#include <iprt/mem.h>
20#include <iprt/assert.h>
21#include <iprt/string.h>
22
23#include <VBox/log.h>
24
25#include "VDScriptAst.h"
26
27/**
28 * Put all child nodes of the given expression AST node onto the given to free list.
29 *
30 * @returns nothing.
31 * @param pList The free list to append everything to.
32 * @param pAstNode The expression node to free.
33 */
34static void vdScriptAstNodeExpressionPutOnFreeList(PRTLISTANCHOR pList, PVDSCRIPTASTCORE pAstNode)
35{
36 AssertMsgReturnVoid(pAstNode->enmClass == VDSCRIPTASTCLASS_EXPRESSION,
37 ("Given AST node is not a statement\n"));
38
39 PVDSCRIPTASTEXPR pExpr = (PVDSCRIPTASTEXPR)pAstNode;
40 switch (pExpr->enmType)
41 {
42 case VDSCRIPTEXPRTYPE_PRIMARY_NUMCONST:
43 case VDSCRIPTEXPRTYPE_PRIMARY_BOOLEAN:
44 break;
45 case VDSCRIPTEXPRTYPE_PRIMARY_STRINGCONST:
46 RTStrFree((char *)pExpr->pszStr);
47 break;
48 case VDSCRIPTEXPRTYPE_PRIMARY_IDENTIFIER:
49 {
50 RTListAppend(pList, &pExpr->pIde->Core.ListNode);
51 break;
52 }
53 case VDSCRIPTEXPRTYPE_ASSIGNMENT_LIST:
54 {
55 while (!RTListIsEmpty(&pExpr->ListExpr))
56 {
57 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pExpr->ListExpr, VDSCRIPTASTCORE, ListNode);
58 RTListNodeRemove(&pNode->ListNode);
59 RTListAppend(pList, &pNode->ListNode);
60 }
61 break;
62 }
63 case VDSCRIPTEXPRTYPE_POSTFIX_FNCALL:
64 {
65 RTListAppend(pList, &pExpr->FnCall.pFnIde->Core.ListNode);
66 while (!RTListIsEmpty(&pExpr->FnCall.ListArgs))
67 {
68 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pExpr->FnCall.ListArgs, VDSCRIPTASTCORE, ListNode);
69 RTListNodeRemove(&pNode->ListNode);
70 RTListAppend(pList, &pNode->ListNode);
71 }
72 break;
73 }
74 case VDSCRIPTEXPRTYPE_POSTFIX_DEREFERENCE:
75 case VDSCRIPTEXPRTYPE_POSTFIX_DOT:
76 {
77 RTListAppend(pList, &pExpr->Deref.pIde->Core.ListNode);
78 RTListAppend(pList, &pExpr->Deref.pExpr->Core.ListNode);
79 break;
80 }
81 case VDSCRIPTEXPRTYPE_POSTFIX_INCREMENT:
82 case VDSCRIPTEXPRTYPE_POSTFIX_DECREMENT:
83 case VDSCRIPTEXPRTYPE_UNARY_INCREMENT:
84 case VDSCRIPTEXPRTYPE_UNARY_DECREMENT:
85 case VDSCRIPTEXPRTYPE_UNARY_POSSIGN:
86 case VDSCRIPTEXPRTYPE_UNARY_NEGSIGN:
87 case VDSCRIPTEXPRTYPE_UNARY_INVERT:
88 case VDSCRIPTEXPRTYPE_UNARY_NEGATE:
89 case VDSCRIPTEXPRTYPE_UNARY_REFERENCE:
90 case VDSCRIPTEXPRTYPE_UNARY_DEREFERENCE:
91 {
92 RTListAppend(pList, &pExpr->pExpr->Core.ListNode);
93 break;
94 }
95 case VDSCRIPTEXPRTYPE_MULTIPLICATION:
96 case VDSCRIPTEXPRTYPE_DIVISION:
97 case VDSCRIPTEXPRTYPE_MODULUS:
98 case VDSCRIPTEXPRTYPE_ADDITION:
99 case VDSCRIPTEXPRTYPE_SUBTRACTION:
100 case VDSCRIPTEXPRTYPE_LSR:
101 case VDSCRIPTEXPRTYPE_LSL:
102 case VDSCRIPTEXPRTYPE_LOWER:
103 case VDSCRIPTEXPRTYPE_HIGHER:
104 case VDSCRIPTEXPRTYPE_LOWEREQUAL:
105 case VDSCRIPTEXPRTYPE_HIGHEREQUAL:
106 case VDSCRIPTEXPRTYPE_EQUAL:
107 case VDSCRIPTEXPRTYPE_NOTEQUAL:
108 case VDSCRIPTEXPRTYPE_BITWISE_AND:
109 case VDSCRIPTEXPRTYPE_BITWISE_XOR:
110 case VDSCRIPTEXPRTYPE_BITWISE_OR:
111 case VDSCRIPTEXPRTYPE_LOGICAL_AND:
112 case VDSCRIPTEXPRTYPE_LOGICAL_OR:
113 case VDSCRIPTEXPRTYPE_ASSIGN:
114 case VDSCRIPTEXPRTYPE_ASSIGN_MULT:
115 case VDSCRIPTEXPRTYPE_ASSIGN_DIV:
116 case VDSCRIPTEXPRTYPE_ASSIGN_MOD:
117 case VDSCRIPTEXPRTYPE_ASSIGN_ADD:
118 case VDSCRIPTEXPRTYPE_ASSIGN_SUB:
119 case VDSCRIPTEXPRTYPE_ASSIGN_LSL:
120 case VDSCRIPTEXPRTYPE_ASSIGN_LSR:
121 case VDSCRIPTEXPRTYPE_ASSIGN_AND:
122 case VDSCRIPTEXPRTYPE_ASSIGN_XOR:
123 case VDSCRIPTEXPRTYPE_ASSIGN_OR:
124 {
125 RTListAppend(pList, &pExpr->BinaryOp.pLeftExpr->Core.ListNode);
126 RTListAppend(pList, &pExpr->BinaryOp.pRightExpr->Core.ListNode);
127 break;
128 }
129 case VDSCRIPTEXPRTYPE_INVALID:
130 default:
131 AssertMsgFailedReturnVoid(("Invalid AST node expression type %d\n",
132 pExpr->enmType));
133 }
134}
135
136/**
137 * Free a given statement AST node and put everything on the given to free list.
138 *
139 * @returns nothing.
140 * @param pList The free list to append everything to.
141 * @param pAstNode The statement node to free.
142 */
143static void vdScriptAstNodeStatmentPutOnFreeList(PRTLISTANCHOR pList, PVDSCRIPTASTCORE pAstNode)
144{
145 AssertMsgReturnVoid(pAstNode->enmClass == VDSCRIPTASTCLASS_STATEMENT,
146 ("Given AST node is not a statement\n"));
147
148 PVDSCRIPTASTSTMT pStmt = (PVDSCRIPTASTSTMT)pAstNode;
149 switch (pStmt->enmStmtType)
150 {
151 case VDSCRIPTSTMTTYPE_COMPOUND:
152 {
153 /* Put all declarations on the to free list. */
154 while (!RTListIsEmpty(&pStmt->Compound.ListDecls))
155 {
156 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListDecls, VDSCRIPTASTCORE, ListNode);
157 RTListNodeRemove(&pNode->ListNode);
158 RTListAppend(pList, &pNode->ListNode);
159 }
160
161 /* Put all statements on the to free list. */
162 while (!RTListIsEmpty(&pStmt->Compound.ListStmts))
163 {
164 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListStmts, VDSCRIPTASTCORE, ListNode);
165 RTListNodeRemove(&pNode->ListNode);
166 RTListAppend(pList, &pNode->ListNode);
167 }
168 break;
169 }
170 case VDSCRIPTSTMTTYPE_EXPRESSION:
171 {
172 if (pStmt->pExpr)
173 RTListAppend(pList, &pStmt->pExpr->Core.ListNode);
174 break;
175 }
176 case VDSCRIPTSTMTTYPE_IF:
177 {
178 RTListAppend(pList, &pStmt->If.pCond->Core.ListNode);
179 RTListAppend(pList, &pStmt->If.pTrueStmt->Core.ListNode);
180 if (pStmt->If.pElseStmt)
181 RTListAppend(pList, &pStmt->If.pElseStmt->Core.ListNode);
182 break;
183 }
184 case VDSCRIPTSTMTTYPE_SWITCH:
185 {
186 RTListAppend(pList, &pStmt->Switch.pCond->Core.ListNode);
187 RTListAppend(pList, &pStmt->Switch.pStmt->Core.ListNode);
188 break;
189 }
190 case VDSCRIPTSTMTTYPE_WHILE:
191 {
192 RTListAppend(pList, &pStmt->While.pCond->Core.ListNode);
193 RTListAppend(pList, &pStmt->While.pStmt->Core.ListNode);
194 break;
195 }
196 case VDSCRIPTSTMTTYPE_FOR:
197 {
198 RTListAppend(pList, &pStmt->For.pExprStart->Core.ListNode);
199 RTListAppend(pList, &pStmt->For.pExprCond->Core.ListNode);
200 RTListAppend(pList, &pStmt->For.pExpr3->Core.ListNode);
201 RTListAppend(pList, &pStmt->For.pStmt->Core.ListNode);
202 break;
203 }
204 case VDSCRIPTSTMTTYPE_RETURN:
205 {
206 if (pStmt->pExpr)
207 RTListAppend(pList, &pStmt->pExpr->Core.ListNode);
208 break;
209 }
210 case VDSCRIPTSTMTTYPE_CASE:
211 {
212 RTListAppend(pList, &pStmt->Case.pExpr->Core.ListNode);
213 RTListAppend(pList, &pStmt->Case.pStmt->Core.ListNode);
214 break;
215 }
216 case VDSCRIPTSTMTTYPE_DEFAULT:
217 {
218 RTListAppend(pList, &pStmt->Case.pStmt->Core.ListNode);
219 break;
220 }
221 case VDSCRIPTSTMTTYPE_CONTINUE:
222 case VDSCRIPTSTMTTYPE_BREAK:
223 break;
224 case VDSCRIPTSTMTTYPE_INVALID:
225 default:
226 AssertMsgFailedReturnVoid(("Invalid AST node statement type %d\n",
227 pStmt->enmStmtType));
228 }
229}
230
231DECLHIDDEN(void) vdScriptAstNodeFree(PVDSCRIPTASTCORE pAstNode)
232{
233 RTLISTANCHOR ListFree;
234
235 /*
236 * The node is not allowed to be part of a list because we need it
237 * for the nodes to free list.
238 */
239 Assert(RTListIsEmpty(&pAstNode->ListNode));
240 RTListInit(&ListFree);
241 RTListAppend(&ListFree, &pAstNode->ListNode);
242
243 do
244 {
245 pAstNode = RTListGetFirst(&ListFree, VDSCRIPTASTCORE, ListNode);
246 RTListNodeRemove(&pAstNode->ListNode);
247
248 switch (pAstNode->enmClass)
249 {
250 case VDSCRIPTASTCLASS_FUNCTION:
251 {
252 PVDSCRIPTASTFN pFn = (PVDSCRIPTASTFN)pAstNode;
253
254 if (pFn->pRetType)
255 RTListAppend(&ListFree, &pFn->pRetType->Core.ListNode);
256 if (pFn->pFnIde)
257 RTListAppend(&ListFree, &pFn->pFnIde->Core.ListNode);
258
259 /* Put argument list on the to free list. */
260 while (!RTListIsEmpty(&pFn->ListArgs))
261 {
262 PVDSCRIPTASTCORE pArg = RTListGetFirst(&pFn->ListArgs, VDSCRIPTASTCORE, ListNode);
263 RTListNodeRemove(&pArg->ListNode);
264 RTListAppend(&ListFree, &pArg->ListNode);
265 }
266
267 /* Put compound statement onto the list. */
268 RTListAppend(&ListFree, &pFn->pCompoundStmts->Core.ListNode);
269 break;
270 }
271 case VDSCRIPTASTCLASS_FUNCTIONARG:
272 {
273 PVDSCRIPTASTFNARG pAstNodeArg = (PVDSCRIPTASTFNARG)pAstNode;
274 if (pAstNodeArg->pType)
275 RTListAppend(&ListFree, &pAstNodeArg->pType->Core.ListNode);
276 if (pAstNodeArg->pArgIde)
277 RTListAppend(&ListFree, &pAstNodeArg->pArgIde->Core.ListNode);
278 break;
279 }
280 case VDSCRIPTASTCLASS_IDENTIFIER:
281 break;
282 case VDSCRIPTASTCLASS_DECLARATION:
283 case VDSCRIPTASTCLASS_TYPENAME:
284 {
285 AssertMsgFailed(("TODO\n"));
286 break;
287 }
288 case VDSCRIPTASTCLASS_STATEMENT:
289 {
290 vdScriptAstNodeStatmentPutOnFreeList(&ListFree, pAstNode);
291 break;
292 }
293 case VDSCRIPTASTCLASS_EXPRESSION:
294 {
295 vdScriptAstNodeExpressionPutOnFreeList(&ListFree, pAstNode);
296 break;
297 }
298 case VDSCRIPTASTCLASS_INVALID:
299 default:
300 AssertMsgFailedReturnVoid(("Invalid AST node class given %d\n", pAstNode->enmClass));
301 }
302
303 RTMemFree(pAstNode);
304 } while (!RTListIsEmpty(&ListFree));
305
306}
307
308DECLHIDDEN(PVDSCRIPTASTCORE) vdScriptAstNodeAlloc(VDSCRIPTASTCLASS enmClass)
309{
310 size_t cbAlloc = 0;
311
312 switch (enmClass)
313 {
314 case VDSCRIPTASTCLASS_FUNCTION:
315 cbAlloc = sizeof(VDSCRIPTASTFN);
316 break;
317 case VDSCRIPTASTCLASS_FUNCTIONARG:
318 cbAlloc = sizeof(VDSCRIPTASTFNARG);
319 break;
320 case VDSCRIPTASTCLASS_DECLARATION:
321 cbAlloc = sizeof(VDSCRIPTASTDECL);
322 break;
323 case VDSCRIPTASTCLASS_STATEMENT:
324 cbAlloc = sizeof(VDSCRIPTASTSTMT);
325 break;
326 case VDSCRIPTASTCLASS_EXPRESSION:
327 cbAlloc = sizeof(VDSCRIPTASTEXPR);
328 break;
329 case VDSCRIPTASTCLASS_TYPENAME:
330 cbAlloc = sizeof(VDSCRIPTASTTYPENAME);
331 break;
332 case VDSCRIPTASTCLASS_IDENTIFIER:
333 case VDSCRIPTASTCLASS_INVALID:
334 default:
335 AssertMsgFailedReturn(("Invalid AST node class given %d\n", enmClass), NULL);
336 }
337
338 PVDSCRIPTASTCORE pAstNode = (PVDSCRIPTASTCORE)RTMemAllocZ(cbAlloc);
339 if (pAstNode)
340 {
341 pAstNode->enmClass = enmClass;
342 RTListInit(&pAstNode->ListNode);
343 }
344
345 return pAstNode;
346}
347
348DECLHIDDEN(PVDSCRIPTASTIDE) vdScriptAstNodeIdeAlloc(size_t cchIde)
349{
350 PVDSCRIPTASTIDE pAstNode = (PVDSCRIPTASTIDE)RTMemAllocZ(RT_UOFFSETOF_DYN(VDSCRIPTASTIDE, aszIde[cchIde + 1]));
351 if (pAstNode)
352 {
353 pAstNode->Core.enmClass = VDSCRIPTASTCLASS_IDENTIFIER;
354 RTListInit(&pAstNode->Core.ListNode);
355 }
356
357 return pAstNode;
358}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette