]> git.cryptolib.org Git - arm-crypto-lib.git/blob - __gmsl
added arcfour/rc4
[arm-crypto-lib.git] / __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 9
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 # See if we have $(lastword) (GNU Make 3.81 and above)
83
84 __gmsl_have_lastword := $(lastword $(false) $(true))
85
86 # See if we have native or and and (GNU Make 3.81 and above)
87
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)))
92
93 ifneq ($(__gmsl_have_eval),$(true))
94 $(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$(eval): some functions disabled)
95 endif
96
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))),               \
105         $(false),                                                         \
106         $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))),           \
107             $(true),                                                      \
108             $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))),       \
109                 $(false),                                                 \
110                 $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))),   \
111                     $(true),                                              \
112                     $(call lte,$(word 3,$1),$(word 3,$(gmsl_version))))))))
113
114 # ###########################################################################
115 # LOGICAL OPERATORS
116 # ###########################################################################
117
118 # not is defined in gmsl
119
120 # ----------------------------------------------------------------------------
121 # Function:  and
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))
127 endif
128
129 # ----------------------------------------------------------------------------
130 # Function:  or
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))
136 endif
137
138 # ----------------------------------------------------------------------------
139 # Function:  xor
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)))
144
145 # ----------------------------------------------------------------------------
146 # Function:  nand
147 # Arguments: Two boolean values
148 # Returns:   Returns value of 'not and'
149 # ----------------------------------------------------------------------------
150 nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true))
151
152 # ----------------------------------------------------------------------------
153 # Function:  nor
154 # Arguments: Two boolean values
155 # Returns:   Returns value of 'not or'
156 # ----------------------------------------------------------------------------
157 nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true))
158
159 # ----------------------------------------------------------------------------
160 # Function:  xnor
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)))
165
166 # ###########################################################################
167 # LIST MANIPULATION FUNCTIONS
168 # ###########################################################################
169
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)
176
177 # ----------------------------------------------------------------------------
178 # Function:  last
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)
184 else
185 last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1))
186 endif
187
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)
194
195 # ----------------------------------------------------------------------------
196 # Function:  chop
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)
201
202 # ----------------------------------------------------------------------------
203 # Function:  map
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)))
209
210 # ----------------------------------------------------------------------------
211 # Function:  pairmap
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))))
220
221 # ----------------------------------------------------------------------------
222 # Function:  leq
223 # Arguments: 1: A list to compare against...
224 #            2: ...this list
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)))
229
230 __gmsl_list_equal = $(if $(strip $1),                                       \
231                         $(if $(call seq,$(call first,$1),$(call first,$2)), \
232                             $(call __gmsl_list_equal,                       \
233                                 $(call rest,$1),                            \
234                                 $(call rest,$2)),                           \
235                             $(false)),                                      \
236                      $(true))
237
238 # ----------------------------------------------------------------------------
239 # Function:  lne
240 # Arguments: 1: A list to compare against...
241 #            2: ...this list
242 # Returns:   Returns $(true) if the two lists are different
243 # ----------------------------------------------------------------------------
244 lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2))
245
246 # ----------------------------------------------------------------------------
247 # Function:  reverse
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)) \
252                         $(call first,$1)))
253
254 # ----------------------------------------------------------------------------
255 # Function:  uniq
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))))
261
262 # ----------------------------------------------------------------------------
263 # Function:  length
264 # Arguments: 1: A list
265 # Returns:   The number of elements in the list
266 # ----------------------------------------------------------------------------
267 length = $(__gmsl_tr1)$(words $1)
268
269 # ###########################################################################
270 # STRING MANIPULATION FUNCTIONS
271 # ###########################################################################
272
273 # Helper function that translates any GNU Make 'true' value (i.e. a
274 # non-empty string) to our $(true)
275
276 __gmsl_make_bool = $(if $(strip $1),$(true),$(false))
277
278 # ----------------------------------------------------------------------------
279 # Function:  seq
280 # Arguments: 1: A string to compare against...
281 #            2: ...this string
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))
285
286 # ----------------------------------------------------------------------------
287 # Function:  sne
288 # Arguments: 1: A string to compare against...
289 #            2: ...this string
290 # Returns:   Returns $(true) if the two strings are not the same
291 # ----------------------------------------------------------------------------
292 sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2))
293
294 # ----------------------------------------------------------------------------
295 # Function:  split
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))
302
303 # ----------------------------------------------------------------------------
304 # Function:  merge
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)))))
313
314 ifdef __gmsl_have_eval
315 # ----------------------------------------------------------------------------
316 # Function:  tr
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)                          \
323      $(foreach c,                                                         \
324          $(join $(addsuffix :,$1),$2),                                    \
325          $(eval __gmsl_t :=                                               \
326              $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \
327                  $(__gmsl_t))))$(__gmsl_t))
328
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.
332
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 #
337
338 # ----------------------------------------------------------------------------
339 # Function:  uc
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)
344
345 # ----------------------------------------------------------------------------
346 # Function:  lc
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)
351
352 # ----------------------------------------------------------------------------
353 # Function:  strlen
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 += { } [ ] \ : ; ' " < > , . / ? |
362
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.
369
370 # This results in __gmsl_space containing just a space
371
372 __gmsl_space := 
373 __gmsl_space +=
374
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)))
376
377 # This results in __gmsl_newline containing just a newline
378
379 define __gmsl_newline
380
381
382 endef
383
384 # This results in __gmsl_tab containing a tab
385
386 __gmsl_tab :=   #
387
388 # ----------------------------------------------------------------------------
389 # Function:  substr
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 # ----------------------------------------------------------------------------
396
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)))
398
399 endif # __gmsl_have_eval
400
401 # ###########################################################################
402 # SET MANIPULATION FUNCTIONS
403 # ###########################################################################
404
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
408
409 # This is the empty set
410 empty_set := 
411
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)
418
419 # ----------------------------------------------------------------------------
420 # Function:  set_insert
421 # Arguments: 1: A single element to add to a set
422 #            2: A set
423 # Returns:   Returns the set with the element added
424 # ----------------------------------------------------------------------------
425 set_insert = $(__gmsl_tr2)$(sort $1 $2)
426
427 # ----------------------------------------------------------------------------
428 # Function:  set_remove
429 # Arguments: 1: A single element to remove from a set
430 #            2: A set
431 # Returns:   Returns the set with the element removed
432 # ----------------------------------------------------------------------------
433 set_remove = $(__gmsl_tr2)$(filter-out $1,$2)
434
435 # ----------------------------------------------------------------------------
436 # Function:  set_is_member
437 # Arguments: 1: A single element 
438 #            2: A set
439 # Returns:   Returns $(true) if the element is in the set
440 # ----------------------------------------------------------------------------
441 set_is_member = $(if $(filter $1,$2),$(true),$(false))
442
443 # ----------------------------------------------------------------------------
444 # Function:  set_union
445 # Arguments: 1: A set
446 #            2: Another set
447 # Returns:   Returns the union of the two sets
448 # ----------------------------------------------------------------------------
449 set_union = $(sort $1 $2)
450
451 # ----------------------------------------------------------------------------
452 # Function:  set_intersection
453 # Arguments: 1: A set
454 #            2: Another set
455 # Returns:   Returns the intersection of the two sets
456 # ----------------------------------------------------------------------------
457 set_intersection = $(filter $1,$2)
458
459 # ----------------------------------------------------------------------------
460 # Function:  set_is_subset
461 # Arguments: 1: A set
462 #            2: Another 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)
466
467 # ----------------------------------------------------------------------------
468 # Function:  set_equal
469 # Arguments: 1: A set
470 #            2: Another set
471 # Returns:   Returns $(true) if the two sets are identical
472 # ----------------------------------------------------------------------------
473 set_equal = $(call seq,$1,$2)
474
475 # ###########################################################################
476 # ARITHMETIC LIBRARY
477 # ###########################################################################
478
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
482 # here as 65536
483
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)))))
489
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)
497
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))
504
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:
509 #
510 # plus        Called with integer arguments and returns an integer
511 # int_plus    Called with encoded arguments and returns an encoded result
512 #
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.
518
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
521 # result
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))
525
526 # ----------------------------------------------------------------------------
527 # Function:  int_plus
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)
533
534 # ----------------------------------------------------------------------------
535 # Function:  plus (wrapped version of int_plus)
536 # Arguments: 1: An integer
537 #            2: Another integer
538 # Returns:   Returns the sum of the two integers
539 # ----------------------------------------------------------------------------
540 plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2)
541
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)))
552
553 # ----------------------------------------------------------------------------
554 # Function:  subtract (wrapped version of int_subtract)
555 # Arguments: 1: An integer
556 #            2: Another 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)
561
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))
569
570 # ----------------------------------------------------------------------------
571 # Function:  multiply (wrapped version of int_multiply)
572 # Arguments: 1: An integer
573 #            2: Another integer
574 # Returns:   Returns the product of the two integers
575 # ----------------------------------------------------------------------------
576 multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2)
577
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)))
589
590 # ----------------------------------------------------------------------------
591 # Function:  divide (wrapped version of int_divide)
592 # Arguments: 1: An integer
593 #            2: Another 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)
597
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
603 #            representation
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)))
607
608 # ----------------------------------------------------------------------------
609 # Function:  max, min
610 # Arguments: 1: An integer
611 #            2: Another 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)
616
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)
621 #
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)))
643
644 # ----------------------------------------------------------------------------
645 # Function: gt, gte, lt, lte, eq, ne
646 # Arguments: Two integers to be compared
647 # Returns:   $(true) or $(false)
648 #
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)
662
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
666
667 # ----------------------------------------------------------------------------
668 # Function:  int_inc
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)
673
674 # ----------------------------------------------------------------------------
675 # Function:  inc
676 # Arguments: 1: An integer
677 # Returns:   The argument incremented by 1
678 # ----------------------------------------------------------------------------
679 inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1)
680
681 # ----------------------------------------------------------------------------
682 # Function:  int_dec
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)))
689
690 # ----------------------------------------------------------------------------
691 # Function:  dec
692 # Arguments: 1: An integer
693 # Returns:   The argument decremented by 1
694 # ----------------------------------------------------------------------------
695 dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1)
696
697 # double doubles its argument, and halve halves it
698
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)
705
706 # ----------------------------------------------------------------------------
707 # Function:  double
708 # Arguments: 1: An integer
709 # Returns:   The integer times 2
710 # ----------------------------------------------------------------------------
711 double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1)
712
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)))))
720
721 # ----------------------------------------------------------------------------
722 # Function:  halve
723 # Arguments: 1: An integer
724 # Returns:   The integer divided by 2
725 # ----------------------------------------------------------------------------
726 halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1)
727
728 ifdef __gmsl_have_eval
729 # ###########################################################################
730 # ASSOCIATIVE ARRAYS
731 # ###########################################################################
732
733 # ----------------------------------------------------------------------------
734 # Function:  set
735 # Arguments: 1: Name of associative array
736 #            2: The key value to associate
737 #            3: The value associated with the key
738 # Returns:   None
739 # ----------------------------------------------------------------------------
740 set = $(__gmsl_tr3)$(eval __gmsl_aa_$1_$2 = $3)
741
742 # ----------------------------------------------------------------------------
743 # Function:  get
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)), \
749     $(__gmsl_aa_$1_$2)))
750
751 # ----------------------------------------------------------------------------
752 # Function:  keys
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))))
758
759 # ----------------------------------------------------------------------------
760 # Function:  defined
761 # Arguments: 1: Name of associative array
762 #            2: The key to test
763 # Returns:   Returns true if the key is defined (i.e. not empty)
764 # ----------------------------------------------------------------------------
765 defined = $(__gmsl_tr2)$(call sne,$(call get,$1,$2),)
766
767 endif # __gmsl_have_eval
768
769 ifdef __gmsl_have_eval
770 # ###########################################################################
771 # NAMED STACKS
772 # ###########################################################################
773
774 # ----------------------------------------------------------------------------
775 # Function:  push
776 # Arguments: 1: Name of stack
777 #            2: Value to push onto the top of the stack (must not contain
778 #               a space)
779 # Returns:   None
780 # ----------------------------------------------------------------------------
781 push = $(__gmsl_tr2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\
782     $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1)))
783
784 # ----------------------------------------------------------------------------
785 # Function:  pop
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)))))
792
793 # ----------------------------------------------------------------------------
794 # Function:  peek
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))
799
800 # ----------------------------------------------------------------------------
801 # Function:  depth
802 # Arguments: 1: Name of stack
803 # Returns:   Number of items on the stack
804 # ----------------------------------------------------------------------------
805 depth = $(__gmsl_tr1)$(words $(__gmsl_stack_$1))
806
807 endif # __gmsl_have_eval
808
809 # ###########################################################################
810 # DEBUGGING FACILITIES
811 # ###########################################################################
812
813 # ----------------------------------------------------------------------------
814 # Target:    gmsl-print-%
815 # Arguments: The % should be replaced by the name of a variable that you
816 #            wish to print out.
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
819 #            the SHELL variable
820 # ----------------------------------------------------------------------------
821 gmsl-print-%: ; @echo $* = $($*)
822
823 # ----------------------------------------------------------------------------
824 # Function:  assert
825 # Arguments: 1: A boolean that must be true or the assertion will fail
826 #            2: The message to print with the assertion
827 # Returns:   None
828 # ----------------------------------------------------------------------------
829 assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2))
830
831 # ----------------------------------------------------------------------------
832 # Function:  assert_exists
833 # Arguments: 1: Name of file that must exist, if it is missing an assertion
834 #               will be generated
835 # Returns:   None
836 # ----------------------------------------------------------------------------
837 assert_exists = $(call assert,$(wildcard $1),file '$1' missing)