Tom Lord's Hackery

Anatomy of a Librified Function in libarch, tla-1.3.x

3 Mar 2005

Nearly all new functionns in librified tla will be examples of filling in a single template. The template relies on a set of CPP macros and provides a framework for raising and handling error conditions and for robustly releasing allocated resources when they are no longer needed.

Here is a short form of the template:

    ssize_t
    @FNNAME@ (t_arch const arch)
    {
      ARCH_FN_DECLS(@FNNAME@);

      ARCH_FN_ENTRY
        {}
      ARCH_FN_CLEANUPS
        {}
      ARCH_FN_NORMAL_EXIT
        {
          invariant (answer >= 0);
        }
      ARCH_FN_ERRORS
        {}
      ARCH_FN_BODY
        {}
      ARCH_FN_END;
    }

and here is a commented version:

    /* All functions return a value of type `ssize_t'.
     * Negative return values indicate an error condition.
     *
     * All functions accept a parameter of type type `t_arch'.
     * That parameter *must* (for various macros to work) be 
     * named `arch'.  (Functions may accept additional parameters
     * as well, of course.)
     */
    ssize_t
    @FNNAME@ (t_arch const arch)
    {
      ARCH_FN_DECLS(@FNNAME@);
      /* 
       * The above macro expands to declarations needed by other
       * `ARCH_FN_' macros.
       */


      /* Here, declare all non-const local variables, regardless of
       * their block scope.  Every variable must be initialized and
       * the initialization expression must not contain any function
       * calls:
       */


       /* The first line of non-declaration code must be:
        */

      ARCH_FN_ENTRY
        {
          /* Here, complete initialization of locals.
           * This section is often empty.
           * 
           * It is best practice to *not* put code here which
           * can fail (detect an error condition).
           * 
           * Execution of this code is followed by execution
           * of the function body (see ARCH_FN_BODY, below).
           */
        }
      ARCH_FN_CLEANUPS
        {
          /* All exit paths from the function (both normal
           * returns and error conditions) pass through
           * this section of code.
           * 
           * Use it to release all resources held by local 
           * variables.
           */
        }
      ARCH_FN_NORMAL_EXIT
        {
          /* Normal exit paths (not error conditions)
           * pass through this block.
           * 
           * State invariants relating to the return value.
           * If it is especially convenient, computed values
           * may be copied into return parameters here and the
           * `ssize_t' return value may be canonicalized.
           * 
           * The value that will be returned after leaving this
           * section is stored in the variable `answer', declared
           * above by `ARCH_FN_DECLS'.
           * 
           * Note that *all* functions are subject to the invariant
           * that `answer >= 0' but some functions may impose
           * additional constraints.
           * 
           * Note also that these constraints do not mean the function
           * can not return a negative value.  If this function
           * exits via `ARCH_RAISE' or `ARCH_RERAISE' (see below) then
           * it return a negative error code.
           */
          invariant (answer >= 0);

          /* Execution of this section is followed first by
           * execution of the `ARCH_FN_CLEANUPS' section and
           * then by a /C/ `return'.
        }
      ARCH_FN_ERRORS
        {
          /* List all errors this function might raise and whether or
           * not it might reraise an error raised by a function it
           * calls.
           */
          ARCH_CAN_RAISE(EFATAL);
          ARCH_CAN_RAISE(ENOMEM);
          ARCH_CAN_RAISE(EARCHPARAMS);
        }
      ARCH_FN_BODY
        {
          /* The body of the function goes here.
           * Execution of this section follows that of
           * the `ARCH_FN_ENTRY' section, above.
           * 
           * A statement of the form:
           * 
           *            ARCH_RAISE (ERRORNAME);
           * 
           * raises the arch error named `ERRORNAME' (see
           * `libarch/arch.h' for a list of such errors).
           * `ARCH_RAISE' is a macro which does not "return" -- it 
           * transfters control to the `ARCH_FN_CLEANUPS' section.
           * 
           * If the body calls another function which return a
           * negative error code, this function can re-raise the
           * same error by invoking:
           * 
           *            ARCH_RERAISE;
           * 
           * Before raising an error, formatted error message text
           * can be recorded using:
           * 
           *    arch_msgbuf_printfmt (arch, "format string", ...);
           * 
           * The body must *not* contain a `return' statement.
           * Instead, the form:
           * 
           *            ARCH_RETURN ( VALUE );
           *
           * should be used.
           * 
           * Alternatively, functions can exit by assigning a return
           * value to the variable `answer' and either executing:
           * 
           *            ARCH_NORMAL_EXIT;
           * 
           * or reaching the final `ARCH_FN_END'.
           */
         }
      ARCH_FN_END;
    }

Copyright

Copyright (C) 2004 Tom Lord

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

See the file COPYING for further information about the copyright and warranty status of this work.