This is Info file nana.info, produced by Makeinfo version 1.68 from the
input file nana.texi.

START-INFO-DIR-ENTRY
* Nana: (nana).          The GNU Nana library (assertions, logging, forall,etc)
END-INFO-DIR-ENTRY

   This file documents the features and implementation of the GNU Nana
library.

   Copyright (C) 1996, 1997, 1998, P.J.Maker

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.


File: nana.info,  Node: DI.h,  Next: L.h,  Prev: I.h,  Up: Interface

DI.h: debugger based invariant checking
=======================================

   This implements the debugger based invariant checking code.  The
first two macros are the normal user interface; the remainder are used
for configuring the behaviour on failure, etc. Note that these macros
have no effect unless you run your program under the debugger and read
in the commands generated by the `nana' command.

 - Macro: void DI (bool EXPRN)
     The EXPRN should always be true if the program is working.  If it
     is true then nothing happens otherwise the code given by
     `DI_DEFAULT_HANDLER' will be called which by default prints a
     message and dies just like `assert.h'.

     The checking using DI can be enabled and disabled by using the
     DI_LEVEL and DI_DEFAULT_GUARD macros. See the definitions below
     for these macros for further details.

     Note that EXPRN should have no side-effects(1) since disabling the
     checking shouldn't change your programs behaviour.

 - Macro: void DN (bool EXPRN)
     The opposite of `DI', i.e. the expression must never ever be true
     if the program is working properly. It is equivelant to `I(!(e))'
     and exists as piece of syntactic sugar which is helpful for
     complicated boolean expressions.

 - Macro: int DI_LEVEL
     The `DI_LEVEL' macro is used to globally enable and disable
     checking, in particular it can take on one of three values:

    `0'
          Disable all checking. Regardless of anything else no code
          will be generated for `DI', `DN', etc.

    `1'
          Enable checking only if the corresponding guard condition is
          true. The guard condition can be used to enable and disable
          checking at compile and run time.

    `2'
          Enable all checking regardless of guard conditions, etc.

     `DI_LEVEL' defaults to `1'.

 - Macro: bool DI_DEFAULT_GUARD
     The `DI_DEFAULT_GUARD' is used to selectively enable or disable
     checking at compile or run time.

     `DI_DEFAULT_GUARD' defaults to `TRUE', i.e. always enabled.

     A user would typically define `DI_DEFAULT_GUARD' to be global or
     local variable which is used to turn checking on or off at
     run-time. For example:

          #define DI_DEFAULT_GUARD (i_guard)
          
          extern int i_guard;

 - Macro: text DI_DEFAULT_PARAMS
     This is passed off to the `DI_DEFAULT_HANDLER' and defaults to
     nothing, it is just some text and is intended to pass failure codes
     (e.g. `IEH303') or requests (e.g. `HW_DEAD') information off to
     the handler.

     `DI_DEFAULT_PARAMS' defaults to nothing.

 - Macro: void DI_DEFAULT_HANDLER (char *EXPRN, char *FILE, int LINE,
          PARAM)
     When an error is detected the `DI_DEFAULT_HANDLER' will be called
     to handle the error. The arguments are:

    `exprn'
          A string representation of the expression that has failed,
          e.g. `"I(i>=0)"'.

    `file'
          The file that this error occurred in, i.e. `__FILE__'.

    `line'
          The line number for the error, i.e. `__LINE__'.

    `param'
          An optional parameter which can be passed across which
          defaults to `DI_DEFAULT_PARAMS'. This can be used to pass
          failure codes or other information from the checking code to
          the handler.

 - Macro: void DI_MAKE_VALID_BREAKPOINT (exprn E)
     This macro is used to ensure that a breakpoint can be set at the
     location we are checking using `DI', etc. It defaults to
     `asm("nop")' and can be redefined by the user.

 - Macro: void DI (bool E)
 - Macro: void DIG (bool E, bool G)
 - Macro: void DIH (bool E, Macro H)
 - Macro: void DIP (bool E, Text P)
 - Macro: void DIGH (bool E, bool G, Macro H)
 - Macro: void DIGP (bool E, bool G, Text P)
 - Macro: void DIHP (bool E, Macro H, Text P)
 - Macro: void DIGHP (bool E, bool G, Macro H, Text P)
 - Macro: void DN (bool E)
 - Macro: void DNG (bool E, bool G)
 - Macro: void DNH (bool E, Macro H)
 - Macro: void DNP (bool E, Text P)
 - Macro: void DNGH (bool E, bool G, Macro H)
 - Macro: void DNGP (bool E, bool G, Text P)
 - Macro: void DNHP (bool E, Macro H, Text P)
 - Macro: void DNGHP (bool E, bool G, Macro H, Text P)
     All of these macros are used to individually override the default
     values defined above. Normally these macros would be used in a
     system wide header file to define macros appropriate for the
     application.

 - Macro: void DS (E)
 - Macro: void DSG (E, G)
     These macros are used to assign values to convenience variables in
     the debugger. Convenience variables are dynamically typed, global
     in scope and initialised to 0. They start with a single `$' and
     can be used be used for saving the state of program or for
     counting events. The `DS' macro executes E under the same rules as
     `DI'.  The `DSG' macro executes E only if the the expression G is
     true.

     Note that `DS' and `DSG' can also be used for modifying C
     variables and calling functions.

   ---------- Footnotes ----------

   (1) Side-effects include operations like input/output or assignments.


File: nana.info,  Node: L.h,  Next: L_buffer.h,  Prev: DI.h,  Up: Interface

L.h: support for printf style logging
=====================================

   These routines are used to provide logging functions. Messages can be
divided into classes and separately enabled and disabled.

 - Macro: void L (ARGS...)
     Used to log a message in a similar way to printf.

     Defaults to a using `fprintf' on `stderr'.

 - Macro: void LG (bool GUARD, ARGS...)
 - Macro: void LH (function HANDLER, ARGS...)
 - Macro: void LP (text PARAM, ARGS...)
 - Macro: void LGP (bool GUARD, text PARAM, ARGS...)
 - Macro: void LHP (function HANDLER, text PARAM, ARGS...)
 - Macro: void LGHP (bool GUARD, function HANDLER, text PARAM, ARGS...)
     And all of the special functions.


   The macros such as `L' depend on the GNU CC variable number of
arguments to macros extension. If you wish to compile your code on
other systems you might wish to use the following variations on `L',
etc.

 - Macro: void VL ((ARGS...))
 - Macro: void VLG ((bool GUARD, ARGS...))
 - Macro: void VLH ((function HANDLER, ARGS...))
 - Macro: void VLP ((text PARAM, ARGS...))
 - Macro: void VLGP ((bool GUARD, TEXT PARAM, ARGS...))
 - Macro: void VLHP ((function HANDLER, text PARAM, ARGS...))
 - Macro: void VLGHP ((bool GUARD, function HANDLER, text PARAM,
          ARGS...))
     Each of these macros calls the corresponding function from the
     previous group, i.e. by default `VLG' is the same as a call to
     `LG'.  If you define `WITHOUT_NANA' all these macros are translated
     to `/* empty */'.

     Thus you can have nana under GCC whilst the code is still portable
     to other compilers. However debugging information will not be
     available on other platforms.

     *Note:* the argument list is surrounded by *two* sets of brackets.
     For example:

             VL(("haze in darwin = %d\n", 3.4));

 - Macro: void L_LEVEL
     Used to enable and disable logging independently of guard
     expressions.

    `2'
          Always print message

    `1'
          Print message only if the guard expression is true.

    `0'
          Never print any messages.

     Defaults to `1'.

 - Macro: text L_DEFAULT_HANDLER
     The default handler for printing which is simply the name of the
     logging function or macro.

     Defaults to `fprintf'

 - Macro: bool L_DEFAULT_GUARD
     The default guard condition for logging.

     Defaults to `TRUE'.

 - Macro: text L_DEFAULT_PARAMS
     The default parameter passed off to the logging function or macro.

     Defaults to `stderr'

 - Macro: void L_SHOW_TIME
     If defined then display the time in front of each message.

 - Macro: char* L_SHOW_TIME_FORMAT
     A format string for the time stamp in the log. By default it
     prints the time out in seconds.

 - Macro: value L_SHOW_TIME_NOW
     The name of a function that returns the time for the time stamp.
     This defaults to the `now' function from `now.h'.


File: nana.info,  Node: L_buffer.h,  Next: L_times.h,  Prev: L.h,  Up: Interface

L_buffer.h: a circular buffer for logging.
==========================================

   A traditional embedded systems trick is to log messages to a circular
buffer in core. This has the following benefits:

  1. Speed - writing to a in core buffer is much faster than spitting
     out messages to a file on disk. It is often fast enough to leave
     at least most of the messages in the final product.

  2. Field debugging - what the ... was the user doing before the
     system crashed. Oh lets ask them, I'm sure they'll give us a good
     problem report.

 - Type: struct L_BUFFER
     Used to define buffer variables, it is similar to `FILE*' type in
     `stdio.h'. To create an instance use `L_buffer_create'.

 - Function: L_BUFFER* L_buffer_create (size_t SIZE)
 - Function: L_BUFFER* L_buffer_delete (L_BUFFER *B)
     These are used to create or delete a buffer which can contain SIZE
     characters.

            L_BUFFER *lbuffer;
          
            lbuffer = L_buffer_create(32*1024); /* create a 32K buffer */
            ...;
            L_buffer_delete(lbuffer); /* and delete it after use */

 - Function: void L_buffer_wraparound (L_BUFFER *B, int W)
     A buffer created by `L_buffer_create' is set up so that the new
     messages will overwrite the older messages in the buffer. If you
     wish to disable this overwriting, e.g. to keep the first 32K bytes
     of your system startup messages you should use
     `L_buffer_wraparound'.  For example:

            L_BUFFER *lb = L_buffer_create(32*1024);
            L_buffer_wraparound(lb, 0); /* disable wraparound */

 - Function: void L_buffer_printf (L_BUFFER *B, const char *FMT, ...)
 - Function: void L_buffer_puts (L_BUFFER *B, const char *STR)
 - Function: void L_buffer_putchar (L_BUFFER *B, char CH)
     These are the routines which do that actual printing to the buffer.

            L_buffer_printf(lbuffer, "U: user input %c\n", c);
            L_buffer_puts(lbuffer, "warning: its too hot");
            L_buffer_putchar(lbuffer, '*');

     Note: a null pointer passed to the `L_buffer_puts' function prints
     as `(null)'. (1)

 - Function: void L_buffer_clear (L_BUFFER *B)
     Clear the log, i.e. remove all messages and start again.

 - Function: void L_buffer_dump (L_BUFFER *B, FILE *FP)
     Dump the contents of the log *B to the file descriptor *FP.
     Typically *FP would be `stderr'.

     Note that this does not change the contents of the buffer.  This is
     important since we may have a hardware or software problem part of
     the way through the dump operation and you don't want to loose
     anything.

     To reset the buffer after a successful dump use `L_buffer_clear'.

     The output of `L_buffer_dump' consists of a starting message
     followed by the contents of the log. If a character in the log is
     not printable we print it out in hex on a line by itself.

          * L_buffer_dump =
          log message
          and another
          * non-printable character 0x1
          more log messages
          * end of dump

   You also need to be able to integrate these functions into your
design. See `examples/ott.c' for a complicated example. Here we will
provide a simplified version which implements a new logging macro
called `LFAST' which does a `printf' to the `log_buffer'.  If you want
to have all messages going to a `L_BUFFER' then you can redefine
`L_DEFAULT_HANDLER'.

     /* project.h - the project wide include file */
     
     #include <nana.h>
     #include <L_buffer.h>
     
     /* LFAST(char *, ...) - log a message to the log_buffer */
     /*     ##f translates as the rest of the arguments to LFAST */
     
     #define LFAST(f...) LHP(L_buffer_printf,log_buffer,##f)
     
     extern L_BUFFER *log_buffer; /* the log buffer */

   The main program merely creates the LOG_BUFFER and eventually calls
`L_buffer_dump' to print out the buffer when the system dies.
     /* main.c - initialise the system and start things */
     
     #include <project.h>
     
     L_BUFFER *log_buffer;
     
     main() {
       log_buffer = L_buffer_create(16000);
       if(log_buffer == NULL) { /* not enough store */
         ...
       }
       LFAST("system starting at %f\n", now());
       ...;
     }
     
     void fatal_error() { /* called on fatal errors */
       FILE *f = fopen("project.errors","w");
       L_buffer_dump(b, stderr); /* print log to stderr */
       L_buffer_dump(b, f); /* print log to file */
     }

   ---------- Footnotes ----------

   (1) This was suggested by Phil Blecker.


File: nana.info,  Node: L_times.h,  Next: DL.h,  Prev: L_buffer.h,  Up: Interface

L_times.h: recording events and times.
======================================

   This component is used to record events and times with a lower time
and space overhead than the `L_buffer.h' component. Instead of using a
`printf' style string we simply record the time and a pointer to a
string identifying the event in a circular buffer.

   *Note 0:* the string arguments should not be modified after a call
since we record pointers to the strings rather than the strings
themselves.

   *Note 1:* there is no PRINTF style formatting, e.g.  `%d' in this
package.

 - Type: struct L_TIMES
     Used to define buffers, it is similar to `FILE*' type in
     `stdio.h'. To create an instance use `L_times_create'.

 - Function: L_TIMES* L_times_create (int SIZE)
 - Function: L_TIMES* L_times_delete (L_BUFFER *B)
     These are used to create or delete a buffer which can contain SIZE
     messages.

 - Function: void L_times_wraparound (L_TIMES *B, int W)
     A buffer created by `L_times_create' is set up so that the new
     messages will overwrite the oldest messages in the buffer. If you
     wish to disable this overwriting, e.g. to keep the first few
     messages messages you could use `L_times_wraparound(b,0)'.

 - Function: void L_times_add (L_BUFFER *B, char *M, NANA_TIME T)
     Add an event identified by message M at time T to B.  The type
     NANA_TIME defaults to `double'.

 - Function: void L_times_dump (L_TIMES *B, FILE *FD)
     Dump the contents of the buffer out.

 - Function: void L_times_clear (L_TIMES *B)
     Clear all the messages from B.


File: nana.info,  Node: DL.h,  Next: GDB.h,  Prev: L_times.h,  Up: Interface

DL.h: support for printf style logging
======================================

   These routines are used to provide logging functions. Messages can be
divided into classes and separately enabled and disabled.

 - Macro: void DL (ARGS...)
     Used to log a message.

     Defaults to a using `fprintf' on `stderr'.

 - Macro: void DLG (bool GUARD, ARGS...)
 - Macro: void DLH (function HANDLER, ARGS...)
 - Macro: void DLP (text PARAM, ARGS...)
 - Macro: void DLGP (bool GUARD, text PARAM, ARGS...)
 - Macro: void DLHP (function HANDLER, ARGS...)
 - Macro: void DLGHP (bool GUARD, function HANDLER, ARGS...)
     And all of the special functions.


   The macros such as `DL' depend on the GNU CC variable number of
arguments to macros extension. If you wish to compile your code on
other systems you might wish to use the following variations on `DL',
etc.

 - Macro: void VDL ((ARGS...))
 - Macro: void VDLG ((bool GUARD, ARGS...))
 - Macro: void VDLH ((function HANDLER, ARGS...))
 - Macro: void VDLP ((text PARAM, ARGS...))
 - Macro: void VDLGP ((bool GUARD, TEXT PARAM, ARGS...))
 - Macro: void VDLHP ((function HANDLER, ARGS...))
 - Macro: void VDLGHP ((bool GUARD, function HANDLER, ARGS...))
     Each of these macros calls the corresponding function from the
     previous group, i.e. by default `VDL' is equivelant to a call to
     `DL'.  If `WITHOUT_NANA' is defined then the call too `VDL' is
     equivelant to `/* empty */'.

     Thus you can have debugging under GCC whilst the code is still
     portable to other compilers. However debugging information will
     not be available on other platforms.

     *Note:* the argument list is surrounded by *two* sets of brackets.
     For example:

             VDL(("haze in darwin = %d\n", 3.4));

 - Macro: int DL_LEVEL
     Used to enable and disable logging independently of guard
     expressions.

    `2'
          Always print message

    `1'
          Print message only if the guard expression is true.

    `0'
          Never print any messages.

     Defaults to `1'.

 - Macro: text DL_DEFAULT_HANDLER
     The default handler for printing which is simply the name of the
     printing function.

     Defaults to `printf'

 - Macro: bool DL_DEFAULT_GUARD
     Defaults to `TRUE'.

 - Macro: text DL_DEFAULT_PARAMS
     Defaults to `stderr'

 - Macro: flag DL_SHOW_TIME
     Each message can be given an individual time stamp by defining
     `DL_SHOW_TIME'. This causes the `_L_gettime' routine to be called
     before each message which generates the timestamp. A default
     version is provided by the nana library.


File: nana.info,  Node: GDB.h,  Next: Q.h,  Prev: DL.h,  Up: Interface

GDB.h: sending plain gdb commands to the debugger
=================================================

   `GDB.h' provides macros for generating user specified commands in
the output of the `nana' command.  They are not included by default in
the `nana.h' file.

 - Macro: void GDB (COMMAND)
     Emit a single line command when running this file through `nana'.
     Note that each line must be passed off separately to the `GDB'
     macro.

     This could be used to set debugger options or to define procedures
     inside `gdb', e.g.

            GDB(define checkstack);
            GDB(  if 0 <= n && n <= 10);
            GDB(    print "stack ok");
            GDB(  else);
            GDB(    print "stack corrupted");
            GDB(  end);
            GDB(end);

 - Macro: void GDBCALL (COMMAND)
     Causes a single gdb COMMAND to be executed whenever control passes
     through this line of code. After the users command is executed
     control automatically returns to the program.

            GDBCALL(set memory_check = 1)

   These macros could used for instrumenting code or setting up test
harnesses, e.g.


     GDB(set $siocall = 0);
     GDB(set $sioerr = 0);
     
     void sio_driver() {
       GDBCALL(set $siocall++)
       if(SIO_REQ & 0x010) {
         GDBCALL(set $sioerr++);
         ...
       }
     }


File: nana.info,  Node: Q.h,  Next: Qstl.h,  Prev: GDB.h,  Up: Interface

Q.h: support for quantifiers
============================

   `Q.h' provides support for the quantifiers of predicate logic.  For
example to check that all elements in a data structure have some
property we would use universal (forall, upside down A) quantification.
To check that one or more values in a data structure have some property
we would use existential (exists, back the front E) quantification.  For
example:

       /* all values in a[] must be between 0 and 10 */
       I(A(int i = 0, i < n_array, i++, 0 <= a[i] && a[i] <= 10));
     
       /* there exists a value in linked list l which is smaller than 10 */
       I(E(node *p = l, p != NULL, p = p->next, p->data <= 10));

   The first three arguments to `A' and `E' are similar to a C `for'
loop which iterates over the values we wish to check. The final
argument is the expression that must be true.

   The only minor difference from the C `for' loop is that variables
may be declared at the start of the loop, even if you are using C rather
than C++ which already supports this.(1)

   The `Q.h' macros can also be nested and used anywhere a boolean
value is required. For example:

       if(A(int i = 0, i < MAXX, i++,
            A(int j = 0, j < MAXY, j++,
              m[i][j] == (i == j ? 1 : 0)))) {
             /* identity matrix, i.e. all 0's except for 1's on */
             /* the diagonal */
             ...
       } else {
             /* not an identity matrix */
             ...
       }

   The results from these macros can also be combined using boolean
operations, e.g.

       /* the values in a[i]  are either ALL positive or ALL negative */
       I(A(int i = 0, i < MAX, i++, a[i] >= 0)
         ||
         A(int i = 0, i < MAX, i++, a[i] < 0));

   *Portability:* note the macros in this file require the GNU CC/C++
statement expression extension of GCC to work. If your not using GNU CC
then for now you are out of luck. At some time in the future we may
implement a method which will work for standard C++, standard C is a
bit of a challenge.

   *Portability:* unfortunately these macros do not for the `DI' and
`DL' macros since the statement expression extension has not been
implemented in GDB.

 - Macro: bool A (INIT,CONDITION,NEXT,EXPRN)
     For all values generated by  `for(INT;CONDITION;NEXT)' the EXPRN
     must be true.
            I(A(int i = 0, i < MAX, i++, a[i] >= 0)); /* all a[i] are +ve */

 - Macro: bool E (INIT,CONDITION,NEXT,EXPRN)
     There exists at least one value for EXPRN generated by  `for
     (INT;CONDITION;NEXT)' which is true.

            /* one or more a[i] >= 0 */
            I(E(int i = 0, i < MAX, i++, a[i] >= 0));

 - Macro: long C (INIT,CONDITION,NEXT,EXPRN)
     Returns the number of times the EXPRN is true over the values
     generated by `for(INT;CONDITION;NEXT)'.

            /* 3 elements of a[] are +ve */
            I(C(int i = 0, i < MAX, i++, a[i] >= 0) == 3);

 - Macro: bool E1 (INIT,CONDITION,NEXT,EXPRN)
     There exists only one value generated by
     `for(INT;CONDITION;NEXT)' for which the EXPRN is true.

            /* a single elements of a[] is +ve */
            I(E1(int i = 0, i < MAX, i++, a[i] >= 0));

 - Macro: typeof (EXPRN) S (INIT,CONDITION,NEXT,EXPRN)
     Sum the values generated by EXPRN for all values given by
     `for(INT;CONDITION;NEXT)'. The type of the value returned  is
     given by the type of the EXPRN.(2)

            /* sum of a[] is 10 */
            I(S(int i = 0, i < MAX, i++, a[i]) == 10);
          
            /* sum of all +ve numbers in a[] is 10 */
            I(S(int i = 0, i < MAX, i++, a[i] >= 0 ? a[i] : 0) == 10);

 - Macro: typeof (EXPRN) P (INIT,CONDITION,NEXT,EXPRN)
     Returns the product of the values generated by EXPRN for all
     values given by  `for(INT;CONDITION;NEXT)'.  The type returned is
     the type of the expression.

            /* product of all the values in a[] is 10 */
            I(P(int i = 0, i < MAX, i++, a[i]) == 10);
          
            /* a = x^y i.e. x*x..*x y times */
            I(P(int i = 0, i < y, i++, x) == a);

   ---------- Footnotes ----------

   (1) ANSI C does not allow variable declarations at the beginning of
loops unlike C++. The  `Q.h' macros get around this by starting each
loop with a new scope.

   (2) This uses yet another GNU CC extension, however since we are
already using statement expressions we might as well use `typeof' as
well.


File: nana.info,  Node: Qstl.h,  Next: now.h,  Prev: Q.h,  Up: Interface

Qstl.h: quantifiers for STL containers.
=======================================

   The Standard Template Library (STL) is a library for C++ that makes
extensive use of templates to implement the standard container classes
and much more. Each of the container classes provides an interface to
iterate over all the objects in the container, e.g.

     // MAP is an associate array from location(lat,long) onto the name.
     typedef map<location,string,locationlt> MAP;
     
     void print_map_names(MAP& m) { // print out all the names in the map
       for(MAP::iterator i = m.begin(); i != m.end(); ++i) {
         cout << (*i).second << "\n";
       }
     }

   `Qstl.h' provides the same facilities as `Q.h' but uses the standard
STL iterator protocol shown above. The names in `Qstl.h' are generated
by appending a `O' (O not zero!) to the names in `Q.h'. In particular:

 - Macro: bool AO (NAME,CONTAINER,PREDICATE)
     For all values in the CONTAINER class the PREDICATE must be true.
     The PREDICATE refers to individual values using NAME. See the STL
     documentation for more details.  Another way of putting this is
     forall NAME in CONTAINER the PREDICATE must be true.

            map<int,char *,ltint> m;
            // all keys (or indexes) into m are positive
            I(AO(i, m, (*i).first >= 0));

 - Macro: bool EO (NAME,CONTAINER,PREDICATE)
     There exists one or more values in the CONTAINER class for which
     the PREDICATE is true.

            map<int,char,ltint> m;
          
            // one or more characters in m are '$'
            I(EO(i, m, (*i).second == '$'));

 - Macro: bool E1O (NAME,CONTAINER,PREDICATE)
     There exists one value in the CONTAINER for which the PREDICATE is
     true.

            map<int,char,ltint> m;
          
            // one characters in m is a '$'
            I(E1O(i, m, (*i).second == '$'));

 - Macro: int CO (NAME,CONTAINER,PREDICATE)
     Returns the number of times the PREDICATE was true for all values
     in the CONTAINER.

            map<int,char,ltint> m;
            int nalpha;
            // count the number of alphabetic chars in the map
            nalpha = CO(i, m, isalpha((*i).second));

 - Macro: typeof (EXPRN) SO (NAME,CONTAINER,EXPRN)
     Sum the EXPRN for all values in the CONTAINER.

            map<int,float,ltint> m;
            float sum;
            // sum all the values in m
            sum = SO(i, m, (*i).second);

 - Macro: typeof (EXPRN) PO (NAME,CONTAINER,EXPRN)
     Take the product of the EXPRN for all values in the CONTAINER.

            map<int,float,ltint> m;
            float product;
            // multiply all the values in m
            product = PO(i, m, (*i).second);


File: nana.info,  Node: now.h,  Next: cycles.h,  Prev: Qstl.h,  Up: Interface

now.h: measuring time
=====================

   The `now.h' file provides some simple time measurement routines.  It
is *not* included in `nana.h' so you must include this file separately.

   It uses the `gettimeofday' system call and has an accuracy of
between 1us and 10ms depending on the operating system and hardware
configuration.

   See the IPM package if you require better measurement tools.(1)

 - Function: double now ()
     Returns the time in seconds since the beginning of time as defined
     by your system. If you call `now_reset' the time will start again
     at 0.

 - Function: double now_reset ()
     Reset the times returned by `now' to 0.

 - Function: double now_delta (double *DP)
     Returns the elapsed time between *DP and NOW(). It then sets *DP
     to NOW, thus giving a delta time between particular events.

            t = now();
            for(;;) {
              ...; /* code that must finish in 50ms */
              I(now_delta(&t) <= 0.050);
            }

   ---------- Footnotes ----------

   (1) In the fullness of time, we may integrate these routines in here.


File: nana.info,  Node: cycles.h,  Next: eiffel.h,  Prev: now.h,  Up: Interface

cycles.h: access to CPU cycle counting registers.
=================================================

   Some modern CPU's provide user accessible registers or special
intstructions which can access a counter driven directly by the CPU
clock.  The `cycles.h' library provides access to these instructions
together with some calibration and utility routines.

   Currently we only provide support for pentium/cyrix machines using
the `RDTSC' instruction. If you want to use these routines you need to
run the `configure' script with the `--enable-rdtsc' option. Other
machine architectures will be supported as time goes on.

 - typedef: CYCLES long long
     The CPU cycle measurement type, typically a 64 bit unsigned
     integer.

 - Macro: CYCLES cycles ()
     Returns the current value for the cycle counter.

 - Function: CYCLES cycles_per_second (double T, int N)
     Returns an estimate of the number of cycles per second using the
     `now.h' library. The measurement is taken N times using a
     measurement period of T seconds for each measurement.  The minimum
     and maximum values for the measurement are set by each call to
     `cycles_per_second' and are available from the next two functions.

 - Function: CYCLES cycles_per_second_min ()
 - Function: CYCLES cycles_per_second_max ()
     Return the minimum or maximum of the measurements carried out by
     the previous call to `cycles_per_second'.

 - Function: double cycles_diff (CYCLES START, CYCLES STOP)
     Returns the time difference between START and STOP cycles in
     seconds as a double. As usual there are a few requirements:

        * `cycles_per_second' must be called before hand to calibrate
          the cycle time with the real time clock.

        * START must be less than or equal to STOP.  Note we do not
          handle wraparound currently since the counters start at 0 and
          are 64 bits long and so will not overflow in a reasonable
          period.  (1)

        * The difference between the START and STOP times should be
          able to be represented in a `double', lest overflow and
          misery follow.

        * CPU clocks tend to vary a bit with temperature etc, trust
          this and die.

* Menu:

* RDTSC::

   ---------- Footnotes ----------

   (1) Famous last words I know but: (2^64)/(1e9*60*60*24*365) = 584
yrs.


File: nana.info,  Node: RDTSC,  Prev: cycles.h,  Up: cycles.h

RDTSC: cycle timing for Pentium, Cyrix, etc
-------------------------------------------

   The RDTSC instruction is used for cycle timing on Pentiums and other
compatible CPU's such as the Cyrix chip set. Note that this instruction
does *not* exist on earlier CPU's in the series.

   We could of course try to discover the CPU type at compile or run
time and then use the appropriate instruction. This has all sorts of
problems, e.g. if we compile on a i586 does that mean it will be run on
the same CPU (no of course not....).

   For now we use the `--enable-rdtsc' option for `./configure'.


File: nana.info,  Node: eiffel.h,  Next: assert.h,  Prev: cycles.h,  Up: Interface

eiffel.h: eiffel type assertions
================================

   Eiffel is a very nice language which provides the assertion checking
facilities of nana inside the language itself.  The `eiffel.h' library
is intended to provide a similar setup to Eiffel in the C++ language.

* Menu:

* EIFFEL_CHECK::
* DOEND::
* REQUIRE...::


File: nana.info,  Node: EIFFEL_CHECK,  Next: DOEND,  Prev: eiffel.h,  Up: eiffel.h

EIFFEL_CHECK: enabling and disabling checking.
----------------------------------------------

   Assertion checking is controlled by the EIFFEL_CHECK macro which can
take on any of the following values:

`CHECK_NO'
     Disable all checking.

`CHECK_REQUIRE'
     Check the preconditions for each method.

`CHECK_ENSURE'
     And also check the postconditions.

`CHECK_INVARIANT'
     And also check the class invariant before and after each method is
     called. The programmer should provide a class method called
     `invariant' which returns `true' if the object is consistent,
     `false' otherwise.

`CHECK_LOOP'
     And also check the loop invariants.

`CHECK_ALL'
     And also check any assertions using the `CHECK' instruction.

   Note that the default value for `EIFFEL_CHECK' is `CHECK_REQUIRE',
i.e. check preconditions only.

   A typical compile flag to the compile might be:

     % g++ -c -DEIFFEL_CHECK=CHECK_ALL play.cc


File: nana.info,  Node: DOEND,  Next: REQUIRE...,  Prev: EIFFEL_CHECK,  Up: eiffel.h

DOEND: adding DO ... END.
-------------------------

   At the suggestion of Bertrand Meyer (Eiffel's author) the `DO' and
`END' macros have been added to `eiffel.h'.  Note that these are only
available if you define the `EIFFEL_DOEND' macro. To use these macros
each of your methods should use `DO' ... `END' as their outermost
brackets. For example:

     // compiled with EIFFEL_DOEND defined
     void Stack::push(int n)
     DO  // checks the class invariant + {
        ...
     END // check the class invariant + }

   If you do *not* define the `EIFFEL_DOEND' macro then `eiffel.h'
reverts to its old behaviour where `REQUIRE' and `ENSURE' also check
the class invariant. Thus to check the class invariant when you are not
using `DO' and `END' you would need to call `REQUIRE' and `ENSURE', for
example:

     // compile with EIFFEL_DOEND undefined (i.e. old behaviour)
     void Stack::push(int n)
     {
       REQUIRE(true); // checks the invariant as well as the precondition
     
       ENSURE(true); // checks the invariant as well as the postcondition
     }

   As for which one to option to pick, Bertrand Meyer is in favour of
the `DO' ... `END' solution.


File: nana.info,  Node: REQUIRE...,  Prev: DOEND,  Up: eiffel.h

REQUIRE, ENSURE, CHECK, etc.
----------------------------

   Here are the individual checking macros:

 - Macro: void REQUIRE (EXPRN)
     Called at the beginning of each method to check its precondition
     (requirements). For example:

          void Stack::push(int n) {
            REQUIRE(!full()); // stack has space for push
            ...
          }

     If `EIFFEL_DOEND' is not defined this also checks the class
     invariant.

 - Macro: void ENSURE (EXPRN)
     Called at the end of each method.  This checks the postcondition
     for a method and the class invariant.

          void Stack::push(int n) {
            ...
            ENSURE(!empty()); // it can't be empty after a push!
          }

     If `EIFFEL_DOEND' is not defined this also checks the class
     invariant.

 - Macro: void INVARIANT (EXPRN)
     Used to check a loop invariant.

 - Macro: void CHECK (EXPRN)
     Used for any other inline assertions. For example:

            CHECK(z != 0);
            x = y / z;

   And finally a small example:

     #include <eiffel.h>
     
     class example {
       int nobjects;
       map<location,string,locationlt> layer;
     public:
       bool invariant(); // is this object consistent
       void changeit(location l);
     };
     
     bool example::invariant() {
       return AO(i,layer,valid_location((*i).first)) &&
              nobjects >= 0;
     }
     
     void example::changeit(string n, location l) {
       REQUIRE(E1O(i,layer,(*i).second == n));
       ...;
       while(..) {
         INVARIANT(...);
         ...
         INVARIANT(...);
       }
       ...
       CHECK(x == 5);
       ...
       ENSURE(layer[l] == n);
     }

   Note that the invariant checking macro `example::invariant' is
called automatically on function entry/exit using the `REQUIRE' and
`ENSURE' macros if `EIFFEL_CHECK' is not defined.


File: nana.info,  Node: assert.h,  Next: calls.h,  Prev: eiffel.h,  Up: Interface

assert.h: a drop in replacement for assert.h
============================================

   A drop in replacement for `assert.h' is provided in the `src'
directory. It is *not* installed by default. If you wish to use it then
you need to copy it to your include directory by hand.

   This might be of use if you are already using `assert.h' and wish to
save some code space since the nana implementation is more space
efficient.

   Calls to `assert' are translated to calls to `I' and can be disabled
by defining `NDEBUG'.


File: nana.info,  Node: calls.h,  Prev: assert.h,  Up: Interface

calls.h: checking/printing many objects/facts.
==============================================

   The `calls' module implements a simple list of functions which can be
modified and executed at run-time. It is similar in spirit to the ANSI
C `atexit' function. It is intended to be used for:

   * Checking the consistency of the components in your system.

     For example each module could register a self checking function
     which uses the rest of the nana library. All of these functions
     would then be called using `calls.h' to check that the entire
     system is consistent.

   * Printing out the state of your program in a readable format.

 - Type: typedef FUNC
     A pointer to a `void' function which takes a single `void*'
     argument. The `void *' argument is intended to be used to pass
     information such as arguments or pointers to objects (e.g. `this'
     in C++). All of the checking/printing functions must be of this
     type, e.g.

          void print_object(void *f) {
            ...;
          }

 - Type: struct CALL
     This structure represents a single call to a function, i.e. a
     function pointer (`FUNC') and the `void*' argument.

          	CALL *head = 0;

 - Function: void calls_add (CALL **head, FUNC fp, *arg)
     Adds a call to function `fp' with argument `arg' to the list
     pointed to by `head'.

          	CALL *global_checks = 0;
          
          	calls_add(&global_checks,complex_ok,(void *)x);

 - Function: void calls_exec (CALL **head, FUNC fp, void *arg)
     Execute all/some of the calls in the list given by `head'.  The
     arguments `fp' and `arg' must both match for each individual call.
     The null pointer (`0') matches anything whilst any other value
     requires an exact match between the `CALL' and the arguments to
     `calls_exec'.  For example:

          calls_exec(&l,0,0); /* execute all functions in l  */
          calls_exec(&l,complex_print,0); /* calls complex_print(*) in l */
          calls_exec(&l,0,(void*) &b); /* calls *(&b) in l */
          calls_exec(&l,f,(void*) &b); /* calls f(&b) in l */

 - Function: void calls_delete (CALL **head, FUNC fp, void *arg)
     Delete all/some of the calls in the list given by `head'.  The
     arguments `fp' and `arg' must both match for each individual call.
     The null pointer (`0') matches anything whilst any other value
     requires an exact match between the `CALL' and the arguments to
     `calls_delete'.  For example:

          calls_delete(&l,0,0); /* delete all functions in l  */
          calls_delete(&l,complex_print,0); /* delete complex_print(*) in l */
          calls_delete(&l,0,(void*) &b); /* delete *(&b) in l */
          calls_delete(&l,f,(void*) &b); /* delete f(&b) in l */

   *Note:* that calls are added to the head of the list rather than the
tail. This means that the most recently added call will be executed
first (as in a stack).


File: nana.info,  Node: Shortform,  Next: Performance,  Prev: Interface,  Up: Top

Nana Shortform Generator.
*************************

   The Eiffel language provides a shortform of a class which consists of
the exported methods and their pre and post conditions. The private
part of the class such as the code is hidden in this form leaving only:

  1. Arguments and return values for methods.

  2. `REQUIRE' and `ENSURE' calls which specify the precondition and
     postconditions of each method.

   This is useful to provide a summary of what the code does and how to
use it rather than how it works.

   Nana provides a similar service which can be used to generated a HTML
version of the short form of your program automatically.  The code for
this is kept in `shortform'. Do a `make example' to build an example
document.(1)

   Consider the following program:

     /* smallex.c - a small example */
     
     #include <stdio.h>
     #include <math.h>
     #include <eiffel.h>
     
     void sort(int *v, int n) {
       int i;
       REQUIRE(v != NULL &&
         0 <= n);
     
       for(i = 0; < n; i++) { /* at last, an O(n) sort! */
         v[i] = i;
       }
       /* And no, this isn't what most people think of as sorting */
     
       ENSURE(A(int i = 0, i < n - 1, i++,
           v[i] <= v[i+1]));
     }

   Its short form can be generated by using the `nana-sfg'(2) program
which generates:

     % nana-sfg smallex.c
     ...
     #include <stdio.h>
     #include <math.h>
     #include <eiffel.h>
     ...
     void sort(int *v, int n) {
       ...
       REQUIRE(v != NULL &&
         n >= 0);
       ...
       ENSURE(A(int i = 0, i < n, i++,
           v[i] <= v[i+1]));
     }
     %

   The `nana-sfg' program is a small AWK program which processes its
arguments into shortform and always writes to the standard output. If it
is passed no arguments it works as a normal UNIX filter reading from the
standard input.

   It is suggested that a copy of `nana-sfg' be kept in each projects
`bin' directory so that it can be modified for local taste. The user
will probably wish to modify the rules for short form generation.  For
example you might add rules such as:

     /^\/\//           { emit(); } # print out C++ comments in column 1
     /^\/\*\+/,/\*\//  { emit(); } # print out multi-line /*+ ... */ comments

   Of course for a real project you need to run `nana-sfg' over the
entire source tree. To do this you can use the `nana-sfdir' program.

     % nana-sfdir

   This command simply creates a copy of the source tree in the current
directory under `NANASF' using the `nana-sfg' program. You can then run
a source code to HTML translator over the `NANASF' directory. Currently
we are using the GLOBAL package which was written by Shigio Yamaguchi
which available from:

   * `http://wafu.netgate.net/tama/unix/global.html' - the GLOBAL
     homepage.

   * `ftp://ftp.cs.ntu.edu/pub/nana/global-2.24.tar.gz' - a local
     (well for Darwin at least) copy of the GLOBAL package.

   The alert reader will perhaps be asking themselves why we did not
simply modify GLOBAL. Well that was the original idea, however after a
bit of thinking it seemed better to separate the generation of the short
form of the code from the generation of the HTML. This gives us the
ability to use other translators and other tools. It also simplifies the
interaction between nana and GLOBAL.  For information on other
translators see:

   * `http://www.zib.de/Visual/software/doc++/index.html' - DOC++
      homepage.

   * `http://www.webnz.com/webnz/robert/cpp_site.html#Documentation' -
           an index of other translation tools (e.g. to LaTeX).

   ---------- Footnotes ----------

   (1) Note you need to install the GLOBAL package first. This is
installed by default on FreeBSD systems. If you do not have the GLOBAL
package read on.

   (2) The name `nana-sfg' stands for either Nana Short Form Generator
or Nana Science Fiction Generator. Personally I prefer the later
derivation.


File: nana.info,  Node: Performance,  Next: Tracing,  Prev: Shortform,  Up: Top

Nana Performance Measurement
****************************

   A tool is provided for measuring code/time requirements for arbitrary
code fragments. This is kept in the `perf' directory and is *not* built
by default. If you wish to use this tool use the following targets:

     % cd perf
     % make perf

   The output is `perf.tex', `perf.dvi' and `perf/index.html'.

   Note that the measurement requires the following:

   * GNU CC - it uses the GNU address of label extension to calculate
          the size in bytes of a code fragment.

   * Time is measured using the nana `now()' function.

   * LaTeX - to generate the document from `perf.tex'.

   * LaTeX2HTML - to generate a HTML version of `perf.tex'.

   As an indication of the values you can expect here is part of the
results for `make perf' on a 200Mhz Cyrix MMX (i386) chip which runs at
about 200 BogoMips under FreeBSD 2.2.6 with `-O'.

   `assert(i >= 2);' 28 bytes, 19ns.

   `TRAD_assert(i >= 2);' 47 bytes, 20ns.(1)

   `I(i >= 2);' 9 bytes, 18ns.

   `DI(i >= 2);' 1 byte, 147.4us.

   `I(A(int i=0, i!=10, i++, a[i]>=0));' 28 bytes, 287ns.

   `d = now();' 8 bytes, 3.1us.

   `printf("helloworld\n");' 13 bytes, 9.1us.

   `L("helloworld\n");' 18 bytes, 8.9us.

   `DL("helloworld\n");' 1 byte, 26.4us.

   Note that these measurements were on a system that was configured
with `I_DEFAULT=fast ./configure'. The default output of `./configure'
produces nice error messages at the cost of increased code space.

   ---------- Footnotes ----------

   (1) This is the traditional assert which uses `fprintf' and `exit'
in a macro. The BSD `assert' macro used in FreeBSD is a bit smarter and
calls a function to do the message printing and exiting. Note that the
real cost of this function is even higher since we are only measuring
the code space requirements, not the space required for the message
strings.


File: nana.info,  Node: Tracing,  Next: Usage,  Prev: Performance,  Up: Top

Tracing tools
*************

   A few tools for execution tracing and logging are available in the
`gdb' directory and are installed by default. They are simple shell
scripts and may be of some use in testing/development.  Note that
`gdb-4.17' may be required on some machines for this stuff to work
properly.

* Menu:

* Statement::
* Library::


File: nana.info,  Node: Statement,  Next: Library,  Prev: Tracing,  Up: Tracing

Statement level tracing
=======================

   The `nana-trace' executes a program and generates a message for each
line of code executed (a statement trace). The statement level trace is
useful for things such as:

   * Understanding code.

   * Measuring test coverage.

   * Comparing runs of the code when regression testing, e.g.
     verifying that change X only changes the behaviour of program P
     for test case Z.

   For example the `make ex-trace' command in `gdb' generates:

     % make ex-trace
     gcc -g test.c
     sh ./nana-trace a.out
     47           setbuf(stdout, NULL); /* disable buffering */
     49           printf("** main()\n");
     ** main()
     50           printf("** 1: %d\n", distance(1,-5));
     distance (i=1, j=-5) at test.c:43
     43           return abs(i - j);
     abs (i=6) at test.c:35
     35           if(i >= 0) {
     36                return i;
     40      }
     distance (i=1, j=-5) at test.c:44
     44      }
     ** 1: 6
     main () at test.c:51
     51           printf("** 2: %d\n", distance(twice(1),-5));
     twice (i=1) at test.c:29
     29           i = i * 2;
     31           return i ;
     32      }
     distance (i=2, j=-5) at test.c:43
     43           return abs(i - j);
     abs (i=7) at test.c:35
     35           if(i >= 0) {
     36                return i;
     40      }
     distance (i=2, j=-5) at test.c:44
     44      }
     ** 2: 7
     main () at test.c:52
     52           printf("** 3: %d\n", distance(3,-5));
     distance (i=3, j=-5) at test.c:43
     43           return abs(i - j);
     abs (i=8) at test.c:35
     35           if(i >= 0) {
     36                return i;
     40      }
     distance (i=3, j=-5) at test.c:44
     44      }
     ** 3: 8
     main () at test.c:53
     53      }

