# Librarian and resolver

This chapter covers the use of the `axl` librarian utility as well as the `Librarian` object. The file path resolver is also described as a mean to search for a particular file to execute in a program.

## Librarian object

A librarian file is a special file that acts as a containers for various files. A librarian file is created with the `axl` -- cross librarian -- utility. Once a librarian file is created, it can be added to the interpreter resolver. The file access is later performed automatically by name with the standard interpreter `load` method.

### Creating a librarian

The `axl` utility is the preferred way to create a librarian. Given a set of files, `axl` combines them into a single one.

zsh: axl -h usage: axl [options] [files] [-h] print this help message [-v] print version information [-c] create a new librarian [-x] extract from the librarian [-s] get file names from the librarian [-t] report librarian contents [-f] lib set the librarian file name

The `-c` option creates a new librarian. The librarian file name is specified with the `-f` option.

zsh: axl -c -f librarian.axl file-1.als file-2.als

The previous command combines file-1.als and file-2.als into a single file called librarian.axl . Note that any file can be included in a librarian.

### Using the librarian

Once a librarian is created, the interpreter `-i` option can be used to specify it. The `-i` option accepts either a directory name or a librarian file. Once the librarian has been opened, the interpreter `load` method can be used as usual.

zsh> axi -i librarian.axl (axi) interp:load "file-1.als" (axi) interp:load "file-2.als"

The librarian acts like a file archive. The interpreter file resolver takes care to extract the file from the librarian when the `load` method is invoked.

### Librarian contents

The `axl` utility provides the `-t` and `-s` options to look at the librarian contents. The `-s` option returns all file name in the librarian. The `-t` option returns a one line description for each file in the librarian.

zsh: axl -t -f librarian.axl -------- 1234 file-1.als -------- 5678 file-2.als

The one line report contains the file flags, the file size and the file name. The file flags are not used at this time. One possible use in the future is for example, an auto-load bit or any other useful things.

### Librarian extraction

The `-x` option permits to extract file from the librarian. Without any file argument, all files are extracted. With some file arguments, only those specified files are extracted.

zsh: axl -x -f librarian.axl zsh: axl -x -f librarian.axl file-1.als

## Librarian object

The `Librarian` object can be used within an program as a convenient way to create a collection of files or to extract some of them.

### Output librarian

The `Librarian` object is a standard object. Its predicate is `librarian-p`. Without argument, a librarian is created in output mode. With a string argument, the librarian is opened in input mode, with the file name argument. The output mode is used to create a new librarian by adding file into it. The input mode is created to read file from the librarian.

# create a new librarian const lbr (Librarian) # add a file into it lbr:add "file-1.als" # write it lbr:write "librarian.axl"

The `add` method adds a new file into the librarian. The `write` method the full librarian as a single file those name is `write` method argument.

### Input librarian

With an argument, the librarian object is created in input mode. Once created, file can be read or extracted. The `length` method -- which also work with an output librarian -- returns the number of files in the librarian. The `exists-p` predicate returns true if the file name argument exists in the librarian. The `get-names` method returns a vector of file names in this librarian. The `extract` method returns an input stream object for the specific file name.

# open a librarian for reading const lbr (Librarian "librarian.axl") # get the number of files println (lbr:length) # extract the first file const is (lbr:extract "file-1.als") # is is an input stream - dump each line while (is:valid-p) (println (is:readln))

Most of the time, the librarian object is used to extract file dynamically. Because a librarian is mapped into the memory at the right offset, there is no worry to use big librarian, even for a small file. Note that any type of file can be used, text or binaries.

## File resolver

The file resolver is a special object used by the interpreter to resolve file path based on the search path. The resolver uses a mixed list of directories and librarian files in its search path. When a file path needs to be resolved, the search path is scanned until a matched is found. Because the librarian resolution is integrated inside the resolver, there is no need to worry about file extraction. That process is done automatically. The resolver can also be used inside an program to perform any kind of file path resolution.

### Resolver object

The resolver object is created without argument. The `add` method adds a directory path or a librarian file to the resolver. The `valid` method checks for the existence of a file. The `lookup` method returns an input stream object associated with the object.

# create a new resolver const rslv (Resolver) assert true (resolver-p rslv)

# add the local directory on the search path rslv:add "."

# check if file test.als exists # if this is ok - print its contents if (rslv:valid-p "test.als") { const is (rslv:lookup "test.als") while (is:valid-p) (println (is:readln)) }