
  [[title
      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:

  [[tty
    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:

  [[tty
    /* 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.


  [[null
    ; arch-tag: Tom Lord Thu Mar  3 07:58:47 2005 (librification-notes/fn-anatomy.txt)
  ]]

