├── LICENSE ├── Makefile ├── README ├── __gmsl ├── changelog.md ├── gmsl ├── gmsl-tests └── index.html /LICENSE: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions 3 | are met: 4 | 5 | Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | 8 | Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 12 | Neither the name of the John Graham-Cumming nor the names of its 13 | contributors may be used to endorse or promote products derived from 14 | this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include gmsl 2 | 3 | GMSL_VERSION := $(subst $(__gmsl_space),.,$(gmsl_version)) 4 | PACKAGE := gmsl-$(GMSL_VERSION) 5 | TAR := $(PACKAGE).tar.gz 6 | .PHONY: package 7 | package: $(TAR) 8 | 9 | $(TAR): gmsl __gmsl gmsl-tests README index.html changelog.md 10 | @echo Making $@ 11 | @rm -rf $(PACKAGE) 12 | @mkdir $(PACKAGE) 13 | @cp $^ $(PACKAGE) 14 | @tar -c -z -f $@ $(PACKAGE) 15 | @rm -rf $(PACKAGE) 16 | 17 | .PHONY: test 18 | test: 19 | @$(MAKE) --no-print-directory -f gmsl-tests 20 | @$(MAKE) --no-print-directory -f gmsl-tests EXPORT_ALL=1 21 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | GNU Make Standard Library 2 | ------------------------- 3 | 4 | 1. Visit https://gmsl.jgc.org/ for more details 5 | 6 | 2. To use the GMSL in your Makefile make sure that you have the files 7 | 8 | gmsl 9 | __gmsl 10 | 11 | Add 12 | 13 | include gmsl 14 | 15 | to your Makefile(s). 16 | 17 | 3. To run the GMSL test suite have 18 | 19 | gmsl 20 | __gmsl 21 | gmsl-tests 22 | 23 | And then run 24 | 25 | make test 26 | -------------------------------------------------------------------------------- /__gmsl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgrahamc/gmsl/5e512fbb9c0c129fcd9398d13299669b24d59e06/__gmsl -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # 2025-02-05 v1.2.3 released 2 | 3 | Added fold function 4 | 5 | # 2024-03-30 v1.2.2 released 6 | 7 | Make the strlen and substr functions work with strings containing 8 | $ and # and no longer require $(eval). 9 | 10 | # 2024-03-28 v1.2.1 released 11 | 12 | Make the tr, uc and lc functions work with strings containing 13 | $ and # and allowed the use of : in character substitution in tr. 14 | 15 | # 2022-10-09 v1.2.0 released 16 | 17 | Moved from SourceForge to GitHub and made a release. Functionally the 18 | same as v1.1.9. 19 | 20 | # 2020-04-03 v1.1.9 released 21 | 22 | This version contains a new `gmsl-echo-%` function, fixed 23 | detection of native `and` and `or` and compatibility with GNU Make 24 | 4.3 25 | 26 | # 2018-05-17 v1.1.8 Released 27 | 28 | This release contains an improved `divide` function and a new `modulo` 29 | function. 30 | 31 | # 2014-12-22 v1.1.7 Released 32 | 33 | `set_is_not_member` is the opposite of `set_is_member` and was 34 | added as a convenience for a GMSL user. 35 | 36 | # 2014-04-07 v1.1.5 Released 37 | 38 | Adds decimal to other base conversion functions: `dec2hex`, `dec2bin` 39 | and `dec2oct`. 40 | 41 | # 2014-04-02 v1.1.4 released 42 | 43 | This fixes issue #15 (incompatibility with .EXPORT_ALL_VARIABLES) 44 | 45 | # 2012-03-09 v1.1.3 Released 46 | 47 | GMSL is now compatible with GNU make 3.82. The `uniq` function has 48 | been updated to use a simpler implementation. 49 | 50 | # Prior to v1.1.3 the following appeared in the CVS commit log 51 | 52 | 2013-01-22: Make the `sequence` function work in both directions. 53 | 54 | `$(call sequence,1,5) -> 1 2 3 4 5` 55 | `$(call sequence,5,1) -> 5 4 3 2 1` 56 | 57 | 2013-01-22: Fix bug #12. set function no longer returns a value. 58 | 59 | When the `memoize` function was added the `set` function was changed 60 | to return a value. This causes breakages where `set` is used without 61 | consuming the return value because GNU Make will attempt to parse 62 | the return value. 63 | 64 | Restore `set` to the previous functionality where it did not return 65 | any value and add a wrapper function `__gmsl_set` that does return a 66 | value (and calls `set`) which is used by `memoize`. 67 | 68 | 2012-10-11: Better support for Electric Cloud's emake and Mac OS X 69 | 70 | Electric Cloud's emake did not originally support $(eval), but 71 | that has changed with recent versions. This version of GMSL 72 | detects emake and checks the version number so that with recent 73 | versions of emake all GMSL functions are available. 74 | 75 | It was not possible to run the test suite on Mac OS X because the 76 | md5sum utility does not exist there (it's called md5 instead). Now 77 | the test suite detects whether md5 or md5sum is available. 78 | 79 | 2012-05-09: Bump version number in documentation 80 | 81 | 2012-05-09: Added a new `memoize` function that's used to wrap 82 | potentially slow, repeated function calls 83 | 84 | 2012-05-04: Bump the version number to 1.1.0 85 | 86 | 2012-03-09: Make upload work with new SF structure 87 | 88 | 2010-09-07: Bump version number for 1.0.12 89 | 90 | 2008-05-21: Add test for Electric Cloud's emake which has 91 | incomplete upport 92 | 93 | 2007-11-09: Fix bug 1828923 94 | 95 | 2007-04-10: Added the `strlen` function 96 | 97 | 2006-11-03: Fix two small bugs: one in the test suite so that is 98 | checks the version number correctly and the definition of 99 | `__gmsl_sixteen` was incorrect 100 | 101 | 2006-03-10: Change license from GPL to BSD; this is done to make 102 | it easier for people to include GMSL in their Makefiles 103 | 104 | 2006-01-31: Update documentation for `set_remove` 105 | 106 | 2005-11-29: Add set handling functions, tests and documentation 107 | 108 | 2005-11-25: Clean up HTML. Correct error in version number in 109 | documentation 110 | 111 | 2005-10-28: Update documentation for logical operators 112 | 113 | 2005-09-28: Update documentation for `uniq` function 114 | 115 | 2005-02-08: Add link to discussion forum 116 | 117 | 2005-02-04: Add logo 118 | 119 | # 2005-02-03 First release 120 | 121 | The first release (v1.0.0) of the GMSL is available. 122 | -------------------------------------------------------------------------------- /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-2025 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 | # Determine if the library has already been included and if so don't 43 | # bother including it again 44 | 45 | ifndef __gmsl_included 46 | 47 | # Standard definitions for true and false. true is any non-empty 48 | # string, false is an empty string. These are intended for use with 49 | # $(if). 50 | 51 | true := T 52 | false := 53 | 54 | # ---------------------------------------------------------------------------- 55 | # Function: not 56 | # Arguments: 1: A boolean value 57 | # Returns: Returns the opposite of the arg. (true -> false, false -> true) 58 | # ---------------------------------------------------------------------------- 59 | not = $(if $1,$(false),$(true)) 60 | 61 | # Prevent reinclusion of the library 62 | 63 | __gmsl_included := $(true) 64 | 65 | # Try to determine where this file is located. If the caller did 66 | # include /foo/gmsl then extract the /foo/ so that __gmsl gets 67 | # included transparently 68 | 69 | __gmsl_root := 70 | 71 | ifneq ($(MAKEFILE_LIST),) 72 | __gmsl_root := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) 73 | 74 | # If there are any spaces in the path in __gmsl_root then give up 75 | 76 | ifeq (1,$(words $(__gmsl_root))) 77 | __gmsl_root := $(patsubst %gmsl,%,$(__gmsl_root)) 78 | endif 79 | 80 | endif 81 | 82 | include $(__gmsl_root)__gmsl 83 | 84 | endif # __gmsl_included 85 | 86 | -------------------------------------------------------------------------------- /gmsl-tests: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # 3 | # GNU Make Standard Library (GMSL) Test Suite 4 | # 5 | # Test suite for the GMSL 6 | # 7 | # Copyright (c) 2005-2025 John Graham-Cumming 8 | # 9 | # This file is part of GMSL 10 | # 11 | # Redistribution and use in source and binary forms, with or without 12 | # modification, are permitted provided that the following conditions 13 | # are met: 14 | # 15 | # Redistributions of source code must retain the above copyright 16 | # notice, this list of conditions and the following disclaimer. 17 | # 18 | # Redistributions in binary form must reproduce the above copyright 19 | # notice, this list of conditions and the following disclaimer in the 20 | # documentation and/or other materials provided with the distribution. 21 | # 22 | # Neither the name of the John Graham-Cumming nor the names of its 23 | # contributors may be used to endorse or promote products derived from 24 | # this software without specific prior written permission. 25 | # 26 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 29 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 30 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 31 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 32 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 33 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 34 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 36 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | # POSSIBILITY OF SUCH DAMAGE. 38 | # 39 | # ---------------------------------------------------------------------------- 40 | 41 | ifdef EXPORT_ALL 42 | .EXPORT_ALL_VARIABLES: 43 | endif 44 | 45 | .PHONY: all 46 | all: 47 | @echo 48 | @echo Test Summary 49 | @echo ------------ 50 | @echo "$(call int_decode,$(passed)) tests passed; $(call int_decode,$(failed)) tests failed" 51 | 52 | include gmsl 53 | 54 | passed := 55 | failed := 56 | 57 | ECHO := /bin/echo 58 | 59 | start_test = $(if $0,$(shell $(ECHO) -n "Testing '$1': " >&2))$(eval current_test := OK) 60 | stop_test = $(if $0,$(shell $(ECHO) " $(current_test)" >&2)) 61 | test_pass = .$(eval passed := $(call int_inc,$(passed))) 62 | test_fail = X$(eval failed := $(call int_inc,$(failed)))$(eval current_test := ERROR '$1' != '$2') 63 | test_assert = $(if $0,$(if $(filter undefined,$(origin 2)),$(eval 2 :=))$(shell $(ECHO) -n $(if $(call seq,$1,$2),$(call test_pass,$1,$2),$(call test_fail,$1,$2)) >&2)) 64 | 65 | $(call start_test,not) 66 | $(call test_assert,$(call not,$(true)),$(false)) 67 | $(call test_assert,$(call not,$(false)),$(true)) 68 | $(call stop_test) 69 | 70 | $(call start_test,or) 71 | $(call test_assert,$(call or,$(true),$(true)),$(true)) 72 | $(call test_assert,$(call or,$(true),$(false)),$(true)) 73 | $(call test_assert,$(call or,$(false),$(true)),$(true)) 74 | $(call test_assert,$(call or,$(false),$(false)),$(false)) 75 | $(call stop_test) 76 | 77 | $(call start_test,and) 78 | $(call test_assert,$(call and,$(true),$(true)),$(true)) 79 | $(call test_assert,$(call and,$(true),$(false)),$(false)) 80 | $(call test_assert,$(call and,$(false),$(true)),$(false)) 81 | $(call test_assert,$(call and,$(false),$(false)),$(false)) 82 | $(call stop_test) 83 | 84 | $(call start_test,xor) 85 | $(call test_assert,$(call xor,$(true),$(true)),$(false)) 86 | $(call test_assert,$(call xor,$(true),$(false)),$(true)) 87 | $(call test_assert,$(call xor,$(false),$(true)),$(true)) 88 | $(call test_assert,$(call xor,$(false),$(false)),$(false)) 89 | $(call stop_test) 90 | 91 | $(call start_test,nand) 92 | $(call test_assert,$(call nand,$(true),$(true)),$(false)) 93 | $(call test_assert,$(call nand,$(true),$(false)),$(true)) 94 | $(call test_assert,$(call nand,$(false),$(true)),$(true)) 95 | $(call test_assert,$(call nand,$(false),$(false)),$(true)) 96 | $(call stop_test) 97 | 98 | $(call start_test,nor) 99 | $(call test_assert,$(call nor,$(true),$(true)),$(false)) 100 | $(call test_assert,$(call nor,$(true),$(false)),$(false)) 101 | $(call test_assert,$(call nor,$(false),$(true)),$(false)) 102 | $(call test_assert,$(call nor,$(false),$(false)),$(true)) 103 | $(call stop_test) 104 | 105 | $(call start_test,xnor) 106 | $(call test_assert,$(call xnor,$(true),$(true)),$(true)) 107 | $(call test_assert,$(call xnor,$(true),$(false)),$(false)) 108 | $(call test_assert,$(call xnor,$(false),$(true)),$(false)) 109 | $(call test_assert,$(call xnor,$(false),$(false)),$(true)) 110 | $(call stop_test) 111 | 112 | $(call start_test,first) 113 | $(call test_assert,$(call first,1 2 3),1) 114 | $(call test_assert,$(call first,1),1) 115 | $(call test_assert,$(call first,),) 116 | $(call stop_test) 117 | 118 | $(call start_test,last) 119 | $(call test_assert,$(call last,1 2 3),3) 120 | $(call test_assert,$(call last,1),1) 121 | $(call test_assert,$(call last,),) 122 | $(call stop_test) 123 | 124 | $(call start_test,rest) 125 | $(call test_assert,$(call rest,1 2 3),2 3) 126 | $(call test_assert,$(call rest,1),) 127 | $(call test_assert,$(call rest,),) 128 | $(call stop_test) 129 | 130 | $(call start_test,chop) 131 | $(call test_assert,$(call chop,1 2 3),1 2) 132 | $(call test_assert,$(call chop,1 2 3 4),1 2 3) 133 | $(call test_assert,$(call chop,1),) 134 | $(call test_assert,$(call chop,),) 135 | $(call stop_test) 136 | 137 | $(call start_test,length) 138 | $(call test_assert,$(call length,1 2 3),3) 139 | $(call test_assert,$(call length,1 2 3 4),4) 140 | $(call test_assert,$(call length,1),1) 141 | $(call test_assert,$(call length,),0) 142 | $(call stop_test) 143 | 144 | $(call start_test,map) 145 | $(call test_assert,$(call map,origin,__undefined map MAKE),undefined file default) 146 | $(call test_assert,$(call map,origin,),) 147 | $(call stop_test) 148 | 149 | FOLD_LIST = 1 1 2 3 5 150 | $(call start_test,fold) 151 | $(call test_assert,$(call fold,plus,$(FOLD_LIST)),12) 152 | $(call test_assert,$(call fold,plus,$(FOLD_LIST),0),12) 153 | $(call test_assert,$(call fold,plus,$(FOLD_LIST),1),13) 154 | $(call test_assert,$(call fold,multiply,$(FOLD_LIST)),0) 155 | $(call test_assert,$(call fold,multiply,$(FOLD_LIST),0),0) 156 | $(call test_assert,$(call fold,multiply,$(FOLD_LIST),1),30) 157 | $(call test_assert,$(call fold,multiply,$(FOLD_LIST),2),60) 158 | $(call stop_test) 159 | 160 | joinem = $1$2 161 | $(call start_test,pairmap) 162 | $(call test_assert,$(call pairmap,addsuffix,2 1 3,a b c),a2 b1 c3) 163 | $(call test_assert,$(call pairmap,addprefix,2 1 3,a b c d),2a 1b 3c d) 164 | $(call test_assert,$(call pairmap,addprefix,2 1 3 4,a b c),2a 1b 3c) 165 | $(call test_assert,$(call pairmap,joinem,2 1 3 4,a b c),2a 1b 3c 4) 166 | $(call stop_test) 167 | 168 | $(call start_test,seq) 169 | $(call test_assert,$(call seq,abc,abc),T) 170 | $(call test_assert,$(call seq,x,),) 171 | $(call test_assert,$(call seq,,x),) 172 | $(call test_assert,$(call seq,x,x),T) 173 | $(call test_assert,$(call seq,a%c,abc),) 174 | $(call test_assert,$(call seq,abc,a%c),) 175 | $(call test_assert,$(call seq,abc,ABC),) 176 | $(call test_assert,$(call seq,abc,),) 177 | $(call test_assert,$(call seq,,),T) 178 | $(call test_assert,$(call seq,a b c,a b c),T) 179 | $(call test_assert,$(call seq,aa% bb% cc,aa% bb% cc),T) 180 | $(call test_assert,$(call seq,aa% bb% cc,aa% bb cc),) 181 | $(call test_assert,$(call seq,aa% bb% cc,xx yy zz),) 182 | $(call test_assert,$(call seq,x x,),) 183 | $(call test_assert,$(call seq, xx x,x xx),) 184 | $(call test_assert,$(call seq, x xx,x xx),) 185 | $(call test_assert,$(call seq,$(__gmsl_space)x xx,x xx),) 186 | $(call test_assert,$(call seq, , ),) 187 | $(call test_assert,$(call seq, , ),) 188 | $(call test_assert,$(call seq, , ),) 189 | $(call test_assert,$(call seq, , ),) 190 | $(call test_assert,$(call seq, , ),) 191 | $(call test_assert,$(call seq, , ),T) 192 | $(call test_assert,$(call seq,, ),) 193 | $(call test_assert,$(call seq, ,),) 194 | $(call test_assert,$(call seq,y,xy),) 195 | $(call test_assert,$(call seq,$(__gmsl_space),$(__gmsl_tab)),) 196 | $(call test_assert,$(call seq, $(__gmsl_space) , $(__gmsl_space) ),T) 197 | $(call test_assert,$(call seq,$(__gmsl_tab),$(__gmsl_tab)),T) 198 | $(call test_assert,$(call seq,yy,yyyy),) 199 | $(call test_assert,$(call seq,yyyy,yy),) 200 | $(call stop_test) 201 | 202 | $(call start_test,sne) 203 | $(call test_assert,$(call sne,abc,abc),) 204 | $(call test_assert,$(call sne,x,),T) 205 | $(call test_assert,$(call sne,,x),T) 206 | $(call test_assert,$(call sne,x,x),) 207 | $(call test_assert,$(call sne,abc,ABC),T) 208 | $(call test_assert,$(call sne,abc,),T) 209 | $(call test_assert,$(call sne,,),) 210 | $(call test_assert,$(call sne,a b c,a b c),) 211 | $(call test_assert,$(call sne,aa% bb% cc,aa% bb% cc),) 212 | $(call test_assert,$(call sne,aa% bb% cc,aa% bb cc),T) 213 | $(call stop_test) 214 | 215 | $(call start_test,strlen) 216 | $(call test_assert,$(call strlen,),0) 217 | $(call test_assert,$(call strlen,a),1) 218 | $(call test_assert,$(call strlen,a b),3) 219 | $(call test_assert,$(call strlen,a ),2) 220 | $(call test_assert,$(call strlen, a),2) 221 | $(call test_assert,$(call strlen, ),2) 222 | $(call test_assert,$(call strlen, ),3) 223 | $(call test_assert,$(call strlen, ),4) 224 | $(call test_assert,$(call strlen, ),3) 225 | $(call test_assert,$(call strlen,$$),1) 226 | $(call test_assert,$(call strlen,$$#$$),3) 227 | $(call stop_test) 228 | 229 | $(call start_test,substr) 230 | $(call test_assert,$(call substr,xyz,1,1),x) 231 | $(call test_assert,$(call substr,xyz,1,2),xy) 232 | $(call test_assert,$(call substr,xyz,2,3),yz) 233 | $(call test_assert,$(call substr,some string,1,1),s) 234 | $(call test_assert,$(call substr,some string,1,2),so) 235 | $(call test_assert,$(call substr,some string,1,3),som) 236 | $(call test_assert,$(call substr,some string,1,4),some) 237 | $(call test_assert,$(call substr,some string,1,5),some ) 238 | $(call test_assert,$(call substr,some string,1,6),some s) 239 | $(call test_assert,$(call substr,some string,5,5), ) 240 | $(call test_assert,$(call substr,some string,5,6), s) 241 | $(call test_assert,$(call substr,some string,5,7), st) 242 | $(call test_assert,$(call substr,some string,5,8), str) 243 | $(call test_assert,$(call substr,some string,1,100),some string) 244 | $(call test_assert,$(call substr,some $$trng,6,9),$$trn) 245 | $(call test_assert,$(call substr,some #trng,5,8), #tr) 246 | $(call stop_test) 247 | 248 | $(call start_test,lc) 249 | $(call test_assert,$(call lc,The Quick Brown Fox),the quick brown fox) 250 | $(call test_assert,$(call lc,the1 quick2 brown3 fox4),the1 quick2 brown3 fox4) 251 | $(call test_assert,$(call lc,The_),the_) 252 | $(call test_assert,$(call lc,),) 253 | $(call test_assert,$(call lc,12 # 56 $$ ab $$a HE $$$$ mo),12 # 56 $$ ab $$a he $$$$ mo) 254 | $(call stop_test) 255 | 256 | $(call start_test,uc) 257 | $(call test_assert,$(call uc,The Quick Brown Fox),THE QUICK BROWN FOX) 258 | $(call test_assert,$(call uc,the1 quick2 brown3 fox4),THE1 QUICK2 BROWN3 FOX4) 259 | $(call test_assert,$(call uc,The_),THE_) 260 | $(call test_assert,$(call uc,),) 261 | $(call test_assert,$(call uc,12 # 56 $$ ab $$a HE $$$$ mo),12 # 56 $$ AB $$A HE $$$$ MO) 262 | $(call stop_test) 263 | 264 | $(call start_test,tr) 265 | $(call test_assert,$(call tr,A B C,1 2 3,CAPITAL),31PIT1L) 266 | $(call test_assert,$(call tr,a b c,1 2 3,CAPITAL),CAPITAL) 267 | $(call test_assert,$(call tr,: B C,1 2 3,C:PITAL),31PITAL) 268 | $(call test_assert,$(call tr,E L I,3 1 1,I AM ELITE),1 AM 311T3) 269 | $(call test_assert,$(call tr,E L I $$,3 1 1 %,I $$AM ELITE),1 %AM 311T3) 270 | $(call test_assert,$(call tr,E L I #,3 1 1 ^,I #AM ELITE),1 ^AM 311T3) 271 | $(call test_assert,$(call tr,$$ #,4 3,12 # 56 $$ AB $$A HE $$$$ MO),12 3 56 4 AB 4A HE 44 MO) 272 | $(call test_assert,$(call tr,$$ #,4 3,12#56$$AB$$AHE$$$$MO#$$),123564AB4AHE44MO34) 273 | $(call stop_test) 274 | 275 | $(call start_test,leq) 276 | $(call test_assert,$(call leq,1 2 3,1 2 3),T) 277 | $(call test_assert,$(call leq,1 2 3,1 2 3 4),) 278 | $(call test_assert,$(call leq,1 2 3 4,1 2 3),) 279 | $(call test_assert,$(call leq,1,1),T) 280 | $(call test_assert,$(call leq,,),T) 281 | $(call stop_test) 282 | 283 | $(call start_test,lne) 284 | $(call test_assert,$(call lne,1 2 3,1 2 3),) 285 | $(call test_assert,$(call lne,1 2 3,1 2 3 4),T) 286 | $(call test_assert,$(call lne,1 2 3 4,1 2 3),T) 287 | $(call test_assert,$(call lne,1,1),) 288 | $(call test_assert,$(call lne,,),) 289 | $(call stop_test) 290 | 291 | $(call start_test,empty_set) 292 | $(call test_assert,$(empty_set),) 293 | $(call test_assert,$(empty_set),$(call set_create,)) 294 | $(call stop_test) 295 | 296 | $(call start_test,set_create) 297 | $(call test_assert,$(call set_create,),) 298 | $(call test_assert,$(call set_create,1 2 2 3),1 2 3) 299 | $(call test_assert,$(call set_create,2 1 1 2 2 3),1 2 3) 300 | $(call test_assert,$(call set_create,1),1) 301 | $(call stop_test) 302 | 303 | $(call start_test,set_insert) 304 | $(call test_assert,$(call set_insert,1,$(empty_set)),1) 305 | $(call test_assert,$(call set_insert,1,$(call set_create,1)),1) 306 | $(call test_assert,$(call set_insert,1,$(call set_create,1 2)),1 2) 307 | $(call test_assert,$(call set_insert,0,$(call set_create,1 2)),0 1 2) 308 | $(call stop_test) 309 | 310 | $(call start_test,set_remove) 311 | $(call test_assert,$(call set_remove,1,$(empty_set)),$(empty_set)) 312 | $(call test_assert,$(call set_remove,1,$(call set_create,1 2)),2) 313 | $(call test_assert,$(call set_remove,1,$(call set_create,1 11 2)),11 2) 314 | $(call test_assert,$(call set_remove,0,$(call set_create,1 2)),1 2) 315 | $(call stop_test) 316 | 317 | $(call start_test,set_is_member) 318 | $(call test_assert,$(call set_is_member,1,$(empty_set)),) 319 | $(call test_assert,$(call set_is_member,1,$(call set_create,2 3)),) 320 | $(call test_assert,$(call set_is_member,1,$(call set_create,1 2 3)),T) 321 | $(call test_assert,$(call set_is_member,1,$(call set_create,1)),T) 322 | $(call stop_test) 323 | 324 | $(call start_test,set_is_not_member) 325 | $(call test_assert,$(call set_is_not_member,1,$(empty_set)),T) 326 | $(call test_assert,$(call set_is_not_member,1,$(call set_create,2 3)),T) 327 | $(call test_assert,$(call set_is_not_member,1,$(call set_create,1 2 3)),) 328 | $(call test_assert,$(call set_is_not_member,1,$(call set_create,1)),) 329 | $(call stop_test) 330 | 331 | $(call start_test,set_union) 332 | $(call test_assert,$(call set_union,,),) 333 | $(call test_assert,$(call set_union,1 2,),1 2) 334 | $(call test_assert,$(call set_union,,3 4),3 4) 335 | $(call test_assert,$(call set_union,1 2,3 4),1 2 3 4) 336 | $(call test_assert,$(call set_union,1 2 3,3 4 5),1 2 3 4 5) 337 | $(call stop_test) 338 | 339 | $(call start_test,set_intersection) 340 | $(call test_assert,$(call set_intersection,,),) 341 | $(call test_assert,$(call set_intersection,1 2,),) 342 | $(call test_assert,$(call set_intersection,,3 4),) 343 | $(call test_assert,$(call set_intersection,1 2,3 4),) 344 | $(call test_assert,$(call set_intersection,1 2 3 4,3 4 5),3 4) 345 | $(call stop_test) 346 | 347 | $(call start_test,set_is_subset) 348 | $(call test_assert,$(call set_is_subset,,),T) 349 | $(call test_assert,$(call set_is_subset,1 2,),) 350 | $(call test_assert,$(call set_is_subset,,3 4),T) 351 | $(call test_assert,$(call set_is_subset,1 2,3 4),) 352 | $(call test_assert,$(call set_is_subset,1 2,1 2 3 4 5),T) 353 | $(call test_assert,$(call set_is_subset,1 2,1 2),T) 354 | $(call test_assert,$(call set_is_subset,1 2,1 3 4 5),) 355 | $(call stop_test) 356 | 357 | $(call start_test,set_equal) 358 | $(call test_assert,$(call set_equal,,),T) 359 | $(call test_assert,$(call set_equal,1,),) 360 | $(call test_assert,$(call set_equal,,1),) 361 | $(call test_assert,$(call set_equal,1,1),T) 362 | $(call test_assert,$(call set_equal,1 2,),) 363 | $(call test_assert,$(call set_equal,,1 2),) 364 | $(call test_assert,$(call set_equal,1 2,1 2 3),) 365 | $(call stop_test) 366 | 367 | $(call start_test,__strip_leading_zero) 368 | $(call test_assert,$(call __strip_leading_zero,),0) 369 | $(call test_assert,$(call __strip_leading_zero,0),0) 370 | $(call test_assert,$(call __strip_leading_zero,0000),0) 371 | $(call test_assert,$(call __strip_leading_zero,1),1) 372 | $(call test_assert,$(call __strip_leading_zero,10),10) 373 | $(call test_assert,$(call __strip_leading_zero,01),1) 374 | $(call test_assert,$(call __strip_leading_zero,001),1) 375 | $(call test_assert,$(call __strip_leading_zero,0010),10) 376 | $(call test_assert,$(call __strip_leading_zero,00000011000),11000) 377 | $(call stop_test) 378 | 379 | $(call start_test,int_encode) 380 | $(call test_assert,$(call int_encode,0),) 381 | $(call test_assert,$(call int_encode,1),x) 382 | $(call test_assert,$(call int_encode,001),x) 383 | $(call test_assert,$(call int_encode,2),x x) 384 | $(call test_assert,$(call int_encode,10),x x x x x x x x x x) 385 | $(call test_assert,$(words $(call int_encode,123)),123) 386 | $(call test_assert,$(words $(call int_encode,1234)),1234) 387 | $(call test_assert,$(words $(call int_encode,12345)),12345) 388 | $(call test_assert,$(words $(call int_encode,012345)),12345) 389 | $(call test_assert,$(words $(call int_encode,1000000)),1000000) 390 | $(call stop_test) 391 | 392 | $(call start_test,int_decode) 393 | $(call test_assert,$(call int_decode,),0) 394 | $(call test_assert,$(call int_decode,x),1) 395 | $(call test_assert,$(call int_decode,x x),2) 396 | $(call test_assert,$(call int_decode,x x x x x x x x x x),10) 397 | $(call stop_test) 398 | 399 | $(call start_test,int_plus) 400 | $(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,7)) 401 | $(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,4)),$(call int_encode,4)) 402 | $(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3)) 403 | $(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0)) 404 | $(call test_assert,$(call int_plus,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1)) 405 | $(call stop_test) 406 | 407 | $(call start_test,plus) 408 | $(call test_assert,$(call plus,3,4),7) 409 | $(call test_assert,$(call plus,4,3),7) 410 | $(call test_assert,$(call plus,0,4),4) 411 | $(call test_assert,$(call plus,3,0),3) 412 | $(call test_assert,$(call plus,03,00),3) 413 | $(call test_assert,$(call plus,0,0),0) 414 | $(call stop_test) 415 | 416 | __gmsl_warning = $1 417 | $(call start_test,int_subtract) 418 | $(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,4)),Subtraction underflow) 419 | $(call test_assert,$(call int_subtract,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1)) 420 | $(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3)) 421 | $(call test_assert,$(call int_subtract,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0)) 422 | $(call test_assert,$(call int_subtract,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1)) 423 | $(call stop_test) 424 | 425 | __gmsl_warning = x x x x x x x x x x 426 | $(call start_test,subtract) 427 | $(call test_assert,$(call subtract,3,4),10) 428 | $(call test_assert,$(call subtract,4,3),1) 429 | $(call test_assert,$(call subtract,3,0),3) 430 | $(call test_assert,$(call subtract,0,0),0) 431 | $(call stop_test) 432 | 433 | $(call start_test,int_multiply) 434 | $(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,12)) 435 | $(call test_assert,$(call int_multiply,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,12)) 436 | $(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,0)) 437 | $(call test_assert,$(call int_multiply,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0)) 438 | $(call test_assert,$(call int_multiply,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,0)) 439 | $(call stop_test) 440 | 441 | $(call start_test,multiply) 442 | $(call test_assert,$(call multiply,3,4),12) 443 | $(call test_assert,$(call multiply,4,3),12) 444 | $(call test_assert,$(call multiply,3,0),0) 445 | $(call test_assert,$(call multiply,0,3),0) 446 | $(call test_assert,$(call multiply,0,0),0) 447 | $(call stop_test) 448 | 449 | __gmsl_error = $1 450 | $(call start_test,int_divide) 451 | $(call test_assert,$(call int_divide,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,0)) 452 | $(call test_assert,$(call int_divide,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1)) 453 | $(call test_assert,$(call int_divide,$(call int_encode,31),$(call int_encode,3)),$(call int_encode,10)) 454 | $(call test_assert,$(call int_divide,$(call int_encode,30),$(call int_encode,3)),$(call int_encode,10)) 455 | $(call test_assert,$(call int_divide,$(call int_encode,29),$(call int_encode,3)),$(call int_encode,9)) 456 | $(call test_assert,$(call int_divide,$(call int_encode,0),$(call int_encode,1)),$(call int_encode,0)) 457 | $(call test_assert,$(call int_divide,$(call int_encode,1),$(call int_encode,0)),Division by zero) 458 | $(call stop_test) 459 | 460 | $(call start_test,int_modulo) 461 | $(call test_assert,$(call int_modulo,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,3)) 462 | $(call test_assert,$(call int_modulo,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1)) 463 | $(call test_assert,$(call int_modulo,$(call int_encode,31),$(call int_encode,3)),$(call int_encode,1)) 464 | $(call test_assert,$(call int_modulo,$(call int_encode,30),$(call int_encode,3)),$(call int_encode,0)) 465 | $(call test_assert,$(call int_modulo,$(call int_encode,29),$(call int_encode,3)),$(call int_encode,2)) 466 | $(call test_assert,$(call int_modulo,$(call int_encode,0),$(call int_encode,1)),$(call int_encode,0)) 467 | $(call test_assert,$(call int_modulo,$(call int_encode,1),$(call int_encode,0)),Division by zero) 468 | $(call stop_test) 469 | 470 | __gmsl_error = $1 471 | $(call start_test,divide) 472 | $(call test_assert,$(call divide,3,4),0) 473 | $(call test_assert,$(call divide,4,3),1) 474 | $(call test_assert,$(call divide,21,2),10) 475 | $(call test_assert,$(call divide,20,2),10) 476 | $(call test_assert,$(call divide,19,2),9) 477 | $(call test_assert,$(call divide,1,0),Division by zero) 478 | $(call stop_test) 479 | 480 | $(call start_test,modulo) 481 | $(call test_assert,$(call modulo,3,4),3) 482 | $(call test_assert,$(call modulo,4,3),1) 483 | $(call test_assert,$(call modulo,21,2),1) 484 | $(call test_assert,$(call modulo,20,2),0) 485 | $(call test_assert,$(call modulo,17,3),2) 486 | $(call test_assert,$(call modulo,1,0),Division by zero) 487 | $(call stop_test) 488 | 489 | 490 | $(call start_test,dec2hex) 491 | $(call test_assert,$(call dec2hex,0),0) 492 | $(call test_assert,$(call dec2hex,1),1) 493 | $(call test_assert,$(call dec2hex,10),a) 494 | $(call test_assert,$(call dec2hex,15),f) 495 | $(call test_assert,$(call dec2hex,254),fe) 496 | $(call test_assert,$(call dec2hex,255),ff) 497 | $(call test_assert,$(call dec2hex,513),201) 498 | $(call stop_test) 499 | 500 | $(call start_test,dec2oct) 501 | $(call test_assert,$(call dec2oct,0),0) 502 | $(call test_assert,$(call dec2oct,1),1) 503 | $(call test_assert,$(call dec2oct,8),10) 504 | $(call test_assert,$(call dec2oct,15),17) 505 | $(call test_assert,$(call dec2oct,1024),2000) 506 | $(call test_assert,$(call dec2oct,1025),2001) 507 | $(call stop_test) 508 | 509 | $(call start_test,dec2bin) 510 | $(call test_assert,$(call dec2bin,0),0) 511 | $(call test_assert,$(call dec2bin,1),1) 512 | $(call test_assert,$(call dec2bin,8),1000) 513 | $(call test_assert,$(call dec2bin,15),1111) 514 | $(call test_assert,$(call dec2bin,1024),10000000000) 515 | $(call test_assert,$(call dec2bin,1025),10000000001) 516 | $(call stop_test) 517 | 518 | $(call start_test,associative array) 519 | $(call test_assert,$(call get,myarray,key1),) 520 | $(call test_assert,$(call set,myarray,key1,value1),) 521 | $(call test_assert,$(call get,myarray,key1),value1) 522 | $(call test_assert,$(call get,myarray,key2),) 523 | $(call test_assert,$(call get,myarray1,key1),) 524 | $(call test_assert,$(call defined,myarray,key1),T) 525 | $(call test_assert,$(call defined,myarray,key2),) 526 | $(call test_assert,$(call defined,myarray1,key1),) 527 | $(call test_assert,$(call set,myarray,key2,value2),) 528 | $(call test_assert,$(call keys,myarray),key1 key2) 529 | $(call test_assert,$(call keys,myarray1),) 530 | $(call test_assert,$(call set,foo,bar_baz,bob),) 531 | $(call test_assert,$(call set,foo_bar,baz,alice),) 532 | $(call test_assert,$(call get,foo,bar_baz),bob) 533 | $(call test_assert,$(call get,foo_bar,baz),alice) 534 | $(call test_assert,$(call set,foo,bar,baz/baz),) 535 | $(call test_assert,$(call get,foo,bar),baz/baz) 536 | $(call test-assert,$(call set,foo,bar-baz,baz),) 537 | $(call test_assert,$(call get,foo,bar-baz),baz) 538 | $(call set,foo,bar-baz,baz) 539 | $(call set,foo,bar,baz/baz) 540 | $(call stop_test) 541 | 542 | $(call start_test,named stack) 543 | $(call test_assert,$(call pop,mystack),) 544 | $(call test_assert,$(call push,mystack,e2)) 545 | $(call push,mystack,e1) 546 | $(call test_assert,$(call pop,mystack),e1) 547 | $(call test_assert,$(call pop,mystack),e2) 548 | $(call push,mystack,f3) 549 | $(call push,mystack,f1) 550 | $(call test_assert,$(call pop,mystack),f1) 551 | $(call push,mystack,f2) 552 | $(call test_assert,$(call peek,mystack),f2) 553 | $(call test_assert,$(call depth,mystack),2) 554 | $(call test_assert,$(call pop,mystack),f2) 555 | $(call test_assert,$(call depth,mystack),1) 556 | $(call test_assert,$(call pop,myotherstack),) 557 | $(call stop_test) 558 | 559 | $(call start_test,reverse) 560 | $(call test_assert,$(call reverse,),) 561 | $(call test_assert,$(call reverse,1),1) 562 | $(call test_assert,$(call reverse,1 2),2 1) 563 | $(call test_assert,$(call reverse,1 2 3),3 2 1) 564 | $(call stop_test) 565 | 566 | $(call start_test,uniq) 567 | $(call test_assert,$(call uniq,),) 568 | $(call test_assert,$(call uniq,a),a) 569 | $(call test_assert,$(call uniq,a a),a) 570 | $(call test_assert,$(call uniq,a aa),a aa) 571 | $(call test_assert,$(call uniq,a aa a),a aa) 572 | $(call test_assert,$(call uniq,a b ba ab b a a ba a),a b ba ab) 573 | $(call stop_test) 574 | 575 | c:=, 576 | $(call start_test,split) 577 | $(call test_assert,$(call split,$c,comma$cseparated$cstring),comma separated string) 578 | $(call test_assert,$(call split,*,star*field*record),star field record) 579 | $(call test_assert,$(call split,*,star*),star) 580 | $(call test_assert,$(call split,*,star*field),star field) 581 | $(call test_assert,$(call split,*,star****field),star field) 582 | $(call test_assert,$(call split,*,),) 583 | $(call stop_test) 584 | 585 | $(call start_test,merge) 586 | $(call test_assert,$(call merge,$c,list of things),list$cof$cthings) 587 | $(call test_assert,$(call merge,*,list of things),list*of*things) 588 | $(call test_assert,$(call merge,*,list),list) 589 | $(call test_assert,$(call merge,*,),) 590 | $(call stop_test) 591 | 592 | $(call start_test,int_max) 593 | $(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,2)) 594 | $(call test_assert,$(call int_max,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,2)) 595 | $(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,2)) 596 | $(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,2)) 597 | $(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2)) 598 | $(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0)) 599 | $(call stop_test) 600 | 601 | $(call start_test,max) 602 | $(call test_assert,$(call max,2,1),2) 603 | $(call test_assert,$(call max,1,2),2) 604 | $(call test_assert,$(call max,2,0),2) 605 | $(call test_assert,$(call max,0,2),2) 606 | $(call test_assert,$(call max,2,2),2) 607 | $(call test_assert,$(call max,0,0),0) 608 | $(call stop_test) 609 | 610 | $(call start_test,int_min) 611 | $(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,1)) 612 | $(call test_assert,$(call int_min,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,1)) 613 | $(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,0)) 614 | $(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,0)) 615 | $(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2)) 616 | $(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0)) 617 | $(call stop_test) 618 | 619 | $(call start_test,min) 620 | $(call test_assert,$(call min,2,1),1) 621 | $(call test_assert,$(call min,1,2),1) 622 | $(call test_assert,$(call min,2,0),0) 623 | $(call test_assert,$(call min,0,2),0) 624 | $(call test_assert,$(call min,2,2),2) 625 | $(call test_assert,$(call min,0,0),0) 626 | $(call stop_test) 627 | 628 | __gmsl_error = $1 629 | $(call start_test,assert functions) 630 | $(call test_assert,$(call assert,$(true),ignore),) 631 | $(call test_assert,$(call assert,$(false),failed),Assertion failure: failed) 632 | $(call test_assert,$(call assert_exists,gmsl-tests),) 633 | $(call test_assert,$(call assert_exists,MISSING-gmsl-tests),Assertion failure: file 'MISSING-gmsl-tests' missing) 634 | $(call test_assert,$(call assert_no_dollar,test,only pounds),) 635 | $(call test_assert,$(call assert_no_dollar,test,only$$dollar),Assertion failure: test called with a dollar sign in argument) 636 | $(call test_assert,$(call assert_no_space,test,nospaces),) 637 | $(call test_assert,$(call assert_no_space,test,has space),Assertion failure: test called with space in argument) 638 | $(call test_assert,$(call assert_no_space,test,has tab),Assertion failure: test called with space in argument) 639 | $(call stop_test) 640 | 641 | $(call start_test,int_inc) 642 | $(call test_assert,$(call int_inc,$(call int_encode,0)),$(call int_encode,1)) 643 | $(call test_assert,$(call int_inc,$(call int_encode,1)),$(call int_encode,2)) 644 | $(call test_assert,$(call int_inc,$(call int_encode,4)),$(call int_encode,5)) 645 | $(call test_assert,$(call int_inc,$(call int_encode,10)),$(call int_encode,11)) 646 | $(call stop_test) 647 | 648 | $(call start_test,inc) 649 | $(call test_assert,$(call inc,0),1) 650 | $(call test_assert,$(call inc,1),2) 651 | $(call test_assert,$(call inc,4),5) 652 | $(call test_assert,$(call inc,10),11) 653 | $(call stop_test) 654 | 655 | __gmsl_warning = $1 656 | $(call start_test,int_dec) 657 | $(call test_assert,$(call int_dec,$(call int_encode,1)),$(call int_encode,0)) 658 | $(call test_assert,$(call int_dec,$(call int_encode,4)),$(call int_encode,3)) 659 | $(call test_assert,$(call int_dec,$(call int_encode,10)),$(call int_encode,9)) 660 | $(call stop_test) 661 | 662 | __gmsl_warning = x x x x x x x x x x 663 | $(call start_test,dec) 664 | $(call test_assert,$(call dec,1),0) 665 | $(call test_assert,$(call dec,4),3) 666 | $(call test_assert,$(call dec,10),9) 667 | $(call stop_test) 668 | 669 | $(call start_test,int_double) 670 | $(call test_assert,$(call int_double,$(call int_encode,0)),$(call int_encode,0)) 671 | $(call test_assert,$(call int_double,$(call int_encode,1)),$(call int_encode,2)) 672 | $(call test_assert,$(call int_double,$(call int_encode,4)),$(call int_encode,8)) 673 | $(call stop_test) 674 | 675 | $(call start_test,double) 676 | $(call test_assert,$(call double,0),0) 677 | $(call test_assert,$(call double,1),2) 678 | $(call test_assert,$(call double,4),8) 679 | $(call stop_test) 680 | 681 | $(call start_test,int_halve) 682 | $(call test_assert,$(call int_halve,$(call int_encode,0)),$(call int_encode,0)) 683 | $(call test_assert,$(call int_halve,$(call int_encode,2)),$(call int_encode,1)) 684 | $(call test_assert,$(call int_halve,$(call int_encode,8)),$(call int_encode,4)) 685 | $(call test_assert,$(call int_halve,$(call int_encode,7)),$(call int_encode,3)) 686 | $(call stop_test) 687 | 688 | $(call start_test,halve) 689 | $(call test_assert,$(call halve,0),0) 690 | $(call test_assert,$(call halve,2),1) 691 | $(call test_assert,$(call halve,8),4) 692 | $(call test_assert,$(call halve,7),3) 693 | $(call stop_test) 694 | 695 | $(call start_test,gt) 696 | $(call test_assert,$(call gt,2,3),) 697 | $(call test_assert,$(call gt,3,2),$(true)) 698 | $(call test_assert,$(call gt,2,2),) 699 | $(call stop_test) 700 | 701 | $(call start_test,gte) 702 | $(call test_assert,$(call gte,2,3),) 703 | $(call test_assert,$(call gte,3,2),$(true)) 704 | $(call test_assert,$(call gte,2,2),$(true)) 705 | $(call stop_test) 706 | 707 | $(call start_test,lt) 708 | $(call test_assert,$(call lt,2,3),$(true)) 709 | $(call test_assert,$(call lt,3,2),) 710 | $(call test_assert,$(call lt,2,2),) 711 | $(call stop_test) 712 | 713 | $(call start_test,lte) 714 | $(call test_assert,$(call lte,2,3),$(true)) 715 | $(call test_assert,$(call lte,3,2),) 716 | $(call test_assert,$(call lte,2,2),$(true)) 717 | $(call stop_test) 718 | 719 | $(call start_test,eq) 720 | $(call test_assert,$(call eq,2,3),) 721 | $(call test_assert,$(call eq,3,2),) 722 | $(call test_assert,$(call eq,2,2),$(true)) 723 | $(call stop_test) 724 | 725 | $(call start_test,ne) 726 | $(call test_assert,$(call ne,2,3),$(true)) 727 | $(call test_assert,$(call ne,3,2),$(true)) 728 | $(call test_assert,$(call ne,2,2),) 729 | $(call stop_test) 730 | 731 | $(call start_test,int_gt) 732 | $(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,3)),) 733 | $(call test_assert,$(call int_gt,$(call int_encode,3),$(call int_encode,2)),$(true)) 734 | $(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,2)),) 735 | $(call stop_test) 736 | 737 | $(call start_test,int_gte) 738 | $(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,3)),) 739 | $(call test_assert,$(call int_gte,$(call int_encode,3),$(call int_encode,2)),$(true)) 740 | $(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,2)),$(true)) 741 | $(call stop_test) 742 | 743 | $(call start_test,int_lt) 744 | $(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,3)),$(true)) 745 | $(call test_assert,$(call int_lt,$(call int_encode,3),$(call int_encode,2)),) 746 | $(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,2)),) 747 | $(call stop_test) 748 | 749 | $(call start_test,int_lte) 750 | $(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,3)),$(true)) 751 | $(call test_assert,$(call int_lte,$(call int_encode,3),$(call int_encode,2)),) 752 | $(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,2)),$(true)) 753 | $(call stop_test) 754 | 755 | $(call start_test,int_eq) 756 | $(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,3)),) 757 | $(call test_assert,$(call int_eq,$(call int_encode,3),$(call int_encode,2)),) 758 | $(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,2)),$(true)) 759 | $(call stop_test) 760 | 761 | $(call start_test,int_ne) 762 | $(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,3)),$(true)) 763 | $(call test_assert,$(call int_ne,$(call int_encode,3),$(call int_encode,2)),$(true)) 764 | $(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,2)),) 765 | $(call stop_test) 766 | 767 | $(call start_test,sequence) 768 | $(call test_assert,$(call sequence,0,0),0) 769 | $(call test_assert,$(call sequence,1,1),1) 770 | $(call test_assert,$(call sequence,10,10),10) 771 | $(call test_assert,$(call sequence,0,1),0 1) 772 | $(call test_assert,$(call sequence,0,2),0 1 2) 773 | $(call test_assert,$(call sequence,1,2),1 2) 774 | $(call test_assert,$(call sequence,1,4),1 2 3 4) 775 | $(call test_assert,$(call sequence,10,20),10 11 12 13 14 15 16 17 18 19 20) 776 | $(call test_assert,$(call sequence,1,0),1 0) 777 | $(call test_assert,$(call sequence,2,1),2 1) 778 | $(call test_assert,$(call sequence,3,1),3 2 1) 779 | $(call test_assert,$(call sequence,20,10),20 19 18 17 16 15 14 13 12 11 10) 780 | $(call stop_test) 781 | 782 | $(call start_test,memoize) 783 | memo_counter = $(call int_encode,0) 784 | memo = $(eval memo_counter := $(call int_inc,$(memo_counter)))$(firstword $1) 785 | $(call test_assert,$(call int_decode,$(memo_counter)),0) 786 | $(call test_assert,$(call memoize,memo,hello john),hello) 787 | $(call test_assert,$(call int_decode,$(memo_counter)),1) 788 | $(call test_assert,$(call memoize,memo,hello john),hello) 789 | $(call test_assert,$(call int_decode,$(memo_counter)),1) 790 | $(call test_assert,$(call memoize,memo,hello john how are you),hello) 791 | $(call test_assert,$(call int_decode,$(memo_counter)),2) 792 | $(call test_assert,$(call memoize,memo,john),john) 793 | $(call test_assert,$(call int_decode,$(memo_counter)),3) 794 | $(call test_assert,$(call memoize,memo,hello john),hello) 795 | $(call test_assert,$(call int_decode,$(memo_counter)),3) 796 | $(call test_assert,$(call memoize,memo,hello john how are you),hello) 797 | $(call test_assert,$(call int_decode,$(memo_counter)),3) 798 | $(call test_assert,$(call memoize,memo,john),john) 799 | $(call test_assert,$(call int_decode,$(memo_counter)),3) 800 | md5_counter = $(call int_encode,0) 801 | ifneq ("$(shell echo -n hello | md5sum 2> /dev/null)","") 802 | md5_program := md5sum 803 | endif 804 | ifneq ("$(shell md5 -s hello 2> /dev/null)","") 805 | md5_program := md5 806 | endif 807 | ifeq ("$(md5_program)","") 808 | $(error Can't find suitable MD5 program. Tried md5sum and md5) 809 | endif 810 | md5 = $(eval md5_counter = $(call int_inc,$(md5_counter)))$(firstword $(shell echo "$1" | $(md5_program))) 811 | $(call test_assert,$(call memoize,md5,hello john),2d62190b10246ee2f2e233f9df840445) 812 | $(call test_assert,$(call int_decode,$(memo_counter)),3) 813 | $(call test_assert,$(call int_decode,$(md5_counter)),1) 814 | $(call test_assert,$(call memoize,memo,hello john),hello) 815 | $(call test_assert,$(call int_decode,$(memo_counter)),3) 816 | $(call test_assert,$(call int_decode,$(md5_counter)),1) 817 | $(call test_assert,$(call memoize,md5,hello john),2d62190b10246ee2f2e233f9df840445) 818 | $(call test_assert,$(call int_decode,$(md5_counter)),1) 819 | $(call test_assert,$(call memoize,md5,hello john how are you),fd9b9651aa9f92d3d6d15a60bf5ccf15) 820 | $(call test_assert,$(call int_decode,$(md5_counter)),2) 821 | $(call test_assert,$(call memoize,md5,hello john),2d62190b10246ee2f2e233f9df840445) 822 | $(call test_assert,$(call int_decode,$(md5_counter)),2) 823 | $(call test_assert,$(call memoize,md5,hello john how are you),fd9b9651aa9f92d3d6d15a60bf5ccf15) 824 | $(call test_assert,$(call int_decode,$(md5_counter)),2) 825 | $(call stop_test) 826 | 827 | $(call start_test,gmsl_compatible) 828 | $(call test_assert,$(call gmsl_compatible,$(gmsl_version)),$(true)) 829 | $(call test_assert,$(call gmsl_compatible,0 9 0),$(true)) 830 | $(call test_assert,$(call gmsl_compatible,0 0 1),$(true)) 831 | $(call test_assert,$(call gmsl_compatible,0 0 0),$(true)) 832 | $(call test_assert,$(call gmsl_compatible,1 0 8),$(true)) 833 | $(call test_assert,$(call gmsl_compatible,1 0 8),$(true)) 834 | $(call test_assert,$(call gmsl_compatible,1 0 10),$(true)) 835 | $(call test_assert,$(call gmsl_compatible,1 0 11),$(true)) 836 | $(call test_assert,$(call gmsl_compatible,1 0 12),$(true)) 837 | $(call test_assert,$(call gmsl_compatible,1 0 13),$(true)) 838 | $(call test_assert,$(call gmsl_compatible,1 1 0),$(true)) 839 | $(call test_assert,$(call gmsl_compatible,1 1 1),$(true)) 840 | $(call test_assert,$(call gmsl_compatible,1 1 2),$(true)) 841 | $(call test_assert,$(call gmsl_compatible,1 1 3),$(true)) 842 | $(call test_assert,$(call gmsl_compatible,1 1 4),$(true)) 843 | $(call test_assert,$(call gmsl_compatible,1 1 5),$(true)) 844 | $(call test_assert,$(call gmsl_compatible,1 1 6),$(true)) 845 | $(call test_assert,$(call gmsl_compatible,1 1 7),$(true)) 846 | $(call test_assert,$(call gmsl_compatible,1 1 8),$(true)) 847 | $(call test_assert,$(call gmsl_compatible,1 1 9),$(true)) 848 | $(call test_assert,$(call gmsl_compatible,1 1 10),$(true)) 849 | $(call test_assert,$(call gmsl_compatible,1 2 0),$(true)) 850 | $(call test_assert,$(call gmsl_compatible,1 2 1),$(true)) 851 | $(call test_assert,$(call gmsl_compatible,1 2 2),$(true)) 852 | $(call test_assert,$(call gmsl_compatible,1 2 3),$(true)) 853 | $(call test_assert,$(call gmsl_compatible,1 2 4),$(true)) 854 | $(call test_assert,$(call gmsl_compatible,1 2 5),) 855 | $(call test_assert,$(call gmsl_compatible,2 0 0),) 856 | $(call stop_test) 857 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GNU Make Standard Library 5 | 6 | 7 |

GNU Make Standard Library

8 | The GNU Make Standard Library (GMSL) is a collection of functions 9 | implemented using native GNU Make functionality that provide list and 10 | string manipulation, integer arithmetic, associative arrays, stacks, 11 | and debugging facilities.  The GMSL is released under the BSD License.
12 |
13 | [Project Page] 14 | [Releases] 15 |
16 |

Using GMSL

17 | The two files needed are gmsl 18 | and __gmsl.  To 19 | include the GMSL in your Makefile do
20 |
include gmsl
21 | gmsl automatically includes __gmsl.  To check that 22 | you have the right version of gmsl 23 | use the gmsl_compatible 24 | function (see 25 | below). The current version is 1 2 4.
26 |
27 | The GMSL package also includes a test suite for GMSL.  Just run make -f gmsl-tests.
28 |

Logical Operators

GMSL has boolean $(true) (a non-empty string) 29 | and $(false) (an empty string).  The following operators can be 30 | used with those variables.
31 |
32 |
not
33 | 34 |
35 | 36 | Arguments: A boolean value
37 | 38 | Returns:   Returns $(true) if the boolean is $(false) and vice versa
39 | 40 |
and
41 |
42 | Arguments: Two boolean values
43 | Returns:   Returns $(true) if both of the booleans are true
44 |
or
45 |
46 | Arguments: Two boolean values
47 | Returns:   Returns $(true) if either of the booleans is true
48 |
xor
49 |
50 | Arguments: Two boolean values
51 | Returns:   Returns $(true) if exactly one of the booleans is true
52 |
nand
53 |
54 | Arguments: Two boolean values
55 | Returns:   Returns value of 'not and'
56 |
nor
57 |
58 | Arguments: Two boolean values
59 | Returns:   Returns value of 'not or'
60 |
xnor
61 |
62 | Arguments: Two boolean values
63 | Returns:   Returns value of 'not xor'
64 |
65 |

List Manipulation Functions

66 |  A list is a string of characters; the list separator is a space.
67 | 68 |
69 |
first
70 |
71 | Arguments: 1: A list
72 | Returns:   Returns the first element of a list
73 |
74 |
last
75 |
76 | Arguments: 1: A list
77 | Returns:   Returns the last element of a list
78 |
79 |
rest
80 |
81 | Arguments: 1: A list
82 | Returns:   Returns the list with the first element 83 | removed
84 |
85 |
chop
86 |
87 | Arguments: 1: A list
88 | Returns:   Returns the list with the last element removed
89 |
90 |
map
91 |
92 | Arguments: 1: Name of function to 93 | $(call) for each element of list
94 |            2: List to 95 | iterate over calling the function in 1
96 | Returns:   The list after calling the function on each 97 | element
98 |
99 |
pairmap
100 |
101 | Arguments: 1: Name of function to 102 | $(call) for each pair of elements
103 |            2: List to 104 | iterate over calling the function in 1
105 |            3: Second 106 | list to iterate over calling the function in 1
107 | Returns:   The list after calling the function on each 108 | pair of elements
109 |
110 |
fold
111 |
112 | Arguments: 1: Name of function to $(call) for each element of list
              This function takes two arguments
113 |            2: List to 114 | iterate over calling the function in 1
115 |            3: The "zero" element to be used when the list end is reached
116 | Returns:   The result of calling the function in 1 on each element in
117 |            the list with the previous result of calling 1 as the second
118 |            argument.
119 |
120 |
leq
121 |
122 | Arguments: 1: A list to compare 123 | against...
124 |            2: ...this 125 | list
126 | Returns:   Returns $(true) if the two lists are identical
127 |
128 |
lne
129 |
130 | Arguments: 1: A list to compare 131 | against...
132 |            2: ...this 133 | list
134 | Returns:   Returns $(true) if the two lists are different
135 |
136 |
reverse
137 |
138 | Arguments: 1: A list to reverse
139 | Returns:   The list with its elements in reverse order
140 |
141 |
uniq
142 |
143 | Arguments: 1: A list to deduplicate
144 | Returns:   The list with elements in order without duplicates
145 |
146 |
length
147 |
148 | Arguments: 1: A list
149 | Returns:   The number of elements in the list
150 |
151 |
152 |

String Manipulation Functions

153 | A string is any sequence of characters.
154 |
155 |
seq
156 |
157 | Arguments: 1: A string to compare 158 | against...
159 |            2: ...this 160 | string
161 | Returns:   Returns $(true) if the two strings are 162 | identical
163 |
164 |
sne
165 |
166 | Arguments: 1: A string to compare 167 | against...
168 |            2: ...this 169 | string
170 | Returns:   Returns $(true) if the two strings are not 171 | the same
172 |
173 |
strlen
174 |
175 | Arguments: 1: A string
176 | Returns:   Returns the length of the string
177 |
178 |
substr
179 |
180 | Arguments: 1: A string
181 |            2: Start offset (first character is 1)
182 |            3: Ending offset (inclusive)
Returns:   Returns a substring
183 |
184 |
split
185 |
186 | Arguments: 1: The character to 187 | split on
188 |            2: A 189 | string to split
190 | Returns:   Splits a string into a list separated by 191 | spaces at the split
192 |            character 193 | in the first argument
194 |
195 |
merge
196 |
197 | Arguments: 1: The character to 198 | put between fields
199 |            2: A list 200 | to merge into a string
201 | Returns:   Merges a list into a single string, list 202 | elements are separated
203 |            by the 204 | character in the first argument
205 |
206 |
tr
207 |
208 | Arguments: 1: The list of 209 | characters to translate from
210 |            2: The 211 | list of characters to translate to
212 |            3: The 213 | text to translate
214 | Returns:   Returns the text after translating characters
215 |
216 |
uc
217 |
218 | Arguments: 1: Text to upper case
219 | Returns:   Returns the text in upper case
220 |
221 |
lc
222 |
223 | Arguments: 1: Text to lower case
224 | Returns:   Returns the text in lower case
225 |
226 |
227 |

Set Manipulation Functions

228 | Sets are represented by sorted, deduplicated lists. To create a set 229 | from a list use set_create, or start with the empty_set and set_insert individual elements. 233 | The empty set is defined as empty_set.

235 | 236 |


set_create
237 |
238 | Arguments: 1: A list of set elements
239 | Returns:   Returns the newly created set
240 |
241 | 242 |
set_insert
243 |
244 | Arguments: 1: A single element to add to a set
245 |            2: A set
246 | Returns:   Returns the set with the element added
247 |
248 | 249 |
set_remove
250 |
251 | Arguments: 1: A single element to remove from a set
252 |            2: A set
253 | Returns:   Returns the set with the element removed
254 |
255 | 256 |
set_is_member
257 |
258 | Arguments: 1: A single element
259 |            2: A set
260 | Returns:   Returns $(true) if the element is in the set
261 |
262 | 263 |
set_is_not_member
264 |
265 | Arguments: 1: A single element
266 |            2: A set
267 | Returns:   Returns $(false) if the element is in the set
268 |
269 | 270 |
set_union
271 |
272 | Arguments: 1: A set
273 |            2: Another set
274 | Returns:   Returns the union of the two sets
275 |
276 | 277 |
set_intersection
278 |
279 | Arguments: 1: A set
280 |            2: Another set
281 | Returns:   Returns the intersection of the two sets
282 |
283 | 284 |
set_is_subset
285 |
286 | Arguments: 1: A set
287 |            2: Another set
288 | Returns:   Returns $(true) if the first set is a subset of the second
289 |
290 | 291 |
set_equal
292 |
293 | Arguments: 1: A set
294 |            2: Another set
295 | Returns:   Returns $(true) if the two sets are identical
296 |
297 | 298 |
299 |

Integer Arithmetic Functions

300 | Integers are represented by lists with the equivalent number of 301 | x's.  For example the number 4 is x x x x.  The maximum 302 | integer that the library can handle as input (i.e. as the argument to a 303 | call to int_encode) is 304 | 65536. There is no limit on integer size for internal computations or 305 | output.
306 |
307 | The arithmetic library functions come in two forms: one form of each 308 | function takes integers as arguments and the other form takes the 309 | encoded form (x's created by a call to int_encode).  For example, 310 | there are two plus functions: plus 311 | (called with integer arguments and returns an integer) and int_plus (called with encoded 312 | arguments and returns an encoded result).
313 |
314 | plus will be slower than int_plus because its arguments 315 | and result have to be translated between the x's format and 316 | integers.  If doing a complex calculation use the int_* forms with a single 317 | encoding of inputs and single decoding of the output.  For simple 318 | calculations the direct forms can be used.
319 |
320 |
int_decode
321 |
322 | Arguments: 1: A number of x's 323 | representation
324 | Returns:   Returns the integer for human consumption 325 | that is represented
326 |            by the 327 | string of x's
328 |
329 |
int_encode
330 |
331 | Arguments: 1: A number in 332 | human-readable integer form
333 | Returns:   Returns the integer encoded as a string of x's
334 |
335 |
int_plus
336 |
337 | Arguments: 1: A number in x's 338 | representation
339 |            2: Another 340 | number in x's represntation
341 | Returns:   Returns the sum of the two numbers in x's 342 | representation
343 |
344 |
plus (wrapped version of int_plus)
345 |
346 | Arguments: 1: An integer
347 |            2: Another 348 | integer
349 | Returns:   Returns the sum of the two integers
350 |
351 |
int_subtract
352 |
353 | Arguments: 1: A number in x's 354 | representation
355 |            2: Another 356 | number in x's represntation
357 | Returns:   Returns the difference of the two numbers in 358 | x's representation,
359 |            or outputs 360 | an error on a numeric underflow
361 |
362 |
subtract (wrapped version of int_subtract)
363 |
364 | Arguments: 1: An integer
365 |            2: Another 366 | integer
367 | Returns:   Returns the difference of the two integers,
368 |            or outputs 369 | an error on a numeric underflow
370 |
371 |
int_multiply
372 |
373 | Arguments: 1: A number in x's 374 | representation
375 |            2: Another 376 | number in x's represntation
377 | Returns:   Returns the product of the two numbers in x's 378 | representation
379 |
380 |
multiply (wrapped version of int_multiply)
381 |
382 | Arguments: 1: An integer
383 |            2: Another 384 | integer
385 | Returns:   Returns the product of the two integers
386 |
387 |
int_divide
388 |
389 | Arguments: 1: A number in x's 390 | representation
391 |            2: Another 392 | number in x's represntation
393 | Returns:   Returns the result of integer division of 394 | argument 1 divided
395 |            by 396 | argument 2 in x's representation
397 |
398 |
divide (wrapped version of int_divide)
399 |
400 | Arguments: 1: An integer
401 |            2: Another 402 | integer
403 | Returns:   Returns the integer division of the first 404 | argument by the second
405 |
406 |
int_modulo
407 |
408 | Arguments: 1: A number in x's 409 | representation
410 |            2: Another 411 | number in x's represntation
412 | Returns:   Returns the remainder of integer division of 413 | argument 1 divided
414 |            by 415 | argument 2 in x's representation
416 |
417 |
modulo (wrapped version of int_modulo)
418 |
419 | Arguments: 1: An integer
420 |            2: Another 421 | integer
422 | Returns:   Returns the remainder of integer division of the first 423 | argument by the second
424 |
425 |
int_max, int_min
426 |
427 | Arguments: 1: A number in x's 428 | representation
429 |            2: Another 430 | number in x's represntation
431 | Returns:   Returns the maximum or minimum of its 432 | arguments in x's
433 |            434 | representation
435 |
436 |
max, min
437 |
438 | Arguments: 1: An integer
439 |            2: Another 440 | integer
441 | Returns:   Returns the maximum or minimum of its integer 442 | arguments
443 |
444 |
int_gt, int_gte, int_lt, int_lte, int_eq, int_ne
445 |
446 | Arguments: Two x's representation 447 | numbers to be compared
448 | Returns:   $(true) or $(false)
449 |
450 | int_gt First argument greater than second argument
451 | int_gte First argument greater than or equal to second argument
452 | int_lt First argument less than second argument
453 | int_lte First argument less than or equal to second argument
454 | int_eq First argument is numerically equal to the second argument
455 | int_ne First argument is not numerically equal to the second argument
456 |
457 |
gt, gte, lt, lte, eq, ne
458 |
459 | Arguments: Two integers to be 460 | compared
461 | Returns:   $(true) or $(false)
462 |
463 | gt First argument greater than second argument
464 | gte First argument greater than or equal to second argument
465 | lt First argument less than second argument
466 | lte First argument less than or equal to second argument
467 | eq First argument is numerically equal to the second argument
468 | ne First argument is not numerically equal to the second argument
469 |
470 | increment adds 1 to its argument, decrement subtracts 1. Note that
471 | decrement does not range check and hence will not underflow, but
472 | will incorrectly say that 0 - 1 = 0
473 |
int_inc
474 |
475 | Arguments: 1: A number in x's 476 | representation
477 | Returns:   The number incremented by 1 in x's 478 | representation
479 |
480 |
inc
481 |
482 | Arguments: 1: An integer
483 | Returns:   The argument incremented by 1
484 |
485 |
int_dec
486 |
487 | Arguments: 1: A number in x's 488 | representation
489 | Returns:   The number decremented by 1 in x's 490 | representation
491 |
492 |
dec
493 |
494 | Arguments: 1: An integer
495 | Returns:   The argument decremented by 1
496 |
497 |
int_double
498 |
499 | Arguments: 1: A number in x's 500 | representation
501 | Returns:   The number doubled (i.e. * 2) and returned in 502 | x's representation
503 |
504 |
double
505 |
506 | Arguments: 1: An integer
507 | Returns:   The integer times 2
508 |
509 |
int_halve
510 |
511 | Arguments: 1: A number in x's 512 | representation
513 | Returns:   The number halved (i.e. / 2) and returned in 514 | x's representation
515 |
516 |
halve
517 |
518 | Arguments: 1: An integer
519 | Returns:   The integer divided by 2
520 |
521 |
sequence
522 |
523 | Arguments: 1: An integer
524 |            2: An integer
525 | Returns:   The sequence [arg1 arg2] if arg1 >= arg2 or [arg2 arg1] if arg2 > arg1
526 |
527 |
dec2hex, dec2bin, dec2oct
528 |
529 | Arguments: 1: An integer
530 | Returns:   The decimal argument converted to hexadecimal, binary or octal
531 |
532 |
533 |

Associative Arrays

534 | An associate array maps a key value (a string with no spaces in it) to 535 | a single value (any string).   
536 |
537 |
538 |
set
539 |
540 | Arguments: 1: Name of associative 541 | array
542 |            2: The key 543 | value to associate
544 |            3: The 545 | value associated with the key
546 | Returns:   Nothing
547 |
548 |
get
549 |
550 | Arguments: 1: Name of associative 551 | array
552 |            2: The key 553 | to retrieve
554 | Returns:   The value stored in the array for that key
555 |
556 |
keys
557 |
558 | Arguments: 1: Name of associative 559 | array
560 | Returns:   Returns a list of all defined keys in the 561 | array
562 |
563 |
defined
564 |
565 | Arguments: 1: Name of associative 566 | array
567 |            2: The key 568 | to test
569 | Returns:   Returns true if the key is defined (i.e. not 570 | empty)
571 |
572 |
573 |

Named Stacks

574 | A stack is an ordered list of strings (with no spaces in them).
575 |
576 |
push
577 |
578 | Arguments: 1: Name of stack
579 |            2: Value 580 | to push onto the top of the stack (must not contain
581 |            a space)
582 | Returns:   None
583 |
584 |
pop
585 |
586 | Arguments: 1: Name of stack
587 | Returns:   Top element from the stack after removing it
588 |
589 |
peek
590 |
591 | Arguments: 1: Name of stack
592 | Returns:   Top element from the stack without removing it
593 |
594 |
depth
595 |
596 | Arguments: 1: Name of stack
597 | Returns:   Number of items on the stack
598 |
599 |
600 |

Function memoization

601 | To reduce the number of calls to slow functions (such as $(shell) a single memoization function is provided.
602 |
603 |
memoize
604 |
605 | Arguments: 1: Name of function to memoize
606 |            2: String argument for the function
607 | Returns:   Result of $1 applied to $2 but only calls $1 once for each unique $2
608 |
609 | 610 |
611 |

Miscellaneous and Debugging Facilities

612 | GMSL defines the following constants; all are accessed as normal GNU 613 | Make variables by wrapping them in $() or ${}.
614 |
615 | 616 | 617 | 618 | 620 | 622 | 624 | 625 | 626 | 628 | 630 | 633 | 634 | 635 | 637 | 639 | 642 | 643 | 644 | 646 | 648 | 650 | 651 | 652 |
Constant
619 |
Value
621 |
Purpose
623 |
true
627 |
T
629 |
Boolean for $(if) 631 | and return from  GMSL functions
632 |
false
636 |

638 |
Boolean for $(if) 640 | and return from GMSL functions
641 |
gmsl_version
645 |
1 0 0
647 |
GMSL version number as list: major minor revision
649 |
653 |
654 | gmsl_compatible

655 |
656 | Arguments: List containing the desired library version number (maj min 657 | rev)
658 |
Returns:   659 | $(true) if this version of the library is compatible
660 |
           661 | with the requested version number, otherwise $(false) 662 |
gmsl-print-% (target not a function)
663 |
664 | Arguments: The % should be 665 | replaced by the name of a variable that you
666 |            wish to 667 | print out.
668 | Action:    Echos the name of the variable that matches 669 | the % and its value.
670 |            For 671 | example, 'make gmsl-print-SHELL' will output the value of
672 |            the SHELL 673 | variable
674 |
675 |
gmsl-echo-% (target not a function)
676 |
677 | Arguments: The % should be 678 | replaced by the name of a variable that you
679 |            wish to 680 | print out.
681 | Action:    Echos the value of the variable that matches 682 | the %.
683 |            For 684 | example, 'make gmsl-echo-SHELL' will output the value of
685 |            the SHELL 686 | variable
687 |
688 |
assert
689 |
690 | Arguments: 1: A boolean that must 691 | be true or the assertion will fail
692 |            2: The 693 | message to print with the assertion
694 | Returns:   None
695 |
696 |
assert_exists
697 |
698 | Arguments: 1: Name of file that 699 | must exist, if it is missing an assertion
700 |            will be 701 | generated
702 | Returns:   None
703 |
704 |

705 | GMSL has a number of environment variables (or command-line overrides) 706 | that control various bits of functionality:
707 |
708 | 709 | 710 | 711 | 713 | 715 | 716 | 717 | 719 | 722 | 723 | 724 | 726 | 729 | 730 | 731 | 733 | 736 | 737 | 738 |
Variable
712 |
Purpose
714 |
GMSL_NO_WARNINGS
718 |
If set prevents GMSL from outputting warning messages: 720 | artithmetic functions generate underflow warnings.
721 |
GMSL_NO_ERRORS
725 |
If set prevents GMSL from generating fatal errors: division 727 | by zero or failed assertions are fatal.
728 |
GMSL_TRACE
732 |
Enables function tracing.  Calls to GMSL functions will 734 | result in name and arguments being traced.
735 |
739 |
740 |
741 | Copyright (c) 2005-2025 John Graham-Cumming.
742 |
743 | 744 | --------------------------------------------------------------------------------