GNU make code that finds 'argc' of a macro/user-defined function.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

GNU make code that finds 'argc' of a macro/user-defined function.

Rakesh Sharma-6

GNU make is lacking the feature to find out how many arguments a macro/user-defined function was called with. The code presented below helps in finding that out and pushes that value in the make variable $#.

The max number of arguments that are computable is 16^4 = 65,536. (limited by the MAX_INT variable)



# *-*-* vim settings *-*-*

# :set list ts=3



SHELL := /bin/sh



X16 := X X X X

X16 += $(X16)

X16 += $(X16)



NULL :=

SPC  := $(NULL) $(NULL)



hash := \#



[0-9] := 0 1 2 3 4 5 6 7 8 9



define MAX_INT

$(strip \

$(foreach i,$(X16),              \

$(foreach j,$(X16),           \

$(foreach k,$(X16),$(X16)))))

endef



#

# Iterator function

#

# $(call iterator,$1,$2,$3)

#    $1 => list to iterate upon

#    $2 => target text

#    $3 => function name

define iterator

$(strip \

$(if $(word 2,$1),                          \

$(call iterator,$(strip                  \

$(wordlist 2,$(words $1),$1)),$(strip \

$(call $3,$(word 1,$1),$2)),$(strip   \

$3)),                                 \

$(call $3,$(word 1,$1),$2)))

endef



# $(call split,$1) $1 is number which will be split into digits

define split

$(strip \

$(eval _op = $$(subst $$1,$$1$(SPC),$$2))\

$(call iterator,$([0-9]),$1,_op)\

$(eval undefine _op))

endef



# $(call _halving_algo,$1,$2) $1 and $2 are digits

define _halving_algo

$(strip \

$(subst $(SPC),,\

$(if $(filter 0 2 4 6 8,$1),\

$(if $(filter 0 1,$2),0,\

$(if $(filter 2 3,$2),1,\

$(if $(filter 4 5,$2),2,\

$(if $(filter 6 7,$2),3,\

$(if $(filter 8 9,$2),4))))),\

$(if $(filter 0 1,$2),5,\

$(if $(filter 2 3,$2),6,\

$(if $(filter 4 5,$2),7,\

$(if $(filter 6 7,$2),8,\

$(if $(filter 8 9,$2),9))))))))

endef



# $(call _halve,$1)  $1 is number split into individuval digits

define _halve

$(strip \

$(if $(word 3,$1),\

$(call _halving_algo,$(word 1,$1),$(word 2,$1))$(call _halve,$(wordlist 2,$(words $1),$1)),\

$(call _halving_algo,$(word 1,$1),$(word 2,$1))))

endef



# $(call halve,$1) $1 is a number

define halve

$(if $(filter 0 1,$1),0,$(patsubst 0%,%,$(call _halve,$(call split,0$1))))

endef



# $(call powers_of_2,$1) $1

define powers_of_2

$(if $(filter 0,$1),,$(call powers_of_2,$(call halve,$1)) $1)

endef

POWERS_OF_2 := $(strip $(call powers_of_2,$(words $(MAX_INT))))



# GNU make code that determines the number of arguments passed to a macro/function

define NbArgs

$$(eval $$$$(hash) := 0)$$(eval keepgoing := 1)\

$$(foreach i,$$(POWERS_OF_2),\

$$(if $$(keepgoing),\

$$(if $$(filter undefined,$$(origin $$i)),\

$$(foreach j,$$(words $$(wordlist 1,$$#,$$(MAX_INT))),\

$$(if $$(keepgoing),\

$$(if $$(filter undefined,$$(origin $$(words $$(wordlist 1,$$#,$$(MAX_INT)) X))),\

$$(eval keepgoing :=),\

$$(eval $$$$(hash) = $$(words $$(wordlist 1,$$#,$$(MAX_INT)) X))))),\

$$(eval $$$$(hash) := $$i))))

endef



# demo macro/function called with different number of arguments

define fx

$(strip \

$(eval $(NbArgs))\

$(subst a,XX,abcd))

endef



#x := $(call fx)

#x := $(call fx,a)

#x := $(call fx,a,b)

#x := $(call fx,a,b,c)

x := $(call fx,a,b,c,d)

#x := $(call fx,a,b,c,d,e,1,2,3,4,5,6,7,8,9,10)

$(info $$#=[$#])

$(info $x)



.PHONY: all modif_4_uplod modif_dnlod

all:; @:



modif_4_uplod: $(CODE)

sed -e 'G' $^ > $^.uplod; \

vi $^.uplod



modif_dnlod: $(CODE)

sed -e 'N;s/\n$$//;P;D' $^ > $^.dnlod


_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make