Adding dynamic variables and expressions to control file content

Introduction

With wpkg, your control files support dynamic variables and dynamic C-like expressions.

The parsing of the field values is actually done repetitively until all variables and C-like expressions were transformed. Also references to fields through a variable or an expression can lead to accessing many values to build one field. Note that cyclic references are, however, not allowed. So if field A references B and then B references A an error is generated.

Limitations

All the fields of a control file can include variables and C-like expressions except one: Package.

Debian makes use of the tool deb-substvars to substitute the variables found in control files. This is done at a later time so they do not support variables in the Package, Source, and Architecture fields which may be accessed before being converted.

In our case, we do not allow variables in the Package field only for security reasons (i.e. one control file should not represent more than one package.) As far as we know, the restriction could be removed and everything would still work as expected since the substitution is done transparently at all times in our case.

Variables

Variables are defined with the --field-variables command line option, in the sustvars file, or internally (see table below). They are accessed using the curly brackets ({ and }) syntax as follow:

Architecture: ${PACKAGE_ARCH}

The system defines a set of internal variables that one can use in their control files. The following table lists those variables. It is important to be noted that those variables are not available in expressions. Instead, some other variables or function calls can be used to access that data.

Variable Name Variable Content
Arch This variable represents the Architecture field as defined in the core package. It may not always be available.
To access the architecture the packager tool was compiled with, use the $(architecture()) function instead.
source:Version
source:Upstream-Version
Source-Version
binary:Version
Returns a copy of the Version field value.

I'm not too sure how we could offer an Upstream Version unless we offer such a field in the control file and the package maintainer properly maintains that version. Also it is not unlikely not really useable since that upstream version may not be a Debian compatible version (just a string we cannot do much with.)

These variables are not currently implemented.
Installed-Size
Extra-Size
Format
These names are understood and rejected (with an error).
Newline This variable inserts a newline ("\n") character in the stream.
Space This variable inserts a space (" ") character in the stream.
Tab This variable inserts a tab ("\t") character in the stream (not that tabs are actually forbidden.)
wpkg:Upstream-Version
wpkg:Version
The version of the running wpkg.
F:<field>
f:<field>
Return the value of the named <field>. If the field is not defined, return an empty string and generate a warning. The expression equivalent is $(get_field("<field>")).
V:<variable>
v:<variable>
Return the value of the named <variable>, as defined in the control file (variable-name = <value>). If the variable is not defined, return an empty string and generate a warning.
shlibs:<dependency> Any variable name that starts with "shlibs:" is recognized, but it is currently rejected (with an error).

However, variables are somewhat limited since their value have to be fully defined at the time they get used.

C-Like Expressions

wpkg supports a C-like expression parser which is used to do additional work on your control file data. Such expressions are written between parenthesis starting with a dollar sign as follow:

Date: $(ctime(time()))

In this example we are getting the current Unix time with the time() function call. Then we transform that time to a string with the ctime() function. The whole is inside $(...) which allows wpkg to know that this is an expression that needs to be checked at runtime.

Note that variables (as accessed with the ${...} syntax) are NOT accessible from the C-Like Expression system. We may add those at a later time though.

Expressions support the following identities:

  • Identifiers (variable and function names),
  • Strings (written between double quotes),
  • Characters (written between single quotes),
  • Integer numbers, and
  • Floating point numbers.

The C like expression supports the following operations group by type (i.e. the order of operation or priority is the same that C++, see this table for proper priority of those operators):

Operation Comment
(...) Parenthesis can be used to group operations together. For example 3 * (4 + 9) becomes 3 * 13 and the result is 39.
++, -- Increment, decrement a number. They can be used as prefix or postfix operators. They apply to variables or numbers.
<<, >>, >>=, <<= Shift the value left or right by the specified number of bits. The left-hand value is first transformed to an integer. The assign operators assign the result to the variable on the left side.
!, &&, ||, ^^ Logical not, and, or, and xor; note that xor is an addition from C++, which forces the left and right hand sides to a Boolean value before applying the operation. This is different from ^ by itself, equivalent to !(!a ^ !b) in C/C++. Note that both: the left and right hand sides are always evaluated because we are evaluating this expression dynamically.
<, <=, >, >=, ==, != Comparison operators: less than, less or equal, larger than, larger or equal, equal, and not equal.
*, /, %, *=, /=, %= Multiplicative operators: multiply, divice, and corresponding assignments which set assign the result to the variable on the left side.
+, -, +=, -= Additive operators: add, subtract, and corresponding assignments which set assign the result to the variable on the left side. We also support + and - as unary operators as in: +6.4 and -pi.
~, &, |, ^, &=, |=, ^= Bitwise operators: not, and, or, xor, and corresponding assignments which set assign the result to the variable on the left side.
= The basic assignment operator; other assignment operators are shown along their corresponding operations. All assignment operators expect an identifier on the left hand side: the variable that receives the result.
c ? x : y The conditional operator: if c is true return x otherwise return y. Note that x and y are both evaluated because we compute this expression dynamically.
/* ... */ C-like comments are supported. Although C++ like comments are supported by the expression library, we strongly suggest that you do not use those in a wpkg control file because the new-lines may not all make it to the expression parser as expected.

The C like expression supports the following functions:

Function Operation Support
acos(x) Return the arc cosine of x  
acosh(x) Return the arc cosine hyperbolic of x  
architecture() Return the name of the architecture used to build wpkg wpkg
asin(x) Return the arc sinus of x  
asinh(x) Return the arc sinus hyperbolic of x  
atan(x) Return the arc tangent of x  
atan2(x, y) Return the arc tangent of x / y, if y is zero, return pi / 2  
atanh(x) Return the arc tangent hyperbolic of x  
ceil(x) Return the ceiling of x  
cos(x) Return the cosine of x  
cosh(x) Return the hyperbolic cosine of x  
ctime(x) Return a string representing the Unix time x  
exp(x) Return the exponent of x (ex)  
fabs(x) Return the absolute value of x  
floor(x) Return the floor of x  
fmod(x, y) Return the modulo (rest) of x / y  
getfield(x) Return the value of field x as a string unless it represents a valid number wpkg
log(x) Return the log of x base e  
log10(x) Return the log of x base 10  
lrint(x) Return the closest integral part of x (0.5 is rounded up), the result is an integer number  
os() Return the name of the operating system wpkg was compiled with wpkg
pow(x, y) Return x power y (xy)  
processor() Return the name of the processor wpkg was compiled with wpkg
rint(x) Return the closest integral part of x (0.5 rounded up), the result is a floating point number  
shell(x [, y = "output"]) Return the output (y = "output", the default) or the exit code (y = "exitcode") of the command line x  
sin(x) Return the sinus of x  
sinh(x) Return the sinus hyperbolic of x  
sqrt(x) Return the square root of x  
strlen(x) Return the length of the string x  
tan(x) Return the tangent of x  
tanh(x) Return the tangent hyperbolic of x  
time() Return the current Unix time  
triplet() Return the operating system, vendor, and processor triplet wpkg
vendor() Return the name of the vendor wpkg was compiled with wpkg
versioncmp(x, y)1 Return -1 if x is smaller than y, 0 when x and y are equal, and +1 when x is larger than y wpkg
wpkgversion() Return the version of wpkg as a string wpkg

Internally defined variables:

Variable Name Value
e 2.7182818284590452354
pi 3.14159265358979323846

Strings support the following escape characters:

Escape Sequence Corresponding Octal Comment
\a \007 Bell
\b \008 Backspace
\e \037 Escape2
\f \014 Formfeed
\n \012 Newline
\r \015 Carriage Return
\t \009 Horizontal Tab
\v \013 Vertical Tab

 

  • 1. In versioncmp() x and y must be valid Debian versions defined as strings.
  • 2. This is usually not available in C/C++