Go to the first, previous, next, last section, table of contents.


Using Nana

This chapter is intended to provide some hopefully useful examples of Nana. If any of the users of this library would be so kind as to contribute a section on their usage I would be obliged.

This section is under development

Simplest example

As a nice simple, indeed trivial example consider the following:

  1. Include `nana.h' in your project wide include file.
  2. Use `I' to check invariants in your code. In particular all functions or methods should be required to check their pre and post conditions.
  3. Use `DL' to print debugging messages in your code. This means that debugging messages only occur when you run the program under the debugger.(11)

Syslog

`syslog' is a comprehensive logging system written by Eric Allman which is available on most UNIX systems. It provides facilities for sorting messages by source or severity and mechanisms for sending messages off to files, terminals or other machines. See chapter 12 of the "UNIX System Administration Handbook (2nd Edition)" by Nemeth, Snyder, Seebass and Hein for an excellent tutorial on `syslog'.

The rules used by `syslog' are normally defined in `/etc/syslog.conf'. Each line specifies the destination for messages with particular sources and priorities. For example:

# log mail messages at priority info to mailinfo
mail.info /var/log/mailinfo
# log all ftp information to syslog on a remote machine
ftp.* @remote-machine.cs.ntu.edu.au
# all critical errors to console
*.crit   /dev/console

To use `syslog' we merely redefine the default handlers and parameter values for `nana'. For example:

#include <syslog.h>
#define L_DEFAULT_HANDLER syslog /* replaces fprintf(3) by syslog(3) */
#define L_DEFAULT_PARAMS LOG_USER /* default priority for syslog info */
#include <nana.h>

int main() {
     openlog("nana", /* identifier for these log messages */
        LOG_PID, /* also log the process id */
        LOG_DAEMON /* facility */
     );

     L("temperature is falling to %d", 35); /* logged at LOG_USER priority */
     LP(LOG_CRIT, "the snow is falling in Darwin"); /* LOG_CRIT message */
        
     closelog();
     return 0;
}

This program results in the following addition to `/var/adm/messages':

Jun 12 16:04:46 chingiz nana[2671]: the temperature is falling to 35
Jun 12 16:04:46 chingiz nana[2671]: the snow is falling in Darwin

In addition the `LOG_CRIT' message about snow falling in Darwin is sent to the console for immediate action.

Note: `syslog' normally uses `UDP' for its network communications and that `UDP' does not guarantee delivery.

GNU Programs: how to avoid nana sometimes

Imagine you(12) are building a GNU program. Ideally it should run on systems without any other software including GCC, GDB and even Nana.

To achieve this noble goal you can provide your configure script with a `--without-nana'(13) flag which then `#define's' `WITHOUT_NANA'. You should also use the `VL' macro rather than `L' macro since `L' takes a variable number of arguments and will break non GNU C preprocessors.

int half(int n) {
  /* Don't use L(...) since it takes a variable number of args! */
  VL(("hello world = %d\n", 10)); /* Note the doubled (( */
  ...;
}

Embedded Systems: testing non-deterministic systems.

One of the uses (in fact the original use) for nana is in the testing of non-deterministic systems. These systems behave in a different way each time they are run because of timing or measurement noise. Thus you can't just `diff' the results against a known good run since they run differently each time.

Instead you can use a series of programs which execute over a the results of the program and check that the behaviour meets the specification automatically.

Realtime Systems

Assertions for the timing behaviour of you system can be done in nana nicely. You might also consider using an instruction level simulator such as PSIM and use the `cycles' variable to test realtime constraints.

A database

Ah databases, business boffins using assertions. It would nice to get a real example for this one!

Program Visualisation: pretty pictures

One nice way to use `L', `DL', etc is to punt off the messages off to a program which displays the information. You would use the `L_DEFAULT_PARAM' argument to send commands off to a pipe with gnuplot or TCL/TK interpreter running at the end.

For a small example of this, see `tcl/status.c'.


Go to the first, previous, next, last section, table of contents.