xref: /netbsd-src/usr.sbin/acpitools/aml/aml_name.c (revision 82c98410bee757743f2a7de4ad572bf8527508ad)
1*82c98410Scegger /*	$NetBSD: aml_name.c,v 1.4 2009/10/08 13:16:13 cegger Exp $	*/
253e202c1Schristos 
353e202c1Schristos /*-
453e202c1Schristos  * Copyright (c) 1999 Takanori Watanabe
553e202c1Schristos  * Copyright (c) 1999, 2000 Yasuo Yokoyama
653e202c1Schristos  * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
753e202c1Schristos  * All rights reserved.
853e202c1Schristos  *
953e202c1Schristos  * Redistribution and use in source and binary forms, with or without
1053e202c1Schristos  * modification, are permitted provided that the following conditions
1153e202c1Schristos  * are met:
1253e202c1Schristos  * 1. Redistributions of source code must retain the above copyright
1353e202c1Schristos  *    notice, this list of conditions and the following disclaimer.
1453e202c1Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1553e202c1Schristos  *    notice, this list of conditions and the following disclaimer in the
1653e202c1Schristos  *    documentation and/or other materials provided with the distribution.
1753e202c1Schristos  *
1853e202c1Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1953e202c1Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2053e202c1Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2153e202c1Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2253e202c1Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2353e202c1Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2453e202c1Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2553e202c1Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2653e202c1Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2753e202c1Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2853e202c1Schristos  * SUCH DAMAGE.
2953e202c1Schristos  *
3053e202c1Schristos  *	Id: aml_name.c,v 1.15 2000/08/16 18:14:53 iwasaki Exp
3153e202c1Schristos  *	$FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_name.c,v 1.3 2000/11/09 06:24:45 iwasaki Exp $
3253e202c1Schristos  */
3353e202c1Schristos #include <sys/cdefs.h>
34*82c98410Scegger __RCSID("$NetBSD: aml_name.c,v 1.4 2009/10/08 13:16:13 cegger Exp $");
3553e202c1Schristos 
3653e202c1Schristos #include <sys/param.h>
3753e202c1Schristos 
3853e202c1Schristos #include <acpi_common.h>
3953e202c1Schristos #include <aml/aml_amlmem.h>
4053e202c1Schristos #include <aml/aml_common.h>
4153e202c1Schristos #include <aml/aml_env.h>
4253e202c1Schristos #include <aml/aml_name.h>
4353e202c1Schristos 
4453e202c1Schristos #ifndef _KERNEL
4553e202c1Schristos #include <stdio.h>
4653e202c1Schristos #include <stdlib.h>
4753e202c1Schristos #include <string.h>
4853e202c1Schristos 
4953e202c1Schristos #include "debug.h"
5053e202c1Schristos #else /* _KERNEL */
5153e202c1Schristos #include <sys/systm.h>
5253e202c1Schristos #endif /* !_KERNEL */
5353e202c1Schristos 
5453e202c1Schristos static struct aml_name	*aml_find_name(struct aml_name *, const u_int8_t *);
5553e202c1Schristos static struct aml_name	*aml_new_name(struct aml_name *, const u_int8_t *);
5653e202c1Schristos static void		 aml_delete_name(struct aml_name *);
5753e202c1Schristos 
5853e202c1Schristos static struct	aml_name rootname = {"\\", NULL, NULL, NULL, NULL, NULL};
5953e202c1Schristos 
6053e202c1Schristos static struct	aml_name_group root_group = {
6153e202c1Schristos 	AML_NAME_GROUP_ROOT,
6253e202c1Schristos 	&rootname,
6353e202c1Schristos 	NULL
6453e202c1Schristos };
6553e202c1Schristos 
6653e202c1Schristos struct	aml_name_group *name_group_list = &root_group;
6753e202c1Schristos struct	aml_local_stack *stack_top = NULL;
6853e202c1Schristos 
6953e202c1Schristos struct aml_name *
aml_get_rootname()7053e202c1Schristos aml_get_rootname()
7153e202c1Schristos {
7253e202c1Schristos 
7353e202c1Schristos 	return (&rootname);
7453e202c1Schristos }
7553e202c1Schristos 
7653e202c1Schristos static struct aml_name *
aml_find_name(struct aml_name * parent,const u_int8_t * name)7753e202c1Schristos aml_find_name(struct aml_name *parent, const u_int8_t *name)
7853e202c1Schristos {
7953e202c1Schristos 	struct	aml_name *result;
8053e202c1Schristos 
8153e202c1Schristos 	if (!parent)
8253e202c1Schristos 		parent = &rootname;
8353e202c1Schristos 	for (result = parent->child; result; result = result->brother)
8453e202c1Schristos 		if (!strncmp(result->name, (const char *)name, 4))
8553e202c1Schristos 			break;
8653e202c1Schristos 	return (result);
8753e202c1Schristos }
8853e202c1Schristos 
8953e202c1Schristos /*
9053e202c1Schristos  * Parse given namesppace expression and find a first matched object
9153e202c1Schristos  * under given level of the tree by depth first search.
9253e202c1Schristos  */
9353e202c1Schristos 
9453e202c1Schristos struct aml_name *
aml_find_from_namespace(struct aml_name * parent,const char * name)9553e202c1Schristos aml_find_from_namespace(struct aml_name *parent, const char *name)
9653e202c1Schristos {
9753e202c1Schristos 	const char	*ptr;
9853e202c1Schristos 	int	len;
9953e202c1Schristos 	struct	aml_name *result;
10053e202c1Schristos 
10153e202c1Schristos 	ptr = name;
10253e202c1Schristos 	if (!parent)
10353e202c1Schristos 		parent = &rootname;
10453e202c1Schristos 
10553e202c1Schristos 	if (ptr[0] == '\\') {
10653e202c1Schristos 		ptr++;
10753e202c1Schristos 		parent = &rootname;
10853e202c1Schristos 	}
10953e202c1Schristos 	for (len = 0; ptr[len] != '.' && ptr[len] != '\0'; len++)
11053e202c1Schristos 		;
11153e202c1Schristos 
11253e202c1Schristos 	for (result = parent->child; result; result = result->brother) {
11353e202c1Schristos 		if (!strncmp(result->name, ptr, len)) {
11453e202c1Schristos 			if (ptr[len] == '\0' || ptr[len + 1] == '\0') {
11553e202c1Schristos 				return (result);
11653e202c1Schristos 			}
11753e202c1Schristos 			ptr += len;
11853e202c1Schristos 			if (ptr[0] != '.') {
11953e202c1Schristos 				return (NULL);
12053e202c1Schristos 			}
12153e202c1Schristos 			ptr++;
12253e202c1Schristos 			return (aml_find_from_namespace(result, ptr));
12353e202c1Schristos 		}
12453e202c1Schristos 	}
12553e202c1Schristos 
12653e202c1Schristos 	return (NULL);
12753e202c1Schristos }
12853e202c1Schristos 
12953e202c1Schristos static void
_aml_apply_foreach_found_objects(struct aml_name * parent,char * name,int len,int shallow,int (* func)(struct aml_name *,va_list),va_list ap)13053e202c1Schristos _aml_apply_foreach_found_objects(struct aml_name *parent, char *name,
13153e202c1Schristos     int len, int shallow, int (*func)(struct aml_name *, va_list), va_list ap)
13253e202c1Schristos {
13353e202c1Schristos 	struct	aml_name *child, *ptr;
13453e202c1Schristos 
13553e202c1Schristos 	child = ptr = NULL;
13653e202c1Schristos 
13753e202c1Schristos 	/* function to apply must be specified */
13853e202c1Schristos 	if (func == NULL) {
13953e202c1Schristos 		return;
14053e202c1Schristos 	}
14153e202c1Schristos 
14253e202c1Schristos 	for (child = parent->child; child; child = child->brother) {
14353e202c1Schristos 		if (!strncmp(child->name, name, len)) {
14453e202c1Schristos 			/* if function call was failed, stop searching */
14553e202c1Schristos 			if (func(child, ap) != 0) {
14653e202c1Schristos 				return;
14753e202c1Schristos 			}
14853e202c1Schristos 		}
14953e202c1Schristos 	}
15053e202c1Schristos 
15153e202c1Schristos 	if (shallow == 1) {
15253e202c1Schristos 		return;
15353e202c1Schristos 	}
15453e202c1Schristos 
15553e202c1Schristos 	for (ptr = parent->child; ptr; ptr = ptr->brother) {
15653e202c1Schristos 		/* do more searching */
15753e202c1Schristos 		_aml_apply_foreach_found_objects(ptr, name, len, 0, func, ap);
15853e202c1Schristos 	}
15953e202c1Schristos }
16053e202c1Schristos 
16153e202c1Schristos /*
16253e202c1Schristos  * Find named objects as many as possible under given level of
16353e202c1Schristos  * namespace, and apply given callback function for each
16453e202c1Schristos  * named objects found.  If the callback function returns non-zero
16553e202c1Schristos  * value, then the search terminates immediately.
16653e202c1Schristos  * Note that object name expression is used as forward substring match,
16753e202c1Schristos  * not exact match.  The name expression "_L" will match for objects
16853e202c1Schristos  * which have name starting with "_L" such as "\_SB_.LID_._LID" and
16953e202c1Schristos  * "\_GPE._L00" and so on. The name expression can include parent object
17053e202c1Schristos  * name in it like "\_GPE._L".  In this case, GPE X level wake handlers
17153e202c1Schristos  * will be found under "\_GPE" in shallow level.
17253e202c1Schristos  */
17353e202c1Schristos 
17453e202c1Schristos void
aml_apply_foreach_found_objects(struct aml_name * start,char * name,int (* func)(struct aml_name *,va_list),...)17553e202c1Schristos aml_apply_foreach_found_objects(struct aml_name *start, char *name,
17653e202c1Schristos     int (*func)(struct aml_name *, va_list), ...)
17753e202c1Schristos {
17853e202c1Schristos 	int	i, len, has_dot, last_is_dot, shallow;
17953e202c1Schristos 	struct	aml_name *child, *parent;
18053e202c1Schristos 	va_list	ap;
18153e202c1Schristos 
18253e202c1Schristos 	shallow = 0;
18353e202c1Schristos 	if (start == NULL) {
18453e202c1Schristos 		parent = &rootname;
18553e202c1Schristos 	} else {
18653e202c1Schristos 		parent = start;
18753e202c1Schristos 	}
18853e202c1Schristos 	if (name[0] == '\\') {
18953e202c1Schristos 		name++;
19053e202c1Schristos 		parent = &rootname;
19153e202c1Schristos 		shallow = 1;
19253e202c1Schristos 	}
19353e202c1Schristos 
19453e202c1Schristos 	len = strlen(name);
19553e202c1Schristos 	last_is_dot = 0;
19653e202c1Schristos 	/* the last dot should be ignored */
19753e202c1Schristos 	if (len > 0 && name[len - 1] == '.') {
19853e202c1Schristos 		len--;
19953e202c1Schristos 		last_is_dot = 1;
20053e202c1Schristos 	}
20153e202c1Schristos 
20253e202c1Schristos 	has_dot = 0;
20353e202c1Schristos 	for (i = 0; i < len - 1; i++) {
20453e202c1Schristos 		if (name[i] == '.') {
20553e202c1Schristos 			has_dot = 1;
20653e202c1Schristos 			break;
20753e202c1Schristos 		}
20853e202c1Schristos 	}
20953e202c1Schristos 
21053e202c1Schristos 	/* try to parse expression and find any matched object. */
21153e202c1Schristos 	if (has_dot == 1) {
21253e202c1Schristos 		child = aml_find_from_namespace(parent, name);
21353e202c1Schristos 		if (child == NULL) {
21453e202c1Schristos 			return;
21553e202c1Schristos 		}
21653e202c1Schristos 
21753e202c1Schristos 		/*
21853e202c1Schristos 		 * we have at least one object matched, search all objects
21953e202c1Schristos 		 * under upper level of the found object.
22053e202c1Schristos 		 */
22153e202c1Schristos 		parent = child->parent;
22253e202c1Schristos 
22353e202c1Schristos 		/* find the last `.' */
22453e202c1Schristos 		for (name = name + len - 1; *name != '.'; name--)
22553e202c1Schristos 			;
22653e202c1Schristos 		name++;
22753e202c1Schristos 		len = strlen(name) - last_is_dot;
22853e202c1Schristos 		shallow = 1;
22953e202c1Schristos 	}
23053e202c1Schristos 
23153e202c1Schristos 	if (len > 4) {
23253e202c1Schristos 		return;
23353e202c1Schristos 	}
23453e202c1Schristos 
23553e202c1Schristos 	va_start(ap, func);
23653e202c1Schristos 	_aml_apply_foreach_found_objects(parent, name, len, shallow, func, ap);
23753e202c1Schristos 	va_end(ap);
23853e202c1Schristos }
23953e202c1Schristos 
24053e202c1Schristos struct aml_name_group *
aml_new_name_group(void * id)2417ac7d15dSdogcow aml_new_name_group(void *id)
24253e202c1Schristos {
24353e202c1Schristos 	struct	aml_name_group *result;
24453e202c1Schristos 
24553e202c1Schristos 	result = memman_alloc(aml_memman, memid_aml_name_group);
24653e202c1Schristos 	result->id = id;
24753e202c1Schristos 	result->head = NULL;
24853e202c1Schristos 	result->next = name_group_list;
24953e202c1Schristos 	name_group_list = result;
25053e202c1Schristos 	return (result);
25153e202c1Schristos }
25253e202c1Schristos 
25353e202c1Schristos void
aml_delete_name_group(struct aml_name_group * target)25453e202c1Schristos aml_delete_name_group(struct aml_name_group *target)
25553e202c1Schristos {
25653e202c1Schristos 	struct	aml_name_group *previous;
25753e202c1Schristos 
25853e202c1Schristos 	previous = name_group_list;
25953e202c1Schristos 	if (previous == target)
26053e202c1Schristos 		name_group_list = target->next;
26153e202c1Schristos 	else {
26253e202c1Schristos 		while (previous && previous->next != target)
26353e202c1Schristos 			previous = previous->next;
26453e202c1Schristos 		if (previous)
26553e202c1Schristos 			previous->next = target->next;
26653e202c1Schristos 	}
26753e202c1Schristos 	target->next = NULL;
26853e202c1Schristos 	if (target->head)
26953e202c1Schristos 		aml_delete_name(target->head);
27053e202c1Schristos 	memman_free(aml_memman, memid_aml_name_group, target);
27153e202c1Schristos }
27253e202c1Schristos 
27353e202c1Schristos static struct aml_name *
aml_new_name(struct aml_name * parent,const u_int8_t * name)27453e202c1Schristos aml_new_name(struct aml_name *parent, const u_int8_t *name)
27553e202c1Schristos {
27653e202c1Schristos 	struct	aml_name *newname;
27753e202c1Schristos 
27853e202c1Schristos 	if ((newname = aml_find_name(parent, name)) != NULL)
27953e202c1Schristos 		return (newname);
28053e202c1Schristos 
28153e202c1Schristos 	newname = memman_alloc(aml_memman, memid_aml_name);
28253e202c1Schristos 	strncpy(newname->name, (const char *)name, 4);
28353e202c1Schristos 	newname->parent = parent;
28453e202c1Schristos 	newname->child = NULL;
28553e202c1Schristos 	newname->property = NULL;
286*82c98410Scegger 	if (parent && parent->child)
28753e202c1Schristos 		newname->brother = parent->child;
28853e202c1Schristos 	else
28953e202c1Schristos 		newname->brother = NULL;
290*82c98410Scegger 	if (parent)
29153e202c1Schristos 		parent->child = newname;
29253e202c1Schristos 
29353e202c1Schristos 	newname->chain = name_group_list->head;
29453e202c1Schristos 	name_group_list->head = newname;
29553e202c1Schristos 
29653e202c1Schristos 	return (newname);
29753e202c1Schristos }
29853e202c1Schristos 
29953e202c1Schristos /*
30053e202c1Schristos  * NOTE:
30153e202c1Schristos  * aml_delete_name() doesn't maintain aml_name_group::{head,tail}.
30253e202c1Schristos  */
30353e202c1Schristos static void
aml_delete_name(struct aml_name * target)30453e202c1Schristos aml_delete_name(struct aml_name *target)
30553e202c1Schristos {
30653e202c1Schristos 	struct	aml_name *next;
30753e202c1Schristos 	struct	aml_name *ptr;
30853e202c1Schristos 
30953e202c1Schristos 	for (; target; target = next) {
31053e202c1Schristos 		next = target->chain;
31153e202c1Schristos 		if (target->child) {
31253e202c1Schristos 			target->chain = NULL;
31353e202c1Schristos 			continue;
31453e202c1Schristos 		}
31553e202c1Schristos 		if (target->brother) {
31653e202c1Schristos 			if (target->parent) {
31753e202c1Schristos 				if (target->parent->child == target) {
31853e202c1Schristos 					target->parent->child = target->brother;
31953e202c1Schristos 				} else {
32053e202c1Schristos 					ptr = target->parent->child;
32153e202c1Schristos 					while (ptr && ptr->brother != target)
32253e202c1Schristos 						ptr = ptr->brother;
32353e202c1Schristos 					if (ptr)
32453e202c1Schristos 						ptr->brother = target->brother;
32553e202c1Schristos 				}
32653e202c1Schristos 				target->brother = NULL;
32753e202c1Schristos 			}
32853e202c1Schristos 		} else if (target->parent) {
32953e202c1Schristos 			target->parent->child = NULL;
33053e202c1Schristos 		}
33153e202c1Schristos 		aml_free_object(&target->property);
33253e202c1Schristos 		memman_free(aml_memman, memid_aml_name, target);
33353e202c1Schristos 	}
33453e202c1Schristos }
33553e202c1Schristos 
33653e202c1Schristos #define AML_SEARCH_NAME 0
33753e202c1Schristos #define AML_CREATE_NAME 1
33853e202c1Schristos static struct aml_name	*aml_nameman(struct aml_environ *, const u_int8_t *, int);
33953e202c1Schristos 
34053e202c1Schristos struct aml_name *
aml_search_name(struct aml_environ * env,const u_int8_t * dp)34153e202c1Schristos aml_search_name(struct aml_environ *env, const u_int8_t *dp)
34253e202c1Schristos {
34353e202c1Schristos 
34453e202c1Schristos 	return (aml_nameman(env, dp, AML_SEARCH_NAME));
34553e202c1Schristos }
34653e202c1Schristos 
34753e202c1Schristos struct aml_name *
aml_create_name(struct aml_environ * env,const u_int8_t * dp)34853e202c1Schristos aml_create_name(struct aml_environ *env, const u_int8_t *dp)
34953e202c1Schristos {
35053e202c1Schristos 
35153e202c1Schristos 	return (aml_nameman(env, dp, AML_CREATE_NAME));
35253e202c1Schristos }
35353e202c1Schristos 
35453e202c1Schristos static struct aml_name *
aml_nameman(struct aml_environ * env,const u_int8_t * dp,int flag)35553e202c1Schristos aml_nameman(struct aml_environ *env, const u_int8_t *dp, int flag)
35653e202c1Schristos {
35753e202c1Schristos 	int	segcount;
35853e202c1Schristos 	int	i;
35953e202c1Schristos 	struct	aml_name *newname, *curname;
36053e202c1Schristos 	struct	aml_name *(*searchfunc) (struct aml_name *, const u_int8_t *);
36153e202c1Schristos 
36253e202c1Schristos #define CREATECHECK() do {						\
36353e202c1Schristos 	if (newname == NULL) {						\
36453e202c1Schristos 		AML_DEBUGPRINT("ERROR CANNOT FIND NAME\n");		\
36553e202c1Schristos 		env->stat = aml_stat_panic;				\
36653e202c1Schristos 		return (NULL);						\
36753e202c1Schristos 	}								\
36853e202c1Schristos } while(0)
36953e202c1Schristos 
37053e202c1Schristos 	searchfunc = (flag == AML_CREATE_NAME) ? aml_new_name : aml_find_name;
37153e202c1Schristos 	newname = env->curname;
37253e202c1Schristos 	if (dp[0] == '\\') {
37353e202c1Schristos 		newname = &rootname;
37453e202c1Schristos 		dp++;
37553e202c1Schristos 	} else if (dp[0] == '^') {
37653e202c1Schristos 		while (dp[0] == '^') {
37753e202c1Schristos 			newname = newname->parent;
37853e202c1Schristos 			CREATECHECK();
37953e202c1Schristos 			dp++;
38053e202c1Schristos 		}
38153e202c1Schristos 	}
38253e202c1Schristos 	if (dp[0] == 0x00) {	/* NullName */
38353e202c1Schristos 		dp++;
38453e202c1Schristos 	} else if (dp[0] == 0x2e) {	/* DualNamePrefix */
38553e202c1Schristos 		newname = (*searchfunc) (newname, dp + 1);
38653e202c1Schristos 		CREATECHECK();
38753e202c1Schristos 		newname = (*searchfunc) (newname, dp + 5);
38853e202c1Schristos 		CREATECHECK();
38953e202c1Schristos 	} else if (dp[0] == 0x2f) {	/* MultiNamePrefix */
39053e202c1Schristos 		segcount = dp[1];
39153e202c1Schristos 		for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
39253e202c1Schristos 			newname = (*searchfunc) (newname, dp);
39353e202c1Schristos 			CREATECHECK();
39453e202c1Schristos 		}
39553e202c1Schristos 	} else if (flag == AML_CREATE_NAME) {	/* NameSeg */
39653e202c1Schristos 		newname = aml_new_name(newname, dp);
39753e202c1Schristos 		CREATECHECK();
39853e202c1Schristos 	} else {
39953e202c1Schristos 		curname = newname;
40053e202c1Schristos 		for (;;) {
40153e202c1Schristos 			newname = aml_find_name(curname, dp);
40253e202c1Schristos 			if (newname != NULL)
40353e202c1Schristos 				break;
404379c0e1aSjmcneill 			if (curname == &rootname || curname == NULL)
40553e202c1Schristos 				break;
40653e202c1Schristos 			curname = curname->parent;
40753e202c1Schristos 		}
40853e202c1Schristos 	}
40953e202c1Schristos 	return (newname);
41053e202c1Schristos }
41153e202c1Schristos 
41253e202c1Schristos #undef CREATECHECK
41353e202c1Schristos 
41453e202c1Schristos struct aml_local_stack *
aml_local_stack_create()41553e202c1Schristos aml_local_stack_create()
41653e202c1Schristos {
41753e202c1Schristos 	struct aml_local_stack *result;
41853e202c1Schristos 
41953e202c1Schristos 	result = memman_alloc(aml_memman, memid_aml_local_stack);
42053e202c1Schristos 	memset(result, 0, sizeof(struct aml_local_stack));
42153e202c1Schristos 	return (result);
42253e202c1Schristos }
42353e202c1Schristos 
42453e202c1Schristos void
aml_local_stack_push(struct aml_local_stack * stack)42553e202c1Schristos aml_local_stack_push(struct aml_local_stack *stack)
42653e202c1Schristos {
42753e202c1Schristos 
42853e202c1Schristos 	stack->next = stack_top;
42953e202c1Schristos 	stack_top = stack;
43053e202c1Schristos }
43153e202c1Schristos 
43253e202c1Schristos struct aml_local_stack *
aml_local_stack_pop()43353e202c1Schristos aml_local_stack_pop()
43453e202c1Schristos {
43553e202c1Schristos 	struct aml_local_stack *result;
43653e202c1Schristos 
43753e202c1Schristos 	result = stack_top;
43853e202c1Schristos 	stack_top = result->next;
43953e202c1Schristos 	result->next = NULL;
44053e202c1Schristos 	return (result);
44153e202c1Schristos }
44253e202c1Schristos 
44353e202c1Schristos void
aml_local_stack_delete(struct aml_local_stack * stack)44453e202c1Schristos aml_local_stack_delete(struct aml_local_stack *stack)
44553e202c1Schristos {
44653e202c1Schristos 	int	i;
44753e202c1Schristos 
44853e202c1Schristos 	for (i = 0; i < 8; i++)
44953e202c1Schristos 		aml_free_object(&stack->localvalue[i].property);
45053e202c1Schristos 	for (i = 0; i < 7; i++)
45153e202c1Schristos 		aml_free_object(&stack->argumentvalue[i].property);
45253e202c1Schristos 	aml_delete_name(stack->temporary);
45353e202c1Schristos 	memman_free(aml_memman, memid_aml_local_stack, stack);
45453e202c1Schristos }
45553e202c1Schristos 
45653e202c1Schristos struct aml_name *
aml_local_stack_getLocalX(int idx)45753e202c1Schristos aml_local_stack_getLocalX(int idx)
45853e202c1Schristos {
45953e202c1Schristos 
46053e202c1Schristos 	if (stack_top == NULL)
46153e202c1Schristos 		return (NULL);
46253e202c1Schristos 	return (&stack_top->localvalue[idx]);
46353e202c1Schristos }
46453e202c1Schristos 
46553e202c1Schristos struct aml_name *
aml_local_stack_getArgX(struct aml_local_stack * stack,int idx)46653e202c1Schristos aml_local_stack_getArgX(struct aml_local_stack *stack, int idx)
46753e202c1Schristos {
46853e202c1Schristos 
46953e202c1Schristos 	if (!stack)
47053e202c1Schristos 		stack = stack_top;
47153e202c1Schristos 	if (stack == NULL)
47253e202c1Schristos 		return (NULL);
47353e202c1Schristos 	return (&stack->argumentvalue[idx]);
47453e202c1Schristos }
47553e202c1Schristos 
47653e202c1Schristos struct aml_name *
aml_create_local_object()47753e202c1Schristos aml_create_local_object()
47853e202c1Schristos {
47953e202c1Schristos 	struct aml_name *result;
48053e202c1Schristos 
48153e202c1Schristos 	result = memman_alloc(aml_memman, memid_aml_name);
48253e202c1Schristos 	result->child = result->brother = result->parent = NULL;
48353e202c1Schristos 	result->property = NULL;
48453e202c1Schristos 	result->chain = stack_top->temporary;
48553e202c1Schristos 	stack_top->temporary = result;
48653e202c1Schristos 	return (result);
48753e202c1Schristos }
488