This manual is for FreeM, (version 0.1.6), which is a free and
open-source implementation of the MUMPS programming language and
database system.

Copyright (C) 2020 Coherent Logic Development LLC

     This work is licensed under a Creative Commons
     Attribution-NonCommercial-NoDerivatives 4.0 International License.

The FreeM Manual
****************

This is the official manual for FreeM.

Introduction
************

FreeM started its life as _FreeMUMPS_, written for MS-DOS and ported to
Linux and SCO UNIX by a mysterious individual going by the name of
"Shalom ha-Ashkenaz".  It was released to MUG (MUMPS User Group)
Deutschland in 1998, and maintenance was taken over by the GUMP (Generic
Universal M Project) thereafter, which changed its name first to PSM
(Public Standard MUMPS) and then by popular request to FreeM.

   When GT.M was open-sourced in late 1999, FreeM and GUMP were
essentially abandoned.  L.D. Landis, the owner of the original GUMP
SourceForge project, and one of FreeM's significant contributors, passed
maintenance of FreeM and ownership of its SourceForge project to John
Willis in 2014.  At this point, FreeM would not compile or run on modern
Linux systems, so steps were taken to remedy the most pressing issues in
the codebase.  Limitations on the terminal size (previously hard-coded
to 80x25) were lifted, and new '$VIEW' functions were added to retrieve
the terminal size information.  '$X' and '$Y' intrinsic special
variables were updated to support arbitrary terminal sizes, and FreeM
was once again able to build and run.

   In February of 2020, work began in earnest to build a development and
support infrastructure for FreeM and begin the careful process of
refining it into a more stable and robust product.

Production Readiness
====================

FreeM is not yet production-ready.  There are several show-stopping bugs
that preclude a general release for public use:

   * The use of 'NEW' and argumentless 'DO', only supported when
     '-DNEWSTACK' is passed to the C compiler, causes occasional
     segmentation faults that have not been isolated, as they don't
     appear when running under the control of symbolic debuggers such as
     'gdb', or leak testers such as 'valgrind'.

   * The common idiom of a '$ORDER' loop is broken, as 'QUIT:SUB=""' (or
     similar) is not properly honored, resulting in infinite loops and
     incorrect output.

   * 'MERGE' is not implemented.  Code exists in 'symtab.c' (responsible
     for handling local variables) to support the 'MERGE'ing of local
     variables, but it causes segmentation faults as well.

   * SSVNs (Structured System Variables) are not fully implemented,
     though skeletal support exists in the FreeM source code
     ('ssvn*.c').

   * 'VIEW' commands and '$VIEW' functions are used extensively to
     configure and inspect the run-time behavior of FreeM, rather than
     the "canonical" SSVN-based approach.

   Per the conditions under which Shalom ha-Ashkenaz originally released
the _FreeMUMPS_ implementation to the community, a full and supported
public release of the software is not permitted until the above issues
are resolved, and the MUG (MUMPS User Group) organization (or its
successors) certify its quality and suitability for purpose.

Contributors
============

Current contributors denoted with a _+_ following their name and role.

   * Shalom ha-Ashkenaz (Original Implementer)

   * Jon Diamond (Library, Utilities, Conformance)

   * Winfried Gerum (Code, Advice, MTA coordination)

   * Greg Kreis (Hardhats coordination, Dependencies)

   * Larry Landis (Coordination, Code, Documentation)

   * Frederick D.S. Marshall (MDC Standards Conformance) _+_

   * Lloyd Milligan (Code, Testing, Documentation)

   * Steve Morris (Code, Microsoft)

   * John Murray (Code, Conformance)

   * Wilhelm Pastoors (Testing, Documentation)

   * Kate Schell (Coordination, Conformance, MTA, MDC, Advice)

   * Lyle Schofield (Advice, Prioritization, Tracking, Project
     Management)

   * Axel Trocha (Code, Utilities)

   * Dick Walters (Project Lead, Chief Coordinator, MTA)

   * David Whitten (QA Test Suite, MDC, Advice) _+_

   * David Wicksell (Debugging, Code, Testing) _+_

   * John Willis (Current Maintainer and Project Lead) _+_

   * Steve Zeck (Code)

1 FreeM Invocation
******************

1.1 Synopsis
============

     $ ./mumps [_OPTIONS_...] [[-r <entryref>] | [--routine=<entryref>]]

   When FreeM loads, it searches the system library in '../mlib/' for
the '^%SYS' routine.  When '^%SYS' runs, it searches for a default
namespace, activates it, configures the programmer-mode command prompt,
prints a welcome message, and presents the programmer-mode prompt.

   If no default namespace is configured, FreeM will prompt you to
create a new namespace.

   When '-r' or '--routine' are passed on the command line, FreeM will
load and run the specified routine instead of ^%SYS, which means that
routines launched in this manner will need to do their own namespace
configuration using 'VIEW' commands prior to accessing any routines or
globals existing outside of the system library namespace.

1.2 Command-Line Options
========================

'-h', '--hardcopy'
     Enables hardcopy mode, echoing all output to a disk file.  By
     default, this disk file is '/usr/tmp/hardcopy', but can be changed
     with the following command:

          USER> VIEW 13:"</path/to/hardcopy/file>"

'-f', '--filter'
     Allows your MUMPS routines to be used as UNIX filters.

'-n', '--noclear'
     Disables automatic screen clearing when FreeM loads.

'-s', '--standard'
     Restricts the use of non-standard language features, including
     '$Z...' intrinsic special variables, '$Z...' intrinsic functions,
     'Z...' commands, as well as 'VIEW' and '$VIEW'.

'-i', '--import'
     Causes your UNIX environment variables to be imported into FreeM's
     local symbol table.

'-r _<entryref>_', '--routine=_<entryref>_'
     Causes '<entryref>' to be executed at load, instead of '^%SYS'.

2 The FreeM REPL
****************

3 Intrinsic Special Variables
*****************************

3.1 $DEVICE
===========

Returns the status of the device currently in use, and is writable.

   If '$DEVICE' returns _1_, an error condition exists on the current
device.

3.2 $ECODE
==========

Returns a comma-delimited list of error conditions currently present,
and is writable.  An empty '$ECODE' indicates no errors.

   FreeM currently sets '$ECODE' only for errors established by the MDC
(MUMPS Development Committee).

   Setting '$ECODE' has no effect, as FreeM does not currently implement
standard error-handling with '$ETRAP'.

3.3 $ESTACK
===========

Returns an empty string, as FreeM does not currently implement standard
error-handling with '$ETRAP'.

3.4 $ETRAP
==========

Returns an empty string and is writable, but unused as FreeM does not
currently implement standard error-handling with '$ETRAP'.

3.5 $HOROLOG
============

Returns a string containing the current date and time as
'<days>,<seconds>', where '<days>' represents the number of days since
the MUMPS epoch (midnight on 31 December 1840), and '<seconds>'
represents the number of seconds since the most recent midnight.

     _Non-Standard Behavior_

     In FreeM, '$HOROLOG' is writable, and will set the current system
     time as long as the user has sufficient permissions to do so.

3.6 $IO
=======

Represents the current input/output device.  Read-only.

3.7 $JOB
========

Represents the process ID of the FreeM instance currently in use.

3.8 $KEY
========

Represents the sequence of control characters that terminated the last
'READ' command on '$IO'.

3.9 $PRINCIPAL
==============

Represents the primary input/output device.  Usually a terminal or
virtual terminal.

3.10 $QUIT
==========

If the current execution context was invoked as an extrinsic function,
'$QUIT' returns _1_.  Otherwise, returns _0_.

   When '$QUIT' returns _1_, a subsequent 'QUIT' command must have an
argument.

3.11 $STACK
===========

Represents the current stack level.

3.12 $STORAGE
=============

Represents the number of bytes of free space available in FreeM's heap.

3.13 $SYSTEM
============

Returns the MDC system ID of FreeM.

3.14 $TEST
==========

'$TEST' is a writable ISV that is _1_ if the most recent conditional
expression returned _true_.  Otherwise, returns _false_.

   '$TEST' is implicitly 'NEW'ed when entering a new stack frame.

3.15 $TLEVEL
============

Returns an empty string, as FreeM does not currently implement
transaction processing.

3.16 $TRESTART
==============

Returns an empty string, as FreeM does not currently implement
transaction processing.

3.17 $X
=======

Represents the current column position of the FreeM cursor.  In FreeM,
setting

     _Non-Standard Behavior_

     In FreeM, setting '$X' will move the FreeM cursor.

3.18 $Y
=======

Represents the current row position of the FreeM cursor.

     _Non-Standard Behavior_

     In FreeM, setting '$Y' will move the FreeM cursor.

3.19 $ZA
========

3.20 $ZB
========

3.21 $ZCONTROLC
===============

3.22 $ZDATE
===========

3.23 $ZERROR
============

3.24 $ZF
========

3.25 $ZHOROLOG
==============

3.26 $ZINRPT
============

3.27 $ZJOB
==========

3.28 $ZLOCAL
============

3.29 $ZMATCHCONTROL
===================

3.30 $ZMATCHNUMERIC
===================

3.31 $ZMATCHPUNCTUATION
=======================

3.32 $ZMATCHALPHABETIC
======================

3.33 $ZMATCHLOWERCASE
=====================

3.34 $ZMATCHUPPERCASE
=====================

3.35 $ZMATCHEVERYTHING
======================

3.36 $ZNAME
===========

3.37 $ZORDER
============

3.38 $ZPRECISION
================

3.39 $ZREFERENCE
================

3.40 $ZSYSTEM
=============

3.41 $ZTIME
===========

3.42 $ZTRAP
===========

3.43 $ZVERSION
==============

4 Intrinsic Functions
*********************

4.1 $ASCII
==========

Returns the ASCII code (in decimal) for one character in a string.

     SET RESULT=$ASCII(_<string>_[,_<index>_])

   If _<index>_ is not supplied, '$ASCII' will return the ASCII code of
the first character.  Otherwise, returns the ASCII code of the character
at position _<index>_.

4.2 $CHAR
=========

Returns a string of characters corresponding to a list of ASCII codes.

     SET RESULT=$CHAR(_<ascii-code>_[,_<ascii-code>_,...])

4.3 $DATA
=========

Returns a numeric value 0, 1, 10, or 11, depending on whether a
referenced node is defined, has data, or has children:

     SET RESULT=$DATA(_<node>_)

   The return values are as follows:

     0: _<node>_ is undefined
     1: _<node>_ has data but no children
     10: _<node>_ has children but no data
     11: _<node>_ has children and data

4.4 $EXTRACT
============

4.5 $FIND
=========

4.6 $FNUMBER
============

4.7 $GET
========

4.8 $JUSTIFY
============

4.9 $LENGTH
===========

4.10 $NAME
==========

4.11 $NEXT
==========

4.12 $ORDER
===========

4.13 $PIECE
===========

4.14 $QLENGTH
=============

4.15 $QSUBSCRIPT
================

4.16 $QUERY
===========

4.17 $RANDOM
============

4.18 $REVERSE
=============

4.19 $SELECT
============

4.20 $STACK
===========

4.21 $TEXT
==========

4.22 $TRANSLATE
===============

4.23 $VIEW
==========

4.24 $ZBOOLEAN
==============

4.25 $ZCALL
===========

4.26 $ZCR
=========

4.27 $ZCRC
==========

4.28 $ZDATA
===========

4.29 $ZDATE
===========

4.30 $ZEDIT
===========

4.31 $ZHOROLOG
==============

4.32 $ZHT
=========

4.33 $ZKEY
==========

4.34 $ZLENGTH
=============

4.35 $ZLSD
==========

4.36 $ZM
========

4.37 $ZNAME
===========

4.38 $ZNEXT
===========

4.39 $ZORDER
============

4.40 $ZPIECE
============

4.41 $ZPREVIOUS
===============

4.42 $ZREPLACE
==============

4.43 $ZSYNTAX
=============

4.44 $ZSORT
===========

4.45 $ZTIME
===========

4.46 $ZZIP
==========

5 Commands
**********

5.1 BREAK
=========

5.2 CLOSE
=========

5.3 DO
======

5.4 ELSE
========

5.5 FOR
=======

5.6 GOTO
========

5.7 HALT
========

5.8 HANG
========

5.9 IF
======

5.10 JOB
========

5.11 KILL
=========

5.12 KSUBSCRIPTS
================

5.13 KVALUE
===========

5.14 LOCK
=========

5.15 MERGE
==========

5.16 NEW
========

5.17 OPEN
=========

5.18 QUIT
=========

5.19 READ
=========

5.20 SET
========

5.21 TCOMMIT
============

5.22 TRESTART
=============

5.23 TROLLBACK
==============

5.24 USE
========

5.25 VIEW
=========

5.26 WRITE
==========

5.27 XECUTE
===========

5.28 ZALLOCATE
==============

5.29 ZBREAK
===========

5.30 ZDEALLOCATE
================

5.31 ZGO
========

5.32 ZHALT
==========

5.33 ZINSERT
============

5.34 ZJOB
=========

5.35 ZLOAD
==========

5.36 ZNEW
=========

5.37 ZPRINT
===========

5.38 ZQUIT
==========

5.39 ZREMOVE
============

5.40 ZSAVE
==========

5.41 ZTRAP
==========

5.42 ZWRITE
===========

6 Structured System Variables
*****************************

6.1 ^$CHARACTER
===============

6.2 ^$DEVICE
============

6.3 ^$DISPLAY
=============

6.4 ^$EVENT
===========

6.5 ^$GLOBAL
============

6.6 ^$JOB
=========

6.7 ^$LOCK
==========

6.8 ^$PDISPLAY
==============

6.9 ^$ROUTINE
=============

6.10 ^$SYSTEM
=============

6.11 ^$WINDOW
=============

7 Operators
***********

8 User-Defined Z Functions
**************************

9 User-Defined SSVNs
********************

10 System Library Routines
**************************

10.1 ^%ED
=========

10.2 ^%FLIST
============

10.3 ^%FUTIL
============

10.4 ^%GD
=========

10.5 ^%GL
=========

10.6 ^%KEY
==========

10.7 ^%KEYINT
=============

10.8 ^%KEYTEST
==============

10.9 ^%KILLJOB
==============

10.10 ^%LOGIN
=============

10.11 ^%MEN
===========

10.12 ^%MESS
============

10.13 ^%MUTIL
=============

10.14 ^%N
=========

10.15 ^%RD
==========

10.16 ^%RDEL
============

10.17 ^%SS
==========

10.18 ^%SYS
===========

10.19 ^%SYSDEV
==============

10.20 ^%SYSGEN
==============

10.21 ^%SYSINFO
===============

10.22 ^%SYSNSP
==============

10.23 ^%SYSNSP0
===============

10.24 ^%T
=========

10.25 ^%u
=========

10.26 ^%uflis
=============

10.27 ^%ufxxx
=============

10.28 ^%ug
==========

10.29 ^%ugdir
=============

10.30 ^%ugexp
=============

10.31 ^%ugimp
=============

10.32 ^%uglis
=============

10.33 ^%ugxxx
=============

10.34 ^%ulmath
==============

10.35 ^%ulstring
================

10.36 ^%ur
==========

10.37 ^%urdel
=============

10.38 ^%urdir
=============

10.39 ^%uredi
=============

10.40 ^%urexp
=============

10.41 ^%urimp
=============

10.42 ^%ursea
=============

10.43 ^%urxxx
=============

10.44 ^%uxdat
=============

10.45 ^%uxxxx
=============

10.46 ^%ZCOLUMNS
================

10.47 ^%ZOS
===========

10.48 ^%ZROWS
=============

10.49 ^%UTILITY
===============

11 Namespace Management
***********************

11.1 Namespace Management Overview
==================================

The namespace utilities (provided by '%SYSNSP.m', '%SYSNSP0.m', and
'%SYSGEN.m' in '$DIST_ROOT/mlib') are used for the management of
namespaces.  A _namespace_ is a particular collection of FreeM globals
and routines.  If you are accustomed to other MUMPS implementations, you
might have seen this concept referred to as a _UCI_ or _global
directory_.

   FreeM has something of a _system library_ namespace, located in
'$DIST_ROOT/mlib' which contains the "percent" globals and routines
(globals and routines whose names begin with the percent sign '%').
Routines and globals beginning with the percent sign character must be
contained in '$DIST_ROOT/mlib' in the current version of FreeM. However,
these routines and globals are always accessible, regardless of the
currently-active namespace.

   Any user-defined namespace may only access globals and routines
residing either in the current namespace, or in the system library
namespace.  For instance, if you have two user-defined namespaces,
'USER1' and 'USER2', routines in the 'USER1' namespace may not access
globals in the 'USER2' namespace, but may access globals in the system
library namespace.

   At least one user-defined namespace is required for proper FreeM
operation, and FreeM will automatically ask you to create one if one
does not already exist.  The first user-defined namespace you create is
automatically chosen as the startup namespace when FreeM first runs.
However, the FreeM programmer may easily switch to other namespaces
using the utility entry points contained in the '^%SYSNSP' routine.

   All namespaces aside from the system library namespace are located in
'$DIST_ROOT/namespace', and are laid out as follows:

+---namespace        namespace directory
|   |
|   +---<name>       name of the namespace (can have more than one)
|       |
|       +---routine  namespace routines
|       |
|       +---global   namespace globals

11.2 Listing Namespaces
=======================

From the FreeM REPL, enter the following commands:

     USER> _d show^%SYSNSP_

     index     namespace
     -----  ---------------
        1   *USER
        2    MVTS
   In the above display, the 'USER' namespace is the default, denoted by
the asterisk character preceding its name.  The index column is of
special importance, as it is the index value (and not the name) that is
used when switching namespaces.

11.3 Switching Namespaces
=========================

To switch namespaces, use the 'show^%SYSNSP' entry point documented
above to determine the index of the desired namespace, and then call
'switch^%SYSNSP', passing the index as the sole argument.

   For example, to switch from the 'MVTS' namespace (index 2) to the
'USER' namespace, with an index of 1:

     MVTS> _S RESULT=$$switch^%SYSNSP(1)_

     USER>

   Note that the programmer mode prompt of the FreeM REPL always(1)
indicates the name of the currently-selected namespace.

11.4 Adding New Namespaces
==========================

To add a new namespace, you will use the '^%SYSGEN' routine, which is
user-friendly and menu-driven.

   In this example, we will add a new namespace, called 'TESTING':

     USER> _D ^%SYSGEN_

             FreeM SYSTEM SETUP UTILITY
                2020/02/22  20:28:51

             Main Menu
             ---------

             1  -  Namespace Settings
             2  -  Routine-Editor Settings
             3  -  Configuration Settings
             4  -  Startup Options

             Your choice: _1_

             Namespace Settings
             ------------------

             1  -  List Namespaces
             2  -  add Namespace
             3  -  delete Namespace
             4  -  rename Namespace
             5  -  repair Namespace

             Your choice: _2_

             Name ..........: _TESTING_
             Ok to create? <Y> _y_
             Done.

11.5 Returning to the Default Namespace
=======================================

To switch to the default namespace, enter the following command in the
FreeM REPL:

     TESTING> _S RESULT=$$switch^%SYSNSP($$dflt^%SYSNSP))_

     USER>

   Note that the programmer-mode prompt has changed to 'USER>' to
reflect the namespace change.

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

   (1) This is not entirely true.  'VIEW 200:_<mumps-expression>_' can
be used to adjust the programmer-mode prompt to match the preferences of
specific users and/or sites.

12 Configuration and SYSGEN
***************************

13 Accessing FreeM from C Programs
**********************************

13.1 mlib.h and mref_t Data Structure
=====================================

13.2 Initializing mlib API
==========================

13.3 m_init_mref()
==================

13.4 m_add_subscript()
======================

13.5 m_version()
================

13.6 m_set()
============

13.7 m_get()
============

13.8 m_kill()
=============

13.9 m_kvalue()
===============

13.10 m_ksubscripts()
=====================

13.11 m_data()
==============

13.12 m_order()
===============

13.13 m_query()
===============

13.14 m_lock()
==============

13.15 m_unlock()
================

13.16 m_str_function()
======================

13.17 m_num_function()
======================

13.18 m_procedure()
===================

Appendix A FreeM Utilities
**************************

A.1 Global Compactor (gcompact)
===============================

A.2 Block Examiner (gfix)
=========================

A.3 Global Lister (gl)
======================

A.4 Lock Examiner (glocks)
==========================

A.5 Global Repair Tool (grestore)
=================================

A.6 Global Validator (gverify)
==============================

Appendix B FreeM VIEW Commands and Functions
********************************************

Appendix C Implementation Limits
********************************

Appendix D US-ASCII Character Set
*********************************

Code   Character
-------------------
000    '<NUL>'
001    '<SOH>'
002    '<STX>'
003    '<ETX>'
004    '<EOT>'
005    '<ENQ>'
006    '<ACK>'
007    '<BEL>'
008    '<BS>'
009    '<HT>'
010    '<LF>'
011    '<VT>'
012    '<FF>'
013    '<CR>'
014    '<SO>'
015    '<SI>'
016    '<DLE>'
017    '<DC1>'
018    '<DC2>'
019    '<DC3>'
020    '<DC4>'
021    '<NAK>'
022    '<SYN>'
023    '<ETB>'
024    '<CAN>'
025    '<EM>'
026    '<SUB>'
027    '<ESC>'
028    '<FS>'
029    '<GS>'
030    '<RS>'
031    '<US>'
032    '<space>'
033    !
034    "
035    #

Appendix E FreeM Project Coding Standards
*****************************************

E.1 Module Headers
==================

Module headers should adhere to the following format:

/*
 *                            *
 *                           * *
 *                          *   *
 *                     ***************
 *                      * *       * *
 *                       *  MUMPS  *
 *                      * *       * *
 *                     ***************
 *                          *   *
 *                           * *
 *                            *
 *
 *   mlib.h
 *    Function prototypes, structs, and macros for FreeM
 *    binding library
 *
 *
 *   Author: John P. Willis <jpw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2020 Coherent Logic Development LLC
 *
 *   Last modified: 29 February 2020
 *
 **/
   The Star of David in module headers is a convention started by Shalom
ha-Ashkenaz, the unidentified original author of FreeMUMPS/FreeM. We
will continue to employ it in honor of his most valuable contribution to
the MUMPS community.

E.2 Variable Naming
===================

Variables should be named in all lowercase letters, and words within
them delimited by underscores, such as 'my_useful_variable'.
'PascalCase' and 'camelCase' are not to be used in this codebase under
any circumstances.

   Constants defined via the C preprocessor should be in all uppercase
letters, with words within them likewise delimited by underscores, such
as:

#define MY_USEFUL_CONSTANT 1

E.3 Indentation and General Layout
==================================

This project uses four spaces for indentation.  Tabs are not to be used
under any circumstances, and all source files must use a linefeed
character to delineate lines.  If you are working on a Windows machine,
you must take care to follow this, as Windows will use a carriage return
followed by a linefeed by default.

   This project follows a modified version of what is known as the
Stroustrup indentation style.

E.4 Brace Placement (Functions)
===============================

We use modern, ANSI-style function prototypes, with the type specifier
on the same line as the function name.  You may encounter other styles
in the code, but we are transitioning to the new style as time permits.

   Below is a correct example:

int main(int argc, char **argv, char **envp)
{

}

E.5 Brace Placement (if-for-while-do)
=====================================

The 'if' keyword should be followed by one space, then the opening paren
and conditional expression.  We also use Stroustrup-style 'else' blocks,
rather than the K&R 'cuddled' 'else':

if (x) {
...
}
else {
...
}

while (1) {
...
}

for (i = 1; i < 10; i++) {
...
}

do {
...
} while (x);

   Single-statement if blocks should be isolated to a single line:

if (x) stmt();

   not:

if(x)
    stmt();

   Notice that there is a space between 'if' and '(x)', but not between
'stmt' and '()'.  This should be followed throughout the code.

   If an 'if' block has an 'else if' or 'else', all parts of the
construct must be bracketed, even if one or more of them contain only
one statement:

if (x) {
    foo();
}
else if (y) {
    bar();
}
else {
    bas();
}

E.6 Labels and goto
===================

Labels must begin in column 1, and have two lines of vertical space
above and one beneath.

E.7 Preprocessor Conditionals
=============================

E.8 coding standards, preprocessor conditionals
===============================================

I have struggled with this, but have settled upon the standard practice
of keeping them in column 1.

E.9 Overall Program Spacing
===========================

   * Variable declarations fall immediately beneath the opening curly
     brace, and should initialize the variable right there whenever
     initialization is used.

   * One line between the last variable declaration and the first line
     of real code.

   * The 'return' statement of a function (when used as the last line of
     a function) should have one blank line above it and none below it.

   * Really long functions (those whose entire body is longer than 24
     lines) should have a comment immediately following the closing
     curly brace of the function, telling you what function the closing
     brace terminates.

E.10 The switch() Statement
===========================

We indent 'case' one level beneath 'switch()', and the code within each
'case' beneath the 'case'.  Each 'case' should have one line of vertical
whitespace above it:

switch(foo) {

    case some_const:
        foo();

        break;

    case some_other_const:
        bar();

        break;

    default:
        exit(1);

        break;
}

E.11 Comments
=============

We use C-style comments ('/* comment */') exclusively, even on
single-line comments.  C++ comments ('// comment') are not permitted.

Appendix F Conformance Clause
*****************************