1 /******************************************************************************
3 * Module Name: pstree - Parser op tree manipulation/traversal/search
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #define _COMPONENT ACPI_PARSER
32 MODULE_NAME ("pstree")
35 /*******************************************************************************
37 * FUNCTION: Acpi_ps_get_arg
39 * PARAMETERS: Op - Get an argument for this op
40 * Argn - Nth argument to get
42 * RETURN: The argument (as an Op object). NULL if argument does not exist
44 * DESCRIPTION: Get the specified op's argument.
46 ******************************************************************************/
50 acpi_parse_object *op,
53 acpi_parse_object *arg = NULL;
54 const acpi_opcode_info *op_info;
60 /* Get the info structure for this opcode */
62 op_info = acpi_ps_get_opcode_info (op->opcode);
63 if (op_info->class == AML_CLASS_UNKNOWN) {
64 /* Invalid opcode or ASCII character */
69 /* Check if this opcode requires argument sub-objects */
71 if (!(op_info->flags & AML_HAS_ARGS)) {
72 /* Has no linked argument objects */
77 /* Get the requested argument object */
89 /*******************************************************************************
91 * FUNCTION: Acpi_ps_append_arg
93 * PARAMETERS: Op - Append an argument to this Op.
94 * Arg - Argument Op to append
98 * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
100 ******************************************************************************/
104 acpi_parse_object *op,
105 acpi_parse_object *arg)
107 acpi_parse_object *prev_arg;
108 const acpi_opcode_info *op_info;
118 /* Get the info structure for this opcode */
120 op_info = acpi_ps_get_opcode_info (op->opcode);
121 if (op_info->class == AML_CLASS_UNKNOWN) {
124 REPORT_ERROR (("Ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", op->opcode));
128 /* Check if this opcode requires argument sub-objects */
130 if (!(op_info->flags & AML_HAS_ARGS)) {
131 /* Has no linked argument objects */
137 /* Append the argument to the linked argument list */
140 /* Append to existing argument list */
142 prev_arg = op->value.arg;
143 while (prev_arg->next) {
144 prev_arg = prev_arg->next;
146 prev_arg->next = arg;
150 /* No argument list, this will be the first argument */
156 /* Set the parent in this arg and any args linked after it */
165 /*******************************************************************************
167 * FUNCTION: Acpi_ps_get_child
169 * PARAMETERS: Op - Get the child of this Op
171 * RETURN: Child Op, Null if none is found.
173 * DESCRIPTION: Get op's children or NULL if none
175 ******************************************************************************/
179 acpi_parse_object *op)
181 acpi_parse_object *child = NULL;
187 switch (op->opcode) {
191 case AML_THERMAL_ZONE_OP:
192 case AML_INT_METHODCALL_OP:
194 child = acpi_ps_get_arg (op, 0);
205 child = acpi_ps_get_arg (op, 1);
209 case AML_POWER_RES_OP:
210 case AML_INDEX_FIELD_OP:
212 child = acpi_ps_get_arg (op, 2);
216 case AML_PROCESSOR_OP:
217 case AML_BANK_FIELD_OP:
219 child = acpi_ps_get_arg (op, 3);
228 /*******************************************************************************
230 * FUNCTION: Acpi_ps_get_depth_next
232 * PARAMETERS: Origin - Root of subtree to search
233 * Op - Last (previous) Op that was found
235 * RETURN: Next Op found in the search.
237 * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
238 * Return NULL when reaching "origin" or when walking up from root
240 ******************************************************************************/
243 acpi_ps_get_depth_next (
244 acpi_parse_object *origin,
245 acpi_parse_object *op)
247 acpi_parse_object *next = NULL;
248 acpi_parse_object *parent;
249 acpi_parse_object *arg;
259 /* look for an argument or child */
261 next = acpi_ps_get_arg (op, 0);
266 /* look for a sibling */
273 /* look for a sibling of parent */
278 arg = acpi_ps_get_arg (parent, 0);
279 while (arg && (arg != origin) && (arg != op)) {
284 /* reached parent of origin, end search */
290 /* found sibling of parent */
291 return (parent->next);
295 parent = parent->parent;