Previous: , Up: Built-in functions   [Contents][Index]

File-reading functions

File-reading functions

FILE_DATA interacts with the surrounding system by parsing a named file as a table and returning the contents of a specified row and column.

Function: FILE_DATA (‘(filename [, column [, row [, column-seps [, row-seps]]]] ‘)’)

Read the contents of file filename and parse the data read into rows and columns. Rows are separated by one or more characters appearing in the string row-seps (default: ‘\n’, i.e., a newline character). Columns are separated by one or more characters appearing in the string col-seps (default: ‘ \t, i.e., a space and a tab). Once the data are parsed in this manner, the cell at column column (default: ‘1’) and row row (default: ‘1’) is converted to a number and returned.

Columns and rows are each numbered starting from 1. Negative numbers represent offsets from the last column or row. Zero values cause the program to abort with an error message.

Consider a data file, example.dat, with the following contents:

Eir    231  58 490 703  19 644 967
Gunnr  901 875 141 372 374 618  77
Herja   17 979 363 930 977
Hrist  100 132 981 246  93 614
Svipul 688 536 965 746 209

Then, the following uses of FILE_DATA return the results shown:

The use of FILE_DATA is discouraged in coNCePTuaL programs because of its reliance on external files, whose contents are not automatically preserved in any coNCePTuaL log files (see Interpreting coNCePTuaL log files) and which may exhibit system-specific behavior (e.g., if the file is in fact a named pipe or a file-like interface to a kernel data structure). However, FILE_DATA can be useful in certain circumstances for logging changes in system state of which coNCePTuaL would otherwise be unaware. For example, one might log values from various pseudo-files appearing in Linux’s /proc filesystem or from system log files (e.g., those within Linux’s /var/log directory).

Because coNCePTuaL cannot determine a priori if multiple reads of the same row and column from the same file will produce the same value it pessimistically assumes that each read produces a different value. (Consider even the simple case of FILE_DATA reading the last row of a system log file to which another process is asynchronously appending.) Consequently, FILE_DATA cannot be used in any context that requires multiple tasks to agree on a value, such as within message specifications (see Message specifications) or let bindings (see Binding variables). For cases where the programmer can assert that reads from a particular row and column will always return the same value (on penalty of undefined behavior, including hangs and crashes), coNCePTuaL provides the following function:

Function: STATIC_FILE_DATA (‘(filename [, column [, row [, column-seps [, row-seps]]]] ‘)’)

Perform exactly the same operation as FILE_DATA but with the programmer’s guarantee that the file contents will not change from invocation to invocation. STATIC_FILE_DATA can therefore be used in places where FILE_DATA is disallowed.

Given the example.dat file shown previously, the following let binding is legitimate:

LET msg_size BE STATIC_FILE_DATA("example.dat", 2, iter) AND rank_ofs
BE STATIC_FILE_DATA("example.dat", 3, iter) MOD num_tasks WHILE …

However, the following, which uses FILE_DATA instead of STATIC_FILE_DATA, is not:

LET msg_size BE FILE_DATA("example.dat", 2, iter) AND rank_ofs BE
FILE_DATA("example.dat", 3, iter) MOD num_tasks WHILE …

STATIC_FILE_DATA can be used as above to implement complex, irregular communication patterns that vary across runs of the program. That is, each iteration, a different value read from the file can be used to specify the message size and the distance between senders and receivers.

The use of STATIC_FILE_DATA is even more discouraged than the use of FILE_DATA because an incorrect claim that a file’s contents are unvarying could lead to abnormal program behavior—and not necessarily easily detectable. It is best to avoid both FILE_DATA and STATIC_FILE_DATA if possible. If not, use FILE_DATA unless (a) the compiler rejects the program on the grounds that FILE_DATA is being used in an invalid location and (b) the data being read is known to be invariant throughout the lifetime of the program.

Previous: , Up: Built-in functions   [Contents][Index]

Scott Pakin,