1# ----------------------------------------------------------------------------
2#
3# GNU Make Standard Library (GMSL)
4#
5# A library of functions to be used with GNU Make's $(call) that
6# provides functionality not available in standard GNU Make.
7#
8# Copyright (c) 2005-2007 John Graham-Cumming
9#
10# This file is part of GMSL
11#
12# Redistribution and use in source and binary forms, with or without
13# modification, are permitted provided that the following conditions
14# are met:
15#
16# Redistributions of source code must retain the above copyright
17# notice, this list of conditions and the following disclaimer.
18#
19# Redistributions in binary form must reproduce the above copyright
20# notice, this list of conditions and the following disclaimer in the
21# documentation and/or other materials provided with the distribution.
22#
23# Neither the name of the John Graham-Cumming nor the names of its
24# contributors may be used to endorse or promote products derived from
25# this software without specific prior written permission.
26#
27# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38# POSSIBILITY OF SUCH DAMAGE.
39#
40# ----------------------------------------------------------------------------
41
42# This is the GNU Make Standard Library version number as a list with
43# three items: major, minor, revision
44
45gmsl_version := 1 0 11
46
47# Used to output warnings and error from the library, it's possible to
48# disable any warnings or errors by overriding these definitions
49# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS
50
51__gmsl_name := GNU Make Standard Library
52__gmsl_warning = $(warning $(__gmsl_name): $1)
53__gmsl_error = $(error $(__gmsl_name): $1)
54
55ifdef GMSL_NO_WARNINGS
56__gmsl_warning :=
57endif
58ifdef GMSL_NO_ERRORS
59__gmsl_error :=
60endif
61
62# If GMSL_TRACE is enabled then calls to the library functions are
63# traced to stdout using warning messages with their arguments
64
65ifdef GMSL_TRACE
66__gmsl_tr1 = $(warning $0('$1'))
67__gmsl_tr2 = $(warning $0('$1','$2'))
68__gmsl_tr3 = $(warning $0('$1','$2','$3'))
69else
70__gmsl_tr1 :=
71__gmsl_tr2 :=
72__gmsl_tr3 :=
73endif
74
75# Figure out whether we have $(eval) or not (GNU Make 3.80 and above)
76# if we do not then output a warning message, if we do then some
77# functions will be enabled.
78
79__gmsl_have_eval := $(false)
80__gmsl_ignore := $(eval __gmsl_have_eval := $(true))
81
82# If this is being run with Electric Cloud's emake then warn that
83# their $(eval) support is incomplete.
84
85ifdef ECLOUD_BUILD_ID
86$(warning You are using Electric Cloud's emake which has incomplete $$(eval) support)
87__gmsl_have_eval := $(false)
88endif
89
90# See if we have $(lastword) (GNU Make 3.81 and above)
91
92__gmsl_have_lastword := $(lastword $(false) $(true))
93
94# See if we have native or and and (GNU Make 3.81 and above)
95
96__gmsl_have_or := $(if $(filter-out undefined,  \
97    $(origin or)),$(call or,$(true),$(false)))
98__gmsl_have_and := $(if $(filter-out undefined, \
99    $(origin and)),$(call and,$(true),$(true)))
100
101ifneq ($(__gmsl_have_eval),$(true))
102$(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$$$(eval): some functions disabled)
103endif
104
105# ----------------------------------------------------------------------------
106# Function:  gmsl_compatible
107# Arguments: List containing the desired library version number (maj min rev)
108# Returns:   $(true) if this version of the library is compatible
109#            with the requested version number, otherwise $(false)
110# ----------------------------------------------------------------------------
111gmsl_compatible = $(strip                                                 \
112    $(if $(call gt,$(word 1,$1),$(word 1,$(gmsl_version))),               \
113        $(false),                                                         \
114        $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))),           \
115            $(true),                                                      \
116            $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))),       \
117                $(false),                                                 \
118                $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))),   \
119                    $(true),                                              \
120                    $(call lte,$(word 3,$1),$(word 3,$(gmsl_version))))))))
121
122# ###########################################################################
123# LOGICAL OPERATORS
124# ###########################################################################
125
126# not is defined in gmsl
127
128# ----------------------------------------------------------------------------
129# Function:  and
130# Arguments: Two boolean values
131# Returns:   Returns $(true) if both of the booleans are true
132# ----------------------------------------------------------------------------
133ifneq ($(__gmsl_have_and),$(true))
134and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false))
135endif
136
137# ----------------------------------------------------------------------------
138# Function:  or
139# Arguments: Two boolean values
140# Returns:   Returns $(true) if either of the booleans is true
141# ----------------------------------------------------------------------------
142ifneq ($(__gmsl_have_or),$(true))
143or = $(__gmsl_tr2)$(if $1$2,$(true),$(false))
144endif
145
146# ----------------------------------------------------------------------------
147# Function:  xor
148# Arguments: Two boolean values
149# Returns:   Returns $(true) if exactly one of the booleans is true
150# ----------------------------------------------------------------------------
151xor = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(if $2,$(true),$(false)))
152
153# ----------------------------------------------------------------------------
154# Function:  nand
155# Arguments: Two boolean values
156# Returns:   Returns value of 'not and'
157# ----------------------------------------------------------------------------
158nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true))
159
160# ----------------------------------------------------------------------------
161# Function:  nor
162# Arguments: Two boolean values
163# Returns:   Returns value of 'not or'
164# ----------------------------------------------------------------------------
165nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true))
166
167# ----------------------------------------------------------------------------
168# Function:  xnor
169# Arguments: Two boolean values
170# Returns:   Returns value of 'not xor'
171# ----------------------------------------------------------------------------
172xnor =$(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(if $2,$(false),$(true)))
173
174# ###########################################################################
175# LIST MANIPULATION FUNCTIONS
176# ###########################################################################
177
178# ----------------------------------------------------------------------------
179# Function:  first (same as LISP's car, or head)
180# Arguments: 1: A list
181# Returns:   Returns the first element of a list
182# ----------------------------------------------------------------------------
183first = $(__gmsl_tr1)$(firstword $1)
184
185# ----------------------------------------------------------------------------
186# Function:  last
187# Arguments: 1: A list
188# Returns:   Returns the last element of a list
189# ----------------------------------------------------------------------------
190ifeq ($(__gmsl_have_lastword),$(true))
191last = $(__gmsl_tr1)$(lastword $1)
192else
193last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1))
194endif
195
196# ----------------------------------------------------------------------------
197# Function:  rest (same as LISP's cdr, or tail)
198# Arguments: 1: A list
199# Returns:   Returns the list with the first element removed
200# ----------------------------------------------------------------------------
201rest = $(__gmsl_tr1)$(wordlist 2,$(words $1),$1)
202
203# ----------------------------------------------------------------------------
204# Function:  chop
205# Arguments: 1: A list
206# Returns:   Returns the list with the last element removed
207# ----------------------------------------------------------------------------
208chop = $(__gmsl_tr1)$(wordlist 2,$(words $1),x $1)
209
210# ----------------------------------------------------------------------------
211# Function:  map
212# Arguments: 1: Name of function to $(call) for each element of list
213#            2: List to iterate over calling the function in 1
214# Returns:   The list after calling the function on each element
215# ----------------------------------------------------------------------------
216map = $(__gmsl_tr2)$(strip $(foreach a,$2,$(call $1,$a)))
217
218# ----------------------------------------------------------------------------
219# Function:  pairmap
220# Arguments: 1: Name of function to $(call) for each pair of elements
221#            2: List to iterate over calling the function in 1
222#            3: Second list to iterate over calling the function in 1
223# Returns:   The list after calling the function on each pair of elements
224# ----------------------------------------------------------------------------
225pairmap = $(strip $(__gmsl_tr3)\
226          $(if $2$3,$(call $1,$(call first,$2),$(call first,$3))     \
227                        $(call pairmap,$1,$(call rest,$2),$(call rest,$3))))
228
229# ----------------------------------------------------------------------------
230# Function:  leq
231# Arguments: 1: A list to compare against...
232#            2: ...this list
233# Returns:   Returns $(true) if the two lists are identical
234# ----------------------------------------------------------------------------
235leq = $(__gmsl_tr2)$(strip $(if $(call seq,$(words $1),$(words $2)),     \
236          $(call __gmsl_list_equal,$1,$2),$(false)))
237
238__gmsl_list_equal = $(if $(strip $1),                                       \
239                        $(if $(call seq,$(call first,$1),$(call first,$2)), \
240                            $(call __gmsl_list_equal,                       \
241                                $(call rest,$1),                            \
242                                $(call rest,$2)),                           \
243                            $(false)),                                      \
244                     $(true))
245
246# ----------------------------------------------------------------------------
247# Function:  lne
248# Arguments: 1: A list to compare against...
249#            2: ...this list
250# Returns:   Returns $(true) if the two lists are different
251# ----------------------------------------------------------------------------
252lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2))
253
254# ----------------------------------------------------------------------------
255# Function:  reverse
256# Arguments: 1: A list to reverse
257# Returns:   The list with its elements in reverse order
258# ----------------------------------------------------------------------------
259reverse =$(__gmsl_tr1)$(strip $(if $1,$(call reverse,$(call rest,$1)) \
260                        $(call first,$1)))
261
262# ----------------------------------------------------------------------------
263# Function:  uniq
264# Arguments: 1: A list from which to remove repeated elements
265# Returns:   The list with duplicate elements removed without reordering
266# ----------------------------------------------------------------------------
267uniq = $(strip $(__gmsl_tr1)$(if $1,$(call uniq,$(call chop,$1)) \
268            $(if $(filter $(call last,$1),$(call chop,$1)),,$(call last,$1))))
269
270# ----------------------------------------------------------------------------
271# Function:  length
272# Arguments: 1: A list
273# Returns:   The number of elements in the list
274# ----------------------------------------------------------------------------
275length = $(__gmsl_tr1)$(words $1)
276
277# ###########################################################################
278# STRING MANIPULATION FUNCTIONS
279# ###########################################################################
280
281# Helper function that translates any GNU Make 'true' value (i.e. a
282# non-empty string) to our $(true)
283
284__gmsl_make_bool = $(if $(strip $1),$(true),$(false))
285
286# ----------------------------------------------------------------------------
287# Function:  seq
288# Arguments: 1: A string to compare against...
289#            2: ...this string
290# Returns:   Returns $(true) if the two strings are identical
291# ----------------------------------------------------------------------------
292seq = $(__gmsl_tr2)$(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),$(false),$(true))
293
294# ----------------------------------------------------------------------------
295# Function:  sne
296# Arguments: 1: A string to compare against...
297#            2: ...this string
298# Returns:   Returns $(true) if the two strings are not the same
299# ----------------------------------------------------------------------------
300sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2))
301
302# ----------------------------------------------------------------------------
303# Function:  split
304# Arguments: 1: The character to split on
305#            2: A string to split
306# Returns:   Splits a string into a list separated by spaces at the split
307#            character in the first argument
308# ----------------------------------------------------------------------------
309split = $(__gmsl_tr2)$(strip $(subst $1, ,$2))
310
311# ----------------------------------------------------------------------------
312# Function:  merge
313# Arguments: 1: The character to put between fields
314#            2: A list to merge into a string
315# Returns:   Merges a list into a single string, list elements are separated
316#            by the character in the first argument
317# ----------------------------------------------------------------------------
318merge = $(__gmsl_tr2)$(strip $(if $2,                                     \
319            $(if $(call seq,1,$(words $2)),                               \
320                $2,$(call first,$2)$1$(call merge,$1,$(call rest,$2)))))
321
322ifdef __gmsl_have_eval
323# ----------------------------------------------------------------------------
324# Function:  tr
325# Arguments: 1: The list of characters to translate from
326#            2: The list of characters to translate to
327#            3: The text to translate
328# Returns:   Returns the text after translating characters
329# ----------------------------------------------------------------------------
330tr = $(strip $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)              \
331     $(eval __gmsl_t := $3)                                               \
332     $(foreach c,                                                         \
333         $(join $(addsuffix :,$1),$2),                                    \
334         $(eval __gmsl_t :=                                               \
335             $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \
336                 $(__gmsl_t))))$(__gmsl_t))
337
338# Common character classes for use with the tr function.  Each of
339# these is actually a variable declaration and must be wrapped with
340# $() or ${} to be used.
341
342[A-Z] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z #
343[a-z] := a b c d e f g h i j k l m n o p q r s t u v w x y z #
344[0-9] := 0 1 2 3 4 5 6 7 8 9 #
345[A-F] := A B C D E F #
346
347# ----------------------------------------------------------------------------
348# Function:  uc
349# Arguments: 1: Text to upper case
350# Returns:   Returns the text in upper case
351# ----------------------------------------------------------------------------
352uc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([a-z]),$([A-Z]),$1)
353
354# ----------------------------------------------------------------------------
355# Function:  lc
356# Arguments: 1: Text to lower case
357# Returns:   Returns the text in lower case
358# ----------------------------------------------------------------------------
359lc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([A-Z]),$([a-z]),$1)
360
361# ----------------------------------------------------------------------------
362# Function:  strlen
363# Arguments: 1: A string
364# Returns:   Returns the length of the string
365# ----------------------------------------------------------------------------
366__gmsl_characters := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
367__gmsl_characters += a b c d e f g h i j k l m n o p q r s t u v w x y z
368__gmsl_characters += 0 1 2 3 4 5 6 7 8 9
369__gmsl_characters += ` ~ ! @ \# $$ % ^ & * ( ) - _ = +
370__gmsl_characters += { } [ ] \ : ; ' " < > , . / ? |
371
372# Aside: if you read the above you might think that the lower-case
373# letter x is missing, and that that's an error.  It is missing, but
374# it's not an error.  __gmsl_characters is used by the strlen
375# function.  strlen works by transforming every character and space
376# into the letter x and then counting the x's.  Since there's no need
377# to transform x into x I omitted it.
378
379# This results in __gmsl_space containing just a space
380
381__gmsl_space :=
382__gmsl_space +=
383
384strlen = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(eval __temp := $(subst $(__gmsl_space),x,$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,x,$(__temp))))$(eval __temp := $(subst x,x ,$(__temp)))$(words $(__temp)))
385
386# This results in __gmsl_newline containing just a newline
387
388define __gmsl_newline
389
390
391endef
392
393# This results in __gmsl_tab containing a tab
394
395__gmsl_tab :=	#
396
397# ----------------------------------------------------------------------------
398# Function:  substr
399# Arguments: 1: A string
400# 	     2: Start position (first character is 1)
401#	     3: End position (inclusive)
402# Returns:   A substring.
403# Note:      The string in $1 must not contain a �
404# ----------------------------------------------------------------------------
405
406substr = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(strip $(eval __temp := $$(subst $$(__gmsl_space),� ,$$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,$$a$$(__gmsl_space),$(__temp))))$(eval __temp := $(wordlist $2,$3,$(__temp))))$(subst �,$(__gmsl_space),$(subst $(__gmsl_space),,$(__temp)))
407
408endif # __gmsl_have_eval
409
410# ###########################################################################
411# SET MANIPULATION FUNCTIONS
412# ###########################################################################
413
414# Sets are represented by sorted, deduplicated lists.  To create a set
415# from a list use set_create, or start with the empty_set and
416# set_insert individual elements
417
418# This is the empty set
419empty_set :=
420
421# ----------------------------------------------------------------------------
422# Function:  set_create
423# Arguments: 1: A list of set elements
424# Returns:   Returns the newly created set
425# ----------------------------------------------------------------------------
426set_create = $(__gmsl_tr1)$(sort $1)
427
428# ----------------------------------------------------------------------------
429# Function:  set_insert
430# Arguments: 1: A single element to add to a set
431#            2: A set
432# Returns:   Returns the set with the element added
433# ----------------------------------------------------------------------------
434set_insert = $(__gmsl_tr2)$(sort $1 $2)
435
436# ----------------------------------------------------------------------------
437# Function:  set_remove
438# Arguments: 1: A single element to remove from a set
439#            2: A set
440# Returns:   Returns the set with the element removed
441# ----------------------------------------------------------------------------
442set_remove = $(__gmsl_tr2)$(filter-out $1,$2)
443
444# ----------------------------------------------------------------------------
445# Function:  set_is_member
446# Arguments: 1: A single element
447#            2: A set
448# Returns:   Returns $(true) if the element is in the set
449# ----------------------------------------------------------------------------
450set_is_member = $(__gmsl_tr2)$(if $(filter $1,$2),$(true),$(false))
451
452# ----------------------------------------------------------------------------
453# Function:  set_union
454# Arguments: 1: A set
455#            2: Another set
456# Returns:   Returns the union of the two sets
457# ----------------------------------------------------------------------------
458set_union = $(__gmsl_tr2)$(sort $1 $2)
459
460# ----------------------------------------------------------------------------
461# Function:  set_intersection
462# Arguments: 1: A set
463#            2: Another set
464# Returns:   Returns the intersection of the two sets
465# ----------------------------------------------------------------------------
466set_intersection = $(__gmsl_tr2)$(filter $1,$2)
467
468# ----------------------------------------------------------------------------
469# Function:  set_is_subset
470# Arguments: 1: A set
471#            2: Another set
472# Returns:   Returns $(true) if the first set is a subset of the second
473# ----------------------------------------------------------------------------
474set_is_subset = $(__gmsl_tr2)$(call set_equal,$(call set_intersection,$1,$2),$1)
475
476# ----------------------------------------------------------------------------
477# Function:  set_equal
478# Arguments: 1: A set
479#            2: Another set
480# Returns:   Returns $(true) if the two sets are identical
481# ----------------------------------------------------------------------------
482set_equal = $(__gmsl_tr2)$(call seq,$1,$2)
483
484# ###########################################################################
485# ARITHMETIC LIBRARY
486# ###########################################################################
487
488# Integers a represented by lists with the equivalent number of x's.
489# For example the number 4 is x x x x.  The maximum integer that the
490# library can handle as _input_ is __gmsl_input_int which is defined
491# here as 65536
492
493__gmsl_sixteen := x x x x x x x x x x x x x x x x
494__gmsl_input_int := $(foreach a,$(__gmsl_sixteen),         \
495                        $(foreach b,$(__gmsl_sixteen),     \
496                            $(foreach c,$(__gmsl_sixteen), \
497                                $(__gmsl_sixteen)))))
498
499# ----------------------------------------------------------------------------
500# Function:  int_decode
501# Arguments: 1: A number of x's representation
502# Returns:   Returns the integer for human consumption that is represented
503#            by the string of x's
504# ----------------------------------------------------------------------------
505int_decode = $(__gmsl_tr1)$(words $1)
506
507# ----------------------------------------------------------------------------
508# Function:  int_encode
509# Arguments: 1: A number in human-readable integer form
510# Returns:   Returns the integer encoded as a string of x's
511# ----------------------------------------------------------------------------
512int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int))
513
514# The arithmetic library functions come in two forms: one form of each
515# function takes integers as arguments and the other form takes the
516# encoded form (x's created by a call to int_encode).  For example,
517# there are two plus functions:
518#
519# plus        Called with integer arguments and returns an integer
520# int_plus    Called with encoded arguments and returns an encoded result
521#
522# plus will be slower than int_plus because its arguments and result
523# have to be translated between the x's format and integers.  If doing
524# a complex calculation use the int_* forms with a single encoding of
525# inputs and single decoding of the output.  For simple calculations
526# the direct forms can be used.
527
528# Helper function used to wrap an int_* function into a function that
529# takes a pair of integers, perhaps a function and returns an integer
530# result
531__gmsl_int_wrap = $(call int_decode,$(call $1,$(call int_encode,$2),$(call int_encode,$3)))
532__gmsl_int_wrap1 = $(call int_decode,$(call $1,$(call int_encode,$2)))
533__gmsl_int_wrap2 = $(call $1,$(call int_encode,$2),$(call int_encode,$3))
534
535# ----------------------------------------------------------------------------
536# Function:  int_plus
537# Arguments: 1: A number in x's representation
538#            2: Another number in x's represntation
539# Returns:   Returns the sum of the two numbers in x's representation
540# ----------------------------------------------------------------------------
541int_plus = $(strip $(__gmsl_tr2)$1 $2)
542
543# ----------------------------------------------------------------------------
544# Function:  plus (wrapped version of int_plus)
545# Arguments: 1: An integer
546#            2: Another integer
547# Returns:   Returns the sum of the two integers
548# ----------------------------------------------------------------------------
549plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2)
550
551# ----------------------------------------------------------------------------
552# Function:  int_subtract
553# Arguments: 1: A number in x's representation
554#            2: Another number in x's represntation
555# Returns:   Returns the difference of the two numbers in x's representation,
556#            or outputs an error on a numeric underflow
557# ----------------------------------------------------------------------------
558int_subtract = $(strip $(__gmsl_tr2)$(if $(call int_gte,$1,$2), \
559                $(filter-out xx,$(join $1,$2)),                 \
560                $(call __gmsl_warning,Subtraction underflow)))
561
562# ----------------------------------------------------------------------------
563# Function:  subtract (wrapped version of int_subtract)
564# Arguments: 1: An integer
565#            2: Another integer
566# Returns:   Returns the difference of the two integers,
567#            or outputs an error on a numeric underflow
568# ----------------------------------------------------------------------------
569subtract = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_subtract,$1,$2)
570
571# ----------------------------------------------------------------------------
572# Function:  int_multiply
573# Arguments: 1: A number in x's representation
574#            2: Another number in x's represntation
575# Returns:   Returns the product of the two numbers in x's representation
576# ----------------------------------------------------------------------------
577int_multiply = $(strip $(__gmsl_tr2)$(foreach a,$1,$2))
578
579# ----------------------------------------------------------------------------
580# Function:  multiply (wrapped version of int_multiply)
581# Arguments: 1: An integer
582#            2: Another integer
583# Returns:   Returns the product of the two integers
584# ----------------------------------------------------------------------------
585multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2)
586
587# ----------------------------------------------------------------------------
588# Function:  int_divide
589# Arguments: 1: A number in x's representation
590#            2: Another number in x's represntation
591# Returns:   Returns the result of integer division of argument 1 divided
592#            by argument 2 in x's representation
593# ----------------------------------------------------------------------------
594int_divide = $(__gmsl_tr2)$(strip $(if $2,                                 \
595                 $(if $(call int_gte,$1,$2),                               \
596                     x $(call int_divide,$(call int_subtract,$1,$2),$2),), \
597                 $(call __gmsl_error,Division by zero)))
598
599# ----------------------------------------------------------------------------
600# Function:  divide (wrapped version of int_divide)
601# Arguments: 1: An integer
602#            2: Another integer
603# Returns:   Returns the integer division of the first argument by the second
604# ----------------------------------------------------------------------------
605divide = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_divide,$1,$2)
606
607# ----------------------------------------------------------------------------
608# Function:  int_max, int_min
609# Arguments: 1: A number in x's representation
610#            2: Another number in x's represntation
611# Returns:   Returns the maximum or minimum of its arguments in x's
612#            representation
613# ----------------------------------------------------------------------------
614int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2))
615int_min = $(__gmsl_tr2)$(subst xx,x,$(filter xx,$(join $1,$2)))
616
617# ----------------------------------------------------------------------------
618# Function:  max, min
619# Arguments: 1: An integer
620#            2: Another integer
621# Returns:   Returns the maximum or minimum of its integer arguments
622# ----------------------------------------------------------------------------
623max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2)
624min = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_min,$1,$2)
625
626# ----------------------------------------------------------------------------
627# Function: int_gt, int_gte, int_lt, int_lte, int_eq, int_ne
628# Arguments: Two x's representation numbers to be compared
629# Returns:   $(true) or $(false)
630#
631# int_gt    First argument greater than second argument
632# int_gte   First argument greater than or equal to second argument
633# int_lt    First argument less than second argument
634# int_lte   First argument less than or equal to second argument
635# int_eq    First argument is numerically equal to the second argument
636# int_ne    First argument is not numerically equal to the second argument
637# ----------------------------------------------------------------------------
638int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
639                          $(filter-out $(words $2), \
640                              $(words $(call int_max,$1,$2))))
641int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
642                           $(call int_gt,$1,$2)$(call int_eq,$1,$2))
643int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
644                          $(filter-out $(words $1), \
645                              $(words $(call int_max,$1,$2))))
646int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
647                           $(call int_lt,$1,$2)$(call int_eq,$1,$2))
648int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
649                          $(filter $(words $1),$(words $2)))
650int_ne = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
651                          $(filter-out $(words $1),$(words $2)))
652
653# ----------------------------------------------------------------------------
654# Function: gt, gte, lt, lte, eq, ne
655# Arguments: Two integers to be compared
656# Returns:   $(true) or $(false)
657#
658# gt    First argument greater than second argument
659# gte   First argument greater than or equal to second argument
660# lt    First argument less than second argument
661# lte   First argument less than or equal to second argument
662# eq    First argument is numerically equal to the second argument
663# ne    First argument is not numerically equal to the second argument
664# ----------------------------------------------------------------------------
665gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2)
666gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2)
667lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2)
668lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2)
669eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2)
670ne = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_ne,$1,$2)
671
672# increment adds 1 to its argument, decrement subtracts 1.  Note that
673# decrement does not range check and hence will not underflow, but
674# will incorrectly say that 0 - 1 = 0
675
676# ----------------------------------------------------------------------------
677# Function:  int_inc
678# Arguments: 1: A number in x's representation
679# Returns:   The number incremented by 1 in x's representation
680# ----------------------------------------------------------------------------
681int_inc = $(strip $(__gmsl_tr1)$1 x)
682
683# ----------------------------------------------------------------------------
684# Function:  inc
685# Arguments: 1: An integer
686# Returns:   The argument incremented by 1
687# ----------------------------------------------------------------------------
688inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1)
689
690# ----------------------------------------------------------------------------
691# Function:  int_dec
692# Arguments: 1: A number in x's representation
693# Returns:   The number decremented by 1 in x's representation
694# ----------------------------------------------------------------------------
695int_dec = $(__gmsl_tr1)$(strip $(if $(call sne,0,$(words $1)), \
696              $(wordlist 2,$(words $1),$1),                    \
697              $(call __gmsl_warning,Decrement underflow)))
698
699# ----------------------------------------------------------------------------
700# Function:  dec
701# Arguments: 1: An integer
702# Returns:   The argument decremented by 1
703# ----------------------------------------------------------------------------
704dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1)
705
706# double doubles its argument, and halve halves it
707
708# ----------------------------------------------------------------------------
709# Function:  int_double
710# Arguments: 1: A number in x's representation
711# Returns:   The number doubled (i.e. * 2) and returned in x's representation
712# ----------------------------------------------------------------------------
713int_double = $(strip $(__gmsl_tr1)$1 $1)
714
715# ----------------------------------------------------------------------------
716# Function:  double
717# Arguments: 1: An integer
718# Returns:   The integer times 2
719# ----------------------------------------------------------------------------
720double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1)
721
722# ----------------------------------------------------------------------------
723# Function:  int_halve
724# Arguments: 1: A number in x's representation
725# Returns:   The number halved (i.e. / 2) and returned in x's representation
726# ----------------------------------------------------------------------------
727int_halve = $(__gmsl_tr1)$(strip $(subst xx,x,$(filter-out xy x y, \
728                             $(join $1,$(foreach a,$1,y x)))))
729
730# ----------------------------------------------------------------------------
731# Function:  halve
732# Arguments: 1: An integer
733# Returns:   The integer divided by 2
734# ----------------------------------------------------------------------------
735halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1)
736
737ifdef __gmsl_have_eval
738# ###########################################################################
739# ASSOCIATIVE ARRAYS
740# ###########################################################################
741
742# ----------------------------------------------------------------------------
743# Function:  set
744# Arguments: 1: Name of associative array
745#            2: The key value to associate
746#            3: The value associated with the key
747# Returns:   None
748# ----------------------------------------------------------------------------
749set = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(eval __gmsl_aa_$1_$2 = $3)
750
751# ----------------------------------------------------------------------------
752# Function:  get
753# Arguments: 1: Name of associative array
754#            2: The key to retrieve
755# Returns:   The value stored in the array for that key
756# ----------------------------------------------------------------------------
757get = $(strip $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(if $(filter-out undefined,$(origin __gmsl_aa_$1_$2)), \
758    $(__gmsl_aa_$1_$2)))
759
760# ----------------------------------------------------------------------------
761# Function:  keys
762# Arguments: 1: Name of associative array
763# Returns:   Returns a list of all defined keys in the array
764# ----------------------------------------------------------------------------
765keys = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(sort $(patsubst __gmsl_aa_$1_%,%, \
766                  $(filter __gmsl_aa_$1_%,$(.VARIABLES))))
767
768# ----------------------------------------------------------------------------
769# Function:  defined
770# Arguments: 1: Name of associative array
771#            2: The key to test
772# Returns:   Returns true if the key is defined (i.e. not empty)
773# ----------------------------------------------------------------------------
774defined = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(call sne,$(call get,$1,$2),)
775
776endif # __gmsl_have_eval
777
778ifdef __gmsl_have_eval
779# ###########################################################################
780# NAMED STACKS
781# ###########################################################################
782
783# ----------------------------------------------------------------------------
784# Function:  push
785# Arguments: 1: Name of stack
786#            2: Value to push onto the top of the stack (must not contain
787#               a space)
788# Returns:   None
789# ----------------------------------------------------------------------------
790push = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\
791    $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1)))
792
793# ----------------------------------------------------------------------------
794# Function:  pop
795# Arguments: 1: Name of stack
796# Returns:   Top element from the stack after removing it
797# ----------------------------------------------------------------------------
798pop = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(if $(filter-out undefined,$(origin __gmsl_stack_$1)), \
799    $(call first,$(__gmsl_stack_$1))                                       \
800    $(eval __gmsl_stack_$1 := $(call rest,$(__gmsl_stack_$1)))))
801
802# ----------------------------------------------------------------------------
803# Function:  peek
804# Arguments: 1: Name of stack
805# Returns:   Top element from the stack without removing it
806# ----------------------------------------------------------------------------
807peek = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call first,$(__gmsl_stack_$1))
808
809# ----------------------------------------------------------------------------
810# Function:  depth
811# Arguments: 1: Name of stack
812# Returns:   Number of items on the stack
813# ----------------------------------------------------------------------------
814depth = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(words $(__gmsl_stack_$1))
815
816endif # __gmsl_have_eval
817
818# ###########################################################################
819# DEBUGGING FACILITIES
820# ###########################################################################
821
822# ----------------------------------------------------------------------------
823# Target:    gmsl-print-%
824# Arguments: The % should be replaced by the name of a variable that you
825#            wish to print out.
826# Action:    Echos the name of the variable that matches the % and its value.
827#            For example, 'make gmsl-print-SHELL' will output the value of
828#            the SHELL variable
829# ----------------------------------------------------------------------------
830gmsl-print-%: ; @echo $* = $($*)
831
832# ----------------------------------------------------------------------------
833# Function:  assert
834# Arguments: 1: A boolean that must be true or the assertion will fail
835#            2: The message to print with the assertion
836# Returns:   None
837# ----------------------------------------------------------------------------
838assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2))
839
840# ----------------------------------------------------------------------------
841# Function:  assert_exists
842# Arguments: 1: Name of file that must exist, if it is missing an assertion
843#               will be generated
844# Returns:   None
845# ----------------------------------------------------------------------------
846assert_exists = $(call assert,$(wildcard $1),file '$1' missing)
847
848# ----------------------------------------------------------------------------
849# Function:  assert_no_dollar
850# Arguments: 1: Name of a function being executd
851#            2: Arguments to check
852# Returns:   None
853# ----------------------------------------------------------------------------
854assert_no_dollar = $(call assert,$(call not,$(findstring $$,$2)),$1 called with a dollar sign in argument)
855