pstree.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: pstree - Parser op tree manipulation/traversal/search
  4.  *              $Revision: 35 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "acparser.h"
  26. #include "amlcode.h"
  27. #define _COMPONENT          ACPI_PARSER
  28.  MODULE_NAME         ("pstree")
  29. /*******************************************************************************
  30.  *
  31.  * FUNCTION:    Acpi_ps_get_arg
  32.  *
  33.  * PARAMETERS:  Op              - Get an argument for this op
  34.  *              Argn            - Nth argument to get
  35.  *
  36.  * RETURN:      The argument (as an Op object).  NULL if argument does not exist
  37.  *
  38.  * DESCRIPTION: Get the specified op's argument.
  39.  *
  40.  ******************************************************************************/
  41. acpi_parse_object *
  42. acpi_ps_get_arg (
  43. acpi_parse_object       *op,
  44. u32                     argn)
  45. {
  46. acpi_parse_object       *arg = NULL;
  47. const acpi_opcode_info  *op_info;
  48. FUNCTION_ENTRY ();
  49. /* Get the info structure for this opcode */
  50. op_info = acpi_ps_get_opcode_info (op->opcode);
  51. if (op_info->class == AML_CLASS_UNKNOWN) {
  52. /* Invalid opcode or ASCII character */
  53. return (NULL);
  54. }
  55. /* Check if this opcode requires argument sub-objects */
  56. if (!(op_info->flags & AML_HAS_ARGS)) {
  57. /* Has no linked argument objects */
  58. return (NULL);
  59. }
  60. /* Get the requested argument object */
  61. arg = op->value.arg;
  62. while (arg && argn) {
  63. argn--;
  64. arg = arg->next;
  65. }
  66. return (arg);
  67. }
  68. /*******************************************************************************
  69.  *
  70.  * FUNCTION:    Acpi_ps_append_arg
  71.  *
  72.  * PARAMETERS:  Op              - Append an argument to this Op.
  73.  *              Arg             - Argument Op to append
  74.  *
  75.  * RETURN:      None.
  76.  *
  77.  * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
  78.  *
  79.  ******************************************************************************/
  80. void
  81. acpi_ps_append_arg (
  82. acpi_parse_object       *op,
  83. acpi_parse_object       *arg)
  84. {
  85. acpi_parse_object       *prev_arg;
  86. const acpi_opcode_info  *op_info;
  87. FUNCTION_ENTRY ();
  88. if (!op) {
  89. return;
  90. }
  91. /* Get the info structure for this opcode */
  92. op_info = acpi_ps_get_opcode_info (op->opcode);
  93. if (op_info->class == AML_CLASS_UNKNOWN) {
  94. /* Invalid opcode */
  95. REPORT_ERROR (("Ps_append_arg: Invalid AML Opcode: 0x%2.2Xn", op->opcode));
  96. return;
  97. }
  98. /* Check if this opcode requires argument sub-objects */
  99. if (!(op_info->flags & AML_HAS_ARGS)) {
  100. /* Has no linked argument objects */
  101. return;
  102. }
  103. /* Append the argument to the linked argument list */
  104. if (op->value.arg) {
  105. /* Append to existing argument list */
  106. prev_arg = op->value.arg;
  107. while (prev_arg->next) {
  108. prev_arg = prev_arg->next;
  109. }
  110. prev_arg->next = arg;
  111. }
  112. else {
  113. /* No argument list, this will be the first argument */
  114. op->value.arg = arg;
  115. }
  116. /* Set the parent in this arg and any args linked after it */
  117. while (arg) {
  118. arg->parent = op;
  119. arg = arg->next;
  120. }
  121. }
  122. /*******************************************************************************
  123.  *
  124.  * FUNCTION:    Acpi_ps_get_child
  125.  *
  126.  * PARAMETERS:  Op              - Get the child of this Op
  127.  *
  128.  * RETURN:      Child Op, Null if none is found.
  129.  *
  130.  * DESCRIPTION: Get op's children or NULL if none
  131.  *
  132.  ******************************************************************************/
  133. acpi_parse_object *
  134. acpi_ps_get_child (
  135. acpi_parse_object       *op)
  136. {
  137. acpi_parse_object       *child = NULL;
  138. FUNCTION_ENTRY ();
  139. switch (op->opcode) {
  140. case AML_SCOPE_OP:
  141. case AML_ELSE_OP:
  142. case AML_DEVICE_OP:
  143. case AML_THERMAL_ZONE_OP:
  144. case AML_INT_METHODCALL_OP:
  145. child = acpi_ps_get_arg (op, 0);
  146. break;
  147. case AML_BUFFER_OP:
  148. case AML_PACKAGE_OP:
  149. case AML_METHOD_OP:
  150. case AML_IF_OP:
  151. case AML_WHILE_OP:
  152. case AML_FIELD_OP:
  153. child = acpi_ps_get_arg (op, 1);
  154. break;
  155. case AML_POWER_RES_OP:
  156. case AML_INDEX_FIELD_OP:
  157. child = acpi_ps_get_arg (op, 2);
  158. break;
  159. case AML_PROCESSOR_OP:
  160. case AML_BANK_FIELD_OP:
  161. child = acpi_ps_get_arg (op, 3);
  162. break;
  163. }
  164. return (child);
  165. }
  166. /*******************************************************************************
  167.  *
  168.  * FUNCTION:    Acpi_ps_get_depth_next
  169.  *
  170.  * PARAMETERS:  Origin          - Root of subtree to search
  171.  *              Op              - Last (previous) Op that was found
  172.  *
  173.  * RETURN:      Next Op found in the search.
  174.  *
  175.  * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
  176.  *              Return NULL when reaching "origin" or when walking up from root
  177.  *
  178.  ******************************************************************************/
  179. acpi_parse_object *
  180. acpi_ps_get_depth_next (
  181. acpi_parse_object       *origin,
  182. acpi_parse_object       *op)
  183. {
  184. acpi_parse_object       *next = NULL;
  185. acpi_parse_object       *parent;
  186. acpi_parse_object       *arg;
  187. FUNCTION_ENTRY ();
  188. if (!op) {
  189. return (NULL);
  190. }
  191. /* look for an argument or child */
  192. next = acpi_ps_get_arg (op, 0);
  193. if (next) {
  194. return (next);
  195. }
  196. /* look for a sibling */
  197. next = op->next;
  198. if (next) {
  199. return (next);
  200. }
  201. /* look for a sibling of parent */
  202. parent = op->parent;
  203. while (parent) {
  204. arg = acpi_ps_get_arg (parent, 0);
  205. while (arg && (arg != origin) && (arg != op)) {
  206. arg = arg->next;
  207. }
  208. if (arg == origin) {
  209. /* reached parent of origin, end search */
  210. return (NULL);
  211. }
  212. if (parent->next) {
  213. /* found sibling of parent */
  214. return (parent->next);
  215. }
  216. op = parent;
  217. parent = parent->parent;
  218. }
  219. return (next);
  220. }