# 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.

home

## GNU Arch

what is GNU Arch?

GNU Arch Bug Database

popular GNU Arch links

GNU Arch development roadmap

popular GNU Arch writings