1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28/*
29 * Includes
30 */
31
32/* we need to define this to get strtok_r from string.h */
33/* SEEMS LIKE A BUG TO ME */
34#define	_REENTRANT
35
36#ifndef DEBUG
37#define	NDEBUG	1
38#endif
39
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <libgen.h>
44#include <assert.h>
45#include "spec.h"
46#include "expr.h"
47#include "new.h"
48
49
50/*
51 * Typedefs
52 */
53
54typedef enum {
55	MATCH_NONE = 0,
56	MATCH_FALSE,
57	MATCH_TRUE
58
59
60}			   match_t;
61
62
63/*
64 * Declarations
65 */
66
67static boolean_t matchattrs(expr_t * expr_p, const char *attrs);
68static void matchvals(spec_t * spec_p, char *attrstr,
69	char *valstr, void *calldatap);
70static void matched(spec_t * spec_p, char *valstr, void *calldatap);
71
72
73/* ---------------------------------------------------------------- */
74/* ----------------------- Public Functions ----------------------- */
75/* ---------------------------------------------------------------- */
76
77/*
78 * expr() - builds an expr
79 */
80
81expr_t		 *
82expr(spec_t * left_p,
83	spec_t * right_p)
84{
85	expr_t		 *new_p;
86
87	new_p = new(expr_t);
88	queue_init(&new_p->qn);
89	new_p->left_p = left_p;
90	new_p->right_p = right_p;
91
92	return (new_p);
93
94}				/* end expr */
95
96
97/*
98 * expr_dup() - duplicates an expression list
99 */
100
101expr_t		 *
102expr_dup(expr_t * list_p)
103{
104	expr_t		 *expr_p;
105	expr_t		 *head_p;
106
107	if (!list_p)
108		return (NULL);
109
110	/* copy the first node */
111	head_p = expr(spec_dup(list_p->left_p),
112		spec_dup(list_p->right_p));
113
114	/* append each additional node */
115	expr_p = list_p;
116	while (expr_p = (expr_t *) queue_next(&list_p->qn, &expr_p->qn)) {
117		expr_t		 *new_p;
118
119		new_p = expr(spec_dup(expr_p->left_p),
120			spec_dup(expr_p->right_p));
121		(void) queue_append(&head_p->qn, &new_p->qn);
122	}
123
124	return (head_p);
125
126}				/* end expr_dup */
127
128
129/*
130 * expr_destroy() - destroys an expression list
131 */
132
133void
134expr_destroy(expr_t * list_p)
135{
136	expr_t		 *expr_p;
137
138	while (expr_p = (expr_t *) queue_next(&list_p->qn, &list_p->qn)) {
139		(void) queue_remove(&expr_p->qn);
140
141		if (expr_p->left_p)
142			spec_destroy(expr_p->left_p);
143		if (expr_p->right_p)
144			spec_destroy(expr_p->right_p);
145		free(expr_p);
146	}
147
148	if (list_p->left_p)
149		spec_destroy(list_p->left_p);
150	if (list_p->right_p)
151		spec_destroy(list_p->right_p);
152	free(list_p);
153
154}				/* end expr_destroy */
155
156
157/*
158 * expr_list() - append a expr_t to a list
159 */
160
161expr_t		 *
162expr_list(expr_t * h,
163	expr_t * f)
164{
165	/* queue append handles the NULL cases OK */
166	return ((expr_t *) queue_append(&h->qn, &f->qn));
167
168}				/* end expr_list */
169
170
171/*
172 * expr_print() - pretty prints an expr list
173 */
174
175void
176expr_print(FILE * stream,
177	expr_t * list_p)
178{
179	expr_t		 *expr_p = NULL;
180
181	while ((expr_p = (expr_t *) queue_next(&list_p->qn, &expr_p->qn))) {
182		spec_print(stream, expr_p->left_p);
183		(void) fprintf(stream, "=");
184		spec_print(stream, expr_p->right_p);
185		(void) fprintf(stream, " ");
186	}
187
188}				/* end expr_print */
189
190
191/*
192 * expr_match() - figures out whether a probe matches in an expression list
193 */
194
195boolean_t
196expr_match(expr_t * list_p,
197	const char *attrs)
198{
199	expr_t		 *expr_p = NULL;
200
201	while ((expr_p = (expr_t *) queue_next(&list_p->qn, &expr_p->qn))) {
202		if (matchattrs(expr_p, attrs))
203			return (B_TRUE);
204	}
205
206	return (B_FALSE);
207
208}				/* end expr_match */
209
210
211/* ---------------------------------------------------------------- */
212/* ----------------------- Private Functions ---------------------- */
213/* ---------------------------------------------------------------- */
214
215typedef struct matchargs {
216	spec_t		 *spec_p;
217	boolean_t	   match;
218
219}			   matchargs_t;
220
221static		  boolean_t
222matchattrs(expr_t * expr_p,
223	const char *attrs)
224{
225	matchargs_t	 args;
226
227	args.spec_p = expr_p->right_p;
228	args.match = B_FALSE;
229
230	spec_attrtrav(expr_p->left_p,
231		(char *) attrs, matchvals, (void *) &args);
232
233	return (args.match);
234
235}				/* end matchattrs */
236
237
238/*ARGSUSED*/
239static void
240matchvals(spec_t * spec_p,
241	char *attrstr,
242	char *valstr,
243	void *calldatap)
244{
245	matchargs_t	*args_p = (matchargs_t *) calldatap;
246
247	spec_valtrav(args_p->spec_p, valstr, matched, calldatap);
248
249}				/* matchvals */
250
251
252/*ARGSUSED*/
253static void
254matched(spec_t * spec_p,
255	char *valstr,
256	void *calldatap)
257{
258	matchargs_t	*args_p = (matchargs_t *) calldatap;
259
260	args_p->match = B_TRUE;
261
262}				/* end matched */
263