FreeBSD/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
/*
 * The #pragma attributes directive can be used to reset stability attributes
 * on a global identifier or inline definition.  If the identifier is already
 * defined, we can just change di_attr.  If not, we insert the pragma into a
 * hash table of the current pcb's deferred pragmas for later processing.
 */
The #pragma attributes directive can be used to reset stability attributes
on a global identifier or inline definition.  If the identifier is already
defined, we can just change di_attr.  If not, we insert the pragma into a
hash table of the current pcb's deferred pragmas for later processing.
The #pragma attributes directive can be used to reset stability attributes on a global identifier or inline definition . If the identifier is already defined we can just change di_attr . If not we insert the pragma into a hash table of the current pcb ' s deferred pragmas for later processing .
static void
dt_pragma_attributes(const char *prname, dt_node_t *dnp)
{
	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
	dtrace_attribute_t attr, *a;
	dt_provider_t *pvp;
	const char *name, *part;
	dt_ident_t *idp;
	if (dnp == NULL || dnp->dn_kind != DT_NODE_IDENT ||
	    dnp->dn_list == NULL || dnp->dn_list->dn_kind != DT_NODE_IDENT) {
		xyerror(D_PRAGMA_MALFORM, "malformed #pragma %s "
		    "<attributes> <ident>\n", prname);
	}
	if (dtrace_str2attr(dnp->dn_string, &attr) == -1) {
		xyerror(D_PRAGMA_INVAL, "invalid attributes "
		    "specified by #pragma %s\n", prname);
	}
	dnp = dnp->dn_list;
	name = dnp->dn_string;
	if (strcmp(name, "provider") == 0) {
		dnp = dnp->dn_list;
		name = dnp->dn_string;
		dnp = dnp->dn_list;
		part = dnp->dn_string;
		if ((pvp = dt_provider_lookup(dtp, name)) != NULL) {
			if (strcmp(part, "provider") == 0) {
				a = &pvp->pv_desc.dtvd_attr.dtpa_provider;
			} else if (strcmp(part, "module") == 0) {
				a = &pvp->pv_desc.dtvd_attr.dtpa_mod;
			} else if (strcmp(part, "function") == 0) {
				a = &pvp->pv_desc.dtvd_attr.dtpa_func;
			} else if (strcmp(part, "name") == 0) {
				a = &pvp->pv_desc.dtvd_attr.dtpa_name;
			} else if (strcmp(part, "args") == 0) {
				a = &pvp->pv_desc.dtvd_attr.dtpa_args;
			} else {
				xyerror(D_PRAGMA_INVAL, "invalid component "
				    "\"%s\" in attribute #pragma "
				    "for provider %s\n", name, part);
			}
			*a = attr;
			return;
		}
	} else if ((idp = dt_idstack_lookup(
	    &yypcb->pcb_globals, name)) != NULL) {
		if (idp->di_gen != dtp->dt_gen) {
			xyerror(D_PRAGMA_SCOPE, "#pragma %s cannot modify "
			    "entity defined outside program scope\n", prname);
		}
		idp->di_attr = attr;
		return;
	}
	if (yypcb->pcb_pragmas == NULL && (yypcb->pcb_pragmas =
	    dt_idhash_create("pragma", NULL, 0, 0)) == NULL)
		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
	idp = dt_idhash_insert(yypcb->pcb_pragmas, name, DT_IDENT_PRAGAT, 0, 0,
	    attr, 0, &dt_idops_thaw, (void *)prname, dtp->dt_gen);
	if (idp == NULL)
		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
	if (dtp->dt_globals->dh_defer == NULL)
		dtp->dt_globals->dh_defer = &dt_pragma_apply;
}
static void dt_pragma_attributes ( const char * prname , dt_node_t * dnp ) { dtrace_hdl_t * dtp = yypcb -> pcb_hdl ; dtrace_attribute_t attr , * a ; dt_provider_t * pvp ; const char * name , * part ; dt_ident_t * idp ; if ( dnp == NULL || dnp -> dn_kind != DT_NODE_IDENT || dnp -> dn_list == NULL || dnp -> dn_list -> dn_kind != DT_NODE_IDENT ) { xyerror ( D_PRAGMA_MALFORM , " " " \n " , prname ) ; } if ( dtrace_str2attr ( dnp -> dn_string , & attr ) == -1 ) { xyerror ( D_PRAGMA_INVAL , " " " \n " , prname ) ; } dnp = dnp -> dn_list ; name = dnp -> dn_string ; if ( strcmp ( name , " " ) == 0 ) { dnp = dnp -> dn_list ; name = dnp -> dn_string ; dnp = dnp -> dn_list ; part = dnp -> dn_string ; if ( ( pvp = dt_provider_lookup ( dtp , name ) ) != NULL ) { if ( strcmp ( part , " " ) == 0 ) { a = & pvp -> pv_desc . dtvd_attr . dtpa_provider ; } else if ( strcmp ( part , " " ) == 0 ) { a = & pvp -> pv_desc . dtvd_attr . dtpa_mod ; } else if ( strcmp ( part , " " ) == 0 ) { a = & pvp -> pv_desc . dtvd_attr . dtpa_func ; } else if ( strcmp ( part , " " ) == 0 ) { a = & pvp -> pv_desc . dtvd_attr . dtpa_name ; } else if ( strcmp ( part , " " ) == 0 ) { a = & pvp -> pv_desc . dtvd_attr . dtpa_args ; } else { xyerror ( D_PRAGMA_INVAL , " " " \" \" " " \n " , name , part ) ; } * a = attr ; return ; } } else if ( ( idp = dt_idstack_lookup ( & yypcb -> pcb_globals , name ) ) != NULL ) { if ( idp -> di_gen != dtp -> dt_gen ) { xyerror ( D_PRAGMA_SCOPE , " " " \n " , prname ) ; } idp -> di_attr = attr ; return ; } if ( yypcb -> pcb_pragmas == NULL && ( yypcb -> pcb_pragmas = dt_idhash_create ( " " , NULL , 0 , 0 ) ) == NULL ) longjmp ( yypcb -> pcb_jmpbuf , EDT_NOMEM ) ; idp = dt_idhash_insert ( yypcb -> pcb_pragmas , name , DT_IDENT_PRAGAT , 0 , 0 , attr , 0 , & dt_idops_thaw , ( void * ) prname , dtp -> dt_gen ) ; if ( idp == NULL ) longjmp ( yypcb -> pcb_jmpbuf , EDT_NOMEM ) ; if ( dtp -> dt_globals -> dh_defer == NULL ) dtp -> dt_globals -> dh_defer = & dt_pragma_apply ; }
The #pragma attributes directive can be used to reset stability attributes
 on a global identifier or inline definition.
The #pragma attributes directive can be used to reset stability attributes on a global identifier or inline definition .