########################################
#
# Macros for switching between source policy
# and loadable policy module support
#

##############################
#
# For adding the module statement
#
define(`policy_module',`
	ifndef(`self_contained_policy',`
		module $1 $2;

		require {
			role system_r;
			all_kernel_class_perms

			ifdef(`enable_mcs',`
				decl_sens(0,0)
				decl_cats(0,decr(mcs_num_cats))
			')

			ifdef(`enable_mls',`
				decl_sens(0,decr(mls_num_sens))
				decl_cats(0,decr(mls_num_cats))
			')
		}
	')
')

##############################
#
# For use in interfaces, to optionally insert a require block
#
define(`gen_require',`
	ifdef(`self_contained_policy',`
		ifdef(`__in_optional_policy',`
			require {
				$1
			} # end require
		')
	',`
		require {
			$1
		} # end require
	')
')

# helper function, since m4 wont expand macros
# if a line is a comment (#):
define(`policy_m4_comment',`
##### $2 depth: $1
')dnl

##############################
#
# In the future interfaces should be in loadable modules
#
# template(name,rules)
#
define(`template',` dnl
	ifdef(`$1',`refpolicyerr(`duplicate definition of $1(). Original definition on '$1.) define(`__if_error')',`define(`$1',__file__:__line__)') dnl
	`define(`$1',` dnl
	pushdef(`policy_call_depth',incr(policy_call_depth)) dnl
	policy_m4_comment(policy_call_depth,begin `$1'(dollarsstar)) dnl
	$2 dnl
	popdef(`policy_call_depth') dnl
	policy_m4_comment(policy_call_depth,end `$1'(dollarsstar)) dnl
	'')
')

##############################
#
# In the future interfaces should be in loadable modules
#
# interface(name,rules)
#
define(`interface',` dnl
	ifdef(`$1',`refpolicyerr(`duplicate definition of $1(). Original definition on '$1.) define(`__if_error')',`define(`$1',__file__:__line__)') dnl
	`define(`$1',` dnl
	pushdef(`policy_call_depth',incr(policy_call_depth)) dnl
	policy_m4_comment(policy_call_depth,begin `$1'(dollarsstar)) dnl
	$2 dnl
	popdef(`policy_call_depth') dnl
	policy_m4_comment(policy_call_depth,end `$1'(dollarsstar)) dnl
	'')
')

define(`policy_call_depth',0)

##############################
#
# Optional policy handling
#
define(`optional_policy',`
	optional {`'pushdef(`__in_optional_policy')
		$1
	ifelse(`$2',`',`',`} else {
		$2
	')}`'popdef(`__in_optional_policy')`'ifndef(`__in_optional_policy',` # end optional')
')

##############################
#
# Determine if we should use the default
# tunable value as specified by the policy
# or if the override value should be used
#
define(`dflt_or_overr',`ifdef(`$1',$1,$2)')

##############################
#
# Extract booleans out of an expression.
# This needs to be reworked so expressions
# with parentheses can work.

define(`declare_required_symbols',`
ifelse(regexp($1, `\w'), -1, `', `dnl
bool regexp($1, `\(\w+\)', `\1');
declare_required_symbols(regexp($1, `\w+\(.*\)', `\1'))dnl
') dnl
')

##############################
#
# Tunable declaration
#
define(`gen_tunable',`
	bool $1 dflt_or_overr(`$1'_conf,$2);
')

##############################
#
# Tunable policy handling
#
define(`tunable_policy',`
	gen_require(`
		declare_required_symbols(`$1')
	')
	if (`$1') {
		$2
	ifelse(`$3',`',`',`} else { # else $1
		$3
	')} # end $1
')
