Expressions are language constructs, that evaluate to a value, that can subsequently be echoed, tested in a conditional statement, assigned to a variable or passed to a function.
• Constant expressions | String and Numeric Constants. | |
• Function calls | A Function Call is an Expression. | |
• Concatenation | String Concatenation. | |
• Arithmetic operations | ‘+’, ‘-’, etc. | |
• Bitwise shifts | ‘<<’ and ‘>>’. | |
• Relational expressions | ‘=’, ‘<’, etc. | |
• Special comparisons | matches , mx matches , etc.
| |
• Boolean expressions | and , or , not .
| |
• Precedence | How various operators nest. | |
• Type casting |
Next: Function calls, Up: Expressions [Contents][Index]
Literals and numbers are constant expressions. They evaluate to string and numeric types.
Next: Concatenation, Previous: Constant expressions, Up: Expressions [Contents][Index]
A function call is an expression. Its type is the return type of the function.
Next: Arithmetic operations, Previous: Function calls, Up: Expressions [Contents][Index]
Concatenation operator is ‘.’ (a dot). For example, if
$f
is ‘smith’, and $client_addr
is
‘10.10.1.1’, then:
$f . "-" . $client_addr ⇒ "smith-10.10.1.1"
Any two adjacent literal strings are concatenated, producing a new string, e.g.
"GNU's" " not " "UNIX" ⇒ "GNU's not UNIX"
Next: Bitwise shifts, Previous: Concatenation, Up: Expressions [Contents][Index]
The filter script language offers the common arithmetic operators: ‘+’, ‘-’, ‘*’ and ‘/’. In addition, the ‘%’ is a modulo operator, i.e. it computes the remainder of division of its operands.
All of them follow usual precedence rules and work as you would expect them to.
Next: Relational expressions, Previous: Arithmetic operations, Up: Expressions [Contents][Index]
The ‘<<’ represents a bitwise shift left operation, which shifts the binary representation of the operand on its left by the number of bits given by the operand on its right.
Similarly, the ‘>>’ represents a bitwise shift right.
Next: Special comparisons, Previous: Bitwise shifts, Up: Expressions [Contents][Index]
Relational expressions are:
Expression | Result |
---|---|
x < y | True if x is less than y. |
x <= y | True if x is less than or equal to y. |
x > y | True if x is greater than y. |
x >= y | True if x is greater than or equal to y. |
x = y | True if x is equal to y. |
x != y | True if x is not equal to y. |
The relational expressions apply to string as well as to numbers. When a relational operation applies to strings, case-sensitive comparison is used, e.g.:
"String" = "string" ⇒ False "String" < "string" ⇒ True
Next: Boolean expressions, Previous: Relational expressions, Up: Expressions [Contents][Index]
In addition to the traditional relational operators, described
above, mailfromd
provides two operators for regular
expression matching:
Expression | Result |
---|---|
x matches y | True if the string x matches the regexp denoted by y. |
x fnmatches y | True if the string x matches the globbing pattern denoted by y. |
The type of the regular expression used by matches
operator
is controlled by #pragma regex
(see pragma regex). For example:
$f ⇒ "gray@gnu.org.ua" $f matches '.*@gnu\.org\.ua' ⇒true
$f matches '.*@GNU\.ORG\.UA' ⇒false
#pragma regex +icase $f matches '.*@GNU\.ORG\.UA' ⇒true
The fnmatches
operator compares its left-hand operand with a
globbing pattern (see glob(7)) given as its right-hand side
operand. For example:
$f ⇒ "gray@gnu.org.ua" $f fnmatches "*ua" ⇒true
$f fnmatches "*org" ⇒false
$f fnmatches "*org*" ⇒true
Both operators have a special form, for ‘MX’ pattern matching. The expression:
x mx matches y
is evaluated as follows: first, the expression x is analyzed and, if it is an email address, its domain part is selected. If it is not, its value is used verbatim. Then the list of ‘MX’s for this domain is looked up. Each of ‘MX’ names is then compared with the regular expression y. If any of the names matches, the expression returns true. Otherwise, its result is false.
Similarly, the expression:
x mx fnmatches y
returns true only if any of the ‘MX’s for (domain or email) x match the globbing pattern y.
Both mx matches
and mx fnmatches
can signal the
following exceptions: e_temp_failure
, e_failure
.
The value of any parenthesized subexpression occurring within the
right-hand side argument to matches
or mx matches
can be
referenced using the notation ‘\d’, where d is the
ordinal number of the subexpression (subexpressions are numbered from
left to right, starting at 1). This notation is allowed in the
program text as well as within double-quoted strings and
here-documents, for example:
if $f matches '.*@\(.*\)\.gnu\.org\.ua' set message "Your host name is \1;" fi
Remember that the grouping symbols are ‘\(’ and ‘\)’ for basic regular expressions, and ‘(’ and ‘)’ for extended regular expressions. Also make sure you properly escape all special characters (backslashes in particular) in double-quoted strings, or use single-quoted strings to avoid having to do so (see singe-vs-double, for a comparison of the two forms).
Next: Precedence, Previous: Special comparisons, Up: Expressions [Contents][Index]
A boolean expression is a combination of relational or
matching expressions using the boolean operators and
, or
and not
, and, eventually, parentheses to control nesting:
Expression | Result |
---|---|
x and y | True only if both x and y are true. |
x or y | True if any of x or y is true. |
not x | True if x is false. |
Binary boolean expressions are computed using shortcut evaluation:
x and y
If x ⇒
, the result is false
false
and y is not evaluated.
x or y
If x ⇒
, the result is true
true
and
y is not evaluated.
Next: Type casting, Previous: Boolean expressions, Up: Expressions [Contents][Index]
Operator precedence is an abstract value associated with each
language operator, that determines the order in which operators are
executed when they appear together within a single expression.
Operators with higher precedence are executed first. For example,
‘*’ has a higher precedence than ‘+’, therefore the
expression a + b * c
is evaluated in the following order: first
b
is multiplied by c
, then a
is added to the
product.
When operators of equal precedence are used together they are evaluated from left to right (i.e., they are left-associative), except for comparison operators, which are non-associative (these are explicitly marked as such in the table below). This means that you cannot write:
if 5 <= x <= 10
Instead, you should write:
if 5 <= x and x <= 10
The precedence of the mailfromd
operators where selected
so as to match that used in most programming languages.15
The following table lists all operators in order of decreasing precedence:
(...)
Grouping
$ %
Sendmail
macros and mailfromd
variables
* /
Multiplication, division
+ -
Addition, subtraction
<< >>
Bitwise shift left and right
< <= >= >
Relational operators (non-associative)
= != matches fnmatches
Equality and special comparison (non-associative)
&
Logical (bitwise) AND
^
Logical (bitwise) XOR
|
Logical (bitwise) OR
not
Boolean negation
and
Logical ‘and’.
or
Logical ‘or’
.
String concatenation
Previous: Precedence, Up: Expressions [Contents][Index]
When two operands on each side of a binary expression have
different type, mailfromd
evaluator coerces them to a
common type. This is known as implicit type casting. The rules
for implicit type casting are:
The construct for explicit type cast is:
type(expr)
where type is the name of the type to coerce expr to. For example:
string(2 + 4*8) ⇒ "34"
A special case of type casting is cast to void
. It is used to
ignore return value of a function call between the braces, e.g.:
void(dlcall(libh, "extlog", "s", text))
The only exception is ‘not’, whose precedence in MFL is much lower than usual (in most programming languages it has the same precedence as unary ‘-’). This allows to write conditional expressions in more understandable manner. Consider the following condition:
if not x < 2 and y = 3
It is understood as “if x
is not less than 2 and y
equals 3”,
whereas with the usual precedence for ‘not’ it would have meant
“if negated x
is less than 2 and y
equals 3”.
Previous: Precedence, Up: Expressions [Contents][Index]