next up previous contents index
Next: String Manipulation Up: Library Utilities Previous: Ground, Numbervars, Subsumption, Variant   Contents   Index


Lower-Level I/O

XSB has various low-level routines that support input and output, at both the term level and the character level. Unlike the standard Prolog stream I/O, the low-level routines use XSB I/O ports to refer to files. XSB I/O ports should not be confused with the file descriptors used by the OS Both are small integers, but they refer to different things. However, the OS file descriptors are objects returned by the C open function; XSB I/O ports indices into the internal XSB table of open files. The OS does not know about XSB I/O ports, while XSB (obviously) does know about the OS file descriptors. Typically XSB opens files for buffered I/O (whether using the stream I/O predicates or the predicates described here), so XSB I/O ports internally refer to FILE data structures (those returned by the C fopen function).

When it starts, XSB opens a number of standard I/O ports that it uses to print results, errors, debugging info, etc. The descriptors are described in the file prolog_includes/standard.h. This file provides the following symbolic definitions:


    #define STDIN            0
    #define STDOUT           1
    #define STDERR           2
    #define STDWARN          3    /* output stream for xsb warnings  */
    #define STDMSG           4    /* output for regular xsb messages */
    #define STDDBG           5    /* output for debugging info       */
    #define STDFDBK          6    /* output for XSB feedback
                                     (prompt/yes/no/Aborting/answers) */

    #define AF_INET     0     /* XSB-side socket request for Internet domain */
    #define AF_UNIX     1     /* XSB-side socket request for UNIX domain */
In addition, the file emu/file_modes_xsb.h provides the definitions for the file opening modes:

    #define OREAD          0    /* open for read           */
    #define OWRITE         1    /* open for write          */
    #define OAPPEND        2    /* open for append         */
    #define OSTRINGR       3    /* open string for reading */
    #define OSTRINGW       4    /* open string for writing (not implemented) */
These definitions can be used in user programs, if the following is provided at the top of the source file:

    compiler_options([xpp_on]).
    #include "standard.h"
    #include "file_modes_xsb.h"
(Note: the XSB preprocessor is not invoked on clauses typed into an interactive XSB session, so the above applies only to programs loaded from a file using consult and such.)

current_input_port(-IOport)
curr_sym
See current_output_port/1.
current_output_port(-IOport)
curr_sym
The above two predicates instantiate IOport to the XSB I/O port for the current user input and output ( i.e., the things that are manipulated through see/seen and tell/told predicates). Once the I/O port is obtained, it is possible to safely use the lower-level I/O predicates described below interchangeably with stream I/O.

file_open(+FileName,+Mode,-IOport)
file_io
Opens a file with name FileName to be accessed in mode Mode and returns a file-descriptor in IOport that can be used to access the file. If Mode is atom `` r'', the the file is opened for reading; if it is `` w'', the file is opened for writing; if it is `` a'', the file is opened for appending. If Mode is `` sr'', then the string making up the atom FileName is treated as the contents of the file, and a descriptor is returned that allows ``file'' access to that string. This is how one can use XSB's term I/O routines to build terms from atoms. Mode `` sw'' is reserved for ``open string for writing,'' but this has not been implemented as of yet.

The old-style mode specification, 0 ( OREAD), 1 ( OWRITE), 2 ( OAPPEND), or 3 ( OSTRING), is also supported.

file_reopen(+FileName,+Mode,+IOport,-RetCode)
file_io
Takes an existing I/O port, closes it, then opens it and attaches it to a file. This can be used to redirect I/O from any of the standard streams to a file. For instance,

    | ?- file_reopen('/dev/null', w, 3, Error).
redirects all warnings to the Unix black hole.

On success, RetCode is 0; on error, the return code is negative.

tmpfile_open(-IOport)
file_io
Opens a temporary file with a unique filename. The file is deleted when it is closed or when the program terminates.

file_clone(+SrcIOport,?DestIOport,-RetCode)
file_io
This is yet another way to redirect I/O. It is a prolog interface to the C dup and dup2 system calls. If DestIOport is a variable, then this call creates a new XSB I/O port that is a clone of SrcIOport. This means that I/O sent to either descriptor goes to the same place. If DestIOport is not a variable, then it must be a number corresponding to a valid I/O port. In this case, XSB closes DestIOport and makes it into a clone on SrcIOport. For instance, suppose that 10 is a I/O port that is currently open for writing to file foo.bar. Then

    | ?- file_clone(10,3,_).
causes all messages sent to XSB standard warnings port to go to file foo.bar. While this could be also done with file_reopen, there are things that only file_clone can do:

    | ?- file_clone(1,10,_).
This means that I/O port 10 now becomes clone of standard output. So, all subsequent I/O will now go to standard output instead of foo.bar.

On success, RetCode is 0; on error, the return code is negative.

file_close(+IOport)
file_io
Closes the file (or string) for descriptor IOport.

[ fmt_read(+Fmt,-Term,-Ret)] file_io

[ fmt_read(+IOport,+Fmt,-Term,-Ret)] file_io
These predicates provides a routine for reading data from the current input file (which must have been already opened by using see/1) according to a C format, as used in the C function scanf. To use it, it must be imported from the module file_io. Fmt must be a string of characters (enclosed in "") representing the format that will be passed to the C call to scanf. See the C documentation for scanf for the meaning of this string. The usual alphabetical C escape characters ( e.g., $\backslash n$) are recognized, but not the octal or the hexadecimal ones. Another difference with C is that, unlike most C compilers, XSB insists that a single % in the format string signifies format conversion specification. (Some C compilers might output % if it is not followed by a valid type conversion spec.) So, to output % you must type %%. Format can also be an atom enclosed in single quotes. However, in that case, escape sequences are not recognized and are printed as is.

Term is a term ( e.g., args(X,Y,Z)) whose arguments will be unified with the field values read in. (The functor symbol of Term is ignored.) Special syntactic sugar is provided for the case when the format string contains only one format specifier: If Term is a variable, X, then the predicate behaves as if Term were arg(X).

If the number of arguments exceeds the number of format specifiers, a warning is produced and the extra arguments remain uninstantiated. If the number of format specifiers exceeds the number of arguments, then the remainder of the format string (after the last matching specifier) is ignored.

Note that floats do not unify with anything. Ret must be a variable and it will be assigned a return value by the predicate: a negative integer if end-of-file is encountered; otherwise the number of fields read (as returned by scanf.)

fmt_read cannot read strings (that correspond to the %s format specifier) that are longer than 16K. Attempting to read longer strings will cause buffer overflow. It is therefore recommended that one should use size modifiers in format strings ( e.g., %2000s), if such long strings might occur in the input.

[ fmt_write(+Fmt,+Term)] file_io

[ fmt_write(+IOport,+Fmt,+Term)] file_io
This predicate provides a routine for writing data to the current output file (which must have been already opened by using tell/1) according to a C format, as used in the C function printf. To use it, it must be imported from the module file_io. Fmt must be a string of characters (enclosed in "") representing the format that will be passed to the C call to scanf. See the C documentation for scanf for the meaning of this string. The usual alphabetical C escape characters ( e.g., $\backslash n$) are recognized, but not the octal or the hexadecimal ones.

In addition to the usual C conversion specifiers, %S is also allowed. The corresponding argument can be any Prolog term. This provides an easy way to print the values of Prolog variables, etc.

Another difference with C is that, unlike most C compilers, XSB insists that a single % in the format string signifies format conversion specification. (Some C compilers might output % if it is not followed by a valid type conversion spec.) So, to output % you must type %%.

Format can also be an atom, but then escape sequences are not recognized.

Term is a term ( e.g., args(X,Y,Z)) whose arguments will be output. The functor symbol of Term is ignored.

Special syntactic sugar is provided for the following cases: If Term is a variable, X, then it is ignored and only the format string is printed. If Term is a string, integer or a float, then it is assumed that this is the only argument to be printed, i.e., it is equivalent to specifying arg(Term).

If the number of format specifiers is greater than the number of arguments to be printed, an error is issued. If the number of arguments is greater, then a warning is issued.

fmt_write_string(-String,+Fmt,+Term)
file_io
This predicate works like the C function sprintf. It takes the format string and substitutes the values from the arguments of Term ( e.g., args(X,Y,Z)) for the formatting instructions %s, %d, etc. Additional syntactic sugar, as in fmt_write, is recognized. The result is available in String. Fmt is a string or an atom that represents the format, as in fmt_write.

If the number of format specifiers is greater than the number of arguments to be printed, an error is issued. If the number of arguments is greater, then a warning is issued.

fmt_write_string requires that the printed size of each argument ( e.g., X,Y,and Z above) must be less than 16K. Longer arguments are cut to that size, so some loss of information is possible. However, there is no limit on the total size of the output (apart from the maximum atom size imposed by XSB).

file_flush(+IOport, -Return)
file_io
Any buffered data gets delivered. If the call is successful, Return is zero; otherwise EOF is returned.

file_seek(+IOport, +Offset, +Place, -Return)
file_io
Sets the file position indicator for the next input or output operation. The position is Offset bytes from Place. The value of Place can be 0, 1, or 2, which correspond to the beginning of the file, the current position in the file, or the end of the file, respectively. If the call is successful, Return is set to zero.

file_pos(+IOport, -Position)
file_io
Unifies Position with the position inside the file indicated by IOport.

file_truncate(+IOport, +Length, -Return)
file_io
The regular file referenced by the I/O port IOport is chopped to have the size of Length bytes. Upon successful completion Return is set to zero.

file_write(+IOport,+Term)
xsb_writ
Writes the term Term to the file (or string) with descriptor IOport.

file_read(+IOport,-Term)
xsb_read
Reads a term from the file (or string) with descriptor IOport into Term. Note that the term must be terminated with a period (.) (whether it appears in a file or in a string.)

file_read(+IOport,-Term,-Vars)
xsb_read
Reads a term from the file (or string) with descriptor IOport into Term, and returns in Vars an open-tailed list of pairs of names of variables and the variables themselves that appear in Term. For example, reading a term f(a,X,Y,X) would result in term being bound to f(a,_25,_26,_25) (for some internal variables) and Vars being bound to [vv('X',_25) vv('Y',_26) $\mid$ _83]. Note that the pairing functor symbol is vv/2 and it must be imported from xsb_read along with this read predicate. Also note that Vars is not a proper list, but has a free variable instead of [] at its end.

file_read_canonical(+IOport,-Term,-Psc)
machine
Reads a term that is in canonical format from the the I/O port indicated by IOport (as returned by file_open/3 or by stat_flag(10,IOport)), and returns it in Term. It also returns (in Psc) the psc address of the main functor symbol of the term, if it is the same as that of the previously read term, and the current term is a ground (non 0-ary) fact. (This is used for efficiency in the implementation of load_dync/1). Otherwise Psc is set to 0. To initialize its previous psc value to zero, this predicate can be called with IOport of -1000.

file_read_line(+IOport,-String,-IsFullLine)
file_io
This is a low-level predicate that allows XSB to read input files efficiently, line by line. It returns the string read from IOport using the variable String. The output variable IsFullLine is 1, if the line read contains the newline character at the end. Otherwise, it is 0. This latter case arises in two situations: when the last line in the stream does not have a newline character or when the line is very long, longer than the buffer allocated for that purpose. (In such a case file_read_line/3 will read only as much as the buffer allows.)

This predicate fails on reaching the end of file.

Important: This predicate does not intern the string it reads from the input, so you cannot unify or compare the value read with anything. Moreover, if you use this predicate twice, then the second call replaces the value read by the first call. In other words, this predicate is very low-level and should be used with great care. One simple use of this facility is to copy one file into another. See file_read_line_atom and file_read_line_list for alternatives that are easier to use.

file_read_line_atom(+IOport,-String,-IsFullLine)
file_io
This predicate is like file_read_line, but the line read from the input is interned. Therefore, String is instantiated to a normal atom. This predicate fails on reaching the end of file.

Important: At present, XSB does not have atom table garbage collector. Therefore, each line read from the file using this predicate gets stored in the atom table. Thus, large files can cause XSB to run out of memory. This problem will go away when atom table garbage collection is implemented.

file_read_line_atom(-String,-IsFullLine)
file_io
Like file_read_line_atom/3, but IOport is not required. The file being read is the one previously opened with see/1.

file_read_line_list(+IOport,-CharList,-IsFullLine)
file_io
This predicate is like file_read_line_atom, but the line read from the input is converted into a list of characters. This predicate is much more efficient than fget_line/3 (see below), and is recommended when speed is important. This predicate fails on reaching the end of file.

file_read_line_list(-String,-IsFullLine)
file_io
Like file_read_line_list/3, but IOport is not required. The file being read is the one previously opened with see/1.

fget_line(+Str,-Inlist,-Next)
scrptutl
fget_line/3 reads one line from the input stream Str and unifies Inlist to the list of ASCII integers representing the characters in the line, and Next to the line terminator, either a newline ( 10) or EOF ( -1).

This predicate is obsolete and file_read_line_list should be used instead.

file_write_line(+IOport, +String, +Offset)
file_io
Write String beginning with character Offset to the output file represented by the I/O port IOport. String can be an atom or a list of ASCII characters. This does not put the newline character at the end of the string (unless String already had this character). Note that escape sequences, like \n, are recognized if String is a character list, but are output as is if String is an atom.

file_write_line(+String, +Offset)
file_io
Like file_write_line/3, but output goes to the currently open output stream.

file_getbuf(+IOport, +BytesRequested, -String, -BytesRead)
file_io
Read BytesRequested bytes from file represented by I/O port IOport (which must already be open for reading) into variable String. This is analogous to fread in C. This predicate always succeeds. It does not distinguish between a file error and end of file. You can determine if either of these conditions has happened by verifying that $\tt BytesRead < BytesRequested$.

Note: The string read is not interned. Please see explanations to file_read_line on this matter. Because of the difficulties in using this predicate, the predicates file_getbuf_atom and file_getbuf_list are often better alternatives.

file_getbuf_atom(+IOport, +BytesRequested, -String, -BytesRead)
file_io
Like file_getbuf, but String is instantiated to an interned atom.

Note: because XSB does not have an atom table garbage collector yet, this predicate should not be used to read large files.

file_getbuf_atom(+BytesRequested, -String, -BytesRead)
file_io
Like file_getbuf_atom/4, but reads from the currently open input stream (using see/1). This predicate always succeeds. It does not distinguish between a file error and end of file. You can determine if either of these conditions has happened by verifying that $\tt BytesRead < BytesRequested$.

file_getbuf_list(+IOport, +BytesRequested, -CharList, -BytesRead)
file_io
Like file_getbuf_atom/4, but CharList is instantiated to a list of characters that represent the string read from the input.

file_getbuf_list(+BytesRequested, -String, -BytesRead)
file_io
Like file_getbuf_list/3, but reads from the currently open input stream ( i.e., with see/1).

file_putbuf(+IOport, +BytesRequested, +String, +Offset, -BytesWritten)
file_io
Write BytesRequested bytes into file represented by I/O port IOport (which must already be open for writing) from variable String at position Offset. This is analogous to C fwrite. The value of String can be an atom or a list of ASCII characters.

file_putbuf(+BytesRequested, +String, +Offset, -BytesWritten)
file_io
Like file_putbuf/3, but output goes to the currently open output stream.


next up previous contents index
Next: String Manipulation Up: Library Utilities Previous: Ground, Numbervars, Subsumption, Variant   Contents   Index
Baoqiu Cui
2000-04-23