SkillAgentSearch skills...

Gmtt

A toolkit for tabular data and arithmetic for GNU make

Install / Use

/learn @markpiffer/Gmtt
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

gmtt

The GNU make table toolkit

Overview

gmtt is a collection of GNU make functions which extend GNUmake with arithmetic, string, sorting and searching functions. Among other things it also implements the handling of tabular data (e.g. sorting and searching). The intention for this is to manage build configuration data (like platform dependencies, compilation options, memory ranges, interrupt vectors in embedded system bootloaders and so on) in a way that you are not forced to handle value processing in make-shift (and brittle, and non-portable, and finicky) shell calls and at the same time to have the benefits of simple relational database functionality. It is not the be-all-end-all of Make portability but it cushions a lot of thorny issues.

Tables

make has only one complex data type: list. make lists are just sequences of non-empty strings separated by whitespace characters (space, tab, linefeed). Thus tables are implemented as make lists with a first element denoting the table width (number of colons) as a decimal number: 3 tic tac toe is a table, while alpha beta gamma is not. Of course tables can (and usually will) be written as multi-line defines:

define test-tbl =
3
x1|y1  x2|y1  x3|y1
x1|y2  x2|y2  x3|y2
x1|y3  x2|y3  x3|y3
endef

There are some obvious restrictions on tables: make doesn't recognize string delimiters ("" etc.) so there is no way to have spaces inside one cell:

define illegal-table-there-are-no-strings-in-make = 
2
"This table has 4 rows really!"  x2|y1  
endef

As there is nothing like an empty string as member of a make list, we are also prohibited of using empty cells in a table. You will have to supply a string that denotes "nothing" and that will not get in your way further down the processing line. Here is an example where it is assumed that C-style comments don't harm

define table-with-empty-cells =
3
x1|y1      x2|y1       x3|y1
x1|y2    /*void*/      x3|y2
/*void*/   x2|y3       x3|y3
endef

You can alternatively use the spc-mask function (and its inverse spc-unmask) to concatenate strings with spaces into one table entry. But as always in make, using spaces in the processing of arguments requires much care and endurance to get it right.

Functions on tables

  • sort / reverse sort
  • select (with a 'where' clause, remotely comparable to SQL)
  • map (apply a function on each row)

Arithmetic

All operations are supported for decimal, hexadecimal and octal numbers. The arithemtic range is currently ~64 places (don't exploit the maximum) but this limit can be set rather freely. Numbers are not fixed length (there is only an encapsulated internal representation which the user will never see) so they will be fast if small and slow if long. The bases of all operands can be mixed freely but of course the previously mentioned restrictions apply. The output base is decided by the base of the first operand: $(call add,0x1,1) will produce 0x2 but $(call add,1,0x1) will give 2. Generally the module relies on well-formed numbers:

  • 0x1234 (a hexadecimal)
  • -000123 (a negative octal)
  • 123 (a decimal)

are all processed correctly, while

  • 0x1234- (will be taken as negative)
  • 12 34 (will produce garbage)

are not.

Functions on numbers

  • add
  • subtract
  • multiply
  • divide
  • modulus
  • log2
  • bitwise or
  • bitwise and
  • bitwise xor
  • bitwise not
  • round up to a power of 2
  • round down to a power of 2

Function List

String functions

$(call explode,stringlist,string)

Insert a blank after every occurrence of the strings from stringlist in string. This function serves mainly to convert a string into a list.

  • $(call explode,0 1 2 3 4 5 6 7 8 9,0x1337c0de) --> 0 x1 3 3 7 c0 de

$(call implode,string-with-spaces)

Remove all spaces from the given string. Note that make is mostly unaware of escape characters and therefore takes all spaces verbatim.

  • $(call implode,some\ awkward\ Windows\ path) --> some\awkward\Windows\path

$(call n-list,string,number-of-repetitions)

Create a list with exactly number-of-repetitions copies of a string.

  • $(call n-list,foo,3) --> foo foo foo

$(call bincnt,binary-literal)

Count the binary-literal up by 1, yielding the following binary literal. Leading zeros are preserved.

  • $(call bincnt,010011) -> 010100

$(call symgen)

Generate a different string at each call. The last generated symbol is accessible via $(last-symgen).

  • $(call symgen) --> sym0

$(call interval,start,range[,step])

Create a list of integers starting at start and having range elements with an increase (or decrease) of step from one to the next. step is optional and defaults to 1 if not given.

Example:

  • $(call interval,5,5) --> 5 6 7 8 9
  • $(call interval,2,3,100) --> 2 102 202

$(call lpad,string,final-width,padding-character)

Left-pad an alphanumeric string with the given character up to the given length. If the original string is longer than final-width, nothing is padded. Expample:

  • $(call lpad,123,7,0) --> 0000123
  • $(call lpad,123,7,-) --> ----123

$(call lstrip,string,prefix)

Remove a prefix from the given string. If the prefix doesn't exist, the string is unchanged.

  • $(call lstrip,0xABCD,0x) --> ABCD

$(call str-eq,string1,string2)

Compare two strings on equality. Strings are allowed to have blanks. Return non-empty if string $1 and $2 are identical, empty string otherwise.

  • $(call str-eq,yes,no) --> (empty string)
  • $(call str-eq,yes ,yes) --> (empty string)
  • $(call str-eq,yes ,yes ) --> t

$(call str-ne,string1,string2)

Compare two strings on inequality. The obvious inverse to str-eq. Strings are allowed to have blanks. Return empty if string $1 and $2 are identical, a non-empty string otherwise.

  • $(call str-eq,yes,no) --> t
  • $(call str-eq,yes ,yes) --> t
  • $(call str-eq,yes ,yes ) --> (empty string)

$(call str-le,string1,string2)

Compare two strings lexically for string1 less-or-equal string2. Lexical ordering means that 'aa' < 'aaa' < 'aab' < 'ab'. The empty string always compares smaller than any other string. The strings may contain spaces but leading and trailing spaces are not considered in the comparison and multiple interior spaces are substituted by a single one. Spaces compare smaller than downcase characters but greater than upcase. In short: you should know what you are doing if you have spaces inside your strings. Examples:

  • $(call str-le,aaa,ab)) --> t
  • $(call str-le, ab aa,aa)) --> (empty string)
  • $(call str-le,aa,aa)) --> t
  • $(call str-le,aa,a)) --> (empty string)
  • $(call str-le,a,)) --> (empty string)
  • $(call str-le,,a)) --> t
  • $(call str-le,MacGyver John,Mac Gyver John)) --> t
  • $(call str-le,macgyver john,mac gyver john)) --> (empty string)

$(call str-ge,string1,string2)

Compare two strings lexically for string1 greater-or-equal string2. Lexical ordering means that 'aa' < 'aaa' < 'aab' < 'ab'. The empty string always compares smaller than any other string. The strings may contain spaces but leading and trailing spaces are not considered in the comparison and multiple interior spaces are substituted by a single one. Spaces compare smaller than downcase characters but greater than upcase. In short: you should know what you are doing if you have spaces inside your strings. Examples:

  • $(call str-ge,aaa,ab)) --> (empty string)
  • $(call str-ge, ab aa,aa)) --> t
  • $(call str-ge,aa,aa)) --> t
  • $(call str-ge,aa,a)) --> t
  • $(call str-ge,a,)) --> t
  • $(call str-ge,,a)) --> (empty string)
  • $(call str-ge,MacGyver John,Mac Gyver John)) --> (empty string)
  • $(call str-ge,macgyver john,mac gyver john)) --> t

$(call str-match,string1,string2)

Compare two strings on equality under wildcard substitution. The wildcard can appear in both of the strings. Return t if string1 and string2 match where the first % is taken as wildcard, return empty string otherwise.

  • $(call str-match,Mickey%Mouse,Mickey Mouse)) --> t
  • $(call str-match,Mickey%,MickeyMouse)) --> t
  • $(call str-match,Mickey%,)) --> (empty string)
  • $(call str-match,Mickey %ouse,Mickey Mouse)) --> t
  • $(call str-match,MickeyMouse,MickeyMouse%)) --> t
  • $(call str-match,,%)) --> t

$(call glob-match,string,pattern)

Try to match the string with the pattern, applying glob-syntax. Glob-syntax is well known from the shell and https://en.wikipedia.org/wiki/Glob_(programming) All characters match themselves except:

  • * - zero or more arbitrary chars
  • ? - exactly one arbitrary char
  • [] - exactly one character from the set designated inside the brackets:
    • [abc] - explicit, matches one of a, b or c
    • [a-z] - range, matches one of a,b...z. The possibly ranges can be taken from $(all-chars)
    • []abc] - first position is the only way to match a ]
    • [-abc] - first or last position is the only way to match a -
    • [!a-z] - ! inverts the match, i.e. everything but a..z

If no match occurred, the (empty string) is returned. If the string matches, it is returned with all parts corresponding to one of the above wildcards separated by space. As GNUmake treats everything which is different from the empty string as true, this function serves the simple matching test as well as a string dissection by wildcard patterns. Spaces inside your string are automatically preserved. The elements of the string are returned but with all original spaces replaced by an internal character to circumvent the rule that GNUmake treats spaces as list element separators. Use `spc-

View on GitHub
GitHub Stars35
CategoryDevelopment
Updated3mo ago
Forks3

Languages

Makefile

Security Score

87/100

Audited on Dec 24, 2025

No findings