4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Events, FMRIs and authorities must be declared before they can be used.
31 * Routines in this file, driven by the parser, create the data structures
32 * associated with the declarations.
38 #include <inj_event.h>
44 static inj_hash_t inj_decls
[ITEMTYPE_NITEMS
];
45 static int inj_decls_initialized
;
48 item2hash(inj_itemtype_t item
)
52 assert(item
>= 0 && item
< sizeof (inj_decls
) / sizeof (inj_hash_t
));
54 if (!inj_decls_initialized
) {
55 for (i
= 0; i
< sizeof (inj_decls
) / sizeof (inj_hash_t
); i
++)
56 inj_strhash_create(&inj_decls
[i
]);
57 inj_decls_initialized
= 1;
60 return (&inj_decls
[item
]);
64 inj_decl_lookup(const char *name
, inj_itemtype_t type
)
66 inj_hash_t
*hash
= item2hash(type
);
69 if ((v
= inj_strhash_lookup(hash
, name
)) == NULL
)
72 return (inj_hash_get_cookie(v
));
76 inj_decl_mem_destroy(inj_declmem_t
*dlm
)
78 inj_strfree(dlm
->dlm_name
);
80 if (dlm
->dlm_type
== MEMTYPE_ENUM
)
81 inj_strhash_destroy(dlm
->dlm_enumvals
);
85 inj_decl_mem_create(const char *name
, inj_memtype_t type
)
87 inj_declmem_t
*dlm
= inj_zalloc(sizeof (inj_declmem_t
));
95 /* An embedded event, authority, or FMRI */
97 inj_decl_mem_create_defined(const char *name
, const char *declnm
,
100 inj_declmem_t
*dlm
= inj_zalloc(sizeof (inj_declmem_t
));
102 dlm
->dlm_name
= name
;
103 dlm
->dlm_type
= inj_item2mem(type
);
105 if ((dlm
->dlm_decl
= inj_decl_lookup(declnm
, type
)) == NULL
) {
106 yyerror("unknown %s %s", inj_item2str(type
), declnm
);
114 inj_decl_mem_create_enum(const char *name
, inj_hash_t
*vals
)
116 inj_declmem_t
*dlm
= inj_zalloc(sizeof (inj_declmem_t
));
118 dlm
->dlm_name
= name
;
119 dlm
->dlm_type
= MEMTYPE_ENUM
;
120 dlm
->dlm_enumvals
= vals
;
125 /* Turn a previously-declared member into an array */
127 inj_decl_mem_make_array(inj_declmem_t
*dlm
, uint_t dim
)
129 dlm
->dlm_flags
|= DECLMEM_F_ARRAY
;
130 dlm
->dlm_arrdim
= dim
;
134 inj_decl_destroy(inj_decl_t
*decl
)
136 inj_declmem_t
*m
, *n
;
138 inj_strfree(decl
->decl_name
);
139 inj_strhash_destroy(&decl
->decl_memhash
);
141 for (m
= inj_list_next(&decl
->decl_members
); m
!= NULL
; m
= n
) {
142 n
= inj_list_next(m
);
144 inj_decl_mem_destroy(m
);
147 inj_free(decl
, sizeof (inj_declmem_t
));
151 inj_decl_create(inj_declmem_t
*dlm
)
153 inj_decl_t
*decl
= inj_zalloc(sizeof (inj_decl_t
));
155 decl
->decl_lineno
= yylineno
;
157 inj_strhash_create(&decl
->decl_memhash
);
159 inj_list_append(&decl
->decl_members
, dlm
);
160 (void) inj_strhash_insert(&decl
->decl_memhash
, dlm
->dlm_name
,
167 inj_decl_addmem(inj_decl_t
*decl
, inj_declmem_t
*dlm
)
171 if ((v
= inj_strhash_lookup(&decl
->decl_memhash
, dlm
->dlm_name
)) !=
173 inj_decl_t
*other
= inj_hash_get_cookie(v
);
175 yyerror("duplicate member name %s (other on line %d)\n",
176 dlm
->dlm_name
, other
->decl_lineno
);
177 inj_decl_destroy(decl
);
181 inj_list_append(&decl
->decl_members
, dlm
);
182 (void) inj_strhash_insert(&decl
->decl_memhash
, dlm
->dlm_name
,
187 * The various declaration types - events, FMRIs, and authorities - each have
188 * their own semantic validation requirements.
191 /* No user-defined class member. If ena isn't present, we'll generate it */
193 inj_decl_validate_event(inj_decl_t
*decl
)
195 if (inj_strhash_lookup(&decl
->decl_memhash
, "class") != NULL
) {
196 yyerror("class may not be explicitly declared\n");
200 if (inj_strhash_lookup(&decl
->decl_memhash
, "ena") == NULL
)
201 decl
->decl_flags
|= DECL_F_AUTOENA
;
206 /* FMRIs must have a string scheme member */
208 inj_decl_validate_fmri(inj_decl_t
*decl
)
213 if ((v
= inj_strhash_lookup(&decl
->decl_memhash
, "scheme")) == NULL
) {
214 yyerror("fmri declared without scheme member\n");
218 dlm
= inj_hash_get_cookie(v
);
219 if (dlm
->dlm_type
!= MEMTYPE_STRING
) {
220 yyerror("scheme member must be a string\n");
229 inj_decl_validate_nop(inj_decl_t
*decl
)
235 inj_decl_finish(inj_decl_t
*decl
, const char *name
, inj_itemtype_t type
)
237 static int (*const validators
[])(inj_decl_t
*) = {
238 inj_decl_validate_event
,
239 inj_decl_validate_fmri
,
240 inj_decl_validate_nop
, /* no validation for auth */
241 inj_decl_validate_nop
/* no validation for lists */
244 inj_hash_t
*hash
= item2hash(type
);
247 decl
->decl_name
= name
;
248 decl
->decl_type
= type
;
250 if (!validators
[type
](decl
)) {
251 inj_decl_destroy(decl
);
255 if ((v
= inj_strhash_lookup(hash
, name
)) != NULL
) {
256 inj_decl_t
*other
= inj_hash_get_cookie(v
);
258 yyerror("duplicate %s name %s (other on line %d)\n",
259 inj_item2str(type
), name
, other
->decl_lineno
);
260 inj_decl_destroy(decl
);
264 (void) inj_strhash_insert(hash
, name
, (uintptr_t)decl
);