dadlldate-line
DLL Usage Description
Library: dadlldataline
This library contains the following functions:
- scan.sepa : scan a dataline in separator format
- scan.fix : scan a dataline in fixed length format
- concat.sepa: print a dataline in separator format (will not be implemented)
- concat.fix : print a dataline in fixed length format (not yet implemented)
DLL Prototypes
function extern concat.fix(
ref string dataline(),
long offset,
const long spos(,),
const long leng(,),
long index, ... )
pre : let variable part of argument list be arg1, ..., argn (n >= 0)
let the types of these arguments be typei (1 <= i <= n)
space reserved for dataline is long enough to contain result
AND offset >= 1
AND length_of_array(spos) >= n
AND length_of_array(leng) >= n
AND FORALL i: 1 <= i <= length_of_array(spos) : spos(i) >= 1
AND FORALL i: 1 <= i <= length_of_array(leng) : leng(i) >= 0
post : FORALL i: 1 <= i <= n:
- dataline(offset+spos(i)-1; leng(i)) =
( typei = string ? argi : str$(argi) )
desc : This is a rather operational description and certainly not
formally correct. Problems:
- overlapping arguments: if for some arguments the place where
they should come in the result string do overlap the above
statement should hold for at least one of these arguments.
So it is not defined in what order the arguments should be
placed into the string.
- if len(argi) > leng(i) (typei = string) then argi should be
truncated.
if len(str$(argi)) > leng(i) (typei = numeric) then
str$(argi) should be truncated (and hopefully its only
loosing precision).
function extern long scan.fix(
const string dataline(),
ref long offset,
const long spos(,),
const long leng(,),
long index,
long llen, ... )
pre : let variable part of argument list be arg1, ..., argn (n >= 0)
let the types of these arguments be typei (1 <= i <= n)
offset >= 1
AND length_of_array(spos) = length_of_array(leng) >= n
AND FORALL i: 1 <= i <= n : spos(i) >= 0
AND FORALL i: 1 <= i <= n : leng(i) >= 0
AND FORALL i: 1 <= i <= n : spos(i) = 0 => leng(i) = 0
AND llen = MAX j: 1 <= j <= n : spos(j) + leng(j) - 1
return: len(line) >= offset + llen - 1
or (len(line) >= offset + spos(n) - 1 and typen = string)
post : ret ==>
FORALL i: 1 <= i <= n and spos(i) > 0:
typei = string ==> argi = dataline(offset+spos(i)-1;leng(i))
typei = double ==> argi = val( ,, )
typei = long ==> argi = lval( ,, )
AND FORALL i: 1 <= i <= n and spos(i) = 0: argi = old(argi)
AND offset = old(offset) + llen
desc: In contrast to the function concat.fix this function
does not have problems with overlapping fields.
Note that fields that have an spos of 0 may not be changed,
nor emptied (this is to skip multiline fields).
function extern long scan.sepa(
const string dataline(),
ref long offset,
string sepa(1),
string encl(1), ... )
pre : let variable part of argument list be arg1, ..., argn (n >= 0)
let the types of these arguments be typei (1 <= i <= n)
offset >= 1
AND len(sepa) = 1
return: The number of arguments that could be filled
(thus 0 <= retval <= n)
post : FORALL i: 1 <= i <= retval:
typei = long ==> argi = lval(SUBSTR(i)) AND
typei = double ==> argi = val(SUBSTR(i)) AND
typei = string and (encl = "" or SUBSTR(i) = "")
==> argi = SUBSTR(i) AND
typei = string and encl <> ""
==> argi = SUBSTR(2; len(SUBSTR(i)-2))
offset = old(offset) + SEPA.OCC(retval) - 1
desc : where SUBSTR(i) is defined as:
dataline(offset+SEPA.OCC(i-1); SEPA.OCC(i)-SEPA.OCC(i-1)-1)
(informally: the substring between the (i-1)th and the ith
separator)
and where SEPA.OCC is defined as:
SEPA.OCC(0) = 0
SEPA.OCC(1) = pos(dataline(offset), sepa)
SEPA.OCC(n) = SEPA.OCC(n-1) +
pos(dataline(offset+SEPA.OCC(n-1)), sepa)
(as long as this pos is positive and not considering separators
occuring between enclosing characters)
SEPA.OCC(m) = len(dataline) - offset + 2
(otherwise)
(informally: the ith occurence of the separator in
dataline(offset) or the index just after the end of the
string, if not existing)
Thus this function splits dataline into substrings separated
by the separator sepa. The substrings are assigned (if
necessary using the conversion functions lval or val) to the
arguments. The offset is placed behind the last substring
scanned (or if this last substring is followed by a separator
behind this separator).
The return value indicates how many arguments could be scanned
and thus will be limited by:
- the number of variable arguments
- the number of separators occuring in dataline (from
position offset on)
If encl <> "" string arguments must be either:
- enclosed by the enclosing character encl
- empty (ie 2 separators occur on subsequent positions)
Note that it is possible that a string is scanned in several
phases and thus, that offset should be just behind the
separator after the nth argument (and not on it)