Function Library

I've mentioned several times that the name provided to Nm doesn't necessarily refer to the title of the manual in Dt. Let's study a simple function library, using both hi and hello, which demonstrates this concept.

A function library is a collection of object files, which consist mainly of programming functions, within a single file called a library. On most UNIX systems, you can find libraries installed in /usr/local, ending in .a or .so.

This example applies to any number of functions belonging to the same library — not necessarily all functions in the library. In fact, one commonly finds large libraries spread over many manuals, each of which contain several similar functions.

For simplicity's sake, I'll call this C function library libgreeting, implying that the installed library is called libgreeting.a or libgreeting.so. It will consist of two header files, hi.h and hello.h, containing the function prototypes for hi and hello, respectively.

Let's begin with the first few macros, which are also called the manual prologue.

.Dd May 30, 2011
.Dt GREETING 3
.Os

Note that I've changed the document title to be GREETING instead of choosing between function names. This is because the manual documents the entire function library, not just one particular function. In general, a function library should have its name not include the leading lib.

It's a good rule of thumb that the Dt title of your document matches its filename.

Next, I'll list the names of the functions being documented. I also change the description of the manual to be more generic, just in case I want to add new functions, later.

.Sh NAME
.Nm hello ,
.Nm hi
.Nd print greeting messages

Here I've used Nm twice to indicate that the manual documents two functions. In doing so, I'll have to be careful when invoking Nm in later parts of the manual, as it will produce hi if I don't specify a name, and this is probably not desired (nor should it be depended upon, as I may re-order the names).

If we were only documenting a single function in a library, we would only assign Nm and Nd to the relevant function and not that of the library.

It's good practise to alphabetise the function names in the NAME section. We must also be sure to comma-separate each name, leaving the last invocation without a comma. Let's look at the output so far.

NAME

hello, hiprint greeting messages

Even though that is hard to maintain and not very useful, some operating systems, for example FreeBSD and NetBSD, require a LIBRARY section for base system libraries. For portable libraries, do not include such a section.

.Sh LIBRARY
.Lb libgreeting

This uses the macro Lb, which accepts the name of the library starting with lib. This macro is not portable because the list of known library names is system dependent, so it will produce different output on different systems, which is not desirable for a manual page.

NAME

hello, hiprint greeting messages

LIBRARY

library “libgreeting”

The SYNOPSIS section will simply be a collection of the calling syntaxes for both functions, which we've already studied. If we were only documenting one function, would list only that function here.

.Sh SYNOPSIS
.In hello.h
.In hi.h
.Ft int
.Fo hello
.Fa "int C" "const char *prefix"
.Fc
.Ft void
.Fn hi

Note that I've listed both include files prior to the function prototypes. This is familiar to C programmers, where functions may have multiple include files that need a specific order. The functions are listed in the same order as their Nm listing.

Let's examine the output so far.

NAME

hello, hiprint greeting messages

LIBRARY

library “libgreeting”

SYNOPSIS

#include <hello.h>
#include <hi.h>

int
hello(int C, const char *prefix);

void
hi();

Already, a manual reader has lots of pertinent information: the name of the library, its header file, and the function calling syntax. Let's continue in documenting the functions and their arguments, but this time, we'll do so in a different style than before.

Instead of using lists, we describe each function as a free-form stream of text. We depend on the SYNOPSIS to hint the reader as to the function argument types; there's no need to re-state them.

.Sh DESCRIPTION
The
.Fn hi
and
.Fn hello
functions print out greeting messages.
.Pp
The
.Fn hi
function accepts no arguments and prints out
.Qq hello, world .
.Pp
The
.Fn hello
function accepts a value
.Fa C ,
which if non-zero indicates output should be uppercase; and
.Fa prefix ,
which, if non-NULL, shall be prefixed to the output.
The
.Fa prefix
argument, if non-NULL, must be nil-terminated.

Notice how each sentence in this fragment ends on its own line, for example,

which, if non-NULL, shall be prefixed to the output.
The
.Fa prefix

By doing so, the formatter is able to recognise the end of sentence and correctly handle sentential spacing. In most cases, this means adding two spaces between the period and subsequent text. From this follows a rule of thumb, new sentence, new line.

In this DESCRIPTION we've captured what each function does and what its arguments are. What remains are return values.

.Sh RETURN VALUES
The
.Fn hi
function does not return a value.
.Pp
The
.Fn hello
function returns 1 on success, 0 on failure.

Let's collect these fragments into a single document and see if it's enough to use as a programming reference.

NAME

hello, hiprint greeting messages

LIBRARY

library “libgreeting”

SYNOPSIS

#include <hello.h>
#include <hi.h>

int
hello(int C, const char *prefix);

void
hi();

DESCRIPTION

The hi() and hello() functions print out greeting messages.

The hi() function accepts no arguments and prints out “hello, world”.

The hello() function accepts a value C, which if non-zero indicates output should be uppercase; and prefix, which, if non-NULL, shall be prefixed to the output. The prefix argument, if non-NULL, must be nil-terminated.

RETURN VALUES

The hi() function does not return a value.

The hello() function returns 1 on success, 0 on failure.

We'll use our mental checklist as a guide. First we stipulated linking information with the Lb macro. Then we introduced the calling syntax of each function, naming their arguments. We also stipulated the necessary header files in the order they'd be included in source files. In the DESCRIPTION, we described each function and its arguments in full. Lastly, we documented return values in the RETURN VALUES section.

From this information, a programmer should be able to interface with our library.

Last edited by $Author: schwarze $ on $Date: 2016/03/22 14:28:44 $. Copyright © 2011, Kristaps Dzonsons. CC BY-SA.