1 # ----------------------------------------------------------------------------
3 # GNU Make Standard Library (GMSL)
5 # A library of functions to be used with GNU Make's $(call) that
6 # provides functionality not available in standard GNU Make.
8 # Copyright (c) 2005-2007 John Graham-Cumming
10 # This file is part of GMSL
12 # Redistribution and use in source and binary forms, with or without
13 # modification, are permitted provided that the following conditions
16 # Redistributions of source code must retain the above copyright
17 # notice, this list of conditions and the following disclaimer.
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.
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.
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.
40 # ----------------------------------------------------------------------------
42 # This is the GNU Make Standard Library version number as a list with
43 # three items: major, minor, revision
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
51 __gmsl_name := GNU Make Standard Library
52 __gmsl_warning = $(warning $(__gmsl_name): $1)
53 __gmsl_error = $(error $(__gmsl_name): $1)
55 ifdef GMSL_NO_WARNINGS
62 # If GMSL_TRACE is enabled then calls to the library functions are
63 # traced to stdout using warning messages with their arguments
66 __gmsl_tr1 = $(warning $0('$1'))
67 __gmsl_tr2 = $(warning $0('$1','$2'))
68 __gmsl_tr3 = $(warning $0('$1','$2','$3'))
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.
79 __gmsl_have_eval := $(false)
80 __gmsl_ignore := $(eval __gmsl_have_eval := $(true))
82 # See if we have $(lastword) (GNU Make 3.81 and above)
84 __gmsl_have_lastword := $(lastword $(false) $(true))
86 # See if we have native or and and (GNU Make 3.81 and above)
88 __gmsl_have_or := $(if $(filter-out undefined, \
89 $(origin or)),$(call or,$(true),$(false)))
90 __gmsl_have_and := $(if $(filter-out undefined, \
91 $(origin and)),$(call and,$(true),$(true)))
93 ifneq ($(__gmsl_have_eval),$(true))
94 $(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$(eval): some functions disabled)
97 # ----------------------------------------------------------------------------
98 # Function: gmsl_compatible
99 # Arguments: List containing the desired library version number (maj min rev)
100 # Returns: $(true) if this version of the library is compatible
101 # with the requested version number, otherwise $(false)
102 # ----------------------------------------------------------------------------
103 gmsl_compatible = $(strip \
104 $(if $(call gt,$(word 1,$1),$(word 1,$(gmsl_version))), \
106 $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))), \
108 $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))), \
110 $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))), \
112 $(call lte,$(word 3,$1),$(word 3,$(gmsl_version))))))))
114 # ###########################################################################
116 # ###########################################################################
118 # not is defined in gmsl
120 # ----------------------------------------------------------------------------
122 # Arguments: Two boolean values
123 # Returns: Returns $(true) if both of the booleans are true
124 # ----------------------------------------------------------------------------
125 ifneq ($(__gmsl_have_and),$(true))
126 and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false))
129 # ----------------------------------------------------------------------------
131 # Arguments: Two boolean values
132 # Returns: Returns $(true) if either of the booleans is true
133 # ----------------------------------------------------------------------------
134 ifneq ($(__gmsl_have_or),$(true))
135 or = $(__gmsl_tr2)$(if $1$2,$(true),$(false))
138 # ----------------------------------------------------------------------------
140 # Arguments: Two boolean values
141 # Returns: Returns $(true) if exactly one of the booleans is true
142 # ----------------------------------------------------------------------------
143 xor = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(if $2,$(true),$(false)))
145 # ----------------------------------------------------------------------------
147 # Arguments: Two boolean values
148 # Returns: Returns value of 'not and'
149 # ----------------------------------------------------------------------------
150 nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true))
152 # ----------------------------------------------------------------------------
154 # Arguments: Two boolean values
155 # Returns: Returns value of 'not or'
156 # ----------------------------------------------------------------------------
157 nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true))
159 # ----------------------------------------------------------------------------
161 # Arguments: Two boolean values
162 # Returns: Returns value of 'not xor'
163 # ----------------------------------------------------------------------------
164 xnor =$(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(if $2,$(false),$(true)))
166 # ###########################################################################
167 # LIST MANIPULATION FUNCTIONS
168 # ###########################################################################
170 # ----------------------------------------------------------------------------
171 # Function: first (same as LISP's car, or head)
172 # Arguments: 1: A list
173 # Returns: Returns the first element of a list
174 # ----------------------------------------------------------------------------
175 first = $(__gmsl_tr1)$(firstword $1)
177 # ----------------------------------------------------------------------------
179 # Arguments: 1: A list
180 # Returns: Returns the last element of a list
181 # ----------------------------------------------------------------------------
182 ifeq ($(__gmsl_have_lastword),$(true))
183 last = $(__gmsl_tr1)$(lastword $1)
185 last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1))
188 # ----------------------------------------------------------------------------
189 # Function: rest (same as LISP's cdr, or tail)
190 # Arguments: 1: A list
191 # Returns: Returns the list with the first element removed
192 # ----------------------------------------------------------------------------
193 rest = $(__gmsl_tr1)$(wordlist 2,$(words $1),$1)
195 # ----------------------------------------------------------------------------
197 # Arguments: 1: A list
198 # Returns: Returns the list with the last element removed
199 # ----------------------------------------------------------------------------
200 chop = $(__gmsl_tr1)$(wordlist 2,$(words $1),x $1)
202 # ----------------------------------------------------------------------------
204 # Arguments: 1: Name of function to $(call) for each element of list
205 # 2: List to iterate over calling the function in 1
206 # Returns: The list after calling the function on each element
207 # ----------------------------------------------------------------------------
208 map = $(__gmsl_tr2)$(strip $(foreach a,$2,$(call $1,$a)))
210 # ----------------------------------------------------------------------------
212 # Arguments: 1: Name of function to $(call) for each pair of elements
213 # 2: List to iterate over calling the function in 1
214 # 3: Second list to iterate over calling the function in 1
215 # Returns: The list after calling the function on each pair of elements
216 # ----------------------------------------------------------------------------
217 pairmap = $(strip $(__gmsl_tr3)\
218 $(if $2$3,$(call $1,$(call first,$2),$(call first,$3)) \
219 $(call pairmap,$1,$(call rest,$2),$(call rest,$3))))
221 # ----------------------------------------------------------------------------
223 # Arguments: 1: A list to compare against...
225 # Returns: Returns $(true) if the two lists are identical
226 # ----------------------------------------------------------------------------
227 leq = $(__gmsl_tr2)$(strip $(if $(call seq,$(words $1),$(words $2)), \
228 $(call __gmsl_list_equal,$1,$2),$(false)))
230 __gmsl_list_equal = $(if $(strip $1), \
231 $(if $(call seq,$(call first,$1),$(call first,$2)), \
232 $(call __gmsl_list_equal, \
238 # ----------------------------------------------------------------------------
240 # Arguments: 1: A list to compare against...
242 # Returns: Returns $(true) if the two lists are different
243 # ----------------------------------------------------------------------------
244 lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2))
246 # ----------------------------------------------------------------------------
248 # Arguments: 1: A list to reverse
249 # Returns: The list with its elements in reverse order
250 # ----------------------------------------------------------------------------
251 reverse =$(__gmsl_tr1)$(strip $(if $1,$(call reverse,$(call rest,$1)) \
254 # ----------------------------------------------------------------------------
256 # Arguments: 1: A list from which to remove repeated elements
257 # Returns: The list with duplicate elements removed without reordering
258 # ----------------------------------------------------------------------------
259 uniq = $(strip $(__gmsl_tr1)$(if $1,$(call uniq,$(call chop,$1)) \
260 $(if $(filter $(call last,$1),$(call chop,$1)),,$(call last,$1))))
262 # ----------------------------------------------------------------------------
264 # Arguments: 1: A list
265 # Returns: The number of elements in the list
266 # ----------------------------------------------------------------------------
267 length = $(__gmsl_tr1)$(words $1)
269 # ###########################################################################
270 # STRING MANIPULATION FUNCTIONS
271 # ###########################################################################
273 # Helper function that translates any GNU Make 'true' value (i.e. a
274 # non-empty string) to our $(true)
276 __gmsl_make_bool = $(if $(strip $1),$(true),$(false))
278 # ----------------------------------------------------------------------------
280 # Arguments: 1: A string to compare against...
282 # Returns: Returns $(true) if the two strings are identical
283 # ----------------------------------------------------------------------------
284 seq = $(__gmsl_tr2)$(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),$(false),$(true))
286 # ----------------------------------------------------------------------------
288 # Arguments: 1: A string to compare against...
290 # Returns: Returns $(true) if the two strings are not the same
291 # ----------------------------------------------------------------------------
292 sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2))
294 # ----------------------------------------------------------------------------
296 # Arguments: 1: The character to split on
297 # 2: A string to split
298 # Returns: Splits a string into a list separated by spaces at the split
299 # character in the first argument
300 # ----------------------------------------------------------------------------
301 split = $(__gmsl_tr2)$(strip $(subst $1, ,$2))
303 # ----------------------------------------------------------------------------
305 # Arguments: 1: The character to put between fields
306 # 2: A list to merge into a string
307 # Returns: Merges a list into a single string, list elements are separated
308 # by the character in the first argument
309 # ----------------------------------------------------------------------------
310 merge = $(__gmsl_tr2)$(strip $(if $2, \
311 $(if $(call seq,1,$(words $2)), \
312 $2,$(call first,$2)$1$(call merge,$1,$(call rest,$2)))))
314 ifdef __gmsl_have_eval
315 # ----------------------------------------------------------------------------
317 # Arguments: 1: The list of characters to translate from
318 # 2: The list of characters to translate to
319 # 3: The text to translate
320 # Returns: Returns the text after translating characters
321 # ----------------------------------------------------------------------------
322 tr = $(__gmsl_tr3)$(strip $(eval __gmsl_t := $3) \
324 $(join $(addsuffix :,$1),$2), \
326 $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \
327 $(__gmsl_t))))$(__gmsl_t))
329 # Common character classes for use with the tr function. Each of
330 # these is actually a variable declaration and must be wrapped with
331 # $() or ${} to be used.
333 [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 #
334 [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 #
335 [0-9] := 0 1 2 3 4 5 6 7 8 9 #
336 [A-F] := A B C D E F #
338 # ----------------------------------------------------------------------------
340 # Arguments: 1: Text to upper case
341 # Returns: Returns the text in upper case
342 # ----------------------------------------------------------------------------
343 uc = $(__gmsl_tr1)$(call tr,$([a-z]),$([A-Z]),$1)
345 # ----------------------------------------------------------------------------
347 # Arguments: 1: Text to lower case
348 # Returns: Returns the text in lower case
349 # ----------------------------------------------------------------------------
350 lc = $(__gmsl_tr1)$(call tr,$([A-Z]),$([a-z]),$1)
352 # ----------------------------------------------------------------------------
354 # Arguments: 1: A string
355 # Returns: Returns the length of the string
356 # ----------------------------------------------------------------------------
357 __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
358 __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 y z
359 __gmsl_characters += 0 1 2 3 4 5 6 7 8 9
360 __gmsl_characters += ` ~ ! @ \# $$ % ^ & * ( ) - _ = +
361 __gmsl_characters += { } [ ] \ : ; ' " < > , . / ? |
363 # Aside: if you read the above you might think that the lower-case
364 # letter x is missing, and that that's an error. It is missing, but
365 # it's not an error. __gmsl_characters is used by the strlen
366 # function. strlen works by transforming every character and space
367 # into the letter x and then counting the x's. Since there's no need
368 # to transform x into x I omitted it.
370 # This results in __gmsl_space containing just a space
375 strlen = $(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)))
377 # This results in __gmsl_newline containing just a newline
379 define __gmsl_newline
384 # This results in __gmsl_tab containing a tab
388 # ----------------------------------------------------------------------------
390 # Arguments: 1: A string
391 # 2: Start position (first character is 1)
392 # 3: End position (inclusive)
393 # Returns: A substring.
394 # Note: The string in $1 must not contain a §
395 # ----------------------------------------------------------------------------
397 substr = $(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)))
399 endif # __gmsl_have_eval
401 # ###########################################################################
402 # SET MANIPULATION FUNCTIONS
403 # ###########################################################################
405 # Sets are represented by sorted, deduplicated lists. To create a set
406 # from a list use set_create, or start with the empty_set and
407 # set_insert individual elements
409 # This is the empty set
412 # ----------------------------------------------------------------------------
413 # Function: set_create
414 # Arguments: 1: A list of set elements
415 # Returns: Returns the newly created set
416 # ----------------------------------------------------------------------------
417 set_create = $(__gmsl_tr1)$(sort $1)
419 # ----------------------------------------------------------------------------
420 # Function: set_insert
421 # Arguments: 1: A single element to add to a set
423 # Returns: Returns the set with the element added
424 # ----------------------------------------------------------------------------
425 set_insert = $(__gmsl_tr2)$(sort $1 $2)
427 # ----------------------------------------------------------------------------
428 # Function: set_remove
429 # Arguments: 1: A single element to remove from a set
431 # Returns: Returns the set with the element removed
432 # ----------------------------------------------------------------------------
433 set_remove = $(__gmsl_tr2)$(filter-out $1,$2)
435 # ----------------------------------------------------------------------------
436 # Function: set_is_member
437 # Arguments: 1: A single element
439 # Returns: Returns $(true) if the element is in the set
440 # ----------------------------------------------------------------------------
441 set_is_member = $(if $(filter $1,$2),$(true),$(false))
443 # ----------------------------------------------------------------------------
444 # Function: set_union
445 # Arguments: 1: A set
447 # Returns: Returns the union of the two sets
448 # ----------------------------------------------------------------------------
449 set_union = $(sort $1 $2)
451 # ----------------------------------------------------------------------------
452 # Function: set_intersection
453 # Arguments: 1: A set
455 # Returns: Returns the intersection of the two sets
456 # ----------------------------------------------------------------------------
457 set_intersection = $(filter $1,$2)
459 # ----------------------------------------------------------------------------
460 # Function: set_is_subset
461 # Arguments: 1: A set
463 # Returns: Returns $(true) if the first set is a subset of the second
464 # ----------------------------------------------------------------------------
465 set_is_subset = $(call set_equal,$(call set_intersection,$1,$2),$1)
467 # ----------------------------------------------------------------------------
468 # Function: set_equal
469 # Arguments: 1: A set
471 # Returns: Returns $(true) if the two sets are identical
472 # ----------------------------------------------------------------------------
473 set_equal = $(call seq,$1,$2)
475 # ###########################################################################
477 # ###########################################################################
479 # Integers a represented by lists with the equivalent number of x's.
480 # For example the number 4 is x x x x. The maximum integer that the
481 # library can handle as _input_ is __gmsl_input_int which is defined
484 __gmsl_sixteen := x x x x x x x x x x x x x x x x
485 __gmsl_input_int := $(foreach a,$(__gmsl_sixteen), \
486 $(foreach b,$(__gmsl_sixteen), \
487 $(foreach c,$(__gmsl_sixteen), \
488 $(__gmsl_sixteen)))))
490 # ----------------------------------------------------------------------------
491 # Function: int_decode
492 # Arguments: 1: A number of x's representation
493 # Returns: Returns the integer for human consumption that is represented
494 # by the string of x's
495 # ----------------------------------------------------------------------------
496 int_decode = $(__gmsl_tr1)$(words $1)
498 # ----------------------------------------------------------------------------
499 # Function: int_encode
500 # Arguments: 1: A number in human-readable integer form
501 # Returns: Returns the integer encoded as a string of x's
502 # ----------------------------------------------------------------------------
503 int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int))
505 # The arithmetic library functions come in two forms: one form of each
506 # function takes integers as arguments and the other form takes the
507 # encoded form (x's created by a call to int_encode). For example,
508 # there are two plus functions:
510 # plus Called with integer arguments and returns an integer
511 # int_plus Called with encoded arguments and returns an encoded result
513 # plus will be slower than int_plus because its arguments and result
514 # have to be translated between the x's format and integers. If doing
515 # a complex calculation use the int_* forms with a single encoding of
516 # inputs and single decoding of the output. For simple calculations
517 # the direct forms can be used.
519 # Helper function used to wrap an int_* function into a function that
520 # takes a pair of integers, perhaps a function and returns an integer
522 __gmsl_int_wrap = $(call int_decode,$(call $1,$(call int_encode,$2),$(call int_encode,$3)))
523 __gmsl_int_wrap1 = $(call int_decode,$(call $1,$(call int_encode,$2)))
524 __gmsl_int_wrap2 = $(call $1,$(call int_encode,$2),$(call int_encode,$3))
526 # ----------------------------------------------------------------------------
528 # Arguments: 1: A number in x's representation
529 # 2: Another number in x's represntation
530 # Returns: Returns the sum of the two numbers in x's representation
531 # ----------------------------------------------------------------------------
532 int_plus = $(strip $(__gmsl_tr2)$1 $2)
534 # ----------------------------------------------------------------------------
535 # Function: plus (wrapped version of int_plus)
536 # Arguments: 1: An integer
538 # Returns: Returns the sum of the two integers
539 # ----------------------------------------------------------------------------
540 plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2)
542 # ----------------------------------------------------------------------------
543 # Function: int_subtract
544 # Arguments: 1: A number in x's representation
545 # 2: Another number in x's represntation
546 # Returns: Returns the difference of the two numbers in x's representation,
547 # or outputs an error on a numeric underflow
548 # ----------------------------------------------------------------------------
549 int_subtract = $(strip $(__gmsl_tr2)$(if $(call int_gte,$1,$2), \
550 $(filter-out xx,$(join $1,$2)), \
551 $(call __gmsl_warning,Subtraction underflow)))
553 # ----------------------------------------------------------------------------
554 # Function: subtract (wrapped version of int_subtract)
555 # Arguments: 1: An integer
557 # Returns: Returns the difference of the two integers,
558 # or outputs an error on a numeric underflow
559 # ----------------------------------------------------------------------------
560 subtract = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_subtract,$1,$2)
562 # ----------------------------------------------------------------------------
563 # Function: int_multiply
564 # Arguments: 1: A number in x's representation
565 # 2: Another number in x's represntation
566 # Returns: Returns the product of the two numbers in x's representation
567 # ----------------------------------------------------------------------------
568 int_multiply = $(strip $(__gmsl_tr2)$(foreach a,$1,$2))
570 # ----------------------------------------------------------------------------
571 # Function: multiply (wrapped version of int_multiply)
572 # Arguments: 1: An integer
574 # Returns: Returns the product of the two integers
575 # ----------------------------------------------------------------------------
576 multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2)
578 # ----------------------------------------------------------------------------
579 # Function: int_divide
580 # Arguments: 1: A number in x's representation
581 # 2: Another number in x's represntation
582 # Returns: Returns the result of integer division of argument 1 divided
583 # by argument 2 in x's representation
584 # ----------------------------------------------------------------------------
585 int_divide = $(__gmsl_tr2)$(strip $(if $2, \
586 $(if $(call int_gte,$1,$2), \
587 x $(call int_divide,$(call int_subtract,$1,$2),$2),), \
588 $(call __gmsl_error,Division by zero)))
590 # ----------------------------------------------------------------------------
591 # Function: divide (wrapped version of int_divide)
592 # Arguments: 1: An integer
594 # Returns: Returns the integer division of the first argument by the second
595 # ----------------------------------------------------------------------------
596 divide = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_divide,$1,$2)
598 # ----------------------------------------------------------------------------
599 # Function: int_max, int_min
600 # Arguments: 1: A number in x's representation
601 # 2: Another number in x's represntation
602 # Returns: Returns the maximum or minimum of its arguments in x's
604 # ----------------------------------------------------------------------------
605 int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2))
606 int_min = $(__gmsl_tr2)$(subst xx,x,$(filter xx,$(join $1,$2)))
608 # ----------------------------------------------------------------------------
610 # Arguments: 1: An integer
612 # Returns: Returns the maximum or minimum of its integer arguments
613 # ----------------------------------------------------------------------------
614 max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2)
615 min = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_min,$1,$2)
617 # ----------------------------------------------------------------------------
618 # Function: int_gt, int_gte, int_lt, int_lte, int_eq, int_ne
619 # Arguments: Two x's representation numbers to be compared
620 # Returns: $(true) or $(false)
622 # int_gt First argument greater than second argument
623 # int_gte First argument greater than or equal to second argument
624 # int_lt First argument less than second argument
625 # int_lte First argument less than or equal to second argument
626 # int_eq First argument is numerically equal to the second argument
627 # int_ne First argument is not numerically equal to the second argument
628 # ----------------------------------------------------------------------------
629 int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool, \
630 $(filter-out $(words $2), \
631 $(words $(call int_max,$1,$2))))
632 int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool, \
633 $(call int_gt,$1,$2)$(call int_eq,$1,$2))
634 int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool, \
635 $(filter-out $(words $1), \
636 $(words $(call int_max,$1,$2))))
637 int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool, \
638 $(call int_lt,$1,$2)$(call int_eq,$1,$2))
639 int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool, \
640 $(filter $(words $1),$(words $2)))
641 int_ne = $(__gmsl_tr2)$(call __gmsl_make_bool, \
642 $(filter-out $(words $1),$(words $2)))
644 # ----------------------------------------------------------------------------
645 # Function: gt, gte, lt, lte, eq, ne
646 # Arguments: Two integers to be compared
647 # Returns: $(true) or $(false)
649 # gt First argument greater than second argument
650 # gte First argument greater than or equal to second argument
651 # lt First argument less than second argument
652 # lte First argument less than or equal to second argument
653 # eq First argument is numerically equal to the second argument
654 # ne First argument is not numerically equal to the second argument
655 # ----------------------------------------------------------------------------
656 gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2)
657 gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2)
658 lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2)
659 lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2)
660 eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2)
661 ne = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_ne,$1,$2)
663 # increment adds 1 to its argument, decrement subtracts 1. Note that
664 # decrement does not range check and hence will not underflow, but
665 # will incorrectly say that 0 - 1 = 0
667 # ----------------------------------------------------------------------------
669 # Arguments: 1: A number in x's representation
670 # Returns: The number incremented by 1 in x's representation
671 # ----------------------------------------------------------------------------
672 int_inc = $(strip $(__gmsl_tr1)$1 x)
674 # ----------------------------------------------------------------------------
676 # Arguments: 1: An integer
677 # Returns: The argument incremented by 1
678 # ----------------------------------------------------------------------------
679 inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1)
681 # ----------------------------------------------------------------------------
683 # Arguments: 1: A number in x's representation
684 # Returns: The number decremented by 1 in x's representation
685 # ----------------------------------------------------------------------------
686 int_dec = $(__gmsl_tr1)$(strip $(if $(call sne,0,$(words $1)), \
687 $(wordlist 2,$(words $1),$1), \
688 $(call __gmsl_warning,Decrement underflow)))
690 # ----------------------------------------------------------------------------
692 # Arguments: 1: An integer
693 # Returns: The argument decremented by 1
694 # ----------------------------------------------------------------------------
695 dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1)
697 # double doubles its argument, and halve halves it
699 # ----------------------------------------------------------------------------
700 # Function: int_double
701 # Arguments: 1: A number in x's representation
702 # Returns: The number doubled (i.e. * 2) and returned in x's representation
703 # ----------------------------------------------------------------------------
704 int_double = $(strip $(__gmsl_tr1)$1 $1)
706 # ----------------------------------------------------------------------------
708 # Arguments: 1: An integer
709 # Returns: The integer times 2
710 # ----------------------------------------------------------------------------
711 double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1)
713 # ----------------------------------------------------------------------------
714 # Function: int_halve
715 # Arguments: 1: A number in x's representation
716 # Returns: The number halved (i.e. / 2) and returned in x's representation
717 # ----------------------------------------------------------------------------
718 int_halve = $(__gmsl_tr1)$(strip $(subst xx,x,$(filter-out xy x y, \
719 $(join $1,$(foreach a,$1,y x)))))
721 # ----------------------------------------------------------------------------
723 # Arguments: 1: An integer
724 # Returns: The integer divided by 2
725 # ----------------------------------------------------------------------------
726 halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1)
728 ifdef __gmsl_have_eval
729 # ###########################################################################
731 # ###########################################################################
733 # ----------------------------------------------------------------------------
735 # Arguments: 1: Name of associative array
736 # 2: The key value to associate
737 # 3: The value associated with the key
739 # ----------------------------------------------------------------------------
740 set = $(__gmsl_tr3)$(eval __gmsl_aa_$1_$2 = $3)
742 # ----------------------------------------------------------------------------
744 # Arguments: 1: Name of associative array
745 # 2: The key to retrieve
746 # Returns: The value stored in the array for that key
747 # ----------------------------------------------------------------------------
748 get = $(strip $(__gmsl_tr2)$(if $(filter-out undefined,$(origin __gmsl_aa_$1_$2)), \
751 # ----------------------------------------------------------------------------
753 # Arguments: 1: Name of associative array
754 # Returns: Returns a list of all defined keys in the array
755 # ----------------------------------------------------------------------------
756 keys = $(__gmsl_tr1)$(sort $(patsubst __gmsl_aa_$1_%,%, \
757 $(filter __gmsl_aa_$1_%,$(.VARIABLES))))
759 # ----------------------------------------------------------------------------
761 # Arguments: 1: Name of associative array
763 # Returns: Returns true if the key is defined (i.e. not empty)
764 # ----------------------------------------------------------------------------
765 defined = $(__gmsl_tr2)$(call sne,$(call get,$1,$2),)
767 endif # __gmsl_have_eval
769 ifdef __gmsl_have_eval
770 # ###########################################################################
772 # ###########################################################################
774 # ----------------------------------------------------------------------------
776 # Arguments: 1: Name of stack
777 # 2: Value to push onto the top of the stack (must not contain
780 # ----------------------------------------------------------------------------
781 push = $(__gmsl_tr2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\
782 $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1)))
784 # ----------------------------------------------------------------------------
786 # Arguments: 1: Name of stack
787 # Returns: Top element from the stack after removing it
788 # ----------------------------------------------------------------------------
789 pop = $(__gmsl_tr1)$(strip $(if $(filter-out undefined,$(origin __gmsl_stack_$1)), \
790 $(call first,$(__gmsl_stack_$1)) \
791 $(eval __gmsl_stack_$1 := $(call rest,$(__gmsl_stack_$1)))))
793 # ----------------------------------------------------------------------------
795 # Arguments: 1: Name of stack
796 # Returns: Top element from the stack without removing it
797 # ----------------------------------------------------------------------------
798 peek = $(__gmsl_tr1)$(call first,$(__gmsl_stack_$1))
800 # ----------------------------------------------------------------------------
802 # Arguments: 1: Name of stack
803 # Returns: Number of items on the stack
804 # ----------------------------------------------------------------------------
805 depth = $(__gmsl_tr1)$(words $(__gmsl_stack_$1))
807 endif # __gmsl_have_eval
809 # ###########################################################################
810 # DEBUGGING FACILITIES
811 # ###########################################################################
813 # ----------------------------------------------------------------------------
814 # Target: gmsl-print-%
815 # Arguments: The % should be replaced by the name of a variable that you
817 # Action: Echos the name of the variable that matches the % and its value.
818 # For example, 'make gmsl-print-SHELL' will output the value of
820 # ----------------------------------------------------------------------------
821 gmsl-print-%: ; @echo $* = $($*)
823 # ----------------------------------------------------------------------------
825 # Arguments: 1: A boolean that must be true or the assertion will fail
826 # 2: The message to print with the assertion
828 # ----------------------------------------------------------------------------
829 assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2))
831 # ----------------------------------------------------------------------------
832 # Function: assert_exists
833 # Arguments: 1: Name of file that must exist, if it is missing an assertion
836 # ----------------------------------------------------------------------------
837 assert_exists = $(call assert,$(wildcard $1),file '$1' missing)