github.com/crowdsecurity/crowdsec@v1.6.1/mk/gmsl.html (about)

     1  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     2  <html><head>
     3    <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
     4    <title>GNU Make Standard Library</title></head>
     5  
     6  <body>
     7  <h1>GNU Make Standard Library</h1>
     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.&nbsp; The GMSL is released under the BSD License.<br>
    12  <br>
    13  <a href="https://github.com/jgrahamc/gmsl/">[Project Page]</a>
    14  <a href="https://github.com/jgrahamc/gmsl/releases/">[Releases]</a>
    15  <br>
    16  <h2>Using GMSL</h2>
    17  The two files needed are <span style="font-family: monospace;">gmsl</span>
    18  and <span style="font-family: monospace;">__gmsl</span>.&nbsp; To
    19  include the GMSL in your Makefile do<br>
    20  <pre style="margin-left: 40px;">include gmsl</pre>
    21  <span style="font-family: monospace;">gmsl</span> automatically includes<span style="font-family: monospace;"> __gmsl</span>.&nbsp; To check that
    22  you have the right version of <span style="font-family: monospace;">gmsl</span>
    23  use the <span style="font-family: monospace;">gmsl_compatible</span>
    24  function (see
    25  below). The current version is <span style="font-family: monospace;">1 2 0</span>.<br>
    26  <br>
    27  The GMSL package also includes a test suite for GMSL.&nbsp; Just run <span style="font-family: monospace;">make -f gmsl-tests</span>.<br>
    28  <h2>Logical Operators</h2>GMSL has boolean $(true) (a non-empty string)
    29  and $(false) (an empty string).&nbsp; The following operators can be
    30  used with those variables.<br>
    31  <br>
    32  <hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">not</span><br>
    33  
    34  <br>
    35  
    36  <span style="font-family: monospace;">Arguments: A boolean value</span><br style="font-family: monospace;">
    37  
    38  <span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if the boolean is $(false) and vice versa</span><br style="font-family: monospace;">
    39  
    40  <hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;"></span><span style="font-weight: bold;">and</span><br>
    41  <br>
    42  <span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
    43  <span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if both of the booleans are true</span><br style="font-family: monospace;">
    44  <hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">or</span><br>
    45  <br>
    46  <span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
    47  <span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if either of the booleans is true</span><br style="font-family: monospace;">
    48  <hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xor</span><br style="font-weight: bold;">
    49  <br>
    50  <span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
    51  <span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if exactly one of the booleans is true</span><br style="font-family: monospace;">
    52  <hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nand</span><br>
    53  <br>
    54  <span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
    55  <span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not and'</span><br style="font-family: monospace;">
    56  <hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nor</span><br>
    57  <br>
    58  <span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
    59  <span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not or'</span><br style="font-family: monospace;">
    60  <hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xnor</span><br>
    61  <br>
    62  <span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
    63  <span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not xor'</span><br style="font-family: monospace;">
    64  <hr style="width: 100%; height: 2px; font-family: monospace;">
    65  <h2>List Manipulation Functions</h2>
    66  &nbsp;A list is a string of characters; the list separator is a space.<br>
    67  
    68  <br>
    69  <hr style="width: 100%; height: 2px;"><b>first</b><br>
    70  <br>
    71  <span style="font-family: monospace;">Arguments: 1: A list<br>
    72  Returns:&nbsp;&nbsp;&nbsp;Returns the first element of a list<br>
    73  </span>
    74  <hr><b>last</b><br>
    75  <br>
    76  <span style="font-family: monospace;">Arguments: 1: A list<br>
    77  Returns:&nbsp;&nbsp;&nbsp;Returns the last element of a list<br>
    78  </span>
    79  <hr><b>rest</b><br>
    80  <br>
    81  <span style="font-family: monospace;">Arguments: 1: A list<br>
    82  Returns:&nbsp;&nbsp;&nbsp;Returns the list with the first element
    83  removed<br>
    84  </span>
    85  <hr><b>chop</b><br>
    86  <br>
    87  <span style="font-family: monospace;">Arguments: 1: A list<br>
    88  Returns:&nbsp;&nbsp;&nbsp;Returns the list with the last element removed<br>
    89  </span>
    90  <hr><b>map</b><br>
    91  <br>
    92  <span style="font-family: monospace;">Arguments: 1: Name of function to
    93  $(call) for each element of list<br>
    94  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
    95  iterate over calling the function in 1<br>
    96  Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
    97  element<br>
    98  </span>
    99  <hr><b>pairmap</b><br>
   100  <br>
   101  <span style="font-family: monospace;">Arguments: 1: Name of function to
   102  $(call) for each pair of elements<br>
   103  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
   104  iterate over calling the function in 1<br>
   105  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Second
   106  list to iterate over calling the function in 1<br>
   107  Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
   108  pair of elements<br>
   109  </span>
   110  <hr><b>leq</b><br>
   111  <br>
   112  <span style="font-family: monospace;">Arguments: 1: A list to compare
   113  against...<br>
   114  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
   115  list<br>
   116  Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are identical<br>
   117  </span>
   118  <hr><b>lne</b><br>
   119  <br>
   120  <span style="font-family: monospace;">Arguments: 1: A list to compare
   121  against...<br>
   122  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
   123  list<br>
   124  Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are different<br>
   125  </span>
   126  <hr><b>reverse</b><br>
   127  <br>
   128  <span style="font-family: monospace;">Arguments: 1: A list to reverse<br>
   129  Returns:&nbsp;&nbsp;&nbsp;The list with its elements in reverse order<br>
   130  </span>
   131  <hr><b>uniq</b><br>
   132  <br>
   133  <span style="font-family: monospace;">Arguments: 1: A list to deduplicate<br>
   134  Returns:&nbsp;&nbsp;&nbsp;The list with elements in order without duplicates<br>
   135  </span>
   136  <hr><b>length</b><br>
   137  <br>
   138  <span style="font-family: monospace;">Arguments: 1: A list<br>
   139  Returns:&nbsp;&nbsp;&nbsp;The number of elements in the list<br>
   140  </span>
   141  <hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
   142  <h2>String Manipulation Functions</h2>
   143  A string is any sequence of characters.<br>
   144  <br>
   145  <hr style="width: 100%; height: 2px;"><b>seq</b><br>
   146  <br>
   147  <span style="font-family: monospace;">Arguments: 1: A string to compare
   148  against...<br>
   149  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
   150  string<br>
   151  Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are
   152  identical<br>
   153  </span>
   154  <hr><b>sne</b><br>
   155  <br>
   156  <span style="font-family: monospace;">Arguments: 1: A string to compare
   157  against...<br>
   158  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
   159  string<br>
   160  Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are not
   161  the same<br>
   162  </span>
   163  <hr><b>strlen</b><br>
   164  <br>
   165  <span style="font-family: monospace;">Arguments: 1: A string<br>
   166  Returns:&nbsp;&nbsp;&nbsp;Returns the length of the string<br>
   167  </span>
   168  <hr><b>substr</b><br>
   169  <br>
   170  <span style="font-family: monospace;">Arguments: 1: A string<br>
   171  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Start offset (first character is 1)<br>
   172  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Ending offset (inclusive)<br>Returns:&nbsp;&nbsp;&nbsp;Returns a substring<br>
   173  </span>
   174  <hr><b>split</b><br>
   175  <br>
   176  <span style="font-family: monospace;">Arguments: 1: The character to
   177  split on<br>
   178  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A
   179  string to split<br>
   180  Returns:&nbsp;&nbsp;&nbsp;Splits a string into a list separated by
   181  spaces at the split<br>
   182  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; character
   183  in the first argument<br>
   184  </span>
   185  <hr><b>merge</b><br>
   186  <br>
   187  <span style="font-family: monospace;">Arguments: 1: The character to
   188  put between fields<br>
   189  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A list
   190  to merge into a string<br>
   191  Returns:&nbsp;&nbsp;&nbsp;Merges a list into a single string, list
   192  elements are separated<br>
   193  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
   194  character in the first argument<br>
   195  </span>
   196  <hr><b>tr</b><br>
   197  <br>
   198  <span style="font-family: monospace;">Arguments: 1: The list of
   199  characters to translate from <br>
   200  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
   201  list of characters to translate to<br>
   202  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
   203  text to translate<br>
   204  Returns:&nbsp;&nbsp;&nbsp;Returns the text after translating characters<br>
   205  </span>
   206  <hr><b>uc</b><br>
   207  <br>
   208  <span style="font-family: monospace;">Arguments: 1: Text to upper case<br>
   209  Returns:&nbsp;&nbsp;&nbsp;Returns the text in upper case<br>
   210  </span>
   211  <hr><b>lc</b><br>
   212  <br>
   213  <span style="font-family: monospace;">Arguments: 1: Text to lower case<br>
   214  Returns:&nbsp;&nbsp;&nbsp;Returns the text in lower case<br>
   215  </span>
   216  <hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
   217  <h2>Set Manipulation Functions</h2>
   218  Sets are represented by sorted, deduplicated lists.  To create a set
   219  from a list use <span style="font-family:
   220  monospace;">set_create</span>, or start with the <span
   221  style="font-family: monospace;">empty_set</span> and <span
   222  style="font-family: monospace;">set_insert</span> individual elements.
   223  The empty set is defined as <span style="font-family:
   224  monospace;">empty_set</span>.<p>
   225  
   226  <hr><b>set_create</b><br>
   227  <br>
   228  <span style="font-family: monospace;">Arguments: 1: A list of set elements<br>
   229  Returns:&nbsp;&nbsp;&nbsp;Returns the newly created set<br>
   230  </span>
   231  
   232  <hr><b>set_insert</b><br>
   233  <br>
   234  <span style="font-family: monospace;">Arguments: 1: A single element to add to a set<br>
   235  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
   236  Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element added<br>
   237  </span>
   238  
   239  <hr><b>set_remove</b><br>
   240  <br>
   241  <span style="font-family: monospace;">Arguments: 1: A single element to remove from a set<br>
   242  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
   243  Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element removed<br>
   244  </span>
   245  
   246  <hr><b>set_is_member</b><br>
   247  <br>
   248  <span style="font-family: monospace;">Arguments: 1: A single element<br>
   249  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
   250  Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the element is in the set<br>
   251  </span>
   252  
   253  <hr><b>set_is_not_member</b><br>
   254  <br>
   255  <span style="font-family: monospace;">Arguments: 1: A single element<br>
   256  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
   257  Returns:&nbsp;&nbsp;&nbsp;Returns $(false) if the element is in the set<br>
   258  </span>
   259  
   260  <hr><b>set_union</b><br>
   261  <br>
   262  <span style="font-family: monospace;">Arguments: 1: A set<br>
   263  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
   264  Returns:&nbsp;&nbsp;&nbsp;Returns the union of the two sets<br>
   265  </span>
   266  
   267  <hr><b>set_intersection</b><br>
   268  <br>
   269  <span style="font-family: monospace;">Arguments: 1: A set<br>
   270  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
   271  Returns:&nbsp;&nbsp;&nbsp;Returns the intersection of the two sets<br>
   272  </span>
   273  
   274  <hr><b>set_is_subset</b><br>
   275  <br>
   276  <span style="font-family: monospace;">Arguments: 1: A set<br>
   277  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
   278  Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the first set is a subset of the second<br>
   279  </span>
   280  
   281  <hr><b>set_equal</b><br>
   282  <br>
   283  <span style="font-family: monospace;">Arguments: 1: A set<br>
   284  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
   285  Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two sets are identical<br>
   286  </span>
   287  
   288  <hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
   289  <h2>Integer Arithmetic Functions</h2>
   290  Integers are represented by lists with the equivalent number of
   291  x's.&nbsp; For example the number 4 is x x x x.&nbsp; The maximum
   292  integer that the library can handle as <span style="font-style: italic;">input</span> (i.e. as the argument to a
   293  call to <span style="font-family: monospace;">int_encode</span>) is
   294  65536. There is no limit on integer size for internal computations or
   295  output.<br>
   296  <br>
   297  The arithmetic library functions come in two forms: one form of each
   298  function takes integers as arguments and the other form takes the
   299  encoded form (x's created by a call to <span style="font-family: monospace;">int_encode</span>).&nbsp; For example,
   300  there are two plus functions: <span style="font-family: monospace;">plus</span>
   301  (called with integer arguments and returns an integer) and <span style="font-family: monospace;">int_plus</span> (called with encoded
   302  arguments and returns an encoded result).<br>
   303  <br>
   304  <span style="font-family: monospace;">plus</span> will be slower than <span style="font-family: monospace;">int_plus</span> because its arguments
   305  and result have to be translated between the x's format and
   306  integers.&nbsp; If doing a complex calculation use the <span style="font-family: monospace;">int_*</span> forms with a single
   307  encoding of inputs and single decoding of the output.&nbsp; For simple
   308  calculations the direct forms can be used.<br>
   309  <br>
   310  <hr style="width: 100%; height: 2px;"><b>int_decode</b><br>
   311  <br>
   312  <span style="font-family: monospace;">Arguments: 1: A number of x's
   313  representation<br>
   314  Returns:&nbsp;&nbsp;&nbsp;Returns the integer for human consumption
   315  that is represented<br>
   316  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
   317  string of x's<br>
   318  </span>
   319  <hr><b>int_encode</b><br>
   320  <br>
   321  <span style="font-family: monospace;">Arguments: 1: A number in
   322  human-readable integer form<br>
   323  Returns:&nbsp;&nbsp;&nbsp;Returns the integer encoded as a string of x's<br>
   324  </span>
   325  <hr><b>int_plus</b><br>
   326  <br>
   327  <span style="font-family: monospace;">Arguments: 1: A number in x's
   328  representation<br>
   329  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   330  number in x's represntation<br>
   331  Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two numbers in x's
   332  representation<br>
   333  </span>
   334  <hr><b>plus (wrapped version of int_plus)</b><br>
   335  <br>
   336  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   337  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   338  integer<br>
   339  Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two integers<br>
   340  </span>
   341  <hr><b>int_subtract</b><br>
   342  <br>
   343  <span style="font-family: monospace;">Arguments: 1: A number in x's
   344  representation<br>
   345  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   346  number in x's represntation<br>
   347  Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two numbers in
   348  x's representation,<br>
   349  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
   350  an error on a numeric underflow<br>
   351  </span>
   352  <hr><b>subtract (wrapped version of int_subtract)</b><br>
   353  <br>
   354  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   355  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   356  integer<br>
   357  Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two integers,<br>
   358  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
   359  an error on a numeric underflow<br>
   360  </span>
   361  <hr><b>int_multiply</b><br>
   362  <br>
   363  <span style="font-family: monospace;">Arguments: 1: A number in x's
   364  representation<br>
   365  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   366  number in x's represntation<br>
   367  Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two numbers in x's
   368  representation<br>
   369  </span>
   370  <hr><b>multiply (wrapped version of int_multiply)</b><br>
   371  <br>
   372  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   373  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   374  integer<br>
   375  Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two integers<br>
   376  </span>
   377  <hr><b>int_divide</b><br>
   378  <br>
   379  <span style="font-family: monospace;">Arguments: 1: A number in x's
   380  representation<br>
   381  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   382  number in x's represntation<br>
   383  Returns:&nbsp;&nbsp;&nbsp;Returns the result of integer division of
   384  argument 1 divided<br>
   385  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by
   386  argument 2 in x's representation<br>
   387  </span>
   388  <hr><b>divide (wrapped version of int_divide)</b><br>
   389  <br>
   390  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   391  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   392  integer<br>
   393  Returns:&nbsp;&nbsp;&nbsp;Returns the integer division of the first
   394  argument by the second<br>
   395  </span>
   396  <hr><b>int_modulo</b><br>
   397  <br>
   398  <span style="font-family: monospace;">Arguments: 1: A number in x's
   399  representation<br>
   400  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   401  number in x's represntation<br>
   402  Returns:&nbsp;&nbsp;&nbsp;Returns the remainder of integer division of
   403  argument 1 divided<br>
   404  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by
   405  argument 2 in x's representation<br>
   406  </span>
   407  <hr><b>modulo (wrapped version of int_modulo)</b><br>
   408  <br>
   409  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   410  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   411  integer<br>
   412  Returns:&nbsp;&nbsp;&nbsp;Returns the remainder of integer division of the first
   413  argument by the second<br>
   414  </span>
   415  <hr><b>int_max, int_min</b><br>
   416  <br>
   417  <span style="font-family: monospace;">Arguments: 1: A number in x's
   418  representation<br>
   419  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   420  number in x's represntation<br>
   421  Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its
   422  arguments in x's<br>
   423  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
   424  representation<br>
   425  </span>
   426  <hr><b>max, min</b><br>
   427  <br>
   428  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   429  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
   430  integer<br>
   431  Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its integer
   432  arguments<br>
   433  </span>
   434  <hr><b>int_gt, int_gte, int_lt, int_lte, int_eq, int_ne</b><br>
   435  <br>
   436  <span style="font-family: monospace;">Arguments: Two x's representation
   437  numbers to be compared<br>
   438  Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
   439  <br>
   440  int_gt First argument greater than second argument<br>
   441  int_gte First argument greater than or equal to second argument<br>
   442  int_lt First argument less than second argument <br>
   443  int_lte First argument less than or equal to second argument<br>
   444  int_eq First argument is numerically equal to the second argument<br>
   445  int_ne First argument is not numerically equal to the second argument<br>
   446  </span>
   447  <hr><b>gt, gte, lt, lte, eq, ne</b><br>
   448  <br>
   449  <span style="font-family: monospace;">Arguments: Two integers to be
   450  compared<br>
   451  Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
   452  <br>
   453  gt First argument greater than second argument<br>
   454  gte First argument greater than or equal to second argument<br>
   455  lt First argument less than second argument <br>
   456  lte First argument less than or equal to second argument<br>
   457  eq First argument is numerically equal to the second argument<br>
   458  ne First argument is not numerically equal to the second argument<br>
   459  </span>
   460  increment adds 1 to its argument, decrement subtracts 1. Note that<br>
   461  decrement does not range check and hence will not underflow, but<br>
   462  will incorrectly say that 0 - 1 = 0<br>
   463  <hr><b>int_inc</b><br>
   464  <br>
   465  <span style="font-family: monospace;">Arguments: 1: A number in x's
   466  representation<br>
   467  Returns:&nbsp;&nbsp;&nbsp;The number incremented by 1 in x's
   468  representation<br>
   469  </span>
   470  <hr><b>inc</b><br>
   471  <br>
   472  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   473  Returns:&nbsp;&nbsp;&nbsp;The argument incremented by 1<br>
   474  </span>
   475  <hr><b>int_dec</b><br>
   476  <br>
   477  <span style="font-family: monospace;">Arguments: 1: A number in x's
   478  representation<br>
   479  Returns:&nbsp;&nbsp;&nbsp;The number decremented by 1 in x's
   480  representation<br>
   481  </span>
   482  <hr><b>dec</b><br>
   483  <br>
   484  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   485  Returns:&nbsp;&nbsp;&nbsp;The argument decremented by 1<br>
   486  </span>
   487  <hr><b>int_double</b><br>
   488  <br>
   489  <span style="font-family: monospace;">Arguments: 1: A number in x's
   490  representation<br>
   491  Returns:&nbsp;&nbsp;&nbsp;The number doubled (i.e. * 2) and returned in
   492  x's representation<br>
   493  </span>
   494  <hr><b>double</b><br>
   495  <br>
   496  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   497  Returns:&nbsp;&nbsp;&nbsp;The integer times 2<br>
   498  </span>
   499  <hr><b>int_halve</b><br>
   500  <br>
   501  <span style="font-family: monospace;">Arguments: 1: A number in x's
   502  representation<br>
   503  Returns:&nbsp;&nbsp;&nbsp;The number halved (i.e. / 2) and returned in
   504  x's representation<br>
   505  </span>
   506  <hr><b>halve</b><br>
   507  <br>
   508  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   509  Returns:&nbsp;&nbsp;&nbsp;The integer divided by 2<br>
   510  </span>
   511  <hr><b>sequence</b><br>
   512  <br>
   513  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   514  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: An integer<br>
   515  Returns:&nbsp;&nbsp;&nbsp;The sequence [arg1 arg2] if arg1 >= arg2 or [arg2 arg1] if arg2 > arg1<br>
   516  </span>
   517  <hr><b>dec2hex, dec2bin, dec2oct</b><br>
   518  <br>
   519  <span style="font-family: monospace;">Arguments: 1: An integer<br>
   520  Returns:&nbsp;&nbsp;&nbsp;The decimal argument converted to hexadecimal, binary or octal<br>
   521  </span>
   522  <hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
   523  <h2>Associative Arrays</h2>
   524  An associate array maps a key value (a string with no spaces in it) to
   525  a single value (any string).&nbsp;&nbsp;&nbsp; <br>
   526  <b><br>
   527  </b>
   528  <hr style="width: 100%; height: 2px;"><b>set</b><br>
   529  <br>
   530  <span style="font-family: monospace;">Arguments: 1: Name of associative
   531  array<br>
   532  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
   533  value to associate<br>
   534  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
   535  value associated with the key<br>
   536  Returns:&nbsp;&nbsp;&nbsp;Nothing<br>
   537  </span>
   538  <hr><b>get</b><br>
   539  <br>
   540  <span style="font-family: monospace;">Arguments: 1: Name of associative
   541  array<br>
   542  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
   543  to retrieve<br>
   544  Returns:&nbsp;&nbsp;&nbsp;The value stored in the array for that key<br>
   545  </span>
   546  <hr><b>keys</b><br>
   547  <br>
   548  <span style="font-family: monospace;">Arguments: 1: Name of associative
   549  array<br>
   550  Returns:&nbsp;&nbsp;&nbsp;Returns a list of all defined keys in the
   551  array<br>
   552  </span>
   553  <hr><b>defined</b><br>
   554  <br>
   555  <span style="font-family: monospace;">Arguments: 1: Name of associative
   556  array<br>
   557  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
   558  to test<br>
   559  Returns:&nbsp;&nbsp;&nbsp;Returns true if the key is defined (i.e. not
   560  empty)<br>
   561  </span>
   562  <hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
   563  <h2>Named Stacks</h2>
   564  A stack is an ordered list of strings (with no spaces in them).<br>
   565  <br>
   566  <hr style="width: 100%; height: 2px;"><b>push</b><br>
   567  <br>
   568  <span style="font-family: monospace;">Arguments: 1: Name of stack<br>
   569  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Value
   570  to push onto the top of the stack (must not contain<br>
   571  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a space)<br>
   572  Returns:&nbsp;&nbsp;&nbsp;None<br>
   573  </span>
   574  <hr><b>pop</b><br>
   575  <br>
   576  <span style="font-family: monospace;">Arguments: 1: Name of stack<br>
   577  Returns:&nbsp;&nbsp;&nbsp;Top element from the stack after removing it<br>
   578  </span>
   579  <hr><b>peek</b><br>
   580  <br>
   581  <span style="font-family: monospace;">Arguments: 1: Name of stack<br>
   582  Returns:&nbsp;&nbsp;&nbsp;Top element from the stack without removing it<br>
   583  </span>
   584  <hr><b>depth</b><br>
   585  <br>
   586  <span style="font-family: monospace;">Arguments: 1: Name of stack<br>
   587  Returns:&nbsp;&nbsp;&nbsp;Number of items on the stack<br>
   588  </span>
   589  <hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
   590  <h2>Function memoization</h2>
   591  To reduce the number of calls to slow functions (such as $(shell) a single memoization function is provided.<br>
   592  <br>
   593  <hr style="width: 100%; height: 2px;"><b>memoize</b><br>
   594  <br>
   595  <span style="font-family: monospace;">Arguments: 1: Name of function to memoize<br>
   596  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: String argument for the function<br>
   597  Returns:&nbsp;&nbsp;&nbsp;Result of $1 applied to $2 but only calls $1 once for each unique $2<br>
   598  </span>
   599  
   600  <hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
   601  <h2>Miscellaneous and Debugging Facilities</h2>
   602  GMSL defines the following constants; all are accessed as normal GNU
   603  Make variables by wrapping them in <span style="font-family: monospace;">$()</span> or <span style="font-family: monospace;">${}</span>.<br>
   604  <br>
   605  <table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
   606    <tbody>
   607      <tr>
   608        <td><span style="font-style: italic;">Constant</span><br>
   609        </td>
   610        <td><span style="font-style: italic;">Value</span><br>
   611        </td>
   612        <td><span style="font-style: italic;">Purpose</span><br>
   613        </td>
   614      </tr>
   615      <tr>
   616        <td><span style="font-family: monospace;">true</span><br>
   617        </td>
   618        <td><span style="font-family: monospace;">T</span><br>
   619        </td>
   620        <td>Boolean for <span style="font-family: monospace;">$(if)</span>
   621  and return from&nbsp; GMSL functions<br>
   622        </td>
   623      </tr>
   624      <tr>
   625        <td><span style="font-family: monospace;">false</span><br>
   626        </td>
   627        <td><br>
   628        </td>
   629        <td>Boolean for <span style="font-family: monospace;">$(if)</span>
   630  and return from GMSL functions<br>
   631        </td>
   632      </tr>
   633      <tr>
   634        <td><span style="font-family: monospace;">gmsl_version</span><br>
   635        </td>
   636        <td><span style="font-family: monospace;">1 0 0</span><br>
   637        </td>
   638        <td>GMSL version number as list: major minor revision<br>
   639        </td>
   640      </tr>
   641    </tbody>
   642  </table>
   643  <span style="font-weight: bold;"><br>
   644  gmsl_compatible</span><span style="font-family: monospace;"><br>
   645  <br>
   646  Arguments: List containing the desired library version number (maj min
   647  rev)<br>
   648  </span><span style="font-family: monospace;">Returns:&nbsp;&nbsp;
   649  $(true) if this version of the library is compatible<br>
   650  </span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
   651  with the requested version number, otherwise $(false)</span>
   652  <hr><b>gmsl-print-% (target not a function)</b><br>
   653  <br>
   654  <span style="font-family: monospace;">Arguments: The % should be
   655  replaced by the name of a variable that you<br>
   656  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wish to
   657  print out.<br>
   658  Action:&nbsp;&nbsp;&nbsp; Echos the name of the variable that matches
   659  the % and its value.<br>
   660  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For
   661  example, 'make gmsl-print-SHELL' will output the value of<br>
   662  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the SHELL
   663  variable<br>
   664  </span>
   665  <hr><b>gmsl-echo-% (target not a function)</b><br>
   666  <br>
   667  <span style="font-family: monospace;">Arguments: The % should be
   668  replaced by the name of a variable that you<br>
   669  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wish to
   670  print out.<br>
   671  Action:&nbsp;&nbsp;&nbsp; Echos the value of the variable that matches
   672  the %.<br>
   673  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For
   674  example, 'make gmsl-echo-SHELL' will output the value of<br>
   675  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the SHELL
   676  variable<br>
   677  </span>
   678  <hr><b>assert</b><br>
   679  <br>
   680  <span style="font-family: monospace;">Arguments: 1: A boolean that must
   681  be true or the assertion will fail<br>
   682  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
   683  message to print with the assertion<br>
   684  Returns:&nbsp;&nbsp;&nbsp;None<br>
   685  </span>
   686  <hr><b>assert_exists</b><br>
   687  <br>
   688  <span style="font-family: monospace;">Arguments: 1: Name of file that
   689  must exist, if it is missing an assertion<br>
   690  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; will be
   691  generated<br>
   692  Returns:&nbsp;&nbsp;&nbsp;None<br>
   693  </span>
   694  <hr style="width: 100%; height: 2px;"><br>
   695  GMSL has a number of environment variables (or command-line overrides)
   696  that control various bits of functionality:<br>
   697  <br>
   698  <table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
   699    <tbody>
   700      <tr>
   701        <td><span style="font-style: italic;">Variable</span><br>
   702        </td>
   703        <td><span style="font-style: italic;">Purpose</span><br>
   704        </td>
   705      </tr>
   706      <tr>
   707        <td><span style="font-family: monospace;">GMSL_NO_WARNINGS</span><br>
   708        </td>
   709        <td>If set prevents GMSL from outputting warning messages:
   710  artithmetic functions generate underflow warnings.<br>
   711        </td>
   712      </tr>
   713      <tr>
   714        <td><span style="font-family: monospace;">GMSL_NO_ERRORS</span><br>
   715        </td>
   716        <td>If set prevents GMSL from generating fatal errors: division
   717  by zero or failed assertions are fatal.<br>
   718        </td>
   719      </tr>
   720      <tr>
   721        <td><span style="font-family: monospace;">GMSL_TRACE</span><br>
   722        </td>
   723        <td>Enables function tracing.&nbsp; Calls to GMSL functions will
   724  result in name and arguments being traced.<br>
   725        </td>
   726      </tr>
   727    </tbody>
   728  </table>
   729  <span style="font-family: monospace;"></span><br>
   730  <hr>
   731  Copyright (c) 2005-2022 <a href="https://www.jgc.org/">John Graham-Cumming</a>.<br>
   732  <hr style="width: 100%; height: 2px;">
   733  </body></html>