1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Module Name: pswalk - Parser routines to walk parsed op tree(s) |
5 | * |
6 | * Copyright (C) 2000 - 2023, Intel Corp. |
7 | * |
8 | *****************************************************************************/ |
9 | |
10 | #include <acpi/acpi.h> |
11 | #include "accommon.h" |
12 | #include "acparser.h" |
13 | |
14 | #define _COMPONENT ACPI_PARSER |
15 | ACPI_MODULE_NAME("pswalk" ) |
16 | |
17 | /******************************************************************************* |
18 | * |
19 | * FUNCTION: acpi_ps_delete_parse_tree |
20 | * |
21 | * PARAMETERS: subtree_root - Root of tree (or subtree) to delete |
22 | * |
23 | * RETURN: None |
24 | * |
25 | * DESCRIPTION: Delete a portion of or an entire parse tree. |
26 | * |
27 | ******************************************************************************/ |
28 | #include "amlcode.h" |
29 | void acpi_ps_delete_parse_tree(union acpi_parse_object *subtree_root) |
30 | { |
31 | union acpi_parse_object *op = subtree_root; |
32 | union acpi_parse_object *next = NULL; |
33 | union acpi_parse_object *parent = NULL; |
34 | u32 level = 0; |
35 | |
36 | ACPI_FUNCTION_TRACE_PTR(ps_delete_parse_tree, subtree_root); |
37 | |
38 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE_TREES, " root %p\n" , subtree_root)); |
39 | |
40 | /* Visit all nodes in the subtree */ |
41 | |
42 | while (op) { |
43 | if (op != parent) { |
44 | |
45 | /* This is the descending case */ |
46 | |
47 | if (ACPI_IS_DEBUG_ENABLED |
48 | (ACPI_LV_PARSE_TREES, _COMPONENT)) { |
49 | |
50 | /* This debug option will print the entire parse tree */ |
51 | |
52 | acpi_os_printf(format: " %*.s%s %p" , (level * 4), |
53 | " " , |
54 | acpi_ps_get_opcode_name(opcode: op-> |
55 | common. |
56 | aml_opcode), |
57 | op); |
58 | |
59 | if (op->named.aml_opcode == AML_INT_NAMEPATH_OP) { |
60 | acpi_os_printf(format: " %4.4s" , |
61 | op->common.value.string); |
62 | } |
63 | if (op->named.aml_opcode == AML_STRING_OP) { |
64 | acpi_os_printf(format: " %s" , |
65 | op->common.value.string); |
66 | } |
67 | acpi_os_printf(format: "\n" ); |
68 | } |
69 | |
70 | /* Look for an argument or child of the current op */ |
71 | |
72 | next = acpi_ps_get_arg(op, argn: 0); |
73 | if (next) { |
74 | |
75 | /* Still going downward in tree (Op is not completed yet) */ |
76 | |
77 | op = next; |
78 | level++; |
79 | continue; |
80 | } |
81 | } |
82 | |
83 | /* No more children, this Op is complete. */ |
84 | |
85 | next = op->common.next; |
86 | parent = op->common.parent; |
87 | |
88 | acpi_ps_free_op(op); |
89 | |
90 | /* If we are back to the starting point, the walk is complete. */ |
91 | |
92 | if (op == subtree_root) { |
93 | return_VOID; |
94 | } |
95 | |
96 | if (next) { |
97 | op = next; |
98 | } else { |
99 | level--; |
100 | op = parent; |
101 | } |
102 | } |
103 | |
104 | return_VOID; |
105 | } |
106 | |