Home | History | Annotate | Download | only in gmsl
      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 
     45 gmsl_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 
     55 ifdef GMSL_NO_WARNINGS
     56 __gmsl_warning :=
     57 endif
     58 ifdef GMSL_NO_ERRORS
     59 __gmsl_error :=
     60 endif
     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 
     65 ifdef GMSL_TRACE
     66 __gmsl_tr1 = $(warning $0('$1'))
     67 __gmsl_tr2 = $(warning $0('$1','$2'))
     68 __gmsl_tr3 = $(warning $0('$1','$2','$3'))
     69 else
     70 __gmsl_tr1 :=
     71 __gmsl_tr2 :=
     72 __gmsl_tr3 :=
     73 endif
     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 
     85 ifdef ECLOUD_BUILD_ID
     86 $(warning You are using Electric Cloud's emake which has incomplete $$(eval) support)
     87 __gmsl_have_eval := $(false)
     88 endif
     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 
    101 ifneq ($(__gmsl_have_eval),$(true))
    102 $(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$$$(eval): some functions disabled)
    103 endif
    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 # ----------------------------------------------------------------------------
    111 gmsl_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 # ----------------------------------------------------------------------------
    133 ifneq ($(__gmsl_have_and),$(true))
    134 and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false))
    135 endif
    136 
    137 # ----------------------------------------------------------------------------
    138 # Function:  or
    139 # Arguments: Two boolean values
    140 # Returns:   Returns $(true) if either of the booleans is true
    141 # ----------------------------------------------------------------------------
    142 ifneq ($(__gmsl_have_or),$(true))
    143 or = $(__gmsl_tr2)$(if $1$2,$(true),$(false))
    144 endif
    145 
    146 # ----------------------------------------------------------------------------
    147 # Function:  xor
    148 # Arguments: Two boolean values
    149 # Returns:   Returns $(true) if exactly one of the booleans is true
    150 # ----------------------------------------------------------------------------
    151 xor = $(__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 # ----------------------------------------------------------------------------
    158 nand = $(__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 # ----------------------------------------------------------------------------
    165 nor = $(__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 # ----------------------------------------------------------------------------
    172 xnor =$(__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 # ----------------------------------------------------------------------------
    183 first = $(__gmsl_tr1)$(firstword $1)
    184 
    185 # ----------------------------------------------------------------------------
    186 # Function:  last
    187 # Arguments: 1: A list
    188 # Returns:   Returns the last element of a list
    189 # ----------------------------------------------------------------------------
    190 ifeq ($(__gmsl_have_lastword),$(true))
    191 last = $(__gmsl_tr1)$(lastword $1)
    192 else
    193 last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1))
    194 endif
    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 # ----------------------------------------------------------------------------
    201 rest = $(__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 # ----------------------------------------------------------------------------
    208 chop = $(__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 # ----------------------------------------------------------------------------
    216 map = $(__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 # ----------------------------------------------------------------------------
    225 pairmap = $(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 # ----------------------------------------------------------------------------
    235 leq = $(__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 # ----------------------------------------------------------------------------
    252 lne = $(__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 # ----------------------------------------------------------------------------
    259 reverse =$(__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 # ----------------------------------------------------------------------------
    267 uniq = $(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 # ----------------------------------------------------------------------------
    275 length = $(__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 # ----------------------------------------------------------------------------
    292 seq = $(__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 # ----------------------------------------------------------------------------
    300 sne = $(__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 # ----------------------------------------------------------------------------
    309 split = $(__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 # ----------------------------------------------------------------------------
    318 merge = $(__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 
    322 ifdef __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 # ----------------------------------------------------------------------------
    330 tr = $(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 # ----------------------------------------------------------------------------
    352 uc = $(__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 # ----------------------------------------------------------------------------
    359 lc = $(__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 
    384 strlen = $(__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 
    388 define __gmsl_newline
    389 
    390 
    391 endef
    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 
    406 substr = $(__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 
    408 endif # __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
    419 empty_set := 
    420 
    421 # ----------------------------------------------------------------------------
    422 # Function:  set_create
    423 # Arguments: 1: A list of set elements
    424 # Returns:   Returns the newly created set
    425 # ----------------------------------------------------------------------------
    426 set_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 # ----------------------------------------------------------------------------
    434 set_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 # ----------------------------------------------------------------------------
    442 set_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 # ----------------------------------------------------------------------------
    450 set_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 # ----------------------------------------------------------------------------
    458 set_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 # ----------------------------------------------------------------------------
    466 set_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 # ----------------------------------------------------------------------------
    474 set_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 # ----------------------------------------------------------------------------
    482 set_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 # ----------------------------------------------------------------------------
    505 int_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 # ----------------------------------------------------------------------------
    512 int_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 # ----------------------------------------------------------------------------
    541 int_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 # ----------------------------------------------------------------------------
    549 plus = $(__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 # ----------------------------------------------------------------------------
    558 int_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 # ----------------------------------------------------------------------------
    569 subtract = $(__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 # ----------------------------------------------------------------------------
    577 int_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 # ----------------------------------------------------------------------------
    585 multiply = $(__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 # ----------------------------------------------------------------------------
    594 int_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 # ----------------------------------------------------------------------------
    605 divide = $(__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 # ----------------------------------------------------------------------------
    614 int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2))
    615 int_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 # ----------------------------------------------------------------------------
    623 max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2)
    624 min = $(__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 # ----------------------------------------------------------------------------
    638 int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
    639                           $(filter-out $(words $2), \
    640                               $(words $(call int_max,$1,$2))))
    641 int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
    642                            $(call int_gt,$1,$2)$(call int_eq,$1,$2))
    643 int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
    644                           $(filter-out $(words $1), \
    645                               $(words $(call int_max,$1,$2))))
    646 int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
    647                            $(call int_lt,$1,$2)$(call int_eq,$1,$2))
    648 int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
    649                           $(filter $(words $1),$(words $2)))
    650 int_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 # ----------------------------------------------------------------------------
    665 gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2)
    666 gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2)
    667 lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2)
    668 lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2)
    669 eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2)
    670 ne = $(__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 # ----------------------------------------------------------------------------
    681 int_inc = $(strip $(__gmsl_tr1)$1 x)
    682 
    683 # ----------------------------------------------------------------------------
    684 # Function:  inc
    685 # Arguments: 1: An integer
    686 # Returns:   The argument incremented by 1
    687 # ----------------------------------------------------------------------------
    688 inc = $(__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 # ----------------------------------------------------------------------------
    695 int_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 # ----------------------------------------------------------------------------
    704 dec = $(__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 # ----------------------------------------------------------------------------
    713 int_double = $(strip $(__gmsl_tr1)$1 $1)
    714 
    715 # ----------------------------------------------------------------------------
    716 # Function:  double
    717 # Arguments: 1: An integer
    718 # Returns:   The integer times 2
    719 # ----------------------------------------------------------------------------
    720 double = $(__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 # ----------------------------------------------------------------------------
    727 int_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 # ----------------------------------------------------------------------------
    735 halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1)
    736 
    737 ifdef __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 # ----------------------------------------------------------------------------
    749 set = $(__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 # ----------------------------------------------------------------------------
    757 get = $(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 # ----------------------------------------------------------------------------
    765 keys = $(__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 # ----------------------------------------------------------------------------
    774 defined = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(call sne,$(call get,$1,$2),)
    775 
    776 endif # __gmsl_have_eval
    777 
    778 ifdef __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 # ----------------------------------------------------------------------------
    790 push = $(__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 # ----------------------------------------------------------------------------
    798 pop = $(__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 # ----------------------------------------------------------------------------
    807 peek = $(__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 # ----------------------------------------------------------------------------
    814 depth = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(words $(__gmsl_stack_$1))
    815 
    816 endif # __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 # ----------------------------------------------------------------------------
    830 gmsl-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 # ----------------------------------------------------------------------------
    838 assert = $(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 # ----------------------------------------------------------------------------
    846 assert_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 # ----------------------------------------------------------------------------
    854 assert_no_dollar = $(call assert,$(call not,$(findstring $$,$2)),$1 called with a dollar sign in argument)
    855