Reputation: 113
In my makefile, I need to retrieve values from a value list given keys which match a key list. The lists are correctly ordered with respect to each other.
I have a recipe that works, but it uses a shell command to do the heavy lifting:
KEYS=key1 key2 key3 key4 key5
VALUES=val1 val2 val3 val4 val5
# keys to lookup, we want our results to be: val2 val4
LOOKUPS=key2 key4
define CMD
LOOKUPS=($(1)); \
KEYS=($(2)); \
VALUES=($(3)); \
for i in $${!LOOKUPS[@]}; do \
for j in $${!KEYS[@]}; do \
if [[ "$${LOOKUPS[$$i]}" == "$${KEYS[$$j]}" ]]; then \
echo "$${VALUES[$$j]}"; \
fi; \
done; \
done
endef
RESULTS=$(shell $(call CMD,$(LOOKUPS),$(KEYS),$(VALUES)))
$(info RESULTS: $(RESULTS))
Is there a way of doing this without using the shell? Perhaps involving GMSL's pairmap function? Or a better shell based recipe?
Upvotes: 1
Views: 270
Reputation: 2898
The GNUmake library gmtt has the function index-of
which delivers the index of a string in a list. Without having it tested, the solution with ´gmtt´ would look like:
include gmtt.mk
KEYS=key1 key2 key3 key4 key5
VALUES=val1 val2 val3 val4 val5
# keys to lookup, we want our results to be: val2 val4
LOOKUPS=key2 key4
RESULTS := $(foreach s,$(LOOKUPS),$(word $(call index-of,$(s),neverakey $(KEYS)),$(VALUES)))
Notice that you have to elongate the list by one place (in front) because index-of
is 0-based while word
is 1-based (which was a deliberate design decision because going from 0-based to 1-based is much easier in ´make´ than the opposite)
Upvotes: 0
Reputation: 100936
I'm not sure about GMSL but you can cobble something together using GNU make's join
function (solution untested):
KEYS=key1 key2 key3 key4 key5
VALUES=val1 val2 val3 val4 val5
# keys to lookup, we want our results to be: val2 val4
LOOKUPS=key2 key4
JOINED := $(join $(KEYS),$(addprefix :,$(VALUES)))
GETVAL = $(word 2,$(subst :, ,$(filter $1:%,$(JOINED))))
$(foreach K,$(LOOKUPS),$(info key $K = $(call GETVAL,$K)))
This assumes your keys and values don't contain the :
character; if they do choose a different one.
Upvotes: 1