A resource is very similar to a file. Resources however can be represented in two different formats: on files, as well as part of the resource archive of a saved-state (see qsave_program/2).
A resource has a name and a class. The source data of the resource is a file. Resources are declared by declaring the predicate resource/3. They are accessed using the predicate open_resource/3.
Before going into details, let us start with an example. Short texts
can easily be expressed in Prolog sourcecode, but long texts are
cumbersome. Assume our application defines a command `help' that prints
a helptext to the screen. We put the content of the helptext into a file
called help.txt
. The following code implements our help
command such that help.txt is incorperated into the runtime executable.
resource(help, text, 'help.txt'). help :- open_resource(help, text, In), copy_stream(In, user_output), close(In). copy_stream(In, Out) :- get0(In, C), copy_stream(C, In, Out). copy_stream(-1, _, _) :- !. copy_stream(C, In, Out) :- put(Out, C), get0(In, C2), copy_stream(C2, In, Out). |
The predicate help/0
opens the resource as a Prolog stream. If we are executing this from the
development environment, this will actually return a stream to the gelp.txt
itself. When executed from the saved-state, the stream will actually be
a stream opened on the program resource file, taking care of the offset
and length of the resource.
user
. Clauses for it may be defined in any module,
including the user module. Name is the name of the resource
(an atom). A resource name may contain all characters, except for $ and
:, which are reserved for internal usage by the resource library. Class
describes the what kind of object we are dealing with. In the current
implementation, it is just an atom. FileSpec is a file
specification that may exploit file_search_path/2
(see
absolute_file_name/2).
Normally, resources are defined as unit clauses (facts), but the definition of this predicate can also imply rules. For proper generation of the saved state generation, it must be possible to enumerate the available resources by calling this predicate with all its arguments unbound.
Dynamic rules can be useful to turn all files in a certain directory
into resources, without specifying a resources for each file. For
example, assume the file_search_path/2 icons
refers to the resource directory containing (XPM) icons. The following
definition makes all these images available as resources:
resource(Name, image, icons(XpmName)) :- atom(Name), !, file_name_extension(Name, xpm, XpmName). resource(Name, image, XpmFile) :- var(Name), absolute_file_name(icons(.), [type(directory)], Dir) concat(Dir, '/*.xpm', Pattern), expand_file_name(Pattern, XpmFiles), member(XpmFile, XpmFiles). |
The predicate open_resource/3 first checks resource/3. When succesful it will open the returned resource source-file. Otherwise it will look in the programs resource database. When creating a saved-state, the system normally saves the resource contents into the resource archive, but does not save the resource clauses.
This way, the development environment uses the files (and modifications to the resource/3 declarations and/or files containing resource info thus immediately affect the running environment, while the runtime system quickly accesses the system resources.
The utility program plrc can be used to examine and manipulate the contents of a SWI-Prolog resource file. The options are inspired by the Unix ar program. The basic command is:
% plrc option resource-file member ... |
The options are described below.
data
and encoding none
.
This command is also described in the pl(1) Unix manual page.