Skip to content

Commit

Permalink
#96: Simplify var.mk
Browse files Browse the repository at this point in the history
  • Loading branch information
abusalimov committed Sep 23, 2010
1 parent 144be05 commit bca7f3b
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 208 deletions.
43 changes: 0 additions & 43 deletions mk/util/var-3.81.mk

This file was deleted.

30 changes: 0 additions & 30 deletions mk/util/var-3.82.mk

This file was deleted.

204 changes: 69 additions & 135 deletions mk/util/var.mk
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#
# Variable assignment utils.
# Variable manipulation utils.
#
# Note: The most functions here are highly optimized using inlining, make
# version-specific features, and so on.
# This is achieved at the expense of the code readability and simplicity,
# so it is assumed that the reader will not dig into the internals of how does
# it work. You've been warned.
# If you anyway want to understand how it works, there are some cheats at the
# bottom of this file. ;-)
# Implementation note:
# There was an attempt to support all assignment ops and to abstract from
# make version.
# At this point I think it was unnecessary. If some day I'll change my
# opinion, the previous solution can be found in embuild_experimental @ r895.
#
# Author: Eldar Abusalimov
#
Expand Down Expand Up @@ -42,6 +40,25 @@ endef
#
var_info = $(call assert_called,var_info,$0)$(info $(call var_dump,$1))

#
# Function: var_assign_simple, =:
#
# Assigns value to the specified variable using immediate expansion (variable
# flavor becomes simple).
#
# Params:
# 1. The target variable name
# 2. The value to assign
#
# Returns: nothing
#
# Example:
# $(call var_assign_simple,foo,$$(bar))
# $(call var_info,foo) # value is $(bar), flavor is simple
# $(info $(foo)) # the expansion is $(bar) (dollar and 'bar' in braces)
#
var_assign_simple = ${eval $$1 := $$2}

#
# Function: var_assign_recursive, =
#
Expand All @@ -61,8 +78,15 @@ var_info = $(call assert_called,var_info,$0)$(info $(call var_dump,$1))
# and all notes about its arguments are applied for this case too
# (see GNU Make manual).
#
# Example:
# $(call var_assign_recursive,foo,$$(bar))
# $(call var_info,foo) # value is $(bar), flavor is recursive
# $(info $(foo)) # the expansion is expansion of variable 'bar'
#
# See also: var_assign_singleline_recursive var_assign_multiline_recursive
#
var_assign_recursive = $(if $(findstring $(\n),$2 \
),$(var_assign_multiline_recursive),$(var_assign_singleline_recursive))

#
# Function: var_assign_singleline_recursive
Expand All @@ -80,15 +104,15 @@ var_info = $(call assert_called,var_info,$0)$(info $(call var_dump,$1))
# and all notes about its arguments are applied for this case too
# (see GNU Make manual).
#
# Note: all that this function does is just evaluates something like:
# $1 = $2
#
var_assign_singleline_recursive = ${eval $$1 = $2}

#
# Function: var_assign_simple, =:
# Function: var_assign_multiline_recursive
#
# Assigns value to the specified variable using immediate expansion (variable
# flavor becomes simple).
# Assigns value to the specified variable, the variable becomes recursively
# expanded. The value should meet requirements specified for 'define'
# directive, partularly, any nested 'define' must be balanced by the
# corresponding 'endef'.
#
# Params:
# 1. The target variable name
Expand All @@ -100,132 +124,42 @@ var_info = $(call assert_called,var_info,$0)$(info $(call var_dump,$1))
# and all notes about its arguments are applied for this case too
# (see GNU Make manual).
#
${eval $ \
define var_assign_multiline_recursive$(\n)$ \
$${eval define $$$$1$(\n)$$2$(\n)endef}$(\n)$ \
endef$ \
} # eval above is 3.81 bug (Savannah #27394) workaround.

# Here goes the implementation.

# Include version-specific file.
#
# It have to define __var_assign_<line>_<op>_mk variables (8 ones total),
# where <line> is one of these values:
__var_assign_lines := singleline multiline
# and <op> is:
__var_assign_ops := recursive simple append cond
# and __var_assign_undefined_mk variable.
#
# Thus:
__var_assign_lines_ops := $(sort undefined \
$(foreach line,$(__var_assign_lines), \
$(foreach op,$(__var_assign_ops), \
$(line)_$(op) \
) \
) \
)
#
# __var_assign_inline list should be populated with <line>_<op> values
# for which var_assign_<line>_<op> variables could be inlined when being
# constructed from the corresponding __var_assign_<line>_<op>_mk ones.
__var_assign_inline :=

# And some definitions used for ops shorthands and possibly used by internals.
__var_assign_op_recursive := =
__var_assign_op_simple := :=
__var_assign_op_append := +=
__var_assign_op_cond := ?=

# Well, include the implementation.
__var_impl_file = \
$(self_makefile_dir)var-$(if $(call make_version_gte,3.82),3.82,3.81).mk
include $(__var_impl_file)

# Message to barf if something goes wrong.
__var_impl_you_do_this_wrong_msg = \
Check your implementation ($(__var_impl_file))

# Implementation sanity check (to make sure that all needed has been defined).
__var_assign_mk_missing := $(strip \
$(foreach def,$(__var_assign_lines_ops:%=__var_assign_%_mk), \
$(if $(filter undefined,$(origin $(def))),$(def)) \
) \
)
$(call assert,$(call not,$(__var_assign_mk_missing)),Missing def: \
$(__var_assign_mk_missing). $(__var_impl_you_do_this_wrong_msg))

# Implementation sanity check (values of __var_assign_inline list).
__var_assign_inline_bogus := \
$(filter-out $(__var_assign_lines_ops),$(__var_assign_inline))
$(call assert,$(call not,$(__var_assign_inline_bogus)),Invalid values \
in __var_assign_inline: $(__var_assign_inline_bogus). \
$(__var_impl_you_do_this_wrong_msg))

__var_assign_lines_ops_inline := \
$(sort $(filter $(__var_assign_lines_ops),$(__var_assign_inline)))

__var_assign_lines_ops_noinline := \
$(sort $(filter-out $(__var_assign_inline),$(__var_assign_lines_ops)))

ifndef MK_UTIL_VAR_NO_INLINE
__var_assign_def_inline = ${eval $ \
define $1$(\n)$ \
$${eval $(value $2)}$(\n)$ \
endef$ \
}
# Function: var_assign_undefined, var_undefine
#
# Undefines variable with the specified name.
#
# Params:
# 1. The variable to undefine
#
# Returns: nothing
#
# Example:
# foo := bar
# $(call var_undefine,foo)
# $(call var_info,foo) # value is <empty>, flavor is undefined
# # (well, it is not definitely so, because
# # true undefine has been introduced only in 3.82)
#
ifneq ($(filter 3.80 3.81,$(MAKE_VERSION)),)
# This is not true undefine, but
# at least "ifdef" conditionals and "+=" assignment will behave as expected.
var_assign_undefined = $(if $(filter-out undefined,$(flavor $1)),${eval $$1 =})
else
__var_assign_def_inline = __var_assign_def_noinline
# Since version 3.82 GNU Make provides native 'undefine' directive.
var_assign_undefined = ${eval undefine $$1}
endif
__var_assign_def_noinline = ${eval $1 = $${eval $$($2)}}

$(foreach xline,inline noinline, \
$(foreach def,$(__var_assign_lines_ops_$(xline)), \
$(call __var_assign_def_$(xline),var_assign_$(def),__var_assign_$(def)_mk) \
) \
)

__var_assign_autoline_def = ${eval $ \
$1 = $${eval $$(if $$(findstring $$(\n),$$2),$ \
$$(__var_assign_multiline_$2_mk),$ \
$$(__var_assign_singleline_$2_mk)$ \
)}$ \
}

__var_assign_op_escaped_name = =$(subst =,,$(__var_assign_op_$2))
$(foreach op,$(__var_assign_ops), \
$(foreach def,var_assign_$(op) $$(__var_assign_op_escaped_name), \
$(call __var_assign_autoline_def,$(def),$(op)) \
) \
)

# Yes, everything above may look horrible, but it is only at first sight.
# Enabling the following block may help you to understand what is happening
# when one or another function is being expanded.
# -- Eldar
ifeq (1,0)
__var_info_simplified = $(info $1 = $(value $(strip $1))$(\n))
$(call __var_info_simplified,var_assign_undefined)
$(call __var_info_simplified,var_assign_recursive)
$(call __var_info_simplified,var_assign_simple )
$(call __var_info_simplified,var_assign_append )
$(call __var_info_simplified,var_assign_cond )
$(call __var_info_simplified,= )
$(call __var_info_simplified,=:)
$(call __var_info_simplified,=+)
$(call __var_info_simplified,=?)
$(call __var_info_simplified,var_assign_singleline_recursive)
$(call __var_info_simplified,var_assign_singleline_simple )
$(call __var_info_simplified,var_assign_singleline_append )
$(call __var_info_simplified,var_assign_singleline_cond )
$(call __var_info_simplified,var_assign_multiline_recursive)
$(call __var_info_simplified,var_assign_multiline_simple )
$(call __var_info_simplified,var_assign_multiline_append )
$(call __var_info_simplified,var_assign_multiline_cond )
$(call __var_info_simplified,__var_assign_singleline_recursive_mk)
$(call __var_info_simplified,__var_assign_singleline_simple_mk )
$(call __var_info_simplified,__var_assign_singleline_append_mk )
$(call __var_info_simplified,__var_assign_singleline_cond_mk )
$(call __var_info_simplified,__var_assign_multiline_recursive_mk)
$(call __var_info_simplified,__var_assign_multiline_simple_mk )
$(call __var_info_simplified,__var_assign_multiline_append_mk )
$(call __var_info_simplified,__var_assign_multiline_cond_mk )
endif
# Shorthand versions of var_assign_xxx functions.
$(call var_assign_recursive,=,$(value var_assign_recursive))
$(call var_assign_recursive,=:,$(value var_assign_simple))
$(call var_assign_recursive,var_undefine,$(value var_assign_undefined))

# XXX rewrite everything below. -- Eldar

Expand Down

0 comments on commit bca7f3b

Please sign in to comment.