Mailfromd |
|
General-Purpose Mail Filter |
Sergey Poznyakoff |
Mailfromd Manual (split by node): | ? |
The loop statement allows for repeated execution of a block of code, controlled by some conditional expression. It has the following form:
loop [label] [for stmt1] [,while expr1] [,stmt2] do stmt3 done [while expr2] |
where stmt1, stmt2, and stmt3 are statement lists, expr1 and expr2 are expressions.
The control flow is as follows:
Thus, stmt3 is executed until either expr1 or expr2 yield a zero value.
The loop body – stmt3 – can contain special statements:
break [label]
Terminates the loop immediately. Control passes to ‘6’ (End) in the formal definition above. If label is supplied, the statement terminates the loop statement marked with that label. This allows to break from nested loops.
It is similar to break
statement in C or shell.
next [label]
Initiates next iteration of the loop. Control passes to ‘4’ in the formal definition above. If label is supplied, the statement starts next iteration of the loop statement marked with that label. This allows to request next iteration of an upper-level loop from a nested loop statement.
The loop
statement can be used to create iterative statements
of arbitrary complexity. Let's illustrate it in comparison with C.
The statement:
loop do stmt-list done |
creates an infinite loop. The only way to exit from such a loop is to
call break
(or return
, if used within a function),
somewhere in stmt-list.
The following statement is equivalent to while (expr1)
stmt-list
in C:
loop while expr do stmt-list done |
The C construct for (expr1; expr2; expr3)
is written in MFL as follows:
loop for stmt1, while expr2, stmt2 do stmt3 done |
For example, to repeat stmt3 10 times:
loop for set i 0, while %i < 10, set i %i + 1 do stmt3 done |
Finally, the C ‘do’ loop is implemented as follows:
loop do stmt-list done while expr |
As a real-life example of a loop statement, let's consider the
implementation of function ptr_validate
, which takes a single
argument ipstr, and checks its validity using the following algorithm:
Perform a DNS reverse-mapping for ipstr, looking up the
corresponding PTR
record in ‘in-addr.arpa’. For each record
returned, look up its IP addresses (A records). If ipstr is
among the returned IP addresses, return 1 (true
), otherwise
return 0 (false
).
The implementation of this function in MFL is:
#pragma regex push +extended func ptr_validate(string ipstr) returns number do loop for string names dns_getname(%ipstr) . " " number i index(%names, " "), while %i != -1, set names substr(%names, %i + 1) set i index(%names, " ") do loop for string addrs dns_getaddr(substr(%names, 0, %i)) . " " number j index(%addrs, " "), while %j != -1, set addrs substr(%addrs, %j + 1) set j index(%addrs, " ") do if %ipstr == substr(%addrs, 0, %j) return 1 fi done done return 0 done |
Mailfromd Manual (split by node): | ? |
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.